三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

# Kubernetes(K8s)笔记Day13 :工作负载资源概述与 Job (CronJob)控制器

# Kubernetes(K8s)笔记Day13 :工作负载资源概述与 Job (CronJob)控制器

一、Kubernetes 工作负载资源概述

Kubernetes 提供若干种内置的工作负载资源(控制器),用于管理不同场景下的 Pod:

工作负载资源适用场景核心特点
Deployment无状态应用(如 Web 服务、API 网关)Pod 相互等价,可随时替换,支持滚动更新和回滚
StatefulSet有状态应用(如数据库、消息队列)Pod 有固定身份和独立存储,启停有序
DaemonSet节点级支撑服务(如日志采集、网络插件)每个节点上运行且仅运行一个 Pod 副本
Job一次性任务(如数据迁移、批量计算)Pod 运行完成后自动退出,不再重启
CronJob定时任务(如定期备份、定时报表)按照 Cron 表达式周期性地创建 Job

核心概念:工作负载资源本质上就是控制器(Controller) + Pod 模板。控制器负责根据 Pod 模板创建和管理 Pod 的生命周期。

二、Job(一次性任务)

2.1 什么是 Job?

Job是 Kubernetes 中用于管理一次性任务的控制器。它创建一个或多个 Pod,并确保指定数量的 Pod 成功完成执行。

核心特点:

特点说明
一次性执行Job 创建的 Pod 在任务完成后会退出,状态变为Completed,而不是像 Deployment 那样持续运行
自动重启如果 Pod 失败或被删除,Job 控制器会自动创建一个新的 Pod 继续执行,直到任务成功完成
适用场景批处理任务、数据迁移、报表生成、计算任务等只需要执行一次的场景

Job 与普通 Pod 的区别:

对比维度普通 PodJob 管理的 Pod
退出后行为退出后不再处理(除非设置restartPolicy)失败后会重试,直到成功或达到重试上限
管理方式独立存在,需手动管理由 Job 控制器自动管理生命周期
适用场景持续运行的服务执行完即结束的一次性任务

2.2 Job 示例一:简单的批处理任务

下面是一个简单的 Job 示例,它会在 Pod 中执行一条命令,输出信息并等待 15 秒后退出。

# job1.yamlapiVersion:batch/v1kind:Jobmetadata:name:process-itemlabels:jobgroup:jobexamplespec:template:metadata:name:jobexamplelabels:jobgroup:jobexamplespec:containers:-name:cimage:docker.io/library/busybox:1.28imagePullPolicy:IfNotPresentcommand:["sh","-c","echo Processing item && sleep 15"]restartPolicy:Never# ⚠️ Job 中不能使用 Always

这个pod的作用是输出Processing item,等待15秒之后自动退出

参数解析:

字段说明
apiVersion: batch/v1Job 资源所属的 API 组和版本
kind: Job资源类型为 Job
metadata.nameJob 的名称
spec.templatePod 模板,定义要运行的 Pod 规格
spec.template.spec.containers容器定义,指定镜像和要执行的命令
spec.template.spec.restartPolicy重启策略:Job 中必须设置为Never或OnFailure,不能使用默认的Always

restartPolicy在 Job 中的说明:

重启策略行为
NeverPod 失败后,Job 控制器会创建新的 Pod来重试
OnFailurePod 失败后,原地重启容器(不创建新 Pod)
AlwaysJob 中不可用,会导致 Job 无法正常完成

为什么这里没有标签选择器?
因为 Job 采用“命令式创建 + 属主引用”的强绑定方式,控制器创建 Pod 后立即记录引用,后续通过 ownerReferences (通过kubectl describe pod xxx 命令查看)追踪 Pod 的生命周期

