Qingular

工作负载控制器

·CKAk8s练习

Deployment、StatefulSet、DaemonSet、Job、CronJob 的创建与操作

← 返回 CKA 练习目录

概述

工作负载控制器负责管理 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

考试提示

  • 滚动更新中 maxSurgemaxUnavailable 使用百分比更灵活,是 CKA 考点
  • kubectl set image 是最快的更新方式,但考试也常要求通过 kubectl editkubectl patch 修改
  • 回滚后 ReplicaSet 版本不会删除,可再次回滚到任意历史版本
  • 使用 --record 标志创建 Deployment 可以在 CHAGE-CAUSE 中记录命令历史(旧版 K8s)
  • Deployment 的回滚本质是将 Pod 模板替换为历史版本对应的 ReplicaSet

官方文档链接