IT策士 10余年一线大厂经验专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章助你少走弯路。在前两篇中我们用 Deployment 管理了 Flask 应用的副本实现了滚动更新和自愈。Deployment 适合管理无状态、需要多副本、可随时替换的应用。但不是所有工作负载都长这样——有些需要在每个节点上运行有些是一次性任务有些是按周期自动执行的定时任务。比如你想在每个节点上部署一个日志采集器节点级守护你想跑一次数据库迁移脚本一次性任务你想每天凌晨 2 点自动备份 Redis 数据定时任务。Deployment 做这些事就像用牛刀杀鸡——不是不能而是极其别扭。今天我们来解锁三类专为这些场景设计的控制器DaemonSet、Job、CronJob。它们与 Deployment 一起构成了 K8s 工作负载管理的完整拼图。一、DaemonSet每个节点一个 Pod1.1 什么是 DaemonSetDaemonSet 确保每个节点上恰好运行一个 Pod 副本或者匹配特定条件的节点上各运行一个。节点加入集群时自动部署节点移除时自动回收。典型使用场景日志采集每个节点上运行 Fluentd / Filebeat采集所有容器的日志监控代理每个节点上运行 Prometheus Node Exporter暴露节点指标网络插件每个节点上运行 Calico / Flannel 的代理组件存储守护进程每个节点上运行 Ceph / GlusterFS 客户端1.2 实战部署 Node Exporter 监控代理以下 YAML 在每个节点上部署一个 Prometheus Node Exporter采集节点的 CPU、内存、磁盘等指标。这也是我们贯穿案例从“可运行”走向“可观测”的第一步。apiVersion: apps/v1 kind: DaemonSet metadata: name: node-exporter labels: app: node-exporter spec: selector: matchLabels: app: node-exporter template: metadata: labels: app: node-exporter spec: hostNetwork:truehostPID:truecontainers: - name: node-exporter image: prom/node-exporter:latest args: ---path.procfs/host/proc ---path.sysfs/host/sys ---path.rootfs/host/root ports: - containerPort:9100volumeMounts: - name: proc mountPath: /host/proc readOnly:true- name: sys mountPath: /host/sys readOnly:true- name: root mountPath: /host/root readOnly:truevolumes: - name: proc hostPath: path: /proc - name: sys hostPath: path: /sys - name: root hostPath: path: /关键配置说明kind: DaemonSet声明这是一个 DaemonSet 控制器hostNetwork: true使 Pod 直接使用宿主机网络命名空间Node Exporter 需要访问宿主机网络指标hostPID: true使 Pod 能看到宿主机的进程列表hostPath卷将宿主机的/proc、/sys、/挂载到容器内让 Exporter 读取系统指标无需replicas字段——DaemonSet 自动根据节点数量决定副本数部署并验证kubectl apply-fnode-exporter-daemonset.yaml kubectl get daemonset# NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE# node-exporter 1 1 1 1 1 none 30skubectl get pods-lappnode-exporter-owide# NAME READY STATUS NODE AGE# node-exporter-abcde 1/1 Running minikube 30sMinikube 是单节点集群所以只运行 1 个 Pod。在多节点集群中每个节点都会自动运行一个。1.3 DaemonSet vs Deployment二、Job一次性任务2.1 什么是 JobJob 确保指定数量的 Pod成功完成退出码 0。Job 创建的 Pod 在任务完成后不会自动重启restartPolicy通常设为Never或OnFailure而是保留在集群中以便查看日志和状态。典型使用场景数据库迁移Djangomanage.py migrate数据清洗与 ETL 任务一次性报告生成密钥轮换脚本2.2 实战Redis 数据备份 Job为我们的贯穿案例创建一个定期执行的 Redis 备份任务先看一次性 Job再升级为 CronJob。apiVersion: batch/v1 kind: Job metadata: name: redis-backup spec: ttlSecondsAfterFinished:600template: spec: restartPolicy: Never containers: - name: backup image: redis:alpine command: -sh--c-|echo开始备份时间:$(date)redis-cli-hredis-service-p6379--rdb/backup/dump.rdbif[$?-eq0];thenecho备份成功elseecho备份失败exit1fivolumeMounts: - name: backup-storage mountPath: /backup volumes: - name: backup-storage emptyDir:{}关键配置说明restartPolicy: NeverJob 的 Pod 退出后不重启。如果任务失败由 Job Controller 决定是否创建新 Pod 重试ttlSecondsAfterFinished: 600Job 完成后 10 分钟自动清理K8s v1.21。不设则需手动删除command中的exit 1确保备份失败时 Pod 返回非零退出码Job Controller 据此判断任务是否成功部署并验证kubectl apply-fredis-backup-job.yaml kubectl get job# NAME COMPLETIONS DURATION AGE# redis-backup 1/1 3s 10skubectl get pods-ljob-nameredis-backup# NAME READY STATUS RESTARTS AGE# redis-backup-xyz12 0/1 Completed 0 10sPod 的STATUSCompleted表示任务已成功完成。查看日志kubectl logs job/redis-backup# 开始备份时间: Mon May 27 10:00:00 UTC 2025# 备份成功2.3 Job 的三种运行模式2.4 backoffLimit 与失败重试Job 默认会在 Pod 失败后重试由backoffLimit控制最大重试次数默认 6达到上限后 Job 标记为 Failed。对于幂等性任务如数据备份可设置较高重试次数对于非幂等任务如数据库迁移建议设为 1 或 2避免重复执行产生脏数据。2.5 并行 Job 的工作队列模式对于需要并行处理的大规模任务如批量图片压缩、日志分析可以配置并行 Jobspec: completions:50# 总共需要完成 50 个 Podparallelism:10# 同时运行 10 个 Pod这种模式下Job Controller 会始终维持 10 个 Pod 并行运行直至全部 50 个 Pod 成功完成。适合将大型任务拆分为独立子任务并行处理的场景。三、CronJob定时任务3.1 什么是 CronJobCronJob 在指定的时间表上自动创建 Job语法与 Linux crontab 完全一致。它是对 Job 的定时调度封装。典型使用场景每日凌晨数据库备份每小时日志轮转与归档每周生成业务报表定期证书续期检查3.2 实战每日凌晨 2 点备份 Redis将前面的一次性 Job 升级为 CronJobapiVersion: batch/v1 kind: CronJob metadata: name: redis-daily-backup spec: schedule:0 2 * * *jobTemplate: spec: ttlSecondsAfterFinished:86400template: spec: restartPolicy: OnFailure containers: - name: backup image: redis:alpine command: -sh--c-|echo定时备份开始时间:$(date)redis-cli-hredis-service-p6379--rdb/backup/dump.rdbif[$?-eq0];thenecho备份成功elseecho备份失败exit1fivolumeMounts: - name: backup-storage mountPath: /backup volumes: - name: backup-storage emptyDir:{}关键配置说明schedule: 0 2 * * *使用标准 crontab 语法——分、时、日、月、周表示每天凌晨 2:00 执行jobTemplate内嵌了 Job 的完整 spec结构与 Job YAML 完全一致restartPolicy: OnFailure比Never更适合定时任务——偶发性网络抖动导致的失败会被自动重试ttlSecondsAfterFinished: 86400保留 24 小时后自动清理部署并验证kubectl apply-fredis-cronjob.yaml kubectl get cronjob# NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE# redis-daily-backup 0 2 * * * False 0 none 10s3.3 手动触发 CronJob从 K8s v1.27 起可以直接从 CronJob 创建一个一次性 Jobkubectl create job manual-backup--fromcronjob/redis-daily-backup kubectl get pods-ljob-namemanual-backup这个命令会基于 CronJob 的jobTemplate立即创建一个 Job用于测试定时任务的正确性。3.4 CronJob 常见参数三个重要参数的深入说明startingDeadlineSeconds当控制平面因故障恢复后发现某个 CronJob 应该被执行了 5 次但只执行了 3 次。如果设了此参数超过截止时间的任务会被跳过避免积压的 Job 同时爆发占用集群资源。concurrencyPolicyAllow允许同一 CronJob 的多个 Job 并行执行需保证任务是幂等的Forbid如果上一个 Job 未结束则跳过本次调度Replace取消正在运行的 Job 并启动新的。suspend: true可以在不删除 CronJob 对象的情况下暂停调度适合维护窗口期间临时禁制定时任务。四、控制器选择指南至此我们已经学过了 5 类控制器Deployment、StatefulSet将在第 27 篇之后展开、DaemonSet、Job、CronJob。如何根据业务需求选择合适的控制器与 Docker Compose 的对比Compose 没有针对不同工作负载提供不同的管理对象——所有服务都用services定义定时任务需要依赖外部 cron 或脚本触发。K8s 的控制器体系将工作负载按特征分类每种控制器针对特定场景优化了生命周期管理和调度策略。五、命令速查表六、本篇总结DaemonSet每个节点运行一个 Pod适合日志采集、监控代理等节点级守护任务。Job一次性任务运行到完成支持并行和重试适合数据库迁移、数据备份等场景。CronJob定时调度 Job基于 crontab 表达式适合定期备份、报表生成等周期性任务。控制器选型根据工作负载的特征选择合适的控制器——服务类用 Deployment节点级用 DaemonSet批处理用 Job/CronJob。至此K8s 的核心工作负载控制器你已经全部掌握。下一篇文章——第 28 篇Service为 Pod 提供稳定的访问入口我们将解决一个关键问题Deployment 管理着不断变化 IP 的 Pod其他服务如何稳定地找到它们答案就是 Service。想了解更多还可以去各个平台搜索「IT策士」一起升级 IT 思维
第27篇 k8s之控制器:DaemonSet、Job 与 CronJob
发布时间:2026/6/1 5:08:04
IT策士 10余年一线大厂经验专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章助你少走弯路。在前两篇中我们用 Deployment 管理了 Flask 应用的副本实现了滚动更新和自愈。Deployment 适合管理无状态、需要多副本、可随时替换的应用。但不是所有工作负载都长这样——有些需要在每个节点上运行有些是一次性任务有些是按周期自动执行的定时任务。比如你想在每个节点上部署一个日志采集器节点级守护你想跑一次数据库迁移脚本一次性任务你想每天凌晨 2 点自动备份 Redis 数据定时任务。Deployment 做这些事就像用牛刀杀鸡——不是不能而是极其别扭。今天我们来解锁三类专为这些场景设计的控制器DaemonSet、Job、CronJob。它们与 Deployment 一起构成了 K8s 工作负载管理的完整拼图。一、DaemonSet每个节点一个 Pod1.1 什么是 DaemonSetDaemonSet 确保每个节点上恰好运行一个 Pod 副本或者匹配特定条件的节点上各运行一个。节点加入集群时自动部署节点移除时自动回收。典型使用场景日志采集每个节点上运行 Fluentd / Filebeat采集所有容器的日志监控代理每个节点上运行 Prometheus Node Exporter暴露节点指标网络插件每个节点上运行 Calico / Flannel 的代理组件存储守护进程每个节点上运行 Ceph / GlusterFS 客户端1.2 实战部署 Node Exporter 监控代理以下 YAML 在每个节点上部署一个 Prometheus Node Exporter采集节点的 CPU、内存、磁盘等指标。这也是我们贯穿案例从“可运行”走向“可观测”的第一步。apiVersion: apps/v1 kind: DaemonSet metadata: name: node-exporter labels: app: node-exporter spec: selector: matchLabels: app: node-exporter template: metadata: labels: app: node-exporter spec: hostNetwork:truehostPID:truecontainers: - name: node-exporter image: prom/node-exporter:latest args: ---path.procfs/host/proc ---path.sysfs/host/sys ---path.rootfs/host/root ports: - containerPort:9100volumeMounts: - name: proc mountPath: /host/proc readOnly:true- name: sys mountPath: /host/sys readOnly:true- name: root mountPath: /host/root readOnly:truevolumes: - name: proc hostPath: path: /proc - name: sys hostPath: path: /sys - name: root hostPath: path: /关键配置说明kind: DaemonSet声明这是一个 DaemonSet 控制器hostNetwork: true使 Pod 直接使用宿主机网络命名空间Node Exporter 需要访问宿主机网络指标hostPID: true使 Pod 能看到宿主机的进程列表hostPath卷将宿主机的/proc、/sys、/挂载到容器内让 Exporter 读取系统指标无需replicas字段——DaemonSet 自动根据节点数量决定副本数部署并验证kubectl apply-fnode-exporter-daemonset.yaml kubectl get daemonset# NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE# node-exporter 1 1 1 1 1 none 30skubectl get pods-lappnode-exporter-owide# NAME READY STATUS NODE AGE# node-exporter-abcde 1/1 Running minikube 30sMinikube 是单节点集群所以只运行 1 个 Pod。在多节点集群中每个节点都会自动运行一个。1.3 DaemonSet vs Deployment二、Job一次性任务2.1 什么是 JobJob 确保指定数量的 Pod成功完成退出码 0。Job 创建的 Pod 在任务完成后不会自动重启restartPolicy通常设为Never或OnFailure而是保留在集群中以便查看日志和状态。典型使用场景数据库迁移Djangomanage.py migrate数据清洗与 ETL 任务一次性报告生成密钥轮换脚本2.2 实战Redis 数据备份 Job为我们的贯穿案例创建一个定期执行的 Redis 备份任务先看一次性 Job再升级为 CronJob。apiVersion: batch/v1 kind: Job metadata: name: redis-backup spec: ttlSecondsAfterFinished:600template: spec: restartPolicy: Never containers: - name: backup image: redis:alpine command: -sh--c-|echo开始备份时间:$(date)redis-cli-hredis-service-p6379--rdb/backup/dump.rdbif[$?-eq0];thenecho备份成功elseecho备份失败exit1fivolumeMounts: - name: backup-storage mountPath: /backup volumes: - name: backup-storage emptyDir:{}关键配置说明restartPolicy: NeverJob 的 Pod 退出后不重启。如果任务失败由 Job Controller 决定是否创建新 Pod 重试ttlSecondsAfterFinished: 600Job 完成后 10 分钟自动清理K8s v1.21。不设则需手动删除command中的exit 1确保备份失败时 Pod 返回非零退出码Job Controller 据此判断任务是否成功部署并验证kubectl apply-fredis-backup-job.yaml kubectl get job# NAME COMPLETIONS DURATION AGE# redis-backup 1/1 3s 10skubectl get pods-ljob-nameredis-backup# NAME READY STATUS RESTARTS AGE# redis-backup-xyz12 0/1 Completed 0 10sPod 的STATUSCompleted表示任务已成功完成。查看日志kubectl logs job/redis-backup# 开始备份时间: Mon May 27 10:00:00 UTC 2025# 备份成功2.3 Job 的三种运行模式2.4 backoffLimit 与失败重试Job 默认会在 Pod 失败后重试由backoffLimit控制最大重试次数默认 6达到上限后 Job 标记为 Failed。对于幂等性任务如数据备份可设置较高重试次数对于非幂等任务如数据库迁移建议设为 1 或 2避免重复执行产生脏数据。2.5 并行 Job 的工作队列模式对于需要并行处理的大规模任务如批量图片压缩、日志分析可以配置并行 Jobspec: completions:50# 总共需要完成 50 个 Podparallelism:10# 同时运行 10 个 Pod这种模式下Job Controller 会始终维持 10 个 Pod 并行运行直至全部 50 个 Pod 成功完成。适合将大型任务拆分为独立子任务并行处理的场景。三、CronJob定时任务3.1 什么是 CronJobCronJob 在指定的时间表上自动创建 Job语法与 Linux crontab 完全一致。它是对 Job 的定时调度封装。典型使用场景每日凌晨数据库备份每小时日志轮转与归档每周生成业务报表定期证书续期检查3.2 实战每日凌晨 2 点备份 Redis将前面的一次性 Job 升级为 CronJobapiVersion: batch/v1 kind: CronJob metadata: name: redis-daily-backup spec: schedule:0 2 * * *jobTemplate: spec: ttlSecondsAfterFinished:86400template: spec: restartPolicy: OnFailure containers: - name: backup image: redis:alpine command: -sh--c-|echo定时备份开始时间:$(date)redis-cli-hredis-service-p6379--rdb/backup/dump.rdbif[$?-eq0];thenecho备份成功elseecho备份失败exit1fivolumeMounts: - name: backup-storage mountPath: /backup volumes: - name: backup-storage emptyDir:{}关键配置说明schedule: 0 2 * * *使用标准 crontab 语法——分、时、日、月、周表示每天凌晨 2:00 执行jobTemplate内嵌了 Job 的完整 spec结构与 Job YAML 完全一致restartPolicy: OnFailure比Never更适合定时任务——偶发性网络抖动导致的失败会被自动重试ttlSecondsAfterFinished: 86400保留 24 小时后自动清理部署并验证kubectl apply-fredis-cronjob.yaml kubectl get cronjob# NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE# redis-daily-backup 0 2 * * * False 0 none 10s3.3 手动触发 CronJob从 K8s v1.27 起可以直接从 CronJob 创建一个一次性 Jobkubectl create job manual-backup--fromcronjob/redis-daily-backup kubectl get pods-ljob-namemanual-backup这个命令会基于 CronJob 的jobTemplate立即创建一个 Job用于测试定时任务的正确性。3.4 CronJob 常见参数三个重要参数的深入说明startingDeadlineSeconds当控制平面因故障恢复后发现某个 CronJob 应该被执行了 5 次但只执行了 3 次。如果设了此参数超过截止时间的任务会被跳过避免积压的 Job 同时爆发占用集群资源。concurrencyPolicyAllow允许同一 CronJob 的多个 Job 并行执行需保证任务是幂等的Forbid如果上一个 Job 未结束则跳过本次调度Replace取消正在运行的 Job 并启动新的。suspend: true可以在不删除 CronJob 对象的情况下暂停调度适合维护窗口期间临时禁制定时任务。四、控制器选择指南至此我们已经学过了 5 类控制器Deployment、StatefulSet将在第 27 篇之后展开、DaemonSet、Job、CronJob。如何根据业务需求选择合适的控制器与 Docker Compose 的对比Compose 没有针对不同工作负载提供不同的管理对象——所有服务都用services定义定时任务需要依赖外部 cron 或脚本触发。K8s 的控制器体系将工作负载按特征分类每种控制器针对特定场景优化了生命周期管理和调度策略。五、命令速查表六、本篇总结DaemonSet每个节点运行一个 Pod适合日志采集、监控代理等节点级守护任务。Job一次性任务运行到完成支持并行和重试适合数据库迁移、数据备份等场景。CronJob定时调度 Job基于 crontab 表达式适合定期备份、报表生成等周期性任务。控制器选型根据工作负载的特征选择合适的控制器——服务类用 Deployment节点级用 DaemonSet批处理用 Job/CronJob。至此K8s 的核心工作负载控制器你已经全部掌握。下一篇文章——第 28 篇Service为 Pod 提供稳定的访问入口我们将解决一个关键问题Deployment 管理着不断变化 IP 的 Pod其他服务如何稳定地找到它们答案就是 Service。想了解更多还可以去各个平台搜索「IT策士」一起升级 IT 思维