操作命令
# 创建 Job[root@hd1 k8s]# kubectl apply -f job1.yaml# 查看 Job 状态[root@hd1 k8s]# kubectl get jobNAME COMPLETIONS DURATION AGE process-item1/1 16s 20s# 查看 Pod(任务完成后状态为 Completed)[root@hd1 k8s]# kubectl get pod | grep processprocess-item-9wq4m0/1 Completed020s# 查看 Pod 日志(输出命令执行结果)[root@hd1 k8s]# kubectl logs process-item-9wq4mProcessing item#这个语法也有相同的效果,只是用的是job的名称[root@hd1 k8s]# kubectl logs job/process-itemProcessing item

2.3 Job 示例二:计算 π 到小数点后 2000 位

这是一个稍微复杂的 Job 示例,它使用 Perl 镜像计算 π 的值,并打印结果。

# job2.yamlapiVersion:batch/v1kind:Jobmetadata:name:pispec:template:spec:containers:-name:piimage:docker.io/library/perl:5.34.0imagePullPolicy:IfNotPresentcommand:["perl","-Mbignum=bpi","-wle","print bpi(2000)"]restartPolicy:NeverbackoffLimit:4

新增参数解析:

字段说明
backoffLimit: 4重试次数限制:Pod 失败后最多重试 4 次。如果所有尝试都失败,Job 状态变为Failed。默认值为 6
操作命令
# 创建 Job[root@hd1 k8s]# kubectl apply -f job2.yaml# 查看 Job 控制器[root@hd1 k8s]# kubectl get job piNAME COMPLETIONS DURATION AGE pi1/1 12s 30s# 查看 Job 的日志(通过 job 名称直接查看)[root@hd1 k8s]# kubectl logs job/pi3.14159265358979323846264338327950288419716939937510...

2.4 Job 的其他常用配置

配置项说明示例
completions指定需要成功完成的 Pod 数量(并行场景)completions: 5表示需要 5 个 Pod 成功完成
parallelism指定同时运行的 Pod 数量上限parallelism: 2表示最多同时运行 2 个 Pod
activeDeadlineSecondsJob 的最长运行时间(超时则标记失败)activeDeadlineSeconds: 300表示 5 分钟超时
backoffLimit失败重试次数上限backoffLimit: 4

三、CronJob(定时任务)

3.1 什么是 CronJob?

CronJob是 Kubernetes 中用于管理定时任务的控制器。它根据指定的时间表(Cron 表达式)周期性地创建 Job,类似于 Linux 系统中的crontab。

核心特点:

特点说明
周期性执行按照 Cron 表达式在指定的时间点自动创建 Job
自动清理可以配置保留历史 Job 的数量,自动清理旧的 Job
适用场景定期备份、定时报表生成、数据清理、定时同步等

3.2 Cron 表达式格式说明

CronJob 使用标准的 Cron 表达式,格式为:

分钟 小时 日 月 星期
字段取值范围说明
分钟0-59每小时的第几分钟
小时0-23每天的第几小时
日1-31每月的第几天
月1-12每年的第几月
星期0-6(0=星期日)每周的第几天

常见 Cron 表达式示例:

表达式含义
* * * * *每分钟执行一次
0 * * * *每小时整点执行一次(每小时的 0 分)
0 0 * * *每天午夜(0:00)执行一次
0 2 * * *每天凌晨 2:00 执行一次
0 0 * * 0每周日凌晨 0:00 执行一次
0 0 1 * *每月 1 日凌晨 0:00 执行一次
*/5 * * * *每 5 分钟执行一次
0 9-17 * * *每天 9:00 到 17:00 之间每小时执行一次

3.3 CronJob 示例:每分钟打印时间

下面是一个完整的 CronJob 示例,它会在每分钟执行一次,打印当前时间和问候信息。

# cronjob.yamlapiVersion:batch/v1kind:CronJobmetadata:name:hellospec:schedule:"* * * * *"#调度时间表:Cron 表达式,指定何时触发任务jobTemplate:#Job 模板:定义每次触发时创建的 Job 规格spec:#Job 的规格template:spec:containers:-name:helloimage:docker.io/library/busybox:1.28imagePullPolicy:IfNotPresentcommand:-/bin/sh--c-date; echo Hello from the Kubernetes clusterrestartPolicy:OnFailure

