前言
在上一篇文章中,我们学习了 Pod 的创建、管理与生命周期。但单独使用 kubectl run 创建的"裸 Pod"有一个致命缺陷:它不会自愈、不会扩容、也不会滚动更新。一旦节点宕机,Pod 就永远消失了。
为了解决这个问题,Kubernetes 引入了控制器(Controller)------它们通过「声明期望状态 + 持续调谐(reconcile)」的机制,让集群中的实际状态不断逼近用户期望的状态。这种"声明式 API + 控制循环"正是 Kubernetes 的核心设计哲学。
本文将依次讲解常用的五种控制器:ReplicaSet、Deployment、DaemonSet、Job、CronJob,并重点剖析 Deployment 的滚动更新策略。
实验环境与上一篇一致 :k8s-master / k8s-node1 / k8s-node2 三节点集群,镜像仓库
reg.timinglee.org。

五大常用控制器
一、ReplicaSet 控制器
ReplicaSet(简称 RS)的职责只有一个:确保集群中始终运行指定数量的 Pod 副本。它会持续监控 Pod 数量,少了就新建、多了就删除,从而实现自愈。
1.1 创建 ReplicaSet
ReplicaSet 的 YAML 与 Pod 很像,多了一个 replicas 和 selector 字段:
# 先用 deployment 模板生成,再把 kind 改为 ReplicaSet
kubectl create deployment webcluster --image myapp:v1 --dry-run=client -o yaml > repset.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
labels:
app: webcluster
name: webcluster
spec:
replicas: 2
selector:
matchLabels:
app: webcluster
template:
metadata:
labels:
app: webcluster
spec:
containers:
- image: myapp:v1
name: myapp
kubectl apply -f repset.yml
kubectl get pods --show-labels
# NAME READY STATUS AGE LABELS
# webcluster-tbxq4 1/1 Running 6m app=webcluster
# webcluster-jna23 1/1 Running 6m app=webcluster
1.2 扩缩容测试
修改 replicas 字段即可扩缩容:
kubectl scale replicaset webcluster --replicas 4
kubectl scale replicaset webcluster --replicas 2
kubectl scale replicaset webcluster --replicas 0
也可以用 kubectl edit 或修改 YAML 的 replicas 后 apply。
⚠️ 注意:日常生产中几乎不直接使用 ReplicaSet,而是使用 Deployment------Deployment 在背后自动创建并管理 ReplicaSet,从而支持滚动更新与回滚。ReplicaSet 本身不支持版本更新历史。
二、Deployment 控制器
Deployment 是生产环境最常用的控制器,它在 ReplicaSet 之上增加了滚动更新、回滚、版本记录等能力,是无状态服务的首选。
2.1 通过 YAML 创建 Deployment
kubectl create deployment webcluster --image myapp:v1 --dry-run=client -o yaml > dep.yml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: webcluster
name: webcluster
spec:
minReadySeconds: 5 # 新 Pod 就绪后至少等待 5 秒才视为可用(用于平滑切换)
replicas: 2
selector:
matchLabels:
app: webcluster
template:
metadata:
labels:
app: webcluster
spec:
containers:
- image: myapp:v1
name: myapp
kubectl apply -f dep.yml
kubectl get pods --show-labels
kubectl get replicasets.apps # Deployment 自动创建了 ReplicaSet
# NAME DESIRED CURRENT READY AGE
# webcluster-77c87d9946 2 2 2 45s
# 暴露服务并访问
kubectl expose deployment webcluster --port 80 --target-port 80
curl 10.107.142.60
# Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
2.2 滚动升级与回滚(修改镜像)
升级:把镜像版本改成 v2 后重新 apply:
spec:
template:
spec:
containers:
- image: myapp:v2 # 升级为版本 2
name: myapp
kubectl apply -f dep.yml
curl 10.107.142.60
# Hello MyApp | Version: v2 ...
回滚:改回 v1 再 apply 即可(也可以用 kubectl rollout undo):
spec:
template:
spec:
containers:
- image: myapp:v1 # 回滚为版本 1
name: myapp
kubectl apply -f dep.yml
curl 10.107.142.60
# Hello MyApp | Version: v1 ...
💡 建议把
replicas调大(如 6)来更直观地观察滚动过程中新旧 Pod 的交替。每次修改 template 都会生成一个新的 ReplicaSet,旧 RS 会被保留以便回滚。
三、Deployment 版本更新策略与优化
3.1 查看默认更新策略
kubectl describe deployments.apps webcluster
# RollingUpdateStrategy: 25% max unavailable, 25% max surge
默认采用 RollingUpdate(滚动更新),即先启动新 Pod、再下线旧 Pod,保证服务不中断。默认允许最多 25% 的 Pod 不可用、最多超出期望值 25% 的新 Pod。
3.2 自定义滚动更新策略
spec:
minReadySeconds: 5
replicas: 6
strategy:
rollingUpdate:
maxSurge: 1 # 更新时 Pod 数量最多比期望值多 1 个
maxUnavailable: 0 # 更新时不可用 Pod 数量最多为 0(保证零中断)
template:
spec:
containers:
- image: myapp:v1
name: myapp
- maxSurge:更新过程中可超出期望副本数的最大数量(绝对值或百分比)。
- maxUnavailable:更新过程中允许不可用的最大数量(绝对值或百分比)。
maxUnavailable: 0 配合 maxSurge: 1 可实现"先起新、后删旧"的平滑发布,适合对可用性要求极高的服务。

