06 Job/CronJob: 为什么不直接用Pod来处理业务?

news2024/11/26 12:51:17

文章目录

  • 1. 前言
  • 2. 为什么不直接使用pod?
    • 2.1 面向对象的设计思想
  • 3. 为什么要有Job/CronJob
    • 3.1 离线业务的种类
  • 4. 如何使用 YAML 描述 临时任务 Job
    • 4.1 Job 的 YAML“文件头”
    • 4.2 使用kubectl create 生成模板文件
    • 4.3 Job 的 YAML body 部分“spec ”
    • 4.4 如何在Kubernetes 里操作Job?
      • 4.4.1 创建
      • 4.4.2 删除
      • 4.4.3 获取状态
    • 4.5 Job 和 Pod 对象的其他字段
  • 5. 如何使用 YAML 描述 定时任务 CronJob
  • 6. 小结
  • 7. 思考
    • 7.1 你是怎么理解 Kubernetes 组合对象的方式的?它带来了什么好处?
    • 7.2 Job 和 CronJob 的具体应用场景有哪些?能够解决什么样的问题?

1. 前言

 Job 和 CronJob 也是kubernetes 的资源对象。

 学习了 Kubernetes 的核心对象 Pod,用来编排一个或多个容器,让这些容器共享网络、存储等资源,总是共同调度,从而紧密协同工作。

 因为 Pod 比容器更能够表示实际的应用,所以 Kubernetes 不会在容器层面来编排业务,而是把 Pod 作为在集群里调度运维的最小单位。

 前面我们也看到了一张 Kubernetes 的资源对象关系图,以 Pod 为中心,延伸出了很多表示各种业务的其他资源对象。那么你会不会有这样的疑问:Pod 的功能已经足够完善了,为什么还要定义这些额外的对象呢?为什么不直接在 Pod 里添加功能,来处理业务需求呢?

2. 为什么不直接使用pod?

 现在你应该知道,Kubernetes 使用的是 RESTful API,把集群中的各种业务都抽象为 HTTP 资源对象,那么在这个层次之上,我们就可以使用面向对象的方式来考虑问题。
< RESTful API 把集群中的各种业务都抽象为HTTP 资源对象.>

2.1 面向对象的设计思想

 如果你有一些编程方面的经验,就会知道面向对象编程(OOP),它把一切都视为高内聚的对象,强调对象之间互相通信来完成任务。

 虽然面向对象的设计思想多用于软件开发,但它放到 Kubernetes 里却意外地合适。因为 Kubernetes 使用 YAML 来描述资源,把业务简化成了一个个的对象,内部有属性,外部有联系,也需要互相协作,只不过我们不需要编程,完全由 Kubernetes 自动处理(其实 Kubernetes 的 Go 语言内部实现就大量应用了面向对象)。

 面向对象的设计有许多基本原则,其中有两条我认为比较恰当地描述了 Kubernetes 对象设计思路,一个是“单一职责”,另一个是“组合优于继承”。

  • 单一职责
    “单一职责”的意思是对象应该只专注于做好一件事情,不要贪大求全,保持足够小的粒度才更方便复用和管理。
  • 组合优于继承
    “组合优于继承”的意思是应该尽量让对象在运行时产生联系,保持松耦合,而不要用硬编码的方式固定对象的关系。

应用这两条原则,我们再来看 Kubernetes 的资源对象就会很清晰了。因为 Pod 已经是一个相对完善的对象,专门负责管理容器,那么我们就不应该再“画蛇添足”地盲目为它扩充功能,而是要保持它的独立性,容器之外的功能就需要定义其他的对象,把 Pod 作为它的一个成员“组合”进去。

这样每种 Kubernetes 对象就可以只关注自己的业务领域,只做自己最擅长的事情,其他的工作交给其他对象来处理,既不“缺位”也不“越位”,既有分工又有协作,从而以最小成本实现最大收益。

&ensp;#空一格
&emsp;#空两格
<font color='puple'> text </font> #文本添加颜色

