工作负载控制器
Deployment、StatefulSet、DaemonSet、Job、CronJob 的创建与操作
概述
工作负载控制器负责管理 Pod 的生命周期、副本数、更新策略等。CKA 考试重点考察 Deployment、DaemonSet、Job 和 CronJob。
一、Deployment
1.1 创建 Deployment
kubectl create deployment web --image=nginx --replicas=3
# 生成 YAML(--dry-run=client -o yaml 常用)
kubectl create deployment web --image=nginx --replicas=3 --dry-run=client -o yaml > deploy.yaml
# 暴露 Service
kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
1.2 YAML 示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
1.3 滚动更新(RollingUpdate)
# 更新镜像
kubectl set image deployment/nginx-deployment nginx=nginx:1.26
# 或编辑 YAML
kubectl edit deployment/nginx-deployment
# 指定更新策略(Recreate / RollingUpdate)
kubectl patch deployment nginx-deployment -p '{"spec":{"strategy":{"type":"RollingUpdate","rollingUpdate":{"maxSurge":"25%","maxUnavailable":"25%"}}}}'
# 查看更新状态
kubectl rollout status deployment/nginx-deployment
kubectl rollout history deployment/nginx-deployment
更新策略对比
| 策略 | 说明 | 适用场景 |
|---|---|---|
RollingUpdate | 逐步替换 Pod,支持 maxSurge/maxUnavailable | 默认策略,零停机 |
Recreate | 先删除所有旧 Pod,再创建新 Pod | 开发环境、数据库迁移 |
# RollingUpdate 配置
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 允许超出期望副本数的最大 Pod 数(数字或百分比)
maxUnavailable: 0 # 更新过程中允许不可用的最大 Pod 数
1.4 回滚
# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment
# 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2
# 查看版本历史
kubectl rollout history deployment/nginx-deployment
# 查看特定版本详情
kubectl rollout history deployment/nginx-deployment --revision=2
1.5 扩缩容
# 手动扩缩
kubectl scale deployment/nginx-deployment --replicas=5
kubectl scale deployment/nginx-deployment --replicas=2
二、ReplicaSet
ReplicaSet 确保指定数量的 Pod 始终运行。通常由 Deployment 自动管理,不建议直接操作。
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: nginx
image: nginx
# 查看 ReplicaSet(RS)
kubectl get replicasets
kubectl get rs
# 查看 RS 与 Deployment 的关联
kubectl describe deployment nginx-deployment | grep ReplicaSet
kubectl get rs -l app=nginx
# 删除 RS(会同时删除其管理的 Pod,但不能直接删除 Deployment 管理的 RS)
kubectl delete rs <rs-name>
注意:CKA 考试不需手动创建 RS,但需理解 RS 是 Deployment 管理 Pod 的基础。
三、StatefulSet
用于有状态应用(数据库、消息队列等),提供稳定的网络标识和持久化存储。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
关键特性
| 特性 | 说明 |
|---|---|
| 有序部署 | Pod 从 0 到 N-1 依次创建(web-0, web-1, web-2) |
| 有序缩容 | 从 N-1 到 0 依次删除 |
| 稳定网络标识 | Pod 名称固定:<statefulset>-<ordinal> |
| 稳定存储 | PVC 与 Pod 解绑时保留 |
# 查看 StatefulSet Pod 的名称
kubectl get pods -l app=nginx # 输出:web-0, web-1, web-2
# 通过稳定 DNS 访问
# <pod>.<service>.<namespace>.svc.cluster.local
# web-0.nginx.default.svc.cluster.local
更新策略
# OnDelete:手动删除 Pod 后更新
kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"OnDelete"}}}'
# RollingUpdate(默认):按序更新
kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate"}}}'
# 分段更新(Partition)
kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":2}}}}'
四、DaemonSet
在每个节点(或符合条件的节点)上运行一个 Pod。
典型场景
- 节点监控(Node Exporter)
- 日志采集(Fluentd、Filebeat)
- 网络插件(Calico、Flannel)
- 存储插件(Ceph、GlusterFS)
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
spec:
selector:
matchLabels:
name: fluentd
template:
metadata:
labels:
name: fluentd
spec:
tolerations:
- operator: Exists
containers:
- name: fluentd
image: fluent/fluentd:v1.16
# 创建 DaemonSet
kubectl apply -f daemonset.yaml
# 查看 DaemonSet
kubectl get daemonsets
kubectl get ds
# 查看每个节点的 Pod
kubectl get pods -o wide
# 更新镜像
kubectl set image ds/fluentd fluentd=fluent/fluentd:v1.17
# 查看滚动更新状态
kubectl rollout status ds/fluentd
# 考试技巧:创建 DaemonSet 的命令式
kubectl create deployment fluentd --image=fluent/fluentd --dry-run=client -o yaml > ds.yaml
# 然后编辑 ds.yaml 将 kind 改为 DaemonSet,删除 replicas
五、Job
执行一次性任务,Pod 完成后自动终止。
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
completions: 5 # 需要成功完成的 Pod 数
parallelism: 2 # 并行运行数
backoffLimit: 4 # 失败重试次数
activeDeadlineSeconds: 30 # 任务超时时间
template:
spec:
containers:
- name: pi
image: perl:5.34
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
# 创建 Job
kubectl create job pi --image=perl:5.34 -- perl -Mbignum=bpi -wle 'print bpi(2000)'
# 创建 Job(从 CronJob 生成 YAML)
kubectl create job test-job --from=cronjob/backup-cronjob -n default
# 查看 Job 状态
kubectl get jobs
kubectl describe job pi
# 查看 Job Pod 日志
kubectl logs job/pi
kubectl logs -l job-name=pi
# 删除 Job
kubectl delete job pi
# 重要:restartPolicy 只能为 Never 或 OnFailure
高级参数
| 参数 | 说明 | 默认值 |
|---|---|---|
.spec.completions | 需要完成的 Pod 数 | 1 |
.spec.parallelism | 并行 Pod 数 | 1 |
.spec.backoffLimit | 失败重试次数 | 6 |
.spec.activeDeadlineSeconds | 任务超时时间 | 无限制 |
.spec.ttlSecondsAfterFinished | 自动清理时间 | 无限制 |
六、CronJob
定时执行 Job,基于标准的 Cron 语法。
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *" # 每分钟执行一次
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox:1.28
command: ["echo", "Hello CKA"]
restartPolicy: OnFailure
startingDeadlineSeconds: 100 # 启动截止时间
concurrencyPolicy: Forbid # Allow / Forbid / Replace
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
# 创建 CronJob
kubectl create cronjob hello --image=busybox:1.28 --schedule="*/1 * * * *" -- echo "Hello CKA"
# 查看 CronJob
kubectl get cronjobs
kubectl get cj
# 查看触发的 Job
kubectl get jobs
# 暂停 CronJob
kubectl patch cronjob hello -p '{"spec":{"suspend":true}}'
# 恢复
kubectl patch cronjob hello -p '{"spec":{"suspend":false}}'
# 手动触发
kubectl create job --from=cronjob/hello manual-job
Cron 语法速查
分钟 小时 日 月 星期
*/1 * * * * 每分钟
0 * * * * 每小时
0 8 * * 1 每周一 8:00
0 0 1 * * 每月 1 日 0:00
*/5 * * * * 每 5 分钟
CronJob 参数
| 参数 | 说明 |
|---|---|
concurrencyPolicy: Allow | 允许并发执行(默认) |
concurrencyPolicy: Forbid | 禁止并发,前一个未完成则跳过 |
concurrencyPolicy: Replace | 替换前一个运行中的 Job |
startingDeadlineSeconds | 错过调度时间后的最大等待时间 |
successfulJobsHistoryLimit | 保留的历史成功 Job 数 |
failedJobsHistoryLimit | 保留的历史失败 Job 数 |
七、考试实用命令
# 创建 Deployment 并生成 YAML
kubectl create deployment web --image=nginx --replicas=3 --dry-run=client -o yaml
# 更新 Deployment 镜像
kubectl set image deployment/web nginx=nginx:1.26
# 查看 rollout 状态
kubectl rollout status deployment/web
kubectl rollout history deployment/web
# 回滚
kubectl rollout undo deployment/web
kubectl rollout undo deployment/web --to-revision=1
# 扩缩容
kubectl scale deployment/web --replicas=5
# 创建 Job 和 CronJob(--dry-run 支持)
kubectl create job pi --image=perl:5.34 -- perl -Mbignum=bpi -wle 'print bpi(2000)' --dry-run=client -o yaml
kubectl create cronjob hello --image=busybox:1.28 --schedule="*/1 * * * *" --dry-run=client -o yaml
# 创建 DaemonSet 的 JSON 方式
kubectl run ds-test --image=nginx --restart=Always --dry-run=client -o yaml | sed 's/kind: Deployment/kind: DaemonSet/' | sed '/replicas/d'
🧪 完整操作实例:创建 Deployment,执行滚动更新和回滚
场景描述
创建一个 nginx Deployment,更新镜像版本,然后执行回滚操作。
前置条件
- 可用的 Kubernetes 集群
- kubectl 已配置连接集群
操作步骤
Step 1: 创建 Deployment
kubectl create deployment web --image=nginx:1.25 --replicas=3
# 预期输出:deployment.apps/web created
kubectl get deployment web
# 预期输出:NAME READY UP-TO-DATE AVAILABLE AGE
# web 3/3 3 3 <seconds>
kubectl get pods -l app=web
# 预期输出:NAME READY STATUS RESTARTS AGE
# web-<hash1>-<pod-id> 1/1 Running 0 <seconds>
# web-<hash2>-<pod-id> 1/1 Running 0 <seconds>
# web-<hash3>-<pod-id> 1/1 Running 0 <seconds>
Step 2: 升级镜像版本(滚动更新)
kubectl set image deployment/web nginx=nginx:1.26
# 预期输出:deployment.apps/web image updated
# 观察滚动更新过程
kubectl rollout status deployment/web
# 预期输出:Waiting for rollout to finish: 2 out of 3 new replicas are available...
# deployment "web" successfully rolled out
Step 3: 查看滚动更新历史
kubectl rollout history deployment/web
# 预期输出:deployment.apps/web
# REVISION CHANGE-CAUSE
# 1 <none>
# 2 <none>
kubectl rollout history deployment/web --revision=2
# 预期输出:deployment.apps/web with revision #2
# Pod Template:
# Labels: app=web
# Containers:
# nginx:
# Image: nginx:1.26
Step 4: 执行回滚
# 回滚到上一个版本
kubectl rollout undo deployment/web
# 预期输出:deployment.apps/web rolled back
# 确认回滚完成
kubectl rollout status deployment/web
# 预期输出:deployment "web" successfully rolled out
# 验证镜像版本已恢复
kubectl describe deployment web | grep Image
# 预期输出:nginx:1.25
# 回滚到指定版本(可选)
kubectl rollout undo deployment/web --to-revision=2
验证结果
# 检查当前副本数和镜像版本
kubectl get deployment web -o wide
# 预期输出显示 3/3 READY,IMAGE 为 nginx:1.25
# 检查所有 Pod 正常运行
kubectl get pods -l app=web
# 预期输出:3 个 Pod 均为 Running 状态
# 清理
kubectl delete deployment web
# 预期输出:deployment.apps "web" deleted
考试提示
- 滚动更新中
maxSurge和maxUnavailable使用百分比更灵活,是 CKA 考点 kubectl set image是最快的更新方式,但考试也常要求通过kubectl edit或kubectl patch修改- 回滚后 ReplicaSet 版本不会删除,可再次回滚到任意历史版本
- 使用
--record标志创建 Deployment 可以在 CHAGE-CAUSE 中记录命令历史(旧版 K8s) - Deployment 的回滚本质是将 Pod 模板替换为历史版本对应的 ReplicaSet