【探索 Kubernetes|作业管理篇 系列 16】离线业务 Job、CronJob

news2024/9/24 3:24:09

前言

大家好,我是秋意零。

在上一篇中,我们讲解了 DaemonSet 控制器,相信你以及理解了其的工作过程,分为三部。一是,获取所有 Node 节点中的 Pod;二是,判断是否有符合 DaemonSet 管理的 Pod;三是,通过“亲和性”和“容忍”来精确控制并保证 Pod 在目标节点运行。

今天的内容是 Job 与 CronJob 离线业务控制器。

👿 简介

  • 🏠 个人主页: 秋意零
  • 🔥 账号:全平台同名, 秋意零 账号创作者、 云社区 创建者
  • 🧑 个人介绍:在校期间参与众多云计算相关比赛,如:🌟 “省赛”、“国赛”,并斩获多项奖项荣誉证书
  • 🎉 目前状况:24 届毕业生,拿到一家私有云(IAAS)公司 offer,暑假开始实习
  • 💕欢迎大家:欢迎大家一起学习云计算,走向年薪 30 万
  • 💕推广:CSDN 主页左侧,是个人扣扣群推广。方便大家技术交流、技术博客互助

系列文章目录


【云原生|探索 Kubernetes-1】容器的本质是进程
【云原生|探索 Kubernetes-2】容器 Linux Cgroups 限制
【云原生|探索 Kubernetes 系列 3】深入理解容器进程的文件系统
【云原生|探索 Kubernetes 系列 4】现代云原生时代的引擎
【云原生|探索 Kubernetes 系列 5】简化 Kubernetes 的部署,深入解析其工作流程


更多点击专栏查看:深入探索 Kubernetes

正文开始

  • 快速上船,马上开始掌舵了(Kubernetes),距离开船还有 3s,2s,1s...

一、离线业务

通过前面篇章中的学习的控制器,如:Deployment、StatefulSet、DaemonSet 这三个编排控制器,它们所部署的服务都有什么共同点吗?

答案是:有的。

  • 其实,它们主要编排的对象业务,都是“在线业务”,即:Long Running Task(长作业)。比如:Nginx、Tomcat、Apache、MySQL 等等,这部分业务只要一运行起来,如果不出现错误或手动停止删除,这些服务的容器(进程)会一直运行(Running)下去。

既然有了这种“在线业务”,那是不是就一定有“离线业务”呢?

答案:是的。

  • “离线业务”对比“在线业务”是相反的概率,就是服务不会一直运行下去,而是服务自己的任务完成之后就会自动退出。

如果使用控制“在线业务”的控制器,来编排“离线业务”会是怎么样呢?

  • 离线业务”或者叫作 Batch Job(计算业务):这种情况下是没有意义的,比如:使用 Deployment 来编排一个“离线业务”,“离线业务”完成后就会自动退出,而因为 Deployment 的缘故会实际状态的 Pod 个数保持在期望状态的 Pod 个数,也就会重新创建这个“离线业务”。
  • 咋一看,好像也没什么,如果将“离线业务”任务是用来计算 1+1 的这种运行结果时,不断重建“离线业务”是不是就失去了意义了呢?
  • 因为完全没有必要。而使用 Deployment 的“滚动更新”功能也是一样的道理,无意义。

二、Job 基本概念与用法

现在,我们来看一个 Job 计算 π 后 10000 位小数的例子:

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: resouer/ubuntu-bc 
        command: ["sh", "-c", "echo 'scale=10000; 4*a(1)' | bc -l "]
      restartPolicy: Never
  backoffLimit: 4

可以看到,这个例子的 spec.template字段可谓是非常熟悉了吧(Pod 模板)。但是,跟其他控制器不同的是,Job 对象并不要求你定义一个 spec.selector 来绑定要控制哪些 Pod。

这个 Job 使用的一个 ubuntu 镜像 ,安装有 bc 精度的计算命令,并运行了一条计算 π 后 10000 位小数的命令:

