Kubernetes 实战笔记(二):五大 Pod 控制器详解(RS/Deployment/DaemonSet/Job/CronJob)
Kubernetes 实战笔记(二):Pod 控制器详解(ReplicaSet / Deployment / DaemonSet / Job / CronJob)
环境说明
项目 版本/参数 Kubernetes v1.35.7(kubeadm 部署) 集群拓扑 1 Master(172.25.254.100)+ 多 Node 镜像仓库 reg.timinglee.org(Harbor,library 项目) 测试镜像 myapp:v1 / myapp:v2、perl:5.34.0、busybox
Pod 自身没有自愈能力,删除就没了。控制器负责维持"期望状态":副本数不够就补,节点挂了就在别处重建,任务跑完才收工。
一、ReplicaSet 控制器
1. 建立控制器
# 用 deployment 的模板生成 RS 的 yaml(改 kind 即可)
[root@master controler]# 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
[root@master controler]# kubectl apply -f repset.yml
# 开一个新 shell 持续监控 pod 变化
[root@master ~]# watch -n 1 kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
webcluster-tbxq4 1/1 Running 0 6m49s app=webcluster
webcluster-jna23 1/1 Running 0 6m49s app=webcluster
# 命令行扩缩容
kubectl scale replicaset webcluster --replicas 4 # 扩到 4
kubectl scale replicaset webcluster --replicas 2 # 缩回 2
kubectl scale replicaset webcluster --replicas 0 # 清零
2. 测试功能:删掉一个 pod 会怎样?
修改 yml 中 replicas: 4 后 apply:
NAME READY STATUS RESTARTS AGE LABELS
webcluster-4sxz4 1/1 Running 0 13s app=webcluster
webcluster-lvtsn 1/1 Running 0 13s app=webcluster
webcluster-tbxq4 1/1 Running 0 9m23s app=webcluster
webcluster-tr5qk 1/1 Running 0 13s app=webcluster
此时手动删除任意一个 pod,RS 立刻拉起新 pod 补齐到 4 个——这就是"期望副本数"的含义。

二、Deployment 控制器
Deployment 是生产中最常用的控制器,在 ReplicaSet 之上封装了版本管理能力:每次改 Pod 模板都会生成新的 ReplicaSet,旧 RS 保留用于回滚。
1. 监控命令
同时观察 pod 和 rs 两层的变化:
[root@master ~]# watch -n 1 "kubectl get pods --show-labels;echo ====;kubectl get replicasets.apps"
2. 建立 Deployment 并发布服务
[root@master controler]# 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
[root@master controler]# kubectl apply -f dep.yml
# Deployment 创建的 pod 带 pod-template-hash 标签,且底下挂着一个 RS
Every 1.0s: kubectl get pods --show-labels;echo ====;kubectl get replicase... master: Sat Apr 11 10:43:24 2026
NAME READY STATUS RESTARTS AGE LABELS
webcluster-77c87d9946-49kh5 1/1 Running 0 45s app=webcluster,pod-template-hash=77c87d9946
webcluster-77c87d9946-m2x2d 1/1 Running 0 45s app=webcluster,pod-template-hash=77c87d9946
====
NAME DESIRED CURRENT READY AGE
webcluster-77c87d9946 2 2 2 45s
发布 ClusterIP 服务并验证负载均衡:
[root@master controler]# kubectl expose deployment webcluster --port 80 --target-port 80
service/webcluster exposed
[root@master controler]# kubectl describe services webcluster
Name: webcluster
Namespace: default
Selector: app=webcluster
Type: ClusterIP
IP: 10.107.142.60
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.2.6:80,10.244.1.9:80
[root@master controler]# curl 10.107.142.60
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
3. 升级和回滚
升级即修改 Pod 模板中的镜像版本:
# 升级 v1 → v2
containers:
- image: myapp:v2 # 改这里
name: myapp
[root@master controler]# kubectl apply -f dep.yml
deployment.apps/webcluster configured
[root@master controler]# curl 10.107.142.60
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
# 回滚 v2 → v1(把镜像改回去再 apply)
containers:
- image: myapp:v1 # 改回 v1
name: myapp
[root@master controler]# kubectl apply -f dep.yml
deployment.apps/webcluster configured
[root@master controler]# curl 10.107.142.60
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
整个过程中 Service 不变,流量无感知切换。

