Kubernetes 控制器与工作负载策略
本文最后更新于 2025年8月14日 上午
工作负载概述
Pod对象不具备自动故障恢复能力,而且对需要水平扩容的多副本管理也非常复杂。kubernetes通过定义管理Pod的工作负载资源来完成对于Pod的创建,调度,水平扩/缩容,故障恢复等生命周期管理的工作
RC控制器
RC独立于所控制的Pod并通过标签的松耦合关系控制目标Pod实例的创建和销毁。
ReplicaSet
ReplicaSet在RC的基础上,提供了更灵活的标签选择模式。RS可以一次性选择多个标签,并且选择多个不同的版本进行部署,如
1 | |
1 | |
特殊需求
- 不同Pod之间的亲和性, 比如MySQL数据库与Redis中间件不能被调度到同一个目标Node上,或者两个需要紧密连接的微服务Pod必须调度到同一个Node上,以实现本地文件共享或本地网络通信等需求。
- 有状态集群的调度。对于ZooKeeper,Elasticsearch,MongoDB,Kafka等有状态集群,虽然集群中的每个Node看起来都是相同的,但每个Node都必须有明确的不变的唯一身份标识
- 在每个Node上调度并且仅仅创建一个Pod副本,这种调度通常用于系统监控相关的Pod
- 批处理作业,需要创建多个Pod副本来协同工作,当这些Pod副本都完成自己的任务时,整个批处理作业就结束了。
- 控制器与Pod间是松绑定关系,如果控制Pod与控制器间的控制逻辑
Deployment
面向无状态应用的Pod副本集管理
Deployment是一种面向无状态应用的多个Pod副本进行自动化管理的工作负载控制器。无状态应用通常要求每个Pod副本的工作机制相同,提供的服务也相同。Deployment在部署Pod之后会持续监控副本的运行状况和数量,始终保证用户指定的副本数量的Pod正常运行。
配置示例
1 | |
创建deployment
1 | |
查看deployment状态
1 | |
NAME: Deployment的名称
READY: 处于Ready状态的Pod副本数量,“/” 右侧为期望的Pod副本数量,即spec.replicas字段的设置值
UP-TO-DATE: 更新到最新Pod模板的Pod副本数量
AVAILABLE: 可供用户使用的Pod副本数量
AGE: Deployment的运行时间
1 | |
NAME : ReplicaSet的名称
DESIRED: 期望的副本数量
CURRENT: 当前处于运行状态的Pod副本数量
READY: 处于Ready状态的Pod副本数量
AGE: Deployment的运行时间
查看pod运行状态
1 | |
配置信息
- selector : 标签选择器,用于关联具有指定标签的Pod列表
- template : Pod模板,其中的配置项就是Pod的定义,作为Deployment资源的一部分存在,无须在设置apiVersion 和 kind这两个元素
- replicas : 期望的Pod副本数量,默认值为1。通过kubectl scale命令调整后的副本数量将会覆盖初始设置的值。如果使用自动扩缩容来自动调整Pod副本数量,则不需要设置这个值
- strategy : 更新策略,可选项包括Recreate和RollingUpdate
- minReadySeconds : Pod最短就绪时间,达到这个时间,系统才会设置Pod为Ready状态
- progressDeadlineSeconds : 设置未能处于部署完成状态的超时时间,默认值为600s。达到这个时间之后,系统将设置Progressing的状态为False,并将Reason设置为ProgressDeadlineExceeded
- revisionHistoryLimit: 修订历史最大数量,每个修订版本都有一个对应的ReplicaSet资源,保存地过多将消耗更多资源
- paused : 设置为true来表示部署过程处于暂停状态,设置为false表示处于正常部署过程。
- matchLabels: 设置一个或多个标签的值,以key:value 格式表示,如果设置了多个标签,需要满足全部条件才能与Pod关联成功
1 | |
- matchExpressions: 设置一个或多个标签取值表达式,以(key,operation,values)三元组格式进行设置,其中values 可以设置多个值。
1 | |
Deployment的更新
配置更新过程
1 | |
查询已运行的Pod
1 | |
更新nginx的镜像版本
- 通过命令好修改
1 | |
- 使用kubectl edit 编辑deployment配置文件
1 | |
Deployment 通过创建一个新的ReplicaSet ,先扩展创建新版本的Pod ,如何将旧版本的Pod进行对应缩减,同时维持替换过程中,至少有期望副本数量-1的Pod 是可用的。
更新策略
- Recreate: 设置spec.strategy.type=Recreate表示 在更新时需要先杀死所有旧Pod在创建更新
- RollingUpdate: 设置spec.strategy.type=RollingUpdate表示 以滚动更新的方式逐个更新Pod
Deployment的回滚
回滚过程
查询回滚历史
1 | |
查询之前的版本
1 | |
回滚
1 | |
Deployment的暂停与恢复
通过kubectl rollout pause 暂停Deployment的更新操作
1 | |
使用kubectl rollout resume deploy nginx-deployment恢复更新
1 | |
期间可以对deployment进行修改而不会触发deployment的更新
Deployment的生命周期
Progressing
- 正在创建新的ReplicaSet
- 正在创建最新的ReplicaSet
- 正在为旧的RelicaSet进行水平缩容
- 新的Pod处于Ready或者Available状态
Complete
- 最新版本的ReplicaSet已部署完成
- Pod副本数量达到期望副本数量,并且都处于可用状态
- 没有旧的Pod副本还在运行
Failed
- 容器镜像下载失败
- Pod所需的资源配额一直不足
- 启动Pod所需的权限不足
- 资源限制范围LimitRange配置不正确
- Pod的服务就绪探针一直失败
- 容器应用启动一直失败
DeamonSet
DeamonSet用于管理集群中的每个Node上仅运行一个Pod副本,当新增Node或删除Node时 会自动增删Node上的副本
场景
- 在每个Node上都运行一个共享存储驱动的守护进程
- 在每个Node上都运行一个日志采集程序,采集Node上全部容器的日志
- 在每个Node上都运行一个性能监控程序,采集Node上容器和操作系统的运行性能数据
1 | |
创建DeamonSet
1 | |
配置信息
- selector: 标签选择器,用于关联具有指定标签的Pod列表
- template: Pod模板,配置项就是Pod的定义
- updateStratgy: 更新策略,可选项包括OnDelete和RollingUpdate
- minReadySecond: Pod最短就绪时间
- revisionHistoryLimit: 修订历史最大数量
更新策略
- OnDelete : 旧版本需要用户手动删除才能触发新的创建
- RollingUpdate : 旧版本自动被杀掉,然后创建新版本的Pod
回滚
与Deploy类似
StatefulSet
面向有状态应用的Pod副本管理
由StatefulSet管理的Pod 意味着每个Pod副本都应该具有唯一不变的身份标识,例如ID或者服务名称;多个Pod副本不是对等无差别的,而是相互之间可能需要通信来实现某种功能。以及需要独立的持久化存储,以及多个Pod可能需要按固定的顺序逐个启动扽业务需求
StatefulSet 提供了以下功能
- 每个Pod 都具有唯一且不变的身份标识,包括ID和网络访问地址
- 为每个Pod都配置稳定的持久化存储
- 对多个Pod提供有序的,优雅的部署和扩缩容等管理功能
- 对多个Pod提供有序的,优雅的滚动更新等管理功能
限制:
- 为每个Pod配置的持久化存储必须是PVC类型的共享存储
- 删除Pod时不会删除关联的后端存储,主要考虑的是容器应用的数据通常都具有业务价值
- 必须创建一个Headless Service,用于创建每个Pod的网络访问地址
- 删除StatefulSet资源时,系统不保证Pod终止
- 使用OrderedReady 策略滚动更新时,如果某个Pod一直无法Ready可能需要人工干预
配置信息
1 | |
- selector: 标签选择器,用于关联具有指定标签的Pod列表
- template: Pod模板,配置项就是Pod的定义
- updateStratgy: 更新策略,可选项包括OnDelete和RollingUpdate
- minReadySeconds: Pod最短就绪时间
- podManagementPolicy: Pod管理策略
- OrderedReady 按顺序创建
- Parallel 并行创建
- volumeClaimTemplates: 后端存储的PVC模板
- serviceName : 关联的无头服务名称
- replicas : Pod副本数量
- persistentVolumeClaimRetentionPolicy: PVC存储的保留策略
- ordinals.start: Pod名称的起始序号
创建Pod唯一稳定的网络访问地址
查看Headless Service信息,可以看到服务后端Endpoints列表中包含了每个Pod的IP地址
1 | |
StatefulSet会将 无头服务名与Pod名组合成服务访问地址,以DNS域名的格式进行表示
结构类似为 <pod-name>.<service-name>.<namespace>.svc.<clusterDomain>
后端存储
StatefulSet会为每个Pod 创建一个PVC,当发生故障时,之重新创建Pod,再将之前的PVC挂载给新的Pod
删除机制
默认情况下 StatefulSet控制器管理的Pod 会全部删除,而使用非级联模式,可以不影响Pod的情况下进行删除 kubectl delete statefulset web —cascade=orphan=true
水平 扩容/缩容
- 扩容
1 | |
- 缩容
1 | |
更新策略
- 策略为OnDelete时, 需要用户手动触发删除后,自动触发创建
- 策略为RollingUpdate时,删除所有创建的Pod对象,再依次创建新的对象
- 通过设置spec.update.Strategy.rollingUpdate.partition ,可以进行分区更新,只对大于partition的Pods进行更新
Pod管理策略
- OrderedReady: 扩容时按照顺序管理Pod的创建和扩/缩容操作
- Parallel: 表示可以并行创建或删除所有Pod
PVC保存策略
- whenDeleted: 设置删除Statefulset时的存储保留策略
- whenScaled: 设置缩容时的保留策略
子策略
- Retain: 保留数据,不执行自动删除操作
- Delete: 自动删除Pod关联的PVC
1 | |
Job批处理任务
配置信息
1 | |
- template: Pod模板,其中的配置项是Pod的定义
- selector: 默认情况下,不需要特别设置标签选择器
- restartPolicy: Pod重启策略,可选项保活Never和OnFailure,不能被设置为Always
- parallelism: 可以并行运行的任务数量
- completions和completionMode: 用于设置成功完成的Pod数量,默认为1
- backoffLimit: 设置失败任务的重试上限
- podFailurePolicy: 失效特性
- podReplacementPolicy: 替换策略
Job处理机制
单个一次性任务
通常一个Job只启动一个Pod,除非Pod异常,才会重启该Pod
有指定数量的并行任务
同时控制多个Job来执行任务
带工作队列的并行任务
一个Pod处理一个工作队列
这种情况,需要Job从外部拉取任务队列中的工作项,将每个工作项打包定义为Worker Pod,Worker Pod的逻辑是从队列中拉去一个工作项并处理,完成后结束
Pod数量可变的队列
这种情况,Job不确定队列中工作项的具体数目,由多个Pod对任务项进行处理,当所有工作项处理完成后,Job结束
静态任务分派且带索引的Job
Pod之间需要通信的Job
Job模板扩展
CronJob 定时任务
配置信息
1 | |
- metadata.name:CronJob 名称,必须在命名空间内唯一。
- schedule:Cron 表达式,定义任务运行的时间,这里是 “*/1 * * * *” 表示每分钟执行一次。
- jobTemplate:任务模板,定义每次调度时要运行的 Job 规范。
- startingDeadlineSeconds:可选,单位秒。表示如果某次任务错过了调度时间(例如因集群不可用),在调度时间之后的这段时间内仍然允许启动任务。超过这个时间则放弃本次任务。
- concurrencyPolicy:可选,定义同一 CronJob 多个任务实例的并发策略。可选值有:
- Allow(默认):允许并发运行多个任务实例。
- Forbid:禁止并发运行,如果上一个任务还在运行,则跳过新任务。
- Replace:如果上一个任务还在运行,则先终止它,再启动新的任务。
- suspend:可选,布尔值。设置为 true 时暂停 CronJob 的调度,不会创建新的 Job;已有的 Job 不受影响。
- successfulJobsHistoryLimit:可选,整数。保留的已成功完成的 Job 数量,超过这个数量的旧 Job 会被自动清理。
- failedJobsHistoryLimit:可选,整数。保留的已失败的 Job 数量,超过这个数量的旧 Job 会被自动清理。
- timeZone:可选,指定 Cron 表达式解析使用的时区。例如 “Asia/Shanghai”。如果不指定,默认使用 kube-controller-manager 的时区(通常是 UTC)。