3. 为什么要有Job/CronJob

  现在我们来看看 Kubernetes 里的两种新对象:Job 和 CronJob,它们就组合了 Pod,实现了对离线业务的处理。

  我们运行了两个 Pod:Nginx 和 busybox,它们分别代表了 Kubernetes 里的两大类业务。一类是像 Nginx 这样长时间运行的“在线业务”,另一类是像 busybox 这样短时间运行的“离线业务”。

  • 在线业务”类型的应用有很多,
    比如 Nginx、Node.js、MySQL、Redis 等等,一旦运行起来基本上不会停,也就是永远在线
  • “离线业务”类型的应用也并不少见,
    它们一般不直接服务于外部用户,只对内部用户有意义,比如日志分析、数据建模、视频转码等等,虽然计算量很大,但只会运行一段时间。“离线业务”的特点是必定会退出,不会无期限地运行下去,所以它的调度策略也就与“在线业务”存在很大的不同,需要考虑运行超时、状态检查、失败重试、获取计算结果等管理事项。

  而这些业务特性与容器管理没有必然的联系,如果由 Pod 来实现就会承担不必要的义务,违反了“单一职责”,所以我们应该把这部分功能分离到另外一个对象上实现,让这个对象去控制 Pod 的运行,完成附加的工作。

3.1 离线业务的种类

“离线业务”也可以分为两种。

  • “临时任务”
    跑完就完事了,下次有需求了说一声再重新安排;
  • “定时任务”
    可以按时按点周期运行,不需要过多干预。

  对应到 Kubernetes 里,“临时任务”就是 API 对象 Job,“定时任务”就是 API 对象 CronJob,使用这两个对象你就能够在 Kubernetes 里调度管理任意的离线业务了。

  由于 Job 和 CronJob 都属于离线业务,所以它们也比较相似。我们先学习通常只会运行一次的 Job 对象以及如何操作。如何使用 YAML 描述 Job

4. 如何使用 YAML 描述 临时任务 Job

4.1 Job 的 YAML“文件头”

Job 的 YAML“文件头”部分还是那几个必备字段,我就不再重复解释了,简单说一下:

  • apiVersion 不是 v1,而是 batch/v1。【api-resources 命令可以查看版本号】
  • kind 是 Job,这个和对象的名字是一致的。
  • metadata 里仍然要有 name 标记名字,也可以用 labels 添加任意的标签。

如果记不住这些也不要紧,你还可以使用命令 kubectl explain job 来看它的字段说明。

4.2 使用kubectl create 生成模板文件

  想要生成 YAML 样板文件的话不能使用 kubectl run,因为 kubectl run 只能创建 Pod,要创建 Pod 以外的其他 API 对象,需要使用命令 kubectl create,再加上对象的类型名。

比如用 busybox 创建一个“echo-job”,命令就是这样的

export out="--dry-run=client -o yaml"              # 定义Shell变量
kubectl create job echo-job --image=busybox $out

会生成一个基本的 YAML 文件,保存之后做点修改,就有了一个 Job 对象:

apiVersion: batch/v1
kind: Job
metadata:
  name: echo-job

spec:
  template:
    spec:
      restartPolicy: OnFailure
      containers:
      - image: busybox
        name: echo-job
        imagePullPolicy: IfNotPresent
        command: ["/bin/echo"]
        args: ["hello", "world"]

4.3 Job 的 YAML body 部分“spec ”

  你会注意到 Job 的描述与 Pod 很像,但又有些不一样,主要的区别就在“spec”字段里,多了一个 template 字段,然后又是一个“spec”,显得有点怪。

  如果你理解了刚才说的面向对象设计思想,就会明白这种做法的道理。它其实就是在 Job 对象里应用了组合模式,template 字段定义了一个“应用模板”,里面嵌入了一个 Pod,这样 Job 就可以从这个模板来创建出 Pod。

  而这个 Pod 因为受 Job 的管理控制,不直接和 apiserver 打交道,也就没必要重复 apiVersion 等“头字段”,只需要定义好关键的 spec,描述清楚容器相关的信息就可以了,可以说是一个“无头”的 Pod 对象。

  为了辅助理解,我把 Job 对象重新组织了一下,用不同的颜色来区分字段,这样你就能够很容易看出来,其实这个“echo-job”里并没有太多额外的功能,只是把 Pod 做了个简单的包装:

  总的来说,这里的 Pod 工作非常简单,在 containers 里写好名字和镜像,command 执行 /bin/echo,输出“hello world”。
  不过,因为 Job 业务的特殊性,所以我们还要在 spec 里多加一个字段 restartPolicy,确定 Pod 运行失败时的策略,OnFailure 是失败原地重启容器,而 Never 则是不重启容器,让 Job 去重新调度生成一个新的 Pod。