可以观测到,cronjob与job的语法基本一致,只是包裹了一层调度时间表schedule,并且将基本job的配置放到了jobTemplate下。

CronJob 中restartPolicy的选择:
在 CronJob 的 Pod 模板中,restartPolicy通常设置为OnFailure或Never。

重启策略适用场景
OnFailure推荐:Pod 失败时原地重启,能快速恢复,适合大多数定时任务
Never任务失败时重建新 Pod,适合完全隔离的重试场景
应用yaml
# 创建 CronJob[root@hd1 k8s]# kubectl apply -f cronjob.yamlcronjob.batch/hello created# 查看 CronJob[root@hd1 k8s]# kubectl get cronjobNAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE hello * * * * * False044s 60s# 查看由 CronJob 创建的 Job[root@hd1 k8s]# kubectl get jobNAME COMPLETIONS DURATION AGE hello-282290831/1 3s 90s hello-282290841/1 3s 30s# 查看 Pod[root@hd1 k8s]# kubectl get pod | grep hellohello-28229083-2n6gz0/1 Completed090s hello-28229084-xkzsj0/1 Completed030s# 查看第一次执行的日志[root@hd1 k8s]# kubectl logs hello-28229083-2n6gzSun Sep312:43:01 UTC2023Hello from the Kubernetes cluster# 查看第二次执行的日志[root@hd1 k8s]# kubectl logs hello-28229084-xkzsjSun Sep312:44:01 UTC2023Hello from the Kubernetes cluster

3.4 CronJob 的其他常用配置

配置项说明示例
startingDeadlineSeconds任务启动的截止时间(秒)。如果错过调度时间超过此值,则跳过本次执行startingDeadlineSeconds: 60
concurrencyPolicy并发策略:
-Allow(默认):允许并发执行
-Forbid:禁止并发,如果上一次未完成则跳过本次
-Replace:替换,取消上一次未完成的并启动新的
concurrencyPolicy: Forbid
successfulJobsHistoryLimit保留的成功 Job 数量(默认 3)successfulJobsHistoryLimit: 3
failedJobsHistoryLimit保留的失败 Job 数量(默认 1)failedJobsHistoryLimit: 1
suspend是否暂停调度(true暂停,false正常运行)suspend: true

带完整配置的 CronJob 示例:

apiVersion:batch/v1kind:CronJobmetadata:name:hellospec:schedule:"0 2 * * *"startingDeadlineSeconds:60concurrencyPolicy:ForbidsuccessfulJobsHistoryLimit:5failedJobsHistoryLimit:2jobTemplate:spec:template:spec:containers:-name:helloimage:busybox:1.28command:["sh","-c","date; echo Hello"]restartPolicy:OnFailure

四、Job 与 CronJob 对比总结

对比维度JobCronJob
执行频率一次性执行周期性执行(按 Cron 表达式)
适用场景批处理任务、数据迁移、一次性计算定期备份、定时报表、周期性清理
是否持续运行❌ 执行完成后 Pod 退出(Completed)❌ 每次执行完成即退出,但会定期创建新任务
失败重试✅ 支持(通过backoffLimit控制)✅ 支持(通过 Job 模板的backoffLimit控制)
并发控制通过parallelism和completions控制通过concurrencyPolicy控制
历史保留❌ 不涉及✅ 支持保留成功/失败的历史 Job 数量
暂停调度❌ 不涉及✅ 支持(suspend: true)
错过调度处理❌ 不涉及✅ 支持(startingDeadlineSeconds)

五、核心知识点速查

5.1 Job 核心要点

知识点说明
restartPolicy限制Job 中不能使用Always,只能使用Never或OnFailure
backoffLimit失败重试次数上限,默认 6 次
completions需要成功完成的 Pod 数量(默认 1)
parallelism并行运行的 Pod 数量上限(默认 1)
查看日志kubectl logs job/<job-name>可直接查看 Job 的日志
删除 Job删除 Job 时会自动删除其创建的 Pod(kubectl delete job <name>)

5.2 CronJob 核心要点

