32、Kubernetes 集群管理与微服务部署指南
本文详细介绍了在本地使用Minikube管理Kubernetes集群的方法,包括集群的休眠、恢复与删除。深入讲解了Kubernetes核心组件及其在微服务架构中的应用,演示了如何用Kubernetes内置服务替代Netflix Eureka实现服务发现。结合Spring Boot的优雅关闭和健康探针功能,提升微服务稳定性。引入Helm作为包管理工具,通过图表化方式简化部署流程,并提供了完整的微服务
Kubernetes 集群管理与微服务部署指南
1. 本地 Kubernetes 集群管理
运行中的 Kubernetes 集群会消耗大量资源,主要是内存。因此,当我们使用 Minikube 中的 Kubernetes 集群完成工作后,需要将其休眠以释放分配的资源,同时要知道如何在需要继续工作时恢复集群,以及在不再需要时永久删除集群。
1.1 休眠和恢复 Kubernetes 集群
- 休眠集群 :使用
minikube stop命令可以休眠(即停止)Kubernetes 集群。
minikube stop
- 恢复集群 :使用
minikube start命令可以恢复(即启动)Kubernetes 集群。
minikube start
在重启集群后直接运行 kubectl 命令可能会出现错误消息,例如:
E0428 09:44:16.333361 79175 memcache.go:106] couldn't get
resource list for metrics.k8s.io/v1beta1: the server is
currently unable to handle the request
这是因为 metrics-server 启动有点慢,短时间后错误消息会消失。
当恢复现有集群时, start 命令会忽略创建集群时使用的开关。恢复 Kubernetes 集群后, kubectl 上下文将更新为使用该集群,当前使用的命名空间设置为 default 。如果要使用其他命名空间,可以使用以下命令更新 kubectl 上下文:
kubectl config set-context $(kubectl config current-context) --namespace=hands-on
后续的 kubectl 命令将在适用时应用于 hands-on 命名空间。
Minikube 还提供了比 stop 和 start 命令更轻量级、更快的替代方案: pause 和 unpause 命令。在这种情况下,控制平面中的组件会被暂停而不是停止,将集群的 CPU 消耗降至最低。但在最近的使用中,这些命令出现过问题,因此建议使用 start 和 stop 命令。
1.2 终止 Kubernetes 集群
如果以后要终止 Kubernetes 集群,可以运行以下命令:
minikube delete --profile handson-spring-boot-cloud
实际上可以在不指定配置文件的情况下运行 delete 命令,但明确指定配置文件更安全,否则可能会意外删除错误的 Kubernetes 集群。
1.3 管理流程总结
| 操作 | 命令 | 说明 |
|---|---|---|
| 休眠集群 | minikube stop |
释放集群占用的资源 |
| 恢复集群 | minikube start |
继续使用集群 |
| 终止集群 | minikube delete --profile handson-spring-boot-cloud |
永久删除集群 |
2. Kubernetes 简介
Kubernetes 是一个容器编排器,使用它可以将服务器集群作为一个大的逻辑服务器来运行容器。我们为 Kubernetes 集群声明一个期望状态,它会确保实际状态始终与期望状态相同,前提是集群中有足够的硬件资源。
2.1 核心组件
- API 服务器 :通过创建资源来声明期望状态。
- 控制器管理器 :对 API 服务器创建的各种资源做出反应,并采取行动确保当前状态符合新的期望状态。
- 调度器 :为新创建的容器(即包含一个或多个容器的 Pod)分配节点。
- kubelet :在每个节点上运行,确保调度到该节点的 Pod 正常运行。
- kube - proxy :作为网络代理,通过将发送到服务的请求转发到集群中的可用 Pod 来实现服务抽象。
2.2 外部请求处理方式
- Kubernetes 感知的负载均衡器 :为服务提供公共 IP 地址和/或 DNS 名称。
- 节点端口 :在集群的所有节点上可用。
- Ingress 资源 :专门用于处理外部请求。
2.3 本地单节点集群实践
使用 Minikube 创建本地单节点集群,该集群使用 Docker 驱动作为 Docker 容器运行。可以使用 minikube start 命令的 --ports 选项使端口在 Docker 引擎外部可用。使用 kubectl 工具部署基于 NGINX 的简单 Web 服务器,测试其弹性能力,手动扩展 Pod 数量,并创建具有节点端口的服务,验证可以从外部和集群内部访问该服务。
3. 用 Kubernetes 服务替换 Netflix Eureka
Kubernetes 自带基于 Kubernetes 服务对象和 kube - proxy 运行时组件的内置发现服务,因此无需部署像 Netflix Eureka 这样的单独发现服务。
3.1 优缺点分析
| 优点 | 缺点 |
|---|---|
| 不需要像 Spring Cloud LoadBalancer 这样的客户端库,易于使用,独立于微服务所基于的语言或框架 | 仅在 Kubernetes 环境中工作 |
3.2 代码和配置更改
为了用 Kubernetes 中的内置发现服务替换基于 Netflix Eureka 的发现服务器,需要对构建和配置文件进行一些更改,Java 源代码除了部分测试类外无需更改。具体更改如下:
- 从配置仓库 config - repo 中移除 Netflix Eureka 和 Spring Cloud LoadBalancer 特定的配置(客户端和服务器)。
- 从 config - repo/gateway.yml 文件中移除网关服务到 Eureka 服务器的路由规则。
- 移除 spring - cloud/eureka - server 文件夹中的 Eureka 服务器项目。
- 从 Docker Compose 文件和 settings.gradle Gradle 文件中移除 Eureka 服务器。
- 从所有 Eureka 客户端构建文件 build.gradle 中移除对 spring - cloud - starter - netflix - eureka - client 的依赖。
- 从所有前 Eureka 客户端的集成测试中移除属性设置 eureka.client.enabled=false 。
- 网关服务不再使用基于 Spring Cloud LoadBalancer 中客户端负载均衡器的路由,例如,将 config - repo/gateway.yml 文件中的 lb://product - composite 路由目标替换为 http://product - composite 。
- 将微服务和授权服务器使用的 HTTP 端口从 8080(授权服务器为 9999)更改为默认 HTTP 端口 80。
spring.config.activate.on - profile:
docker
server.port:
80
移除 Netflix Eureka 后,使用 Docker Compose 仍然可以工作,因为 Docker Compose 文件中的容器名称与 Kubernetes 中使用的相应服务名称相同,这意味着微服务的 DNS 名称在两个环境中相同。但移除 Netflix Eureka 后,使用普通 Docker 和 Docker Compose 时不再有发现服务,因此微服务的扩展仅在部署到 Kubernetes 时有效。
4. 引入 Kubernetes 对象
为了将微服务和它们依赖的资源管理器(如数据库和队列管理器)部署到 Kubernetes,将使用以下 Kubernetes 对象:
- Deployment 对象 :为每个要部署的微服务、数据库和队列管理器创建一个 Deployment 对象。
- Service 对象 :除了名为 gateway 的边缘服务器外,其他组件的 Service 对象类型为 ClusterIP ; gateway 的 Service 对象类型为 NodePort ,接受端口 30433 上的外部 HTTPS 请求。
- ConfigMap :配置服务器使用 ConfigMap 包含 config - repo 中的配置文件。
- Secrets :创建两个 Secrets,一个用于配置服务器,一个用于其客户端,以保存配置服务器及其客户端的凭据。
4.1 部署对象关系图
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(微服务):::process --> B(Deployment):::process
C(数据库):::process --> B
D(队列管理器):::process --> B
B --> E(Service):::process
F(Config Server):::process --> G(ConfigMap):::process
F --> H(Secret for Config Server):::process
I(Client):::process --> J(Secret for Client):::process
E --> |ClusterIP| K(Internal Access):::process
E --> |NodePort| L(External Access):::process
5. 使用 Spring Boot 支持进行部署
Spring Boot v2.3 增加了一些有用的功能来支持部署到 Kubernetes。
5.1 优雅关闭
在滚动升级等场景中,当需要停止微服务实例时,可能会影响正在处理的请求。为了降低这种风险,Spring Boot 增加了对优雅关闭的支持。当应用优雅关闭时,微服务停止接受新请求,并等待可配置的时间让活动请求完成,然后再关闭应用。超过关闭等待时间仍未完成的请求将被中止。
在 config - repo 文件夹的公共文件 application.yml 中添加以下内容,为所有微服务启用 10 秒的等待时间进行优雅关闭:
server.shutdown:
graceful
spring.lifecycle.timeout - per - shutdown - phase:
10s
更多信息请参考:https://docs.spring.io/spring - boot/docs/3.0.4/reference/htmlsingle/#features.graceful - shutdown
5.2 活性和就绪性探针
正确实现活性和就绪性探针对于 Kubernetes 管理 Pod 至关重要。活性探针告诉 Kubernetes 是否需要替换 Pod,就绪性探针告诉 Kubernetes Pod 是否准备好接受请求。Spring Boot 增加了对实现活性和就绪性探针的支持,探针分别通过 /actuator/health/liveness 和 /actuator/health/readiness URL 暴露。
在 config - repo 文件夹的公共文件 application.yml 中使用以下配置声明探针:
management.endpoint.health.probes.enabled:
true
management.endpoint.health.group.readiness.include:
readinessState, rabbit,
db,
mongo
第一行配置启用活性和就绪性探针,第二行声明就绪性探针将包括 RabbitMQ、MongoDB 和 SQL 数据库(如果可用)的健康指标。对于活性探针,在本章范围内,只要 Spring Boot 应用程序正常运行,报告为 UP 即可。
更多信息请参考:https://docs.spring.io/spring - boot/docs/3.0.4/reference/htmlsingle/#actuator.endpoints.kubernetes - probes
6. 引入 Helm
部署微服务到 Kubernetes 需要编写声明 Deployment 对象和 Service 对象期望状态的清单文件,如果还需要为微服务添加一些配置,还必须添加 ConfigMap 和 Secret 的清单文件。虽然声明期望状态并让 Kubernetes 确保实际状态尽可能接近期望状态的方法很有用,但编写和维护这些清单文件会带来很大的维护开销。
6.1 Helm 简介
Helm 是一个用于 Kubernetes 的开源包管理器,带有模板语言,可以从各种 Kubernetes 对象的通用定义中提取特定于微服务或环境的设置。
6.2 图表类型和结构
- 库图表 :名为
common的可重用库图表,不包含任何可部署的定义,仅包含其他图表用于 Kubernetes 清单(如 Deployment、Service、ConfigMap 和 Secret 对象)的模板。 - 组件图表 :一组特定于微服务和资源管理器的图表,放置在
components文件夹中。 - 环境图表 :两个特定于环境的父图表,放置在
environments文件夹中,分别为dev - env和prod - env,每个环境作为一个父图表,依赖于不同的子图表集,并提供特定于环境的默认值。
文件结构如下:
|-- common
| |-- Chart.yaml
| |-- templates
| |-- templates_org
| `-- values.yaml
|-- components
| |-- auth - server
| |-- config - server
| |-- gateway
| |-- mongodb
| |-- mysql
| |-- product
| |-- product - composite
| |-- rabbitmq
| |-- recommendation
| |-- review
| `-- zipkin - server
`-- environments
|-- dev - env
`-- prod - env
6.3 图表关系图
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(Common Library Chart):::process --> B(Component Chart 1):::process
A --> C(Component Chart 2):::process
D(Dev - Env Parent Chart):::process --> B
D --> C
E(Prod - Env Parent Chart):::process --> B
E --> C
B --> F(Deployment):::process
B --> G(Service):::process
B --> H(ConfigMap):::process
B --> I(Secret):::process
在学习如何构建图表之前,我们需要先了解最常用的 Helm 命令以及如何运行它们。通过以上内容,我们已经了解了如何管理本地 Kubernetes 集群、用 Kubernetes 服务替换 Netflix Eureka、使用 Spring Boot 支持进行部署以及引入 Helm 进行微服务打包和配置,为后续在 Kubernetes 中部署微服务系统奠定了基础。
7. 常用 Helm 命令
Helm 提供了一系列命令来帮助我们管理和部署 Kubernetes 应用。以下是一些常用的 Helm 命令及其使用说明:
7.1 安装 Chart
使用 helm install 命令可以将 Chart 安装到 Kubernetes 集群中。
helm install <release-name> <chart-path>
<release-name>:为本次安装指定一个唯一的名称,方便后续管理。<chart-path>:Chart 的路径,可以是本地路径,也可以是远程仓库的路径。
7.2 查看 Release 状态
使用 helm status 命令可以查看已安装 Release 的状态。
helm status <release-name>
7.3 升级 Release
使用 helm upgrade 命令可以对已安装的 Release 进行升级。
helm upgrade <release-name> <chart-path>
7.4 回滚 Release
如果升级出现问题,可以使用 helm rollback 命令将 Release 回滚到上一个版本。
helm rollback <release-name> <revision-number>
<revision-number>:要回滚到的版本号。
7.5 删除 Release
使用 helm uninstall 命令可以删除已安装的 Release。
helm uninstall <release-name>
7.6 常用 Helm 命令总结
| 命令 | 功能 | 示例 |
|---|---|---|
helm install |
安装 Chart | helm install my-release ./my-chart |
helm status |
查看 Release 状态 | helm status my-release |
helm upgrade |
升级 Release | helm upgrade my-release ./my-chart |
helm rollback |
回滚 Release | helm rollback my-release 1 |
helm uninstall |
删除 Release | helm uninstall my-release |
8. 微服务部署流程
结合前面介绍的知识,我们可以总结出在 Kubernetes 中部署微服务的一般流程:
8.1 准备工作
- 确保 Minikube 或其他 Kubernetes 集群正常运行。
- 完成代码和配置文件的修改,如用 Kubernetes 服务替换 Netflix Eureka。
- 准备好 Helm Charts,包括库图表、组件图表和环境图表。
8.2 部署微服务
- 使用 Helm 安装各个微服务和资源管理器的 Chart。
helm install <release-name> <chart-path>
- 检查部署状态,确保所有 Pod 和 Service 正常运行。
kubectl get pods,svc
8.3 测试微服务
- 使用测试脚本
test-em-all.bash验证微服务的功能。 - 从外部和集群内部访问微服务,确保服务正常响应。
8.4 管理和维护
- 根据需要休眠、恢复或终止 Kubernetes 集群。
minikube stop
minikube start
minikube delete --profile handson-spring-boot-cloud
- 使用 Helm 对微服务进行升级、回滚等操作。
8.5 微服务部署流程图
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(准备工作):::process --> B(部署微服务):::process
B --> C(测试微服务):::process
C --> D{测试是否通过?}:::process
D -->|是| E(管理和维护):::process
D -->|否| B
E --> F(休眠/恢复/终止集群):::process
E --> G(Helm 操作):::process
9. 总结与展望
通过本文的学习,我们掌握了本地 Kubernetes 集群的管理方法,包括休眠、恢复和终止集群。了解了 Kubernetes 的核心组件和工作原理,学会了用 Kubernetes 服务替换 Netflix Eureka,以及如何使用 Spring Boot 的支持进行优雅关闭和探针配置。同时,引入了 Helm 作为微服务的包管理器,简化了部署和配置的过程。
在实际应用中,我们可以根据不同的环境和需求,灵活调整 Helm Charts 的配置,实现微服务的高效部署和管理。未来,随着 Kubernetes 和微服务技术的不断发展,我们可以进一步探索更多的高级功能,如自动伸缩、服务网格等,提升系统的性能和可靠性。
9.1 关键知识点回顾
| 知识点 | 主要内容 |
|---|---|
| 本地 Kubernetes 集群管理 | 休眠、恢复和终止集群的命令及注意事项 |
| Kubernetes 核心组件 | API 服务器、控制器管理器、调度器、kubelet、kube - proxy |
| 替换 Netflix Eureka | 优缺点分析及代码和配置更改 |
| Spring Boot 支持 | 优雅关闭和活性、就绪性探针配置 |
| Helm | 包管理器,包括图表类型、结构和常用命令 |
9.2 后续探索方向
- 研究 Kubernetes 的自动伸缩功能,根据负载自动调整 Pod 数量。
- 学习服务网格技术,如 Istio,实现微服务之间的流量管理和安全控制。
- 探索 Helm 的高级用法,如自定义模板和值文件,实现更灵活的配置管理。
通过不断学习和实践,我们可以更好地利用 Kubernetes 和相关技术,构建高效、稳定的微服务系统。
更多推荐


所有评论(0)