在这里插入图片描述

4.4 如何在Kubernetes 里操作Job?

yaml 文件可参考上图

4.4.1 创建

kubectl apply -f job.yml

4.4.2 删除

kubectl delete -f sleep-job.yml

在这里插入图片描述

4.4.3 获取状态

kubectl get job
kubectl get pod

  可以看到,因为 Pod 被 Job 管理,它就不会反复重启报错了,而是会显示为 Completed 表示任务完成,而 Job 里也会列出运行成功的作业数量,这里只有一个作业,所以就是 1/1。

  你还可以看到,Pod 被自动关联了一个名字,用的是 Job 的名字(echo-job)再加上一个随机字符串(pb5gh),这当然也是 Job 管理的“功劳”,免去了我们手工定义的麻烦,这样我们就可以使用命令 kubectl logs 来获取 Pod 的运行结果:
在这里插入图片描述

4.5 Job 和 Pod 对象的其他字段

  其实 Kubernetes 的这套 YAML 描述对象的框架提供了非常多的灵活性,可以在 Job 级别、Pod 级别添加任意的字段来定制业务,这种优势是简单的容器技术无法相比的。

这里我列出几个控制离线作业的重要字段,其他更详细的信息可以参考 Job 文档:

  • activeDeadlineSeconds,设置 Pod 运行的超时时间。
  • backoffLimit,设置 Pod 的失败重试次数。
  • completions,Job 完成需要运行多少个 Pod,默认是 1 个。
  • parallelism,它与 completions 相关,表示允许并发运行的 Pod 数量,避免过多占用资源。

  要注意这 4 个字段并不在 template 字段下,而是在 spec 字段下,所以它们是属于 Job 级别的,用来控制模板里的 Pod 对象。

举个栗子:
  下面我再创建一个 Job 对象,名字叫“sleep-job”,它随机睡眠一段时间再退出,模拟运行时间较长的作业(比如 MapReduce)。Job 的参数设置成 15 秒超时,最多重试 2 次,总共需要运行完 4 个 Pod,但同一时刻最多并发 2 个 Pod:

apiVersion: batch/v1
kind: Job
metadata:
  name: sleep-job

spec:
  activeDeadlineSeconds: 15
  backoffLimit: 2
  completions: 4
  parallelism: 2

  template:
    spec:
      restartPolicy: OnFailure
      containers:
      - image: busybox
        name: echo-job
        imagePullPolicy: IfNotPresent
        command:
          - sh
          - -c
          - sleep $(($RANDOM % 10 + 1)) && echo done

  使用 kubectl apply 创建 Job 之后,我们可以用 kubectl get pod -w 来实时观察 Pod 的状态,看到 Pod 不断被排队、创建、运行的过程:

kubectl apply -f sleep-job.yml
kubectl get pod -w

  等到 4 个 Pod 都运行完毕,我们再用 kubectl get 来看看 Job 和 Pod 的状态:
  就会看到 Job 的完成数量如同我们预期的是 4,而 4 个 Pod 也都是完成状态。
  显然,“声明式”的 Job 对象让离线业务的描述变得非常直观,简单的几个字段就可以很好地控制作业的并行度和完成数量,不需要我们去人工监控干预,Kubernetes 把这些都自动化实现了
在这里插入图片描述

