运维实战

Kubernetes 工作负载控制器:Deployment、StatefulSet、DaemonSet 与 Job

理解不同工作负载控制器的选择边界,并通过滚动发布、回滚、有状态身份、节点代理和批处理完成实战。

TY
Tycho
技术博主
• 2026-09-15 • 24 分钟阅读 • 2 次浏览
Kubernetes 工作负载控制器:Deployment、StatefulSet、DaemonSet 与 Job

实验基线:Kubernetes v1.37.0、kubectl v1.37.0。先在测试环境执行,记录变更前状态与回滚点;生产集群不得直接照抄节点地址、网段、存储类或资源额度。

先按生命周期选择控制器

控制器适用场景关键保证
Deployment无状态常驻服务滚动更新、回滚
StatefulSet稳定网络身份和存储有序编号与 PVC 模板
DaemonSet每个合格节点一个代理随节点增删
Job一次性任务完成次数与重试
CronJob按计划运行并发策略与历史保留

Deployment 滚动发布

kubectl create deployment web -n lab --image=nginx:1.27-alpine --replicas=3
kubectl set image deployment/web web=nginx:1.27.1-alpine -n lab --record=false
kubectl rollout status deployment/web -n lab --timeout=120s
kubectl rollout history deployment/web -n lab
kubectl rollout undo deployment/web -n lab

在 YAML 中设置 maxUnavailable: 0与maxSurge: 1可优先保证容量,但要求集群有额外资源。镜像应使用不可变摘要;滚动成功只代表 Pod Ready,还要执行业务冒烟测试。

有状态与批处理注意点

StatefulSet 不会替你完成数据库复制、选主或数据一致性;它只提供稳定身份和有序操作。DaemonSet 要配置容忍度与资源限制,避免节点代理挤压业务。CronJob 应设置 concurrencyPolicy: Forbid防止任务重叠,并配置 startingDeadlineSeconds与历史保留。

kubectl get deploy,rs,sts,ds,job,cronjob -A
kubectl describe job <job> -n lab
kubectl logs -n lab job/<job>

Deployment 生产清单

apiVersion: apps/v1
kind: Deployment
metadata: {name: web, namespace: lab}
spec:
  replicas: 3
  strategy:
    rollingUpdate: {maxUnavailable: 0, maxSurge: 1}
  minReadySeconds: 10
  progressDeadlineSeconds: 300
  selector: {matchLabels: {app: web}}
  template:
    metadata: {labels: {app: web}}
    spec:
      containers:
      - name: web
        image: nginx:1.27-alpine
        ports: [{containerPort: 80}]
        readinessProbe: {httpGet: {path: /, port: 80}, periodSeconds: 5}
        resources:
          requests: {cpu: 50m, memory: 32Mi}
          limits: {cpu: 200m, memory: 128Mi}

selector 创建后不可随意修改;Pod 模板 label 必须与 selector 对齐。发布时同时观察新旧 ReplicaSet、副本数和业务指标。

StatefulSet 的最小闭环

StatefulSet 通常配合 headless Service 和 volumeClaimTemplates。Pod 名称按序固定,如 db-0、db-1;删除 Pod 后同名身份会恢复,但数据可靠性取决于后端存储和应用复制协议。

kubectl get statefulset,pod,pvc -n lab
kubectl rollout status statefulset/db -n lab --timeout=300s
kubectl delete pod db-0 -n lab
kubectl get pod,pvc -n lab -w

缩容前确认被移除副本的数据已经安全迁移;PVC 默认不会随 StatefulSet 删除,这是保护机制,不是垃圾数据。

DaemonSet 与批处理

日志、监控和网络代理适合 DaemonSet。设置 requests、更新策略与必要容忍度,避免覆盖所有控制平面节点。Job 应设置 backoffLimit和activeDeadlineSeconds;CronJob 应设置时区、并发策略、截止时间和历史保留。

