摘要:除 Deployment 和 StatefulSet 外,K8s 还提供 DaemonSet(每节点运行)、Job(一次性任务)和 CronJob(定时任务)等工作负载类型。本文详解 DaemonSet 调度机制与更新策略、Job 并行与失败处理、CronJob 并发策略及生产实践。

一、K8s 工作负载概览

类型 运行模式 典型用途
Deployment 长期运行,副本数可配置 Web 服务、API 服务
StatefulSet 长期运行,有状态 数据库、消息队列
DaemonSet 每节点一个 Pod 日志收集、监控代理、网络插件
Job 一次性任务 数据处理、迁移
CronJob 定时创建 Job 定时备份、报表生成

CronJob

定时任务

Job

一次性任务

DaemonSet

每节点一个 Pod

StatefulSet

有状态长期服务

Deployment

无状态长期服务

二、DaemonSet — 节点级工作负载

2.1 什么是 DaemonSet

DaemonSet 确保集群中每个节点(或满足条件的节点)上恰好运行一个 Pod 副本。新增节点时自动部署,节点移除时自动清理对应 Pod。

K8s 集群

Node 3

fluentd

App Pod

Node 2

fluentd

App Pod

Node 1

fluentd

App Pod

上图中,每个节点运行一个 fluentd Pod,用于日志收集;应用 Pod 分布在多个节点上。新增节点时,DaemonSet 会自动在该节点上创建 Pod。

2.2 典型使用场景

场景 示例组件
监控代理 Prometheus Node Exporter、Datadog Agent
日志收集 Fluentd、Fluent Bit、Filebeat
网络插件 Calico Node、Cilium Agent、kube-proxy
存储守护进程 GlusterFS、Ceph

2.3 DaemonSet 调度机制

通过 nodeSelectoraffinitytolerations 控制 DaemonSet Pod 的部署范围。

机制 说明
nodeSelector 仅调度到含指定标签的节点
nodeAffinity 更灵活的节点选择
tolerations 容忍节点污点,如允许在 Master 节点运行

默认 Master 节点有 node-role.kubernetes.io/control-plane:NoSchedule 污点,DaemonSet Pod 不会调度上去。若需在 Master 上运行,需配置对应 tolerations。

2.4 DaemonSet YAML 示例

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: fluentd
  template:
    metadata:
      labels:
        app: fluentd
    spec:
      containers:
      - name: fluentd
        image: fluentd:v1.16
        resources:
          requests:
            cpu: "100m"
            memory: "200Mi"
          limits:
            cpu: "200m"
            memory: "500Mi"
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: containers
          mountPath: /var/lib/docker/containers
          readOnly: true
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: containers
        hostPath:
          path: /var/lib/docker/containers

      tolerations:
      - key: node-role.kubernetes.io/control-plane
        effect: NoSchedule
字段 说明
spec.template Pod 模板
tolerations 容忍 Master 污点,允许在控制平面节点运行
hostPath 挂载节点目录,用于读取日志

2.5 指定节点运行

spec:
  template:
    spec:
      nodeSelector:
        disk: ssd
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/os
                operator: In
                values: ["linux"]

2.6 DaemonSet 更新策略

策略 说明
RollingUpdate(默认) 滚动更新,逐个节点替换 Pod
OnDelete 仅当 Pod 被手动删除后才用新模板重建
spec:
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1

maxUnavailable 表示更新过程中允许不可用的 Pod 数量,默认 1。

三、Job — 一次性任务

3.1 什么是 Job

Job 创建 Pod 执行一次性任务,任务完成后 Pod 不再重启。与 Deployment 的持续运行不同,Job 有明确的完成条件。

Job

Pod 启动

执行任务

完成后退出

Deployment

Pod 启动

持续运行

失败则重启

3.2 Job 完成模式

模式 说明
NonIndexed(默认) 无序号,任意 Pod 完成即计入 completions
Indexed 每个 Pod 有唯一索引 0 到 completions-1,通过 JOB_COMPLETION_INDEX 环境变量传递

Indexed Job 适用于需要将任务分片且按索引处理的场景。

3.3 Job YAML 示例

apiVersion: batch/v1
kind: Job
metadata:
  name: data-migration
spec:
  template:
    spec:
      containers:
      - name: migrate
        image: my-app:v1
        command: ["python", "migrate.py"]
      restartPolicy: OnFailure

  backoffLimit: 4
  activeDeadlineSeconds: 300
字段 说明
restartPolicy 必须为 OnFailure 或 Never,不可为 Always
backoffLimit 失败重试次数,默认 6
activeDeadlineSeconds 总运行时间上限,超时后 Job 失败

3.4 Job 并行处理

apiVersion: batch/v1
kind: Job
metadata:
  name: batch-process
spec:
  completions: 10
  parallelism: 3
  template:
    spec:
      containers:
      - name: worker
        image: batch-worker:v1
      restartPolicy: OnFailure
字段 说明
completions 成功完成的总次数
parallelism 同时运行的 Pod 数

完成一个会启动下一个,直到达到 completions。

Pod 1-3 并行

Pod 4-6

Pod 7-9

Pod 10

3.5 Job 失败处理

参数 说明
backoffLimit 失败重试次数,超限后 Job 标记为 Failed
activeDeadlineSeconds 总运行时间限制,超时强制终止
ttlSecondsAfterFinished 完成后自动删除 Job 的延迟秒数
spec:
  backoffLimit: 4
  activeDeadlineSeconds: 3600
  ttlSecondsAfterFinished: 3600

3.6 Job 完成后清理

spec:
  ttlSecondsAfterFinished: 3600