echo 'scale=10000; 4*a(1)' | bc -l
  • scale:定义某些操作如何使用小数点后的数字,默认为 0;
  • 4*a(1):a(1),是调用数学库中的 arctangent 函数,4*atan(1) 正好就是 π,也就是 3.1415926…;
  • -l 参数:定义使用的标准数学库。

  1. 运行这个 Job:
[root@master01 yaml]# kubectl apply -f job.yaml
job.batch/pi created

[root@master01 yaml]# kubectl describe job/pi

我们来查看一下这个 Job 对象详细信息:

  • 可以看到创建 Job 之后,Job 自动为 Pod Template 添加了一个标签,格式为:controller-uid=<一个随机字符串>。Job 本身也添加了对应的 Selector,从而保证了 Job 与它所管理的 Pod 之间的匹配关系。
  • 而 Job 控制器使用这种 UID 的标签,就是为了避免不同 Job 对象所管理的 Pod 发生重合。因为它不需要对特定的副本进行选择或管理,Job 仅负责执行一次性任务,而不需要与其他副本进行交互或进行标签选择。
  • Job 中也没有 replicas 字段。因为, Job 的主要目的是确保任务的完成,不是保持一定数量的副本运行。当 Job 中定义的任务成功完成后,Job 会认为任务已经完成,并且不会重新创建新的任务。因此,replicas 字段在 Job 中没有意义。

  1. 创建 Job 后,查看 Pod 的状态:
[root@master01 yaml]# kubectl get pod
NAME       READY   STATUS    RESTARTS   AGE
pi-nxplz   1/1     Running   0          31s

几分钟后 Pod 进入 Completed 状态,说明它的任务已经完成。不重启的原因:我们在 Pod 模板中定义过了 restartPolicy=Never 策略。

Job 中的重启策略 restartPolicy,只能被设置为 Never 和 OnFailure;

[root@master01 yaml]# kubectl get pod
NAME       READY   STATUS      RESTARTS   AGE
pi-nxplz   0/1     Completed   0          4m

[root@master01 yaml]# kubectl get job
NAME   COMPLETIONS   DURATION   AGE
pi     0/1           3s         3s

  1. kubectl logs 命令,查看运行结果:
[root@master01 ~]# kubectl logs pod/pi-nxplz
3.141592653589793238462643383279502884197169399375105820974944592307\
81640628620899862803482534211706798214808651328230664709384460955058\
22317253594081284811174502841027019385211055596446229489549303819644\
28810975665933446128475648233786783165271201909145648566923460348610\
....

  1. 离线作业失败了要怎么办?

由于,定义了 restartPolicy=Never,那么离线作业失败后 Job Controller 就会不断地尝试创建一个新 Pod,如:

$ kubectl get pods
NAME                                READY     STATUS              RESTARTS   AGE
pi-55h89                            0/1       ContainerCreating   0          2s
pi-tqbcz                            0/1       Error               0          5s

不过,为了不让这个 Pod 一直创建下去,因为一直创建下去说明我们程序就有问题,这个时候我们使用 spec.backoffLimit字段来设置重试次数,这个 Job 为 4,这个字段的默认值是 6。

需要注意的是:Job Controller 重新创建 Pod 的间隔是呈指数增加的,即:下一次重新创建 Pod 的动作会分别发生在 10 s、20 s、40 s …后。

而如果你定义的 restartPolicy=OnFailure,那么离线作业失败后,Job Controller 就不会去尝试创建新的 Pod。但是,它会不断地尝试重启 Pod 里的容器。

  1. 如果这个 Pod 因为某种原因一直不肯结束呢?

spec.activeDeadlineSeconds字段可以设置最长运行时间,比如:

spec:
 backoffLimit: 4
 activeDeadlineSeconds: 100

这个程序运行一旦超过 100 s,那 Pod 会被终止。