三、版本更新策略及优化
1. 查看默认更新策略
先把副本调到 6 个方便观察滚动过程:
[root@master controler]# kubectl describe deployments.apps webcluster
RollingUpdateStrategy: 25% max unavailable, 25% max surge
默认策略含义(replicas=6 时):更新期间最多允许 1~2 个 pod 不可用(25% 向下取整)、最多比期望值多创建 1~2 个 pod(25% 向上取整)。
2. 设定自定义更新策略
spec:
minReadySeconds: 5
replicas: 6
selector:
matchLabels:
app: webcluster
strategy:
rollingUpdate:
maxSurge: 1 # 更新时 pod 数量最多比期望值多 1 个
maxUnavailable: 0 # 不可用 pod 数量允许超出期望值 0 个(全程保住服务容量)
这组配置的效果:先建新 pod → 新 pod Ready 且稳定 5 秒 → 再杀旧 pod,任何时刻可用容量都不低于 6 个,适合不允许容量下跌的业务。
3. 更新暂停和恢复
金丝雀发布的底层机制——暂停时已提交的变更不执行,恢复时一次性生效:
# 查看历史版本
[root@master controler]# kubectl rollout history deployment webcluster
REVISION CHANGE-CAUSE
7 <none>
8 <none>
# 暂停更新
[root@master controler]# kubectl rollout pause deployment webcluster
deployment.apps/webcluster paused
# 提交新版本(apply 成功,但监控中看不到任何变化)
containers:
- image: myapp:v2
name: myapp
[root@master controler]# kubectl apply -f dep.yml
deployment.apps/webcluster configured
# 版本号没变,确认更新被挂起
[root@master controler]# kubectl rollout history deployment webcluster
REVISION CHANGE-CAUSE
7 <none>
8 <none>
# 恢复更新,一次性完成滚动
[root@master controler]# kubectl rollout resume deployment webcluster
deployment.apps/webcluster resumed
[root@master controler]# kubectl rollout history deployment webcluster
REVISION CHANGE-CAUSE
8 <none>
9 <none>
四、DaemonSet 控制器
DaemonSet 保证每个节点上有且只有一个指定 pod,新增节点自动部署、节点退出自动回收。典型场景:日志采集、监控 agent、网络插件本身。
[root@master controler]# kubectl create deployment daemonset --image myapp:v1 --dry-run=client -o yaml > 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
[root@master controler]# kubectl apply -f daemonset.yml
验证"新节点加入即自动部署":
# 准备一台新机器 node3,完成初始化集群时的所有设定并确保服务开启
# master 上重新生成注册 token
[root@master controler]# kubeadm token create --print-join-command
kubeadm join 172.25.254.100:6443 --token lqcz14.xxxxxxxx --discovery-token-ca-cert-hash sha256:6b59...
# node3 加入集群
[root@node3 ~]# kubeadm join 172.25.254.100:6443 --token lqcz14.xxxxxxxx \
--discovery-token-ca-cert-hash sha256:6b59... \
--cri-socket unix:///var/run/cri-dockerd.sock
# node3 一加入集群,DaemonSet 立即在它上面拉起 pod —— 无需任何手动操作

五、Job 控制器
前面的控制器都追求"一直活着",Job 相反:把任务跑完就结束。适用于一次性批处理任务。restartPolicy 必须设为 OnFailure 或 Never。
# 准备 perl 镜像推入仓库
[root@master ~]# docker load -i perl-5.34.tar.gz
[root@master ~]# docker tag perl:5.34.0 reg.timinglee.org/library/perl:5.34.0
[root@master ~]# docker login reg.timinglee.org -u admin
Password:
Login Succeeded
[root@master ~]# docker push reg.timinglee.org/library/perl:5.34.0
[root@master controler]# 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 # Job 场景必须显式声明
[root@master controler]# kubectl apply -f job.yml
# 查看某个已完成 pod 的输出
[root@master ~]# kubectl logs pods/testjob-4cdlr
this is testjob message
三个参数的协作逻辑:并发度 2 × 轮次 = 依次跑满 6 次 completions;单个 pod 失败计入 backoffLimit 重试。

六、Cronjob 控制器
CronJob 在 Job 之上加了定时调度,schedule 字段与 Linux crontab 语法完全一致:分 时 日 月 周。
[root@master controler]# kubectl create cronjob cronjob --image busybox --schedule "* * * * *" --dry-run=client -o yaml > cronjob.yml
apiVersion: batch/v1
kind: CronJob
metadata:
name: cronjob
spec:
jobTemplate: # 内嵌的就是一个 Job 模板
metadata:
name: cronjob
spec:
template:
spec:
containers:
- image: busybox
name: cronjob
command:
- /bin/sh
- -c
- echo "hello timinglee"
restartPolicy: OnFailure
schedule: '* * * * *' # 每分钟执行一次(整分触发)
[root@master controler]# kubectl apply -f cronjob.yml
[root@master controler]# kubectl get cronjobs.batch
NAME SCHEDULE TIMEZONE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob * * * * * <none> False 0 17s 70s
# 到点生成的 pod 里能看到任务输出
[root@master controler]# kubectl logs cronjob-29598241-pxggh
hello timinglee

总结:控制器选型速查表
| 控制器 | 核心职责 | 典型场景 |
|---|---|---|
| ReplicaSet | 维持固定副本数 | 一般不直接使用,被 Deployment 包含 |
| Deployment | 副本管理 + 滚动更新 + 版本回滚 | 无状态应用首选 |
| DaemonSet | 每节点一个 pod | 日志/监控 agent、网络存储插件 |
| Job | 跑完 N 次就结束 | 数据迁移、批量计算 |
| CronJob | 定时创建 Job | 定时备份、周期报表 |
核心记忆点:
- 层级关系:Deployment → ReplicaSet → Pod;CronJob → Job → Pod;
- pod-template-hash 是 Deployment 区分新旧版本的依据,也是回滚能工作的基础;
maxSurge+maxUnavailable+minReadySeconds三件套控制滚动更新的平滑程度;rollout pause/resume实现金丝雀:一部分节点先验证新版本,确认无误再全量;- Job/CronJob 的容器必须配
restartPolicy: Never/OnFailure,用 Always 会直接被 API 拒绝。
更多推荐

所有评论(0)