摘要:K8s 控制器是集群工作负载的核心,用来维持 Pod 期望状态。 ReplicaSet
目录:Deployment、DaemonSet、Job、CronJob 五大常用控制器,包含 yaml 配置、命令操作、滚动更新、暂停恢复、定时任务
一、什么是 K8s 控制器
Pod 是 K8s 最小调度单元,但自主 Pod 故障退出后不会自动重建。控制器就是用来管理 Pod,持续保证集群内 Pod 维持用户定义的期望状态。控制器通过标签选择器(label selector)关联 Pod,对比期望状态与实际状态,出现差异就自动调谐修复。
常用 5 种控制器:
- ReplicaSet:维护指定副本 Pod,底层组件,不建议直接使用
- Deployment:管理无状态应用,封装 ReplicaSet,支持滚动更新、回滚、扩缩容,生产最常用
- DaemonSet:每个节点运行一份 Pod 实例,多用于日志采集、监控 agent
- Job:一次性批处理任务,保证任务成功执行完成
- CronJob:定时任务,基于 cron 表达式周期性创建 Job 执行任务
| 控制器 | 核心作用 | 典型场景 |
|---|---|---|
| ReplicaSet | 维持固定数量 Pod 副本 | Deployment 底层依赖,不单独使用 |
| Deployment | 无状态应用部署、滚动升级回滚 | Web 服务、API 后端 |
| DaemonSet | 每个节点运行一个 Pod | filebeat、node-exporter 节点代理 |
| Job | 一次性任务执行 | 数据迁移、批量处理 |
| CronJob | 周期性定时任务 | 数据库定时备份、日志清理 |
二、ReplicaSet 控制器
ReplicaSet 核心作用:保证集群中持续运行 N 个 Pod 副本;没有版本更新、回滚能力,实际生产不建议直接创建 RS,优先使用 Deployment。
1. 编写 yaml 配置 repset.yml
[root@k8s-master ~]# kubectl create deployment webcluster --image myapp:v1 --dry-run=client -o yaml > repset.yml
[root@k8s-master ~]# vim repset.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
labels:
app: webcluster
name: webcluster
spec:
replicas: 2
selector:
matchLabels:
app: webcluster
# strategy: {}
template:
metadata:
labels:
app: webcluster
spec:
containers:
- image: myapp:v1
name: myapp
2. 执行创建与监控
#应用资源
[root@k8s-master ~]# kubectl apply -f repset.yml
replicaset.apps/webcluster created
#新开终端实时观察pod标签状态
root@k8s-master ~]# watch -n 1 kubectl get pods --show-labels
Every 1.0s: kubectl get pods --show-labels k8s-master: Tue Aug 25 21:24:22 2026
NAME READY STATUS RESTARTS AGE LABELS
webcluster-fr7vk 1/1 Running 0 93s app=webcluster
webcluster-lcxxc 1/1 Running 0 93s app=webcluster
3. 副本扩缩容操作
#副本扩容到4
[root@k8s-master ~]# kubectl scale replicaset webcluster --replicas 4
replicaset.apps/webcluster scaled
Every 1.0s: kubectl get pods --show-labels k8s-master: Tue Aug 25 21:25:55 2026
NAME READY STATUS RESTARTS AGE LABELS
webcluster-bp6kz 1/1 Running 0 20s app=webcluster
webcluster-fr7vk 1/1 Running 0 3m6s app=webcluster
webcluster-glc4k 1/1 Running 0 20s app=webcluster
webcluster-lcxxc 1/1 Running 0 3m6s app=webcluster
#缩容到2
[root@k8s-master ~]# kubectl scale replicaset webcluster --replicas 0
replicaset.apps/webcluster scaled
very 1.0s: kubectl get pods --show-labels k8s-master: Tue Aug 25 21:26:42 2026
No resources found in default namespace.
修改 yaml 文件中replicas数值,再执行kubectl apply -f repset.yml同样完成副本调整。
注意:ReplicaSet 只管理副本数量,修改镜像不会触发 Pod 版本更新,这也是为什么生产环境使用 Deployment。
[root@k8s-master ~]# vim repset.yml
spec:
replicas: 4
[root@k8s-master ~]# kubectl apply -f reset.yml
replicaset.apps/webcluster configured
[root@k8s-master ~]# watch -n 1 kubectl get pods --show-labels
Every 1.0s: kubectl get pods --show-labels k8s-master: Tue Aug 25 21:31:54 2026
NAME READY STATUS RESTARTS AGE LABELS
webcluster-2l4rq 1/1 Running 0 15s app=webcluster
webcluster-6tgd2 1/1 Running 0 15s app=webcluster
webcluster-cmj2z 1/1 Running 0 15s app=webcluster
webcluster-ggtbd 1/1 Running 0 15s app=webcluster
三、Deployment 控制器
Deployment 构建在 ReplicaSet 之上,是无状态应用首选控制器。能力包含副本管理、滚动更新、版本回滚、更新暂停恢复;每一次版本变更会生成新 ReplicaSet,旧 RS 保留用于回滚。
1. 创建 Deployment dep.yml
[root@k8s-master ~]# kubectl create deployment webcluster --image myapp:v1 --dry-run=client -o yaml > dep.yml
[root@k8s-master ~]# vim dep.yml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: webcluster
name: webcluster
spec:
minReadySeconds: 5
replicas: 2
selector:
matchLabels:
app: webcluster
# strategy: {}
template:
metadata:
labels:
app: webcluster
spec:
containers:
- image: myapp:v1
name: myapp
[root@k8s-master ~]# kubectl apply -f dep.yml
deployment.apps/webcluster created
#同时监控pod和replicaset状态
[root@k8s-master ~]# watch -n 1 " kubectl get pods --show-labels;echo ====;kubectl get replicasets.apps"
Every 1.0s: kubectl get pods --show-labels;echo ====;kubectl get replicasets.apps k8s-master: Tue Aug 25 21:38:19 2026
NAME READY STATUS RESTARTS AGE LABELS
webcluster-2l4rq 1/1 Running 0 6m40s app=webcluster
webcluster-ggtbd 1/1 Running 0 6m40s app=webcluster
====
NAME DESIRED CURRENT READY AGE
webcluster 2 2 2 15m
2. 暴露 Service 访问服务
#创建service,端口80,容器端口80
[root@k8s-master ~]# kubectl expose deployment webcluster --port 80 --target-port 80
service/webcluster exposed
#查看service详情
root@k8s-master ~]# kubectl describe services webcluster
Name: webcluster
Namespace: default
Labels: app=webcluster
Annotations: <none>
Selector: app=webcluster
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.101.56.123
IPs: 10.101.56.123
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.2.14:80,10.244.2.13:80
Session Affinity: None
Internal Traffic Policy: Cluster
Events: <none>
#集群内访问
[root@k8s-master ~]# curl 10.101.56.123
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
3. 版本升级与回滚
修改 yaml 中镜像版本,执行 apply 触发滚动更新。 升级镜像为 v2:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: webcluster
name: webcluster
spec:
minReadySeconds: 5
replicas: 2
selector:
matchLabels:
app: webcluster
# strategy: {}
template:
metadata:
labels:
app: webcluster
spec:
containers:
- image: myapp:v2 #升级为版本2
name: myapp
[root@k8s-master ~]# kubectl apply -f dep.yml
deployment.apps/webcluster configured
[root@k8s-master ~]# curl 10.101.56.123
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
回滚,把镜像改回myapp:v1再次 apply 即可。
提示:除修改 yaml,也可以使用
kubectl set image deployment webcluster myapp=myapp:v2快速更新镜像。
4. 滚动更新策略配置
滚动更新两个核心参数:
maxSurge:更新期间允许超出期望副本的最大 Pod 数量,可以数字或百分比maxUnavailable:更新期间最多允许不可用 Pod 数量,数字或百分比;两者默认都是 25%Kubernetes。
修改 dep.yml 自定义更新策略:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: webcluster
name: webcluster
spec:
minReadySeconds: 5
replicas: 6
selector:
matchLabels:
app: webcluster
strategy:
rollingUpdate:
maxSurge: 1 #更新时pod数量最多比期望值多一个
maxUnavailable: 0 #不能使用pod数量比期望值数量多0
template:
metadata:
labels:
app: webcluster
spec:
containers:
- image: myapp:v1
name: myapp
[root@k8s-master ~]# kubectl apply -f dep.yml
deployment.apps/webcluster configured
#查看deployment更新策略
[root@k8s-master ~]# kubectl describe deployments.apps webcluster
RollingUpdateStrategy: 25% max unavailable, 25% max surge
5. 更新暂停与恢复
场景:多次修改配置,希望全部修改完成后再一次性执行发布。
#查看发布历史
[root@k8s-master ~]# kubectl rollout history deployment webcluster
deployment.apps/webcluster
REVISION CHANGE-CAUSE
2 <none>
3 <none>
#暂停滚动更新
[root@k8s-master ~]# kubectl rollout pause deployment webcluster
deployment.apps/webcluster paused
#修改镜像为v2,apply,此时不会执行滚动更新
[root@k8s-master ~]# vim dep.yml
containers:
- image: myapp:v2
name: myapp
[root@k8s-master ~]# kubectl apply -f dep.yml
deployment.apps/webcluster configured
#恢复更新,才真正执行版本发布
root@k8s-master ~]# kubectl rollout resume deployment webcluster
deployment.apps/webcluster resumed
[root@k8s-master ~]# kubectl rollout history deployment webcluster
deployment.apps/webcluster
REVISION CHANGE-CAUSE
3 <none>
4 <none>
四、DaemonSet 控制器
DaemonSet 特性:集群每一个节点上运行一个 Pod 副本;新增节点加入集群,会自动在新节点创建 Pod;节点删除自动清理 Pod。不设置 replicas,副本数等于匹配标签的节点数量。适合日志采集、监控代理组件。
root@k8s-master ~]# kubectl create deployment daemonset --image myapp:v1 --dry-run=client -o yaml > daemonset.yml
[root@k8s-master ~]# vim daemonset.yml
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
#另外开启一个主机node3,并设定在初始化集群时的所有设定确保所有服务的开启
#在master中重新生成集群主机注册时需要的token
[root@k8s-master ~]# kubeadm token create --print-join-command
kubeadm join 172.25.254.100:6443 --token jitysk.3uo82ejy6bt8doz3 --discovery-token-ca-cert-hash sha256:bb480a79316ad10f529e7cd4627508daca68c39e6c5a3fe1671bbdb92a9ff87a
root@k8s-master ~]# kubectl apply -f daemonset.yml
daemonset.apps/daemonset created
[root@node3 ~]# kubeadm join 172.25.254.100:6443 --token jitysk.3uo82ejy6bt8doz3 --discovery-token-ca-cert-hash sha256:bb480a79316ad10f529e7cd4627508daca68c39e6c5a3fe1671bbdb92a9ff87a --cri-socket unix:///var/run/cri-dockerd.sock
#当node3加入集群后会在node3中立即群星指定的pod,其原因是因为运行了daemonset
#查看pod,可以看到每个node节点启动一个pod
[root@k8s-master ~]# kubectl get pods -o wide
五、Job 控制器
Job 控制器用于一次性批处理任务,保证任务 Pod 成功完成。Pod 执行成功退出标记 Completed;失败则重启创建新 Pod 重试,直到任务达成目标完成数。
-
completions:需要成功完成任务总数量
-
parallelism:并发执行数量
-
backoffLimit:失败最大重试次数
-
restartPolicy:一次性任务一般配置
Never或OnFailure,不能用 Always。[root@k8s-master ~]# kubectl create job job --image perl:5.34.0 --dry-run=client -o yaml > job.yml
[root@k8s-master ~]# vim job.ymlapiVersion: batch/v1
kind: Job
metadata:
name: testjob
spec:
completions: 6
parallelism: 2
backoffLimit: 4
template:
spec:
containers:
- image: busybox
name: testjob
command: ["/bin/sh", "-c"]
args:
- |
echo this is testjob message
sleep 10
restartPolicy: Neverroot@k8s-master ~]# kubectl apply -f job.yml
job.batch/testjob created#查看job状态
[root@k8s-master ~]# kubectl get jobs
NAME STATUS COMPLETIONS DURATION AGE
testjob Running 2/6 15s 15s#查看任务pod日志
[root@k8s-master ~]# kubectl logs pods/testjob-42xrv
this is testjob message
六、CronJob 控制器
CronJob 实现定时任务,类似 Linux crontab,按照 cron 表达式定时创建 Job 对象执行任务。
root@k8s-master ~]# kubectl create cronjob cronjob --image busybox --schedule "* * * * *" --dry-run=client -o yaml > cronjob.yml
[root@k8s-master ~]# vim cronjob.yml
apiVersion: batch/v1
kind: CronJob
metadata:
name: cronjob
spec:
jobTemplate:
metadata:
name: cronjob
spec:
template:
spec:
containers:
- image: busybox
name: cronjob
command:
- /bin/sh
- -c
- echo "hello timinglee"
restartPolicy: OnFailure
schedule: '* * * * *'
root@k8s-master ~]# kubectl apply -f cronjob.yml
cronjob.batch/cronjob created
#查看cronjob资源
[root@k8s-master ~]# kubectl get cronjobs.batch
NAME SCHEDULE TIMEZONE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob * * * * * <none> False 0 <none> 5s
#查看定时任务输出日志
[root@k8s-master ~]# kubectl logs cronjob-29794455-4n26w
hello timinglee
cron 表达式格式:
分 时 日 月 周。
七、控制器总结
- ReplicaSet 只负责副本数量维护,无升级回滚,生产直接使用 Deployment;
- Deployment 面向无状态业务,底层管理 ReplicaSet,掌握滚动更新参数 maxSurge、maxUnavailable,支持暂停发布;
- DaemonSet 保证每个节点运行一份 Pod,多用于节点级代理程序;
- Job 执行一次性批任务,CronJob 定时调度 Job 执行周期任务;
- 控制器核心逻辑:对比 etcd 中期望状态与集群实际状态,不断调谐,保证业务符合预期