知识点说明
时间表格式标准 Cron 表达式:分钟 小时 日 月 星期
Job 模板spec.jobTemplate.spec中定义 Job 规格,与独立 Job 完全相同
并发策略Allow(默认)、Forbid、Replace
历史限制successfulJobsHistoryLimit(默认 3)和failedJobsHistoryLimit(默认 1)
暂停调度suspend: true可暂停 CronJob 的调度

5.3 常用命令速查

# ---------- Job 相关 ----------# 创建 Jobkubectl apply-fjob.yaml# 查看 Jobkubectl get job kubectl get job-owide# 查看 Job 详情kubectl describe job<job-name># 查看 Job 的日志kubectl logs job/<job-name># 删除 Job(同时删除关联的 Pod)kubectl delete job<job-name># ---------- CronJob 相关 ----------# 创建 CronJobkubectl apply-fcronjob.yaml# 查看 CronJobkubectl get cronjob kubectl get cj# 查看 CronJob 详情kubectl describe cronjob<cronjob-name># 查看 CronJob 创建的 Jobkubectl get job|grep<cronjob-name># 删除 CronJob(同时删除关联的 Job 和 Pod)kubectl delete cronjob<cronjob-name># 暂停 CronJobkubectl patch cronjob<cronjob-name>-p'{"spec":{"suspend":true}}'# 恢复 CronJobkubectl patch cronjob<cronjob-name>-p'{"spec":{"suspend":false}}'

5.4 Job 与 CronJob 创建的资源链

┌─────────────────────────────────────────────────────────────────────────────┐ │ 资源创建链关系 │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ Deployment → ReplicaSet → Pod │ │ StatefulSet → Pod(直接管理) │ │ DaemonSet → Pod(直接管理) │ │ │ │ Job → Pod(直接管理,Pod 完成后进入 Completed) │ │ CronJob → Job → Pod(定期创建新的 Job) │ │ │ └─────────────────────────────────────────────────────────────────────────────┘

六、常见问题排查

问题现象可能原因解决方法
Job 一直卡在Running不结束容器内的进程没有退出,或进入死循环检查命令是否正确;确保命令执行完成后进程自然退出
Job 显示Failed容器退出码非 0,且重试次数已用完kubectl logs <pod>查看失败原因;调整backoffLimit增加重试次数
CronJob 没有按时执行时间表表达式写错,或节点时间不同步检查 Cron 表达式格式;确认节点系统时间是否正确
CronJob 积累了过多的 Job未设置历史限制,或限制值过大设置successfulJobsHistoryLimit和failedJobsHistoryLimit
同一个 CronJob 的任务重叠执行并发策略为Allow(默认)将concurrencyPolicy改为Forbid或Replace

七、总结

资源类型一句话总结
Job“一次性任务”:只执行一次,执行完 Pod 自动退出,失败会自动重试
CronJob“定时任务”:根据 Cron 表达式周期性创建 Job,适合定期执行的任务

八、部分参数的补充说明

1. 关于 CronJob 的时间表

重要提示:CronJob 的时间表是基于Kubernetes 控制平面所在的时区(通常是 UTC 时间),而非本地时区。如果需要在特定本地时间执行任务,需要注意时区换算,或使用CRON_TZ变量(部分版本支持)。

2. 关于 Job 的completions和parallelism的补充

原文未涉及这两个参数。补充说明如下:

spec:completions:5# 总共需要成功完成 5 个 Podparallelism:2# 最多同时运行 2 个 Pod

工作流程:

  1. Job 控制器首先启动 2 个 Pod(受parallelism限制)
  2. 每完成一个 Pod,就启动下一个
  3. 直到累计完成 5 个 Pod(受completions限制),Job 标记为完成

3. 关于 Job 的超时控制

示例中未涉及activeDeadlineSeconds,补充说明:

spec:activeDeadlineSeconds:300# Job 最长运行 300 秒(5 分钟)

如果 Job 运行时间超过此值,Job 会被标记为Failed,即使重试次数未用完。超时控制常用于防止任务因异常而无限执行。

← 返回列表