DaemonSet、Job 与 CronJob:节点级与批处理工作负载
DaemonSet 确保集群中每个节点(或满足条件的节点)上恰好运行一个 Pod 副本。新增节点时自动部署,节点移除时自动清理对应 Pod。fill:#333;important;important;fill:none;color:#333;color:#333;important;fill:none;fill:#333;height:1em;K8s 集群Node 3fluentdApp PodN
摘要:除 Deployment 和 StatefulSet 外,K8s 还提供 DaemonSet(每节点运行)、Job(一次性任务)和 CronJob(定时任务)等工作负载类型。本文详解 DaemonSet 调度机制与更新策略、Job 并行与失败处理、CronJob 并发策略及生产实践。
一、K8s 工作负载概览
| 类型 | 运行模式 | 典型用途 |
|---|---|---|
| Deployment | 长期运行,副本数可配置 | Web 服务、API 服务 |
| StatefulSet | 长期运行,有状态 | 数据库、消息队列 |
| DaemonSet | 每节点一个 Pod | 日志收集、监控代理、网络插件 |
| Job | 一次性任务 | 数据处理、迁移 |
| CronJob | 定时创建 Job | 定时备份、报表生成 |
二、DaemonSet — 节点级工作负载
2.1 什么是 DaemonSet
DaemonSet 确保集群中每个节点(或满足条件的节点)上恰好运行一个 Pod 副本。新增节点时自动部署,节点移除时自动清理对应 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 调度机制
通过 nodeSelector、affinity、tolerations 控制 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 有明确的完成条件。
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。
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,用于定时备份、报表生成等场景。
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 |
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
八、生产环境建议
- DaemonSet:合理设置资源 requests/limits,避免与业务 Pod 争抢;Master 节点部署需显式配置 tolerations
- Job:长任务设置
activeDeadlineSeconds避免无限运行;使用ttlSecondsAfterFinished自动清理 - 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
更多推荐


所有评论(0)