# 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 的区别:

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

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

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

yaml 复制代码
# job1.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: process-item
  labels:
    jobgroup: jobexample
spec:
  template:
    metadata:
      name: jobexample
      labels:
        jobgroup: jobexample
    spec:
      containers:
      - name: c
        image: docker.io/library/busybox:1.28
        imagePullPolicy: IfNotPresent
        command: ["sh", "-c", "echo Processing item && sleep 15"]
      restartPolicy: Never   # ⚠️ Job 中不能使用 Always

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

参数解析:

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

restartPolicy 在 Job 中的说明:

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

为什么这里没有标签选择器?

因为 Job 采用"命令式创建 + 属主引用"的强绑定方式,控制器创建 Pod 后立即记录引用,后续通过 ownerReferences (通过kubectl describe pod xxx 命令查看)追踪 Pod 的生命周期

操作命令
bash 复制代码
# 创建 Job
[root@hd1 k8s]# kubectl apply -f job1.yaml

# 查看 Job 状态
[root@hd1 k8s]# kubectl get job
NAME            COMPLETIONS   DURATION   AGE
process-item    1/1           16s        20s

# 查看 Pod(任务完成后状态为 Completed)
[root@hd1 k8s]# kubectl get pod | grep process
process-item-9wq4m   0/1     Completed   0          20s

# 查看 Pod 日志(输出命令执行结果)
[root@hd1 k8s]# kubectl logs process-item-9wq4m
Processing item

#这个语法也有相同的效果,只是用的是job的名称
[root@hd1 k8s]# kubectl logs job/process-item
Processing item

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

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

yaml 复制代码
# job2.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: docker.io/library/perl:5.34.0
        imagePullPolicy: IfNotPresent
        command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4

新增参数解析:

字段 说明
backoffLimit: 4 重试次数限制 :Pod 失败后最多重试 4 次。如果所有尝试都失败,Job 状态变为 Failed。默认值为 6
操作命令
bash 复制代码
# 创建 Job
[root@hd1 k8s]# kubectl apply -f job2.yaml

# 查看 Job 控制器
[root@hd1 k8s]# kubectl get job pi
NAME   COMPLETIONS   DURATION   AGE
pi     1/1           12s        30s

# 查看 Job 的日志(通过 job 名称直接查看)
[root@hd1 k8s]# kubectl logs job/pi
3.14159265358979323846264338327950288419716939937510...

2.4 Job 的其他常用配置

配置项 说明 示例
completions 指定需要成功完成的 Pod 数量(并行场景) completions: 5 表示需要 5 个 Pod 成功完成
parallelism 指定同时运行的 Pod 数量上限 parallelism: 2 表示最多同时运行 2 个 Pod
activeDeadlineSeconds Job 的最长运行时间(超时则标记失败) 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 表达式,格式为:

text 复制代码
分钟 小时 日 月 星期
字段 取值范围 说明
分钟 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 示例,它会在每分钟执行一次,打印当前时间和问候信息。

yaml 复制代码
# cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec: 
  schedule: "* * * * *"   #调度时间表:Cron 表达式,指定何时触发任务
  jobTemplate:            #Job 模板:定义每次触发时创建的 Job 规格
    spec:           #Job 的规格
      template:
        spec:
          containers:
          - name: hello
            image: docker.io/library/busybox:1.28
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

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

CronJob 中 restartPolicy 的选择 :

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

重启策略 适用场景
OnFailure 推荐:Pod 失败时原地重启,能快速恢复,适合大多数定时任务
Never 任务失败时重建新 Pod,适合完全隔离的重试场景
应用yaml
bash 复制代码
# 创建 CronJob
[root@hd1 k8s]# kubectl apply -f cronjob.yaml
cronjob.batch/hello created

# 查看 CronJob
[root@hd1 k8s]# kubectl get cronjob
NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   * * * * *     False     0        44s             60s

# 查看由 CronJob 创建的 Job
[root@hd1 k8s]# kubectl get job
NAME             COMPLETIONS   DURATION   AGE
hello-28229083   1/1           3s         90s
hello-28229084   1/1           3s         30s

