云原生专栏大纲
文章目录
- SpringCloudk8s介绍
- spring-cloud-kubernetes
- 服务发现
- 配置管理
- 负载均衡
- 选主
- spring-cloud-bookinfo案例
- 构建项目环境
- 配置namespace
- 部署与验证
- productpage
- gateway
- bookinfo-admin
- details
- ratings
- reviews
- reviews-v1
- reviews-v2
- 总结
SpringCloudk8s介绍
https://github.com/spring-cloud/spring-cloud-kubernetes
https://spring.io/projects/spring-cloud-kubernetes
该篇讲述使用k8s作为配置注册中心,使用K8s 中 service 为我们提供了服务注册、负载均衡的能力,configmap 和 secret 为我们提供了配置管理相关的功能。
优点:不用在部署额外的注册配置中心,减轻项目依赖简化微服务应用的整体架构
缺点:本地调试不方便,需部署到k8s进行远程debug调试
spring-cloud-kubernetes
Spring Cloud Kubernetes 是 Spring Cloud 生态系统中的一个组件,旨在简化在 Kubernetes 环境中构建和部署微服务应用程序的过程。它提供了一系列功能和工具,使得基于 Spring Cloud 的微服务应用能够更好地与 Kubernetes 集成,并充分利用 Kubernetes 提供的功能和优势。
以下是 Spring Cloud Kubernetes 的一些主要功能和特点:
- 服务发现:Spring Cloud Kubernetes 与 Kubernetes 的 Service 对接,允许应用程序使用服务名来发现和调用其他微服务,而无需关注服务的具体 IP 地址和端口。这简化了微服务之间的通信。
- 配置管理:Spring Cloud Kubernetes 支持将配置信息以 ConfigMap 或 Secrets 的形式存储在 Kubernetes 中,并通过 Spring Boot 的配置属性来访问这些信息。这样可以实现配置的集中管理和动态更新,而无需重新部署应用程序。
- 负载均衡:通过与 Kubernetes 的 Service 结合,Spring Cloud Kubernetes 实现了负载均衡的功能,使得应用程序可以通过 Kubernetes Service 实现内部负载均衡,提高了应用程序的可用性和性能。
- Kubernetes 原生支持:Spring Cloud Kubernetes 提供了一些特定于 Kubernetes 的配置属性和注解,使得应用程序可以更好地与 Kubernetes 的设计原则和功能进行集成,如自动伸缩、服务发现等。
- Actuator Endpoints:Spring Cloud Kubernetes 集成了 Kubernetes 的健康检查和监控机制,通过 Actuator Endpoints 可以向 Kubernetes 提供应用程序的健康状态信息,帮助 Kubernetes 进行故障检测和恢复。
- Spring Cloud Gateway 集成:Spring Cloud Kubernetes 可以与 Spring Cloud Gateway 结合使用,实现在 Kubernetes 环境中构建 API 网关的功能,统一管理和路由微服务的请求流量。
总的来说,Spring Cloud Kubernetes 提供了一套工具和功能,帮助开发人员更轻松地将基于 Spring Cloud 的微服务应用部署到 Kubernetes 环境中,并充分利用 Kubernetes 的优势,实现更高效、可靠的微服务架构。
一键启用所有特性:
参考:https://docs.spring.io/spring-cloud-kubernetes/reference/getting-started.html
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8-all</artifactId>
</dependency>
服务发现
该项目实现了 SpringCloud 中 Discovery Client 接口,可以从 K8s 的 service 中获取 endpoint信息,实现服务注册与服务发现功能
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8</artifactId>
</dependency>
类中使用@Autowired添加@EnableDiscoveryClient并将DiscoveryClient注入ClientController:
@EnableDiscoveryClient
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(ReviewsApplication.class, args);
}
}
spring-cloud-starter-kubernetes-fabric8项目为Kubernetes提供了客户端服务发现的实现。可以从客户端按名称查询Kubernetes中的service关联的endpoint (这里需要参考K8s中服务的相关概念),客户端如果运行在K8s集群中则可以直接访问这些endpoint,还可以在此基础之上实现负载均衡。
查看 K8s 中 service 具体关联的 endpoint。
kubectl get services -A
kubectl get endpoints -A
通过 service 提供了服务发现(server side)的能力(请参阅:https://kubernetes.io/docs/concepts/services-networking/service/#discovering-services)..)使用原生的 K8s 服务发现可确保与其他工具(如Istio)的兼容性,Istio是一种能够实现负载均衡、熔断器、故障切换等功能的服务网格工具,我的同事也会在本期课程中进行展开讲解。
服务的调用方只需要引用在集群中可以解析的域名,比如kubernetes.default.svc
通常格式如下:{service-name}. {namespace}.svc. {cluster}. local
配置管理
可以从 K8s 的 ConfigMap、Secret 中动态加载应用配置,并实现 reload**
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8-config</artifactId>
</dependency>
通常我们会使用 application.yaml, application-profile.yaml 文件对Spring Boot应用进行配置,配置文件中包含了一些应用配置相关的键值对。
在K8s中我们可以直接使用ConfigMap挂载配置文件到运行的pod中,或者使用spring-cloudstarter-kubernetes-fabric8-config 将对应的配置文件加载到应用程序中,配置文件还支持reload 特性,可以在不重启情况下进行配置变更。
负载均衡
参考:https://docs.spring.io/spring-cloud-kubernetes/reference/load-balancer.html
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8-loadbalancer</artifactId>
</dependency>
该项目提供了基于 K8s service、endpoint 的负载均衡实现。
选主
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8-leader</artifactId>
</dependency>
该项目使用 K8s ConfigMap 实现了 Spring Integration 的选主 API。
在多副本需要主备切换的情况下有非常大的帮助,不用从头去实现选主功能,极大的简化了开发工作。
spring-cloud-bookinfo案例
前面我们介绍了Istio官方bookinfo案例,现在我们通过springcloud进行改造,项目参考:https://gitee.com/zhouwei1996/spring-cloud-bookinfo
整个微服务应用中包含了5个组件
- productpage 是一个由 react 开发的前端组件
- gateway 是一个由 spring-cloud-gateway 提供的 API 网关服务
- details 是一个 spring-cloud 微服务,提供了书籍详情 API
- reviews-v1 提供了基础的书籍评论信息, review-v2 在 review-v1 的基础之上额外的提供了评分数据,依赖 ratings 服务
- ratings 是一个 golang 开发的微服务组件
构建项目环境
项目为gradle项目,跟maven类似,但是没使用过的朋友会比较陌生。
- 下载gradle并配置环境变量,跟mave类似
- 验证gradle是否安装成功
- IDEA中配置gradle
- 导入项目
- 构建项目
配置namespace
- 创建namespace
- 对default serviceaccount进行授权,允许微服务组件从K8s中获取数据,实现服务发现,获取配置文件
部署与验证
productpage
- 配置App.js
- 配置server.js:配置api网关地址
- DockerFile
FROM node:12.13.0-alpine as builder
COPY / /app/builder
WORKDIR /app/builder
# 跳过 HTTPS 证书验证
RUN yarn config set "strict-ssl" false -g
RUN yarn && yarn build
FROM node:12.13.0-alpine
COPY --from=builder /app/builder/dist /app
WORKDIR /app
CMD ["node", "server.js"]
- 构建镜像并推送到远程仓库
docker login -u 账号 -p 密码 registry.cn-hangzhou.aliyuncs.com
# 进入docekrfile文件所在目录执行下述命令
docker build -t registry.cn-hangzhou.aliyuncs.com/yxymzw/productpage:latest -f ./Dockerfile ./
docker push registry.cn-hangzhou.aliyuncs.com/yxymzw/productpage:latest
- 部署指定api网关地址
API_SERVER:http://gateway.spring-cloud.svc
- svc创建
- 访问测试
gateway
是一个 spring-cloud-gateway 应用,作为后端 API 的入口
- 添加相关依赖并启用 spring-cloud-gateway
全局build.gradle
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
mavenBom "org.springframework.cloud:spring-cloud-kubernetes-dependencies:${springCloudK8sVersion}"
mavenBom "com.alibaba.cloud:spring-cloud-alibaba-dependencies:${alibabaCloudVersion}"
mavenBom SpringBootPlugin.BOM_COORDINATES
}
}
dependencies {
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
compileOnly "org.springframework.boot:spring-boot-configuration-processor"
implementation "org.springframework.boot:spring-boot-starter-actuator"
implementation "org.springframework.cloud:spring-cloud-starter"
implementation "org.springframework.cloud:spring-cloud-starter-kubernetes-fabric8-all"
implementation fileTree(dir: 'libs', includes: ['*.jar'])
}
gateway项目build.gradle
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'io.micrometer:micrometer-registry-prometheus'
}
- bootstrap.yml
spring:
cloud:
kubernetes:
reload:
enabled: true
mode: polling
period: 5000
- application.yml配置路由
将下述配置放入
server:
port: ${SERVER_PORT:8080}
spring:
application:
name: gateway
cloud:
gateway:
routes:
- id: details
uri: http://localhost:8001
predicates:
- Path=/api/v1/products/*
- id: reviews-v1
uri: http://localhost:8002
predicates:
- Path=/api/v1/products/*/reviews
- Weight=reviews, 50
- id: reviews-v2
uri: http://localhost:8005
predicates:
- Path=/api/v1/products/*/reviews
- Weight=reviews, 50
management:
endpoints:
web:
exposure:
include: "*"
- 构建镜像并推送
docker login -u 账号 -p 密码 registry.cn-hangzhou.aliyuncs.com
# 进入docekrfile文件所在目录执行下述命令
docker build -t registry.cn-hangzhou.aliyuncs.com/yxymzw/gateway:latest -f ./Dockerfile ./
docker push registry.cn-hangzhou.aliyuncs.com/yxymzw/gateway:latest
- 访问测试
/actuator/gateway/routes
修改配置字典后:
bookinfo-admin
可以借助 admin管理我们的微服务应用,需要启用discovery client 和定时任务,动态创建路由信息
Spring Boot Admin 是一个用于监控和管理 Spring Boot 应用程序的开源项目。它提供了一个用户友好的 Web 界面,可以用来查看应用程序的健康状况、性能指标、日志信息等,并可以进行一些管理操作。以下是关于 Spring Boot Admin 的一些主要特点和功能:
- 监控和健康状况:Spring Boot Admin 可以监控和展示注册的 Spring Boot 应用程序的健康状况,包括内存使用情况、线程数、请求指标等。
- 日志查看:可以在 Spring Boot Admin 界面上查看应用程序的日志信息,方便进行故障排查和监控。
- 应用程序详情:提供了应用程序的详细信息,包括依赖关系、环境变量等,帮助了解应用程序的配置和状态。
- 远程 JMX 支持:支持通过 JMX 监控远程应用程序,可以查看和管理应用程序的 MBeans。
- 事件通知:可以配置事件通知,当应用程序的健康状态发生变化时,可以发送通知邮件或其他方式提醒管理员。
- 应用程序实例管理:可以查看注册的应用程序实例,并对其进行一些管理操作,如重启应用程序、关闭应用程序等。
- 集成 Spring Boot Actuator:Spring Boot Admin 基于 Spring Boot Actuator 构建,可以展示 Actuator 提供的端点信息,如 /info、/metrics、/env 等。
- 界面友好:提供了一个直观的用户界面,展示了应用程序的各种信息,方便管理员监控和管理应用程序。
总的来说,Spring Boot Admin 提供了一个方便的管理界面,帮助管理员监控和管理多个 Spring Boot 应用程序,提高了应用程序的可观测性和管理性。
- bootstrap.yml
server:
port: ${SERVER_PORT:8080}
spring:
application:
name: spring-boot-admin
cloud:
kubernetes:
discovery:
# 用于配置是否在所有 Kubernetes 命名空间中查找服务。在这里,设置为 false 表示只在当前命名空间中查找服务。
all-namespaces: false
# 用于配置是否包括未准备就绪的地址。在这里,设置为 false 表示不包括未准备就绪的地址。
include-not-ready-addresses: false
- DockerFile
FROM java:openjdk-8-jre-alpine
MAINTAINER zw <1293780497@qq.com>
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
ADD target/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar", "--server.port=8080"]
EXPOSE 8080
- 构建镜像并推送
docker login -u 账号 -p 密码 registry.cn-hangzhou.aliyuncs.com
# 进入docekrfile文件所在目录执行下述命令
docker build -t registry.cn-hangzhou.aliyuncs.com/yxymzw/bookinfo-admin:latest -f ./Dockerfile ./
docker push registry.cn-hangzhou.aliyuncs.com/yxymzw/bookinfo-admin:latest
- 创建配置字典
server:
port: ${SERVER_PORT:8080}
spring:
application:
name: spring-boot-admin
cloud:
kubernetes:
discovery:
all-namespaces: false
include-not-ready-addresses: false
- 部署服务
- 访问测试
- 为其他服务配置路由规则
details
- bootstrap.yml
- 这个配置属性用于启用 Spring Cloud Kubernetes 功能。当设置为 true 时,应用程序将使用 Spring Cloud Kubernetes 提供的功能,如服务发现、配置管理等。
spring.cloud.kubernetes.enabled: true
- DockerFile
FROM java:openjdk-8-jre-alpine
MAINTAINER zw <1293780497@qq.com>
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
ADD target/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar", "--server.port=8080"]
EXPOSE 8080
- 构建镜像并推送
docker login -u 账号 -p 密码 registry.cn-hangzhou.aliyuncs.com
# 进入docekrfile文件所在目录执行下述命令
docker build -t registry.cn-hangzhou.aliyuncs.com/yxymzw/details:latest -f ./Dockerfile ./
docker push registry.cn-hangzhou.aliyuncs.com/yxymzw/details:latest
- 部署details
- 创建配置文件
- 创建工作负载和服务
- 打开bookinfo-admin检查服务是否正常注册
- 通过bookinfo-admin配置路由规则
- id: details
uri: http://localhost:8001
predicates:
- Path=/api/v1/products/*
- 检查规则是否生效
/api/v1/products/1
- 检查productpage中书籍详情是否正常显示
- 访问测试
- 访问页面
ratings
- DockerFile
FROM golang:1.16-alpine3.14 as builder
LABEL stage=gobuilder
ENV CGO_ENABLED 0
ENV GOPROXY https://goproxy.cn,direct
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk update --no-cache && apk add --no-cache tzdata
WORKDIR /build
ADD go.mod .
ADD go.sum .
RUN go mod download
COPY . .
RUN go build -ldflags="-s -w" -o /app/main main.go
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
ENV TZ Asia/Shanghai
WORKDIR /app
COPY --from=builder /app/main /app/main
CMD ["./main"]
- 构建镜像并推送
docker login -u 账号 -p 密码 registry.cn-hangzhou.aliyuncs.com
# 进入docekrfile文件所在目录执行下述命令
docker build -t registry.cn-hangzhou.aliyuncs.com/yxymzw/ratings:latest -f ./Dockerfile ./
docker push registry.cn-hangzhou.aliyuncs.com/yxymzw/ratings:latest
- 部署
- 配置路由规则
- id: ratings
uri: lb://ratings
predicates:
- Path=/api/v1/reviews/*/ratings
- 访问接口测试
reviews
- DockerFile
FROM java:openjdk-8-jre-alpine
MAINTAINER zw <1293780497@qq.com>
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
ADD target/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar", "--server.port=8080"]
EXPOSE 8080
- 构建镜像并推送
docker login -u 账号 -p 密码 registry.cn-hangzhou.aliyuncs.com
# 进入docekrfile文件所在目录执行下述命令
docker build -t registry.cn-hangzhou.aliyuncs.com/yxymzw/reviews:latest -f ./Dockerfile ./
docker push registry.cn-hangzhou.aliyuncs.com/yxymzw/reviews:latest
reviews-v1
reviews应用提供书籍评论相关的api,可以通过配置 开启是否开启评分
@RestController
@RequestMapping("/api/v1")
public class ReviewsController {
@Value("${ratings.enabled:false}")
boolean enableRatings;
}
创建 v21版本的 reviews 服务
- 创建配置文件:注意禁用评分功能
- 创建工作负载和服务
SPRING_PROFILES_ACTIVE=v1
- 通过 spring-boot-admin 检查服务是否正常注册
- 通 spring-boot-admin配置路由规则
- 访问接口测试
- 访问页面测试
reviews-v2
通过 spring-cloud-gateway 的 WeightRoutePredicateFactory 实现简单的灰度发布,根据不同的版本配置流量权重
创建 v2 版本的 reviews 服务
- 创建配置文件:注意启用ratings
- 创建工作负载
- 创建服务
- 通过 spring-boot-admin 检查服务是否正常注册
- 配置路由规则,v1、v2 各占一半的权重
- id: reviews-v1
uri: lb://reviews-v1
predicates:
- Path=/api/v1/products/*/reviews
- Weight=reviews, 50
- id: reviews-v2
uri: lb://reviews-v2
predicates:
- Path=/api/v1/products/*/reviews
- Weight=reviews, 50
- 打开 productpage,刷新界面,预期 review-v1/review-v2 的概率各占一半
总结
部署情况如下,跟我们使用nacos作为注册配置中心类似,需提前通过kubesphere中配置字典进行配置。但是我们更加希望自动化,通过使用CICD形式来配置,这儿就需在资源清单项目中编写ConfigMap资源文件,但是有的配置我们是不希望明文在文件中展示的,这儿就需要加密处理,参考:24.云原生ArgoCD高级之数据加密seale sealed-CSDN博客
下篇小编将通过这个案例项目实现devops+istio+安全的实践