完成后 1 小时自动删除 Job 及 Pod。

四、CronJob — 定时任务

4.1 什么是 CronJob

CronJob 按 Cron 表达式定期创建 Job,用于定时备份、报表生成等场景。

CronJob

Job 1

Job 2

Job 3

4.2 CronJob YAML 示例

apiVersion: batch/v1
kind: CronJob
metadata:
  name: db-backup
spec:
  schedule: "0 2 * * *"
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: mysql:8.0
            command:
            - /bin/sh
            - -c
            - mysqldump -h mysql-svc -u root -p$MYSQL_PASSWORD mydb > /backup/db-$(date +%Y%m%d).sql
            env:
            - name: MYSQL_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: password
            volumeMounts:
            - name: backup-vol
              mountPath: /backup
          restartPolicy: OnFailure
          volumes:
          - name: backup-vol
            persistentVolumeClaim:
              claimName: backup-pvc
字段 说明
schedule Cron 表达式
concurrencyPolicy Allow / Forbid / Replace
successfulJobsHistoryLimit 保留成功 Job 数量
failedJobsHistoryLimit 保留失败 Job 数量
jobTemplate 创建的 Job 模板

4.3 Cron 表达式

格式:分 时 日 月 周(分钟 0-59,小时 0-23,日 1-31,月 1-12,周 0-6,0=周日)

表达式 含义
*/5 * * * * 每 5 分钟
0 * * * * 每小时整点
0 2 * * * 每天凌晨 2 点
0 0 * * 0 每周日午夜
0 0 1 * * 每月 1 号午夜
30 8 * * 1-5 工作日 8:30

4.4 CronJob 并发策略详解

策略 行为
Allow(默认) 允许并发,新触发会创建新 Job
Forbid 禁止并发,上一 Job 未完成时跳过新触发
Replace 取消正在运行的 Job,启动新 Job

Replace

Job-1 被取消

Job-2 启动

Forbid

Job-1 运行中

Job-2 被跳过

Forbid 适用于备份等不可并发的任务;Replace 适用于可中断的定时任务。

4.5 CronJob 时区配置

K8s 1.27+ 支持 spec.timeZone

spec:
  schedule: "0 2 * * *"
  timeZone: "Asia/Shanghai"

更早版本需在容器内设置 TZ 环境变量。

五、三种资源对比总结

对比项 DaemonSet Job CronJob
运行模式 持续运行 一次性 定时触发
Pod 数量 每节点一个 完成指定次数 按 schedule 创建 Job
结束条件 不结束 任务完成 不结束
restartPolicy Always OnFailure/Never OnFailure/Never
更新策略 RollingUpdate / OnDelete
典型用途 系统守护进程 数据处理、迁移 定时备份、报表

六、Indexed Job 示例

Indexed Job 为每个 Pod 分配唯一索引,适用于分片处理:

apiVersion: batch/v1
kind: Job
metadata:
  name: indexed-job
spec:
  completions: 5
  parallelism: 2
  completionMode: Indexed
  template:
    spec:
      containers:
      - name: worker
        image: batch-worker:v1
        env:
        - name: JOB_COMPLETION_INDEX
          valueFrom:
            fieldRef:
              fieldPath: metadata.annotations['batch.kubernetes.io/job-completion-index']
      restartPolicy: OnFailure
字段 说明
completionMode: Indexed 启用索引模式
JOB_COMPLETION_INDEX Pod 索引,0 到 completions-1

七、验证命令

# DaemonSet
kubectl get daemonset
kubectl get ds
kubectl describe daemonset fluentd

# Job
kubectl get jobs
kubectl logs job/data-migration
kubectl delete job data-migration

# CronJob
kubectl get cronjobs
kubectl create job --from=cronjob/db-backup manual-backup-001

八、生产环境建议

  1. DaemonSet:合理设置资源 requests/limits,避免与业务 Pod 争抢;Master 节点部署需显式配置 tolerations
  2. Job:长任务设置 activeDeadlineSeconds 避免无限运行;使用 ttlSecondsAfterFinished 自动清理
  3. CronJob:备份类任务使用 Forbid 避免并发;配置 timeZone 确保执行时间符合预期

九、FAQ

Q1:DaemonSet Pod 被驱逐或无法调度怎么办?

检查节点污点与 Pod tolerations 是否匹配;确认 nodeSelector/affinity 是否过严;查看节点资源是否充足;若为节点维护导致驱逐,维护完成后会重新调度。

Q2:Job 超时如何处理?

设置 activeDeadlineSeconds 可强制终止超时 Job。若需更细粒度控制,可在应用内实现超时逻辑。超时后 Job 状态为 Failed,可根据 ttlSecondsAfterFinished 自动清理或手动删除。

Q3:CronJob 的时区如何设置?

K8s 1.27+ 支持 spec.timeZone,例如 timeZone: "Asia/Shanghai"。更早版本需在容器内设置 TZ 环境变量。

Q4:Job 失败后如何手动重试?

可删除原 Job 后重新创建;或使用 kubectl create job --from=job/<name> <new-name> 基于原 Job 创建新 Job。

十、总结

  • DaemonSet:每节点一个 Pod,用于系统级守护进程(日志、监控、网络等);新增节点自动部署;通过 nodeSelector、tolerations 控制部署范围
  • Job:一次性任务,支持并行(completions、parallelism)与重试(backoffLimit);适用于数据处理、迁移等
  • CronJob:按 Cron 计划创建 Job;并发策略 Forbid/Replace 适用于不同场景;K8s 1.27+ 支持 timeZone
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