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 和相关技术,构建高效、稳定的微服务系统。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