5. 如何使用 YAML 描述 定时任务 CronJob

  学习了“临时任务”的 Job 对象之后,再学习“定时任务”的 CronJob 对象也就比较容易了,我就直接使用命令 kubectl create 来创建 CronJob 的样板。

  要注意两点。第一,因为 CronJob 的名字有点长,所以 Kubernetes 提供了简写 cj,这个简写也可以使用命令 kubectl api-resources 看到;第二,CronJob 需要定时运行,所以我们在命令行里还需要指定参数 --schedule。

export out="--dry-run=client -o yaml"              # 定义Shell变量
kubectl create cj echo-cj --image=busybox --schedule="" $out

然后我们编辑这个 YAML 样板,生成 CronJob 对象:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: echo-cj
spec:
  schedule: '*/1 * * * *'
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - image: busybox
            name: echo-cj
            imagePullPolicy: IfNotPresent
            command: ["/bin/echo"]
            args: ["hello", "world"]

我们还是重点关注它的 spec 字段,你会发现它居然连续有三个 spec 嵌套层次:

  • 第一个 spec 是 CronJob 自己的对象规格声明
  • 第二个 spec 从属于“jobTemplate”,它定义了一个 Job 对象。
  • 第三个 spec 从属于“template”,它定义了 Job 里运行的 Pod。

所以,CronJob 其实是又组合了 Job 而生成的新对象,我还是画了一张图,方便你理解它的“套娃”结构:
在这里插入图片描述
  除了定义 Job 对象的“jobTemplate”字段之外,CronJob 还有一个新字段就是“schedule”,用来定义任务周期运行的规则。它使用的是标准的 Cron 语法,指定分钟、小时、天、月、周,和 Linux 上的 crontab 是一样的。像在这里我就指定每分钟运行一次,格式具体的含义你可以课后参考 Kubernetes 官网文档。

  除了名字不同,CronJob 和 Job 的用法几乎是一样的,使用 kubectl apply 创建 CronJob,使用 kubectl get cj、kubectl get pod 来查看状态:

kubectl apply -f cronjob.yml
kubectl get cj
kubectl get pod

在这里插入图片描述

6. 小结

  今天我们以面向对象思想分析了一下 Kubernetes 里的资源对象设计,它强调“职责单一”和“对象组合”,简单来说就是“对象套对象”。
  通过这种嵌套方式,Kubernetes 里的这些 API 对象就形成了一个“控制链”:
  CronJob 使用定时规则控制 Job,Job 使用并发数量控制 Pod,Pod 再定义参数控制容器,容器再隔离控制进程,进程最终实现业务功能,层层递进的形式有点像设计模式里的 Decorator(装饰模式),链条里的每个环节都各司其职,在 Kubernetes 的统一指挥下完成任务。

小结一下今天的内容:

  1. Pod 是 Kubernetes 的最小调度单元,但为了保持它的独立性,不应该向它添加多余的功能。
  2. Kubernetes 为离线业务提供了 Job 和 CronJob 两种 API 对象,分别处理“临时任务”和“定时任务”。
  3. Job 的关键字段是 spec.template,里面定义了用来运行业务的 Pod 模板,其他的重要字段有 completions、parallelism 等
  4. CronJob 的关键字段是 spec.jobTemplate 和 spec.schedule,分别定义了 Job 模板和定时运行的规则。

7. 思考

7.1 你是怎么理解 Kubernetes 组合对象的方式的?它带来了什么好处?

  Kubernetes中组合对象,类似于面向对象编程中的继承,即不破坏父对象的功能,又扩展了自己领域场景中的功能,在API层面也简单了,只需要处理自己扩展的功能即可,比在一个对象上做加法进入逻辑判断要优雅很多。

7.2 Job 和 CronJob 的具体应用场景有哪些?能够解决什么样的问题?

  Job与CronJob分别对应一次性调用的任务与周期性定时任务;

  • 临时任务 Job
    前者任务只运行一次,比如用在手工触发的场景如数据库备份、恢复与还原,数据同步,安全检查,巡检等;
  • 定时任务 CronJob
    后者用于定时任务,非手工触发,由CronJobController每隔10s遍历需要执行的CronJob,
    同样也使用在如数据库备份、恢复与还原、数据同步、安全检查、定期巡检以及所有周期性的运维任务。

  Job与CronJob解决了任务的管理,如执行超时、失败尝试、执行数量与并行数量、任务结果记录等等,方便对任务执行的监控与管理;另外,Pod解决了批处理任务关联打包统一调度,容器解决了任务运行时环境。

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

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