以上,就是一个 Job API 对象最主要的概念和用法了。不过,离线业务之所以被称为 Batch Job,当然是因为它们可以以“Batch”(批处理),也就是并行的方式去运行。

三、Job Controller 并行作业的控制方法

在 Job 对象中,负责并行控制的参数有两个:

  • 1. spec.parallelism:Job 最多可以启动多少个 Pod 同时运行;
  • 2. spec.completions:Job 至少要完成的 Pod 数目,即 Job 的最小完成数。

在之前计算 Pi 值的 Job 里,添加这两个参数:

  • 并行数量为 2
  • 至少完成的数量为 4
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  parallelism: 2
  completions: 4
  template:
    spec:
      containers:
      - name: pi
        image: resouer/ubuntu-bc
        command: ["sh", "-c", "echo 'scale=5000; 4*a(1)' | bc -l "]
      restartPolicy: Never
  backoffLimit: 4
  1. 创建 Job:
[root@master01 yaml]# kubectl apply -f job.yaml
  1. 查看 Job:
  • COMPLETIONS:需要完成的数量以及完成的数量,比如:2/4,已完成 2 个任务,至少需要完成 4 个任务。
[root@master01 yaml]# kubectl get job
NAME   COMPLETIONS   DURATION   AGE
pi     2/4           57s        57s

当一组 Pod 完成后,就会有新的一组 Pod 继续执行

[root@master01 yaml]# kubectl get pod
NAME       READY   STATUS      RESTARTS   AGE
pi-js98q   1/1     Running     0          25s
pi-mhfsl   1/1     Running     0          25s
pi-t2w8n   0/1     Completed   0          55s
pi-z7gqh   0/1     Completed   0          55s

当所有 Pod 任务完成之后,Job 的 COMPLETIONS 字段也就变成了 4/4

[root@master01 yaml]# kubectl get pod
NAME       READY   STATUS      RESTARTS   AGE
pi-js98q   0/1     Completed   0          8m56s
pi-mhfsl   0/1     Completed   0          8m56s
pi-t2w8n   0/1     Completed   0          9m26s
pi-z7gqh   0/1     Completed   0          9m26s

[root@master01 yaml]# kubectl get job
NAME   COMPLETIONS   DURATION   AGE
pi     4/4           59s        3m59s

Job Controller 实际上控制了,作业执行的并行度,以及总共需要完成的任务数这两个重要参数。而在实际使用时,你需要根据作业的特性,来决定并行度(parallelism)和任务数(completions)的合理取值。

四、使用 Job 常用的方法

外部管理器 +Job 模板

这种模式的用法是:把 Job 的 YAML 文件当作一个模板,然后使用外部工具来控制生成 Job。如下:

apiVersion: batch/v1
kind: Job
metadata:
  name: process-item-$ITEM
  labels:    
    jobgroup: jobexample
spec:
  template:
    metadata:
      name: job-example
      labels: 
        jobgroup: jobexample
    spec:
      containers:
      - name: busybox-job
        image: busybox
        command: ["sh", "-c", "echo Hello $ITEM && sleep 5"]
      restartPolicy: Never

Job 的 YAML 中,定义了 $ITEM 变量,所以在控制这中 Job 时,需要注意两个方面:

  • 1. 创建 Job 时,替换掉 $ITEM 变量,为自己的信息;
  • 2. 来自于同一个模板的 Job,这里都有一个 jobgroup: jobexample标签,也就是说这一组 Job 使用这样一个相同的标识。

使用 Shell 把 $ITME 替换掉

[root@master01 yaml]# mkdir ./jobs
[root@master01 yaml]# for i in qyl-1 qyl-2 qyl-3
> do
>   cat job-1.yaml | sed "s/\$ITEM/$i/g" > ./jobs/job-$i.yaml
> done

这样通过 Shell 脚本的方式,同一个 Job 模板生成了不同的 Job 的 YAML 文件

