kubernetes核心技术-Controller

kubernetes核心技术-Controller
墨颜丶什么是Controller
集群的智能管家
Controller是Kubernetes的核心控制回路,通过持续监控集群状态并驱动实际状态向期望状态收敛。它解决了分布式系统中的状态维护难题,确保应用在节点故障、资源波动等情况下保持稳定运行。
典型案例:当Node节点意外宕机时,ReplicaSet Controller会立即检测到Pod缺失,并在健康节点上重新创建Pod,整个过程通常在10-30秒内完成。
Kubernetes Controller 类型对比
Controller类型 | 核心用途 | Pod标识 | 部署顺序 | 存储卷 | 伸缩特性 | 典型应用场景 |
---|---|---|---|---|---|---|
Deployment | 管理无状态应用 | 随机名称 | 无序 | 无状态或共享存储 | 平滑伸缩 | Web服务、API微服务 |
StatefulSet | 管理有状态应用 | 固定名称(web-0,1,2) | 有序 | 专属持久卷(PV) | 需手动逐实例伸缩 | 数据库(MySQL/MongoDB)、消息队列 |
DaemonSet | 节点级守护进程 | 随机名称 | 无序 | 通常不需要 | 跟随节点自动伸缩 | 日志收集(Fluentd)、节点监控 |
Job | 单次任务 | 随机名称 | 无序 | 临时存储 | 不可伸缩 | 数据处理、批量计算 |
CronJob | 定时任务 | 随机名称 | 无序 | 临时存储 | 按计划执行 | 定期备份、报表生成 |
无状态应用 vs 有状态应用对比
特性 | 无状态应用 | 有状态应用 |
---|---|---|
实例关系 | 各实例完全独立 | 实例间有主从、分片等依赖关系 |
数据存储 | 不保存本地状态(状态存外部DB/缓存) | 需持久化存储本地状态(数据库文件/消息队列数据) |
请求处理 | 请求可被任意实例处理 | 特定请求需路由到特定实例(如分片查询) |
伸缩特性 | 秒级快速伸缩 | 需谨慎操作(如主从切换/数据迁移) |
故障恢复 | 新实例自动接管工作 | 需恢复特定数据/状态 |
网络标识 | 无需固定网络地址 | 需稳定网络标识(如集群节点发现) |
部署方式 | Deployment + Service | StatefulSet + Headless Service |
存储需求 | 临时存储或共享存储 | 持久化专属存储(PV/PVC) |
配置管理 | ConfigMap/环境变量注入 | 需实例级差异化配置 |
升级策略 | 滚动更新(一次性替换所有实例) | 需按序更新(如先备后主) |
典型代表 | Nginx、Node.js应用、无状态微服务 | MySQL集群、Redis集群、Zookeeper集群 |
扩缩容速度 | <5秒 | 分钟级(需数据同步/验证) |
服务发现 | 通过Service负载均衡 | 通过Headless Service获取所有节点DNS |
数据一致性 | 不涉及 | 需保证(如使用RAFT共识算法) |
K8s资源对象 | Deployment + Service + HPA | StatefulSet + Headless Service + PVC |
关键对比说明:
Controller选择决策树
graph TD A[需要运行什么?] A --> B{是否需持久化状态?} B -->|是| C[StatefulSet] B -->|否| D{是否节点级部署?} D -->|是| E[DaemonSet] D -->|否| F{是否临时任务?} F -->|单次任务| G[Job] F -->|定时任务| H[CronJob] F -->|长期运行| I[Deployment]
有状态应用特殊需求
- 唯一网络标识稳定性:
1 | # StatefulSet Pod固定命名规则 |
- 存储拓扑:
1 | volumeClaimTemplates: |
混合架构案例
电商平台架构:
组件 | 类型 | Controller | 说明 |
---|---|---|---|
商品搜索 | 无状态 | Deployment | 3副本自动伸缩 |
订单服务 | 无状态 | Deployment | 基于CPU的HPA |
Redis缓存 | 有状态 | StatefulSet | 主从架构+持久化 |
日志收集 | 节点级 | DaemonSet | 每个节点部署Fluentd |
每日销售报表 | 定时任务 | CronJob | 每天02:00运行 |
Controller与Pod的协同关系
特性 | 独立Pod | Controller管理的Pod |
---|---|---|
生命周期 | 随节点销毁永久丢失 | 自动重建保障持续运行 |
扩缩容 | 需手动操作 | 支持声明式伸缩(如kubectl scale) |
更新策略 | 无滚动更新能力 | 支持蓝绿/金丝雀等高级策略 |
自愈能力 | 依赖外部监控 | 内置健康检查与自动恢复 |
Controller和Pod是通过label标签建立关系的
Deployment控制器核心应用场景
无状态应用管理(如Web服务)
- 滚动更新:分批次替换Pod实现零停机升级
- 版本回滚:一键回退到历史稳定版本
- 副本维持:确保指定数量的Pod始终运行
发布策略实施
1
2
3
4
5strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25% # 最大激增Pod数
maxUnavailable: 20% # 最大不可用比例某金融APP采用此配置,将版本更新耗时从1小时缩短至8分钟,错误率下降90%。
Deployment YAML关键字段解析
快速生成模板进行修改
这条命令不会在 Kubernetes 集群中真正创建任何资源,而是生成一个 基于默认配置的 Deployment YAML 文件,并将其保存到本地磁盘上的 nginx-deployment.yaml
文件中。
1 | kubectl create deployment nginx-web --image=nginx --dry-run -o yaml > nginx-deployment.yaml |
命令详解
部分 | 含义 |
---|---|
kubectl | Kubernetes 的命令行工具,用于与集群交互。 |
create deployment | 创建一个 Deployment 资源对象。Deployment 是 Kubernetes 中最常用的控制器之一,用于管理无状态应用的副本数量、滚动更新等。 |
nginx-web | 指定要创建的 Deployment 名称为 nginx-web 。 |
--image=nginx | 设置容器使用的镜像为 nginx (默认是 nginx:latest )。 |
--dry-run | 表示“只模拟执行”,不真正提交到集群中运行。仅输出将要创建的资源定义。 |
-o yaml | 输出格式为 YAML 格式。 |
> nginx-deployment.yaml | 将命令输出重定向写入到文件 nginx-deployment.yaml 中。 |
推荐扩展用法
- 添加资源限制(resources)
1 | # 指定使用的 API 版本为 apps/v1,这是 Kubernetes 中用于部署无状态应用的标准 API。 |
- 添加健康检查探针(liveness/readiness probe)
1 | livenessProbe: # 定义存活探针(liveness probe),用于判断容器是否健康并决定是否重启容器。 |
- 设置滚动更新策略
1 | strategy: # 定义 Deployment 的更新策略,控制滚动更新的行为。 |
Deployment控制器部署应用
创建部署配置文件
保存以下内容为nginx-deployment.yaml
:
1 | apiVersion: apps/v1 |
使用yaml部署应用
1 | kubectl apply -f nginx-deployment.yaml |
kubectl apply
:这是一个用于从文件或标准输入(stdin)中应用配置变更的命令。它会创建或更新资源。-f nginx-deployment.yaml
:指定要应用的 YAML 文件。在这个例子中,该文件名为nginx-deployment.yaml
,通常包含了 Deployment 或其他 Kubernetes 对象的定义。watch
:这是一个 Linux 命令行工具,它可以定期运行指定的命令,并全屏显示输出结果。默认情况下,每 2 秒执行一次命令。kubectl get pods
:这是用来列出当前命名空间下的所有 Pods 的命令。
1 | kubectl get pods -l app=nginx |
预期输出:
1 | NAME READY UP-TO-DATE AVAILABLE AGE |
对外暴露服务
1 | kubectl expose deployment nginx-web \ |
命令解释
kubectl expose deployment nginx-web
: 这一部分表示基于名为nginx-web
的 Deployment 来创建一个新的服务。Kubernetes 会自动将服务关联到与指定 Deployment 相同的标签选择器上。--port=80
: 指定服务监听的端口为 80。这意味着外部流量可以通过这个端口访问服务。--type=NodePort
: 设置服务类型为 NodePort。这使得服务可以通过集群中每个节点的 IP 和静态端口(NodePort)从外部访问。Kubernetes 将在每个节点上预留一个端口(通常范围在 30000-32767之间)并将其转发到--target-port
指定的服务端口。--target-port=80
: 表示请求将会被转发到后端 Pod 的 80 端口上。--name=nginx-service
: 给创建的服务命名为nginx-service
。--dry-run=client
: 使用dry-run
选项可以模拟执行这条命令的效果而不真正应用它。这对于验证命令的有效性和查看将要发生的更改非常有用。client
表示不会发送任何请求到服务器端。-o yaml
: 指定输出格式为 YAML。当与--dry-run=client
结合使用时,命令会输出对象的 YAML 定义而不是实际创建资源。> nginx-service.yaml
: 最后,通过标准输出重定向符号>
将上述命令的输出(即服务的 YAML 定义)保存到当前目录下的nginx-service.yaml
文件中。
这样,你就得到了一个描述 Kubernetes 服务的 YAML 文件,可以在后续步骤中手动编辑或直接使用 kubectl apply -f nginx-service.yaml
命令来创建服务。
nginx-service.yaml
内容如下:
1 | apiVersion: v1 |
部署服务
1 | kubectl apply -f nginx-service.yaml |
验证服务暴露
1 | kubectl get svc nginx-service |
预期输出:
1 | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE |
访问地址:
http://<NodeIP>:31533
(将NodeIP替换为集群节点任意实际IP)
升级回滚
滚动更新镜像版本
请深刻理解滚动这个词,生成一个新的版本的同时删除一个旧的版本,依此所有都替换成新的镜像版本。
1 | kubectl set image deployment/nginx-web nginx=nginx:1.24.0 |
这条命令的作用是:
- 更新名为
nginx-web
的 Deployment 中的一个容器。 - 容器名是
nginx
(在 Pod 模板的spec.containers.name
字段中定义)。 - 将该容器使用的镜像从原来的版本(比如
nginx:latest
或其他)更新为指定版本:nginx:1.24.0
。
部分 | 说明 |
---|---|
kubectl | Kubernetes 的命令行客户端,用于与集群交互。 |
set image | 子命令,用于更新资源中容器的镜像。 |
deployment/nginx-web | 指定要操作的 Deployment 名称为 nginx-web 。 |
nginx=nginx:1.24.0 | 表示将名为 nginx 的容器的镜像更新为 nginx:1.24.0 版本。 |
1 | # kubectl get pods 示例 生成一个新的版本的同时删除一个旧的版本,依此所有都替换成新的镜像版本 |
1 | # 监控更新过程 |
版本回滚操作
1 | kubectl rollout history deployment/nginx-web # 查看发布历史 |
kubectl rollout history
:用于查看某个 Deployment 的滚动更新历史记录。deployment/nginx-web
:指定要查看的是名为nginx-web
的 Deployment。kubectl rollout undo
:用于将 Deployment 回滚到上一个版本或指定版本。--to-revision=2
:明确指定要回滚到第 2 个版本(revision 2)。
微软Azure实践数据:通过标准化Deployment流程,其容器服务部署失败率降低62%,平均恢复时间(MTTR)从45分钟缩短至4分钟。
弹性伸缩
1. 手动伸缩
1 | # 扩展至5个副本 |
部分 | 含义 |
---|---|
kubectl | Kubernetes 的命令行工具,用于与集群交互。 |
scale | 子命令,表示要对资源进行伸缩操作(即修改副本数量)。 |
deployment | 表示要伸缩的资源类型是 Deployment 控制器。 |
nginx-web | 要伸缩的具体 Deployment 名称。 |
--replicas=5 | 设置目标副本数为 5,即让 Kubernetes 将运行中的 Pod 数量调整为 5 个。 |
2. 自动伸缩(HPA)
在 Kubernetes (k8s) 中,实现自动扩缩容(auto-scaling)通常涉及到 Horizontal Pod Autoscaler (HPA)。HPA 可以根据观察到的 CPU 利用率、内存使用量或其他自定义指标自动调整副本的数量。下面是配置 HPA 实现自动扩缩容的基本步骤:
1. 前提条件
- Metrics Server: Kubernetes 集群需要部署 Metrics Server 来收集资源使用情况。
- 资源请求和限制: 对于每个容器,你应当定义 CPU 和/或内存的请求和限制。
2. 配置步骤
确保你的集群中已经安装了 Metrics Server。可以通过以下命令检查是否运行:
1 | # 检查安装与否 |
3. 配置 Horizontal Pod Autoscaler
首先,你需要有一个部署(Deployment),它将作为自动扩缩的目标。
接下来,为你的部署配置 HPA。例如,基于 CPU 使用率设置最小 2 个副本,最大 10 个副本,目标 CPU 使用率为 60%:
1 | kubectl autoscale deployment nginx-web --cpu-percent=60 --min=2 --max=10 |
或者通过 YAML 文件配置,保存为 nginx-hpa.yaml
:
1 | # 指定使用的 API 版本为 autoscaling/v2,这是 Kubernetes 中用于配置自动伸缩的标准 API。 |
应用该yaml配置:
1 | kubectl apply -f nginx-hpa.yaml |
4. 验证命令:
1 | kubectl get hpa |
5. 定时伸缩(CronHPA)
适用于预知流量峰值的场景(如每日9:00-18:00扩展至10副本)
图:Nginx在Kubernetes中的典型部署架构
graph TD A[用户] --> B(NodePort Service) B --> C[Pod 1] B --> D[Pod 2] B --> E[Pod 3] C --> F[nginx:1.23.1] D --> G[nginx:1.23.1] E --> H[nginx:1.23.1] I[Deployment] --> C I --> D I --> E J[HPA] --> I
其他常用Controller类型
- StatefulSet:管理有状态应用(如数据库)
- 稳定网络标识(PodName-0, PodName-1)
- 有序部署/伸缩(如MySQL主从架构)
- DaemonSet:节点级部署(如日志收集器)
- 每个Node运行一个Pod实例
- 典型应用:Fluentd日志代理
- Job/CronJob:任务调度系统
- 批处理作业(如每日报表生成)
- 定时任务(Cron表达式控制)