# 查看 Pod
[root@hd1 k8s]# kubectl get pod | grep hello
hello-28229083-2n6gz   0/1     Completed   0          90s
hello-28229084-xkzsj   0/1     Completed   0          30s

# 查看第一次执行的日志
[root@hd1 k8s]# kubectl logs hello-28229083-2n6gz
Sun Sep 3 12:43:01 UTC 2023
Hello from the Kubernetes cluster

# 查看第二次执行的日志
[root@hd1 k8s]# kubectl logs hello-28229084-xkzsj
Sun Sep 3 12:44:01 UTC 2023
Hello 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 示例:

yaml 复制代码
apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "0 2 * * *"
  startingDeadlineSeconds: 60
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 5
  failedJobsHistoryLimit: 2
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox:1.28
            command: ["sh", "-c", "date; echo Hello"]
          restartPolicy: OnFailure

四、Job 与 CronJob 对比总结

对比维度 Job CronJob
执行频率 一次性执行 周期性执行(按 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 常用命令速查

bash 复制代码
# ---------- Job 相关 ----------

# 创建 Job
kubectl apply -f job.yaml

# 查看 Job
kubectl get job
kubectl get job -o wide

# 查看 Job 详情
kubectl describe job <job-name>

# 查看 Job 的日志
kubectl logs job/<job-name>

# 删除 Job(同时删除关联的 Pod)
kubectl delete job <job-name>


# ---------- CronJob 相关 ----------

# 创建 CronJob
kubectl apply -f cronjob.yaml

# 查看 CronJob
kubectl get cronjob
kubectl get cj

# 查看 CronJob 详情
kubectl describe cronjob <cronjob-name>

# 查看 CronJob 创建的 Job
kubectl get job | grep <cronjob-name>

# 删除 CronJob(同时删除关联的 Job 和 Pod)
kubectl delete cronjob <cronjob-name>

# 暂停 CronJob
kubectl patch cronjob <cronjob-name> -p '{"spec":{"suspend":true}}'

# 恢复 CronJob
kubectl patch cronjob <cronjob-name> -p '{"spec":{"suspend":false}}'

5.4 Job 与 CronJob 创建的资源链

text 复制代码
┌─────────────────────────────────────────────────────────────────────────────┐
│                         资源创建链关系                                       │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  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 的补充

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

yaml 复制代码
spec:
  completions: 5      # 总共需要成功完成 5 个 Pod
  parallelism: 2      # 最多同时运行 2 个 Pod

工作流程:

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

3. 关于 Job 的超时控制

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

yaml 复制代码
spec:
  activeDeadlineSeconds: 300   # Job 最长运行 300 秒(5 分钟)

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

相关推荐
yi0115 小时前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
_upupup6 小时前
Linux的调试工具——gdb/cgdb
linux·服务器
JeJe同学6 小时前
Docker镜像导入、容器启动
linux·运维·docker
志尊宝6 小时前
Vue3 零基础每日笔记(073):keep-alive 页面缓存实战——列表页返回不丢状态
vue.js·笔记·缓存·#vue #前端 #前端开发·#javascript·#vue.js
Jason_zhao_MR7 小时前
Linux与实时控制如何兼得
linux·嵌入式硬件·机器人·工业控制
闲云野鹤在人间7 小时前
MySQL|从理论、安装、备份到主从复制、MHA高可用详解
linux·运维·数据库·mysql·云计算
weixin_448119948 小时前
Datawhale Easy Data × AI:笔记1 已重做,看新的笔记
笔记
openFuyao8 小时前
新增Agent沙箱调度能力!openFuyao v26.09社区发行版上线,AI原生基础设施能力进一步升级
云原生·ai-native·ai推理·openfuyao·多样化算力集群软件
一个风轻云淡8 小时前
GCC 和 GDB命令简单解读
java·linux·前端
H.莓飛9 小时前
【数据结构】二叉树_OJ题
linux·开发语言·数据结构·算法