[root@master01 yaml]# ll ./jobs
total 12
-rw-r--r-- 1 root root 372 Jun 25 17:31 job-qyl-1.yaml
-rw-r--r-- 1 root root 372 Jun 25 17:31 job-qyl-2.yaml
-rw-r--r-- 1 root root 372 Jun 25 17:31 job-qyl-3.yaml

[root@master01 yaml]# kubectl apply -f ./jobs
job.batch/process-item-qyl-1 created
job.batch/process-item-qyl-2 created
job.batch/process-item-qyl-3 created

[root@master01 yaml]# kubectl get pods -l jobgroup=jobexample
NAME                       READY   STATUS      RESTARTS   AGE
process-item-qyl-1-tgr5k   0/1     Completed   0          53s
process-item-qyl-2-bftz4   0/1     Completed   0          53s
process-item-qyl-3-cgvwd   0/1     Completed   0          53s

五、CronJob

顾名思义,CronJob 描述的,是定时任务。

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            imagePullPolicy: IfNotPresent
            args:
            - /bin/sh
            - -c
            - date; echo Hello qyl-0
          restartPolicy: OnFailure

CronJob 的 YAML 文件中,spec.jobTemplate字段表示的是“Job模板”,所以 CronJob 是 Job 对象的控制器。CronJob 与 Job 之间的关系就与 Deployment 和 ReplicaSet 一样的。不过它生命周期是由 schedule 字段控制的。

它也像我们 Linxu 里面的 CronTab,所以这里的 schedule 字段的格式是一个标准的 Cron 格式。比如:"*/1 * * * *"

这个 Cron 表达式里 */1 中的 * 表示从 0 开始,/ 表示“每”,1 表示偏移量。所以,它的意思就是:从 0 开始,每 1 个时间单位执行一次。

所以,上面的 CronJob 的 YAML 文件会一分钟后创建 Job:

[root@master01 yaml]# kubectl get cronjob
NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   */1 * * * *   False     0        26s             58s
[root@master01 yaml]# kubectl get job
NAME             COMPLETIONS   DURATION   AGE
hello-28128130   1/1           4s         27s

需要注意的是,由于定时任务的特殊性,很可能某个 Job 还没有执行完,另外一个新 Job 就产生了。这时候,你可以通过 spec.concurrencyPolicy字段来定义具体的处理策略。比如:

  • concurrencyPolicy=Allow:这也是默认情况,这意味着这些 Job 可以同时存在
  • concurrencyPolicy=Forbid:这意味着不会创建新的 Pod,该创建周期被跳过;
  • concurrencyPolicy=Replace:这意味着新产生的 Job 会替换旧的、没有执行完的 Job。

而如果某一次 Job 创建失败,这次创建就会被标记为“miss”。当在指定的时间窗口内,miss 的数目达到 100 时,那么 CronJob 会停止再创建这个 Job。

这个时间窗口,可以由 spec.startingDeadlineSeconds字段指定。比如:

  • startingDeadlineSeconds=200,意味着在过了 200 s 后,如果 miss 的数目达到了 100 次,那么这个 Job 就不会被创建执行了。

总结

今天,主要讲解了 Job 这种“离线业务”控制器的概率用法,并行控制的方法。

最后,解释了 CronJob 的使用,CronJob 也体现了,用一个对象控制另一个对象,是 Kubernetes 编排的精髓所在。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/710638.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

osg实现镜面成像、倒影效果

目录 1. 需求提出 2. 代码实现 3. 功能讲解 3.1. 设置地面半透明 3.2. 设置镜面倒影成像 3.3. 设置地面颜色 3.4. 设置相机初始位置 4. 总结 1. 需求提出 平时的业务需求&#xff0c;有时需要实现镜面成像、倒影效果&#xff0c;如下&#xff1a…