相关文章

【C++ STL容器】:vector存放数据

前言 时不可以苟遇&#xff0c;道不可以虚行。 STL 中最常用的容器为&#xff1a;vector&#xff0c;暂且把它理解为我们之前学过的数组Array。 一、创建一个vector容器&#xff08;数组&#xff09; 添加头文件&#xff1a;#include <vector> vector<int> v;二、…

数商云渠道商协同系统对机械企业的应用价值体现

当前&#xff0c;国内机械市场环境较复杂&#xff0c;竞争日趋激烈&#xff0c;使用单一营销渠道模式已不能适应多变的环境&#xff0c;而代理商群体作为机械行业主流营销渠道&#xff0c;也在“价格战”环境下生存空间被进一步挤压&#xff0c;因此&#xff0c;如何采用领先的…

小啊呜产品读书笔记001:《邱岳的产品手记-13》第24讲 产品案例分析:PathSource的混乱与直观 25讲 产品世界的暗黑模式:操纵的诱惑

小啊呜产品读书笔记001&#xff1a;《邱岳的产品手记-13》第24讲 产品案例分析&#xff1a;PathSource的混乱与直观 & 第25讲 产品世界的暗黑模式&#xff1a;操纵的诱惑一、今日阅读计划二、泛读&知识摘录1、第24讲 产品案例分析&#xff1a;PathSource的混乱与直观2、…

进程与信号(一)

目录 一、前言 二、What Is a Process 三、Process Structure 1、The Process Table 2、Viewing Processes 3、System Processes 4、Process Scheduling 一、前言 进程和信号是 Linux 操作环境的基本组成部分。它们控制 Linux 和所有其他类 unix 计算机系统执行的几乎所…

全新版互联网大厂面试题,分类65份PDF,累计2000页

全新版互联网大厂面试题题库非常全面 包括 Java 集合、JVM、多线程、并发编程、设计模式、Spring全家桶、Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、MongoDB、Redis、MySQL、RabbitMQ、Kafka、Linux、Netty、Tomcat、Python、HTML、CSS、Vue、React、JavaS…

github-将本地代码上传到github上

1. 步骤&#xff1a; 准备&#xff1a;因为本地和远程是通过ssh加密的&#xff0c;所以需要生成秘钥和私钥 ssh-keygen -t rsa -C "youremailexample.com" "" 双括号里的是 关联 github的个人邮箱 cmd 里 输入 上述指令&#xff0c;然后 按三次 ent…

MySQL 进阶篇1.0

01-课程介绍 02-存储引擎-MySQL体系结构 03存储引擎-简介 查询建表语句 --默认存储引擎:InnoDBshow create table account; 查询当前数据库支持的存储引擎show engines; 04存储引擎-InnoDB介绍 开关为"ON": 表示每个innodb引擎的表都有一个idb表共享文件 …

2012-04 《信息资源管理 02378》真卷解析,逐题解析+背诵技巧

本系列博客合计 21 篇&#xff0c;每篇都将解析一张《信息资源管理》真卷&#xff0c;并附带答案解析与背诵技巧。 全国 2012 年 4 月自学考试信息资源管理试题&#xff08;02378&#xff09; 单选题 1、作为现代社会的支柱产业&#xff0c;信息产业的主体有&#xff1a;信息…

【雕爷学编程】Arduino动手做(109)---3路电压转换模块

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

MySQL 数据库 group by 语句怎么优化?