kubectl get daemonset -A -o wide
kubectl get jobs -n lab
kubectl describe job <job> -n lab
kubectl logs -n lab job/<job> --all-containers
kubectl create job --from=cronjob/<cronjob> manual-check -n lab

选择错误的典型后果

错误选择后果正确方向
数据库用 Deployment身份与存储关系不稳定StatefulSet + 成熟运维方案
定时任务常驻进程自调度多副本重复执行CronJob + 幂等任务
节点代理用 Deployment覆盖节点不完整DaemonSet

四类控制器的最小可运行样例

StatefulSet:稳定身份与独立 PVC

apiVersion: v1
kind: Service
metadata: {name: db, namespace: lab}
spec: {clusterIP: None, selector: {app: db}, ports: [{port: 5432}]}
---
apiVersion: apps/v1
kind: StatefulSet
metadata: {name: db, namespace: lab}
spec:
  serviceName: db
  replicas: 3
  selector: {matchLabels: {app: db}}
  template:
    metadata: {labels: {app: db}}
    spec:
      containers:
      - name: db
        image: postgres:17-alpine
        env:
        - {name: POSTGRES_PASSWORD, valueFrom: {secretKeyRef: {name: db-auth, key: password}}}
        volumeMounts: [{name: data, mountPath: /var/lib/postgresql/data}]
  volumeClaimTemplates:
  - metadata: {name: data}
    spec:
      accessModes: [ReadWriteOnce]
      resources: {requests: {storage: 5Gi}}

此清单只演示身份与存储,不包含 PostgreSQL 复制和故障转移;生产数据库应使用经过验证的 Operator 或托管服务。

DaemonSet:节点诊断代理

apiVersion: apps/v1
kind: DaemonSet
metadata: {name: node-agent, namespace: lab}
spec:
  selector: {matchLabels: {app: node-agent}}
  template:
    metadata: {labels: {app: node-agent}}
    spec:
      containers:
      - {name: agent, image: busybox:1.36, command: ["sh","-c","while true; do date; sleep 60; done"], resources: {requests: {cpu: 5m, memory: 8Mi}, limits: {cpu: 50m, memory: 32Mi}}}

Job 与 CronJob:幂等批处理

apiVersion: batch/v1
kind: CronJob
metadata: {name: report, namespace: lab}
spec:
  schedule: "0 2 * * *"
  timeZone: "Asia/Shanghai"
  concurrencyPolicy: Forbid
  startingDeadlineSeconds: 600
  successfulJobsHistoryLimit: 2
  failedJobsHistoryLimit: 3
  jobTemplate:
    spec:
      backoffLimit: 2
      activeDeadlineSeconds: 900
      template:
        spec:
          restartPolicy: Never
          containers:
          - {name: report, image: busybox:1.36, command: ["sh","-c","date; echo run-report"]}

手工触发一次并查看退出状态:kubectl create job -n lab --from=cronjob/report report-manual。任务逻辑必须幂等,避免重试造成重复扣款或重复写入。

可复现记录模板

每次实验记录:集群版本、容器运行时、CNI/CSI 版本、命名空间、使用的 YAML Git 提交、开始与结束时间。命令输出至少保留对象状态、事件、关键日志和回滚结果。文中的占位符必须替换成自己的值,生产执行前应由第二人复核。

故障处理原则

  1. 先缩小影响面,不删除现场。
  2. 按对象状态—事件—日志—依赖顺序收集证据。
  3. 提出可证伪假设,一次只改变一个变量。
  4. 验证恢复后清理临时权限、调试 Pod、端口转发和测试数据。

完成检查

  • 命令退出码为 0,目标对象状态与预期一致。
  • 保存执行前后 YAML、事件与关键日志,确认没有把测试命名空间以外的对象改动。
  • 故障演练完成后执行清理或回滚,再进行下一章。

官方资料

TY

Tycho

热爱分享技术知识,帮助开发者成长。

评论 (0)

评论功能当前已关闭
暂无评论,快来抢沙发吧!