79、基于STM32单片机DHT11温湿度无线蓝牙手机APP监控报警系统(程序+原理图+PCB图+设计资料+参考论文+开题报告+元器件清单等)

摘 要 温湿度控制已成为当今社会研究的热门项目。是工农业生产过程中必须考虑的因素。作为最常见的被控参数。温度和湿度已经不再是相互独立的物理量&#xff0c;而应在系统中综合考虑。广泛应用于实验室、大棚、花圃、粮仓乃至土壤等各个领域。而传统的温湿度控制则利用湿度…

Qt QLineEdit篇

QLineEdit篇 【1】QLineEdit简介【2】QLineEdit常用方法【3】QLineEdit使用举例UI设计界面效果头文件源文件 PC饱和了&#xff0c;跟我学Qt比较实在&#xff0c;哈哈哈 【1】QLineEdit简介 QLineEdit是Qt框架中的一个类&#xff0c;用于创建一个文本输入框&#xff0c;允许用…

【WSN定位】基于蜣螂优化算法DBO的Dvhop定位算法 不同锚节点比例和不同通信半径情况下对比【Matlab代码#45】

文章目录 【可更换其他算法&#xff0c;获取资源请见文章第5节&#xff1a;资源获取】1. Dvhop定位算法2. 蜣螂优化算法3. 部分代码展示4. 仿真结果展示5. 资源获取 【可更换其他算法&#xff0c;获取资源请见文章第5节&#xff1a;资源获取】 1. Dvhop定位算法 根据距离矢量和…

#systemverilog# 关于随机约束之 约束块

随机变量的值通过由约束块声明的约束表达式来确定。像任务、函数和变量一样,随机块是类的成员。在一个类中,约束块的名字必须是唯一的。 一 语法定义 声明约束块的语法如下: (1)constraint_identifier是约束块的名字。使用constraint_mode()(参见12.8节)方法,这个名字…

初步认识Java垃圾回收算法

GCRoot指被栈上直接或间接引用的对象&#xff0c;或被本地方法栈直接或间接引用的对象&#xff0c;或被方法区引用的对象。 被引用的对象是不能被删除的。 如果对象跟GCRoot并没有直接或间接相连的关系&#xff0c;那么这些对象就可以被删除了。 标记-清理&#xff1a;将需要删…

C++智能指针使用陷阱、shared_ptr实现

一 智能指针使用概述 1.使用场景 1.1 unique_ptr 1.1.1 概念 std::unique_ptr 是通过指针占有并管理另一对象&#xff0c;并在 unique_ptr 离开作用域时释放该对象的智能指针。 std::unique_ptr 常用于管理对象的生存期&#xff0c;包含&#xff1a; 通过正常退出和经由异…

SpringBoot 实现导出数据 - EasyExcel 导出数据

文章目录 1. EasyExcel 介绍2. 导出2.1 引入依赖2.2 构建测试实体类 3. 设置单元格大小 1. EasyExcel 介绍 EasyExcel 官网介绍 传统操作Excel大多都是利用 Apach POI 进行操作的&#xff0c;但是 POI 框架并不完善&#xff0c;使用过程非常繁琐且有较多的缺陷&#xff1a; 动态…

lesson11 Zigbee MAC地址通信

目录 Zigbee MAC地址通信 前言 查看MAC地址&#xff08;含组网过程抓包分析&#xff09; 方法1&#xff1a;通过dongle抓包查看MAC地址 方法2&#xff1a;仿真调试查看MAC 实验过程 实现步骤 实验效果 出错分析 最终现象 结果分析 Zigbee MAC地址通信 前言 1、Zig…

Python中类的变量,一个下划线与两个下划线的区别

形似 功能__xx这是私有变量&#xff0c; 只有内部可以访问&#xff0c;外部不可以访问。但是也不是一定不可以访问&#xff0c;只要以 _类名__xx样式就可以访问 。但最好不要这样做&#xff0c;养成良好编程习惯_x这是实例变量&#xff0c;可以访问&#xff0c;但是不要轻…