一、一个简单使用示例 我这里创建一张订单表 CREATE TABLE order_info ( id int NOT NULL AUTO_INCREMENT COMMENT 主键, order_no int NOT NULL COMMENT 订单号, goods_id int NOT NULL DEFAULT 0 COMMENT 商品id, goods_name varchar(50) NOT NULL COMMENT 商品名称, …

Kamiya丨Kamiya艾美捷狗CRP ELISA说明书

Kamiya艾美捷狗CRP ELISA预期用途&#xff1a; 狗CRP ELISA是一种高灵敏度的双位点酶联免疫分析&#xff08;ELISA&#xff09;&#xff0c;用于定量测定狗生物样品中的C反应蛋白&#xff08;CRP&#xff09;。仅供研究使用。 引言 急性期蛋白质是血浆蛋白质&#xff0c;其在…

开发者实践|如何实现云开发场景联动(内附结构图和教学视频)

一千个住户有一千种生活习惯&#xff0c;智能家居如何才能根据用户个性化的需求&#xff0c;实现真正的“智能”&#xff1f;这就需要家居产品之间智能排列&#xff0c;组合成多样化的场景联动模式。 下面我们就来说说如何通过Tuya OpenAPI来实现云开发场景联动&#xff0c;满…

使用 qrcode 生成二维码

qrcode 1 安装2 引入3 使用3.1 方法1 &#xff1a;QRCode.toCanvas()3.2 方法2 &#xff1a;QRCode.toDataURL()4 完整示例qrcode 是一个用于生成二维码的 JavaScript 库。主要是通过获取 DOM 的标签,再通过 HTML5 Canvas 绘制而成 1 安装 npm install --save qrcode2 引入 …

本地部署开发环境过程和遇到的问题总结

一、 软件安装&#xff0c;环境配置 安装配置jdk(不能只有jre)安装配置maven安装配置git安装idea 二、拉项目 在云效代码管理中选择对应的库&#xff0c;复制其仓库地址 在idea中配置git 参考https://blog.csdn.net/qq_62701769/article/details/125029536 拉代码 URL输入…

叠氮试剂知识整理:6-azidohexan-1-amine|349553-73-7|6-叠氮基己胺

产品描述&#xff1a; 6-azidohexan-1-amine呈淡黄色或无色油状&#xff0c;含有叠氮基。叠氮化物可以与炔烃、DBCO和BCN进行铜催化的点击化学反应。NHS酯可以与胺基反应&#xff0c;形成稳定的酰胺键。点击化学反应效率高&#xff0c;即使在低浓度(μM)和低温(4oc)下&#xff…

安卓蓝牙耳机哪个牌子好?安卓手机蓝牙耳机推荐

目前&#xff0c;蓝牙耳机迅速流行于人们的视野当中&#xff0c;在各种场合中&#xff0c;肯定少不了一款蓝牙耳机&#xff0c;但现在的运动耳机可谓五花八门&#xff0c;虽然苹果手机广泛于市场&#xff0c;但是安卓品牌也在不断的采用最新技术的研发&#xff0c;下面是小编整…

Baklib知识分享|企业产品需求文档的特点

产品或服务是公司的核心。没有产品就没有业务。 虽然我们一直在努力追求卓越的产品&#xff0c;但我们有可能不能够达成目标。你可能经常基于你对产品的基本想法来构建产品。有时&#xff0c;您可能只是运行迭代或向您的产品团队提出特性需求。你不能只是临时拼凑一些构成你业…

分组后统计查询

【问题】 I am trying to select top values in a column based on the variable/field in another column. it is a very large tab delimited file. Input: Names col2 col3 col4 A A1 def 10 A A1 BBB 10 A A1 CED 10 A A1 fff 7.5 B B1…

2022秋季信息安全技术(期末复习)

目录 问答题考点&#xff1a; 1.简单替换密码加解密 2.DES算法的原理&#xff1a; ​编辑3.RSA算法的全过程&#xff1a; 4.基于公开密钥的数字签名方案 5.单项散列函数的特点&#xff1a; 6.简述信息的完整性、可用性、保密性 7.简述数字水印的主要特征 8.论述公开密钥…

Qt 工程添加windows库文件

文章目录背景编译出错查看openTrace函数在Qt 工程中添加库文件添加后pro文件背景 项目中用到了“C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\shared\evntrace.h" 文件中的接口OpenTrace 等。 编译出错 error LNK2019&#xff1a; 查看openTrace函数…