另一种更新策略是
Recreate:先删除全部旧 Pod,再创建新 Pod,会造成短暂服务中断,适合无法多版本共存的场景。
3.3 更新暂停与恢复(金丝雀发布基础)
有时我们希望先更新一部分,观察没问题再全量。可以暂停滚动更新:
kubectl rollout pause deployment webcluster # 暂停
# 修改镜像为 v2 后 apply,此时更新不会真正推进(仅记录新期望)
kubectl apply -f dep.yml
kubectl rollout history deployment webcluster # 版本记录不会新增
kubectl rollout resume deployment webcluster # 恢复,更新真正开始
kubectl rollout history deployment webcluster
# REVISION CHANGE-CAUSE
# 8 <none>
# 9 <none>
这就是金丝雀发布(Canary)和蓝绿部署的基础思路------先小流量验证,再逐步放量。
四、DaemonSet 控制器
DaemonSet 保证集群中每个(或符合选择器条件的)节点上都运行一个 Pod 副本。典型用途:日志采集(Fluentd/Filebeat)、监控代理(node-exporter)、网络插件(CNI)、存储插件。
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app: daemonset
name: daemonset
spec:
selector:
matchLabels:
app: daemonset
template:
metadata:
labels:
app: daemonset
spec:
containers:
- image: myapp:v1
name: myapp
kubectl apply -f daemonset.yml
# 新节点加入集群后,会自动在该节点上运行 DaemonSet 指定的 Pod
实验验证:新建 node3 并
kubeadm join加入集群后,node3 上会立刻自动创建该 DaemonSet 的 Pod。也可以通过nodeSelector/affinity控制只在特定节点部署。
五、Job 控制器
Job 用于运行一次性任务,任务成功完成(容器退出码为 0)后 Pod 不会再重启,适合批处理、数据迁移、测试等场景。
kubectl create job job --image perl:5.34.0 --dry-run=client -o yaml > job.yml
apiVersion: batch/v1
kind: Job
metadata:
name: testjob
spec:
completions: 6 # 总共需要成功完成 6 次
parallelism: 2 # 最大并行运行 2 个 Pod
backoffLimit: 4 # 失败重试上限为 4 次
template:
spec:
containers:
- image: busybox
name: testjob
command: ["/bin/sh","-c"]
args:
- |
echo this is testjob message
sleep 10
restartPolicy: Never
kubectl apply -f job.yml
kubectl logs pods/testjob-4cdlr
# this is testjob message
关键字段:
completions:Job 需要成功完成的 Pod 总数。parallelism:同时运行的 Pod 上限。backoffLimit:失败重试次数上限。restartPolicy:Job 中通常为Never或OnFailure(不能用默认的Always)。
六、CronJob 控制器
CronJob 在 Job 之上增加了基于时间的调度,类似 Linux 的 crontab,用于周期性任务(如定时备份、定时报表、缓存清理)。
kubectl create cronjob cronjob --image busybox --schedule "* * * * *" --dry-run=client -o yaml > cronjob.yml
apiVersion: batch/v1
kind: CronJob
metadata:
name: cronjob
spec:
schedule: '* * * * *' # 分 时 日 月 周,这里表示每分钟执行一次
jobTemplate:
spec:
template:
spec:
containers:
- image: busybox
name: cronjob
command:
- /bin/sh
- -c
- echo "hello timinglee"
restartPolicy: OnFailure
kubectl apply -f cronjob.yml
kubectl get cronjobs.batch
# NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
# cronjob * * * * * False 0 17s 70s
kubectl logs cronjob-29598241-pxggh
# hello timinglee
调度格式为标准的 5 段 cron 表达式(
分 时 日 月 周)。也可设置startingDeadlineSeconds(错过调度的最大容忍时间)、concurrencyPolicy(并发策略:Allow/Forbid/Replace)。
总结
本文介绍了 Kubernetes 中五种最常用的控制器:
| 控制器 | 适用场景 | 核心特点 |
|---|---|---|
| ReplicaSet | 维持 Pod 副本数 | 自愈、扩缩容(通常被 Deployment 间接使用) |
| Deployment | 无状态服务 | 在 RS 之上支持滚动更新、回滚、版本管理 |
| DaemonSet | 节点级守护进程 | 每个节点运行一个副本 |
| Job | 一次性任务 | 任务完成即结束,支持并发与重试 |
| CronJob | 周期性任务 | 基于 cron 表达式定时触发 Job |
此外,官方还提供 StatefulSet (有状态服务,如数据库,提供稳定网络标识与持久存储)、HorizontalPodAutoscaler(HPA) (基于 CPU/内存等指标自动扩缩容)以及 Operator 模式(针对复杂有状态应用的扩展控制器),后续可深入学习。