STM32MP157-正点原子第六章tf-a使用编译错误

原因&#xff1a;交叉编译工具链选择错误 亲测&#xff1a; gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf.tar.xz 和 gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf.tar.xz 可以成功编译 下载网址https://mirrors.tuna.tsinghua.edu.cn/armbian-relea…

全国各城市交通运输邮电业本地电话用户(1999-2020年)

本数据展示了全国各城市的本地电话用户数量。通过对这些数量的分析&#xff0c;可以了解全国各城市通信设施建设的发展情况、人口密度以及工业经济的发展程度等方面的信息。此数据不仅可供政府部门制定信息技术政策&#xff0c;还可以为企业投资提供重要参考。同时&#xff0c;…

Leetcode-每日一题【382.链表随机结点】

题目 给你一个单链表,随机选择链表的一个节点,并返回相应的节点值。每个节点被选中的概率一样 。 实现 Solution 类&#xff1a; Solution(ListNode head) 使用整数数组初始化对象。int getRandom() 从链表中随机选择一个节点并返回该节点的值。链表中所有节点被选中的概率相…

网络空间安全专业未来的发展前景以及薪资待遇如何?

不管是考虑未来报读专业的准大学生&#xff0c;还是初入职场的实习生&#xff0c;亦或是想要跳槽转岗的职场人&#xff0c;当我们开始选择一份工作时&#xff0c;本质上都在考虑以下三个问题&#xff1a; 这份工作的收入水平如何&#xff1b;这份工作有没有发展前景&#xff1…

基于卷积神经网络的目标分类案例

文章目录 一、卷积神经网络二、环境配置及数据集准备三、猫狗数据分类建模1、猫狗图像预处理2、猫狗分类的实例——基准模型3、基准模型的调整 一、卷积神经网络 卷积神经网络&#xff08;Convolutional Neural Networks, CNN 是一类包含卷积计算且具有深度结构的前馈神经网络…

HashMap源码分析

文章目录 1、put方法流程2 、扩容机制3 、get方法 分析源码我们一般从三个方面入手&#xff1a; 常见属性&#xff08;成员变量&#xff09;构造方法关键方法 下面分析一下HashMap源码&#xff1a; 首先常见属性有&#xff1a; DEFAULT_INITIAL_CAPACITY 1 << 4; // a…

二叉树进阶——搜索二叉树

搜索二叉树 1. 概念2. 二叉搜索树的操作2.1 查找2.2 插入2.3 删除&#xff08;重点&#xff09; 3. 搜索二叉树的应用4. 搜索二叉树的性能分析 1. 概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&am…

《项目实战》构建前后端一体化项目查询CSDN博客Top100文章质量分

系列文章目录 构建前后端一体化项目查询CSDN博客Top100文章质量分 文章目录 系列文章目录前言1、搭建后端框架1.1、 创建RestFull风格接口1.2、创建获取数据服务1.2.1、在个人博客页&#xff0c;找到获取全部博文的路径&#xff08;页面-> network->找到加载博文的地址&…

C# ---委托机制 delegate 和 回调方法 callback

C# --- 委托机制 delegate 和 回调 callback 什么是委托机制委托机制的优点C# 中的Action 和 Func委托机制的主要用处 --- 回调 Callback 什么是委托机制 委托机制相当于C语言中的函数指针, 将一个方法的reference传入另外一个方法中 Example //创建一个方法 //创建一个委托 …

青少年机器人技术一级考试备考重点(二):基础结构与力的基础

随着机器人技术的飞速发展&#xff0c;越来越多的青少年开始关注并参与其中。青少年机器人技术考试作为一项评估学生机器人技术水平的重要考试&#xff0c;备受广大青少年和家长的关注。为了更好地备战青少年机器人技术一级考试&#xff0c;了解考试的学习要点和备考重点是非常…