草庐IT

【K8S系列】深入解析Job

颜淡慕潇 2023-06-29 原文

序言

你只管努力,其他交给时间,时间会证明一切。

文章标记颜色说明:

  • 黄色:重要标题
  • 红色:用来标记结论
  • 绿色:用来标记一级论点
  • 蓝色:用来标记二级论点

Kubernetes (k8s) 是一个容器编排平台,允许在容器中运行应用程序和服务。今天学习一下Job-作业管理

希望这篇文章能让你不仅有一定的收获,而且可以愉快的学习,如果有什么建议,都可以留言和我交流

 专栏介绍

这是这篇文章所在的专栏,欢迎订阅:【深入解析k8s】专栏

介绍一下这个专栏要做的事:

主要是深入解析每个知识点,帮助大家完全掌握k8s,以下是已更新的章节

序号文章
第一讲深入解析 k8s:入门指南(一)
第二讲深入解析 k8s:入门指南(二)
第三讲深入解析Pod对象(一)
第四讲深入解析Pod对象(二)
第五讲深入解析无状态服务
第六讲深入解析有状态服务
第七讲深入解析控制器

第八讲

深入解析 ReplicaSet
第九讲深入解析滚动升级
第十讲深入解析StatefulSet(一)
第十一讲深入解析StatefulSet(二)
第十二讲深入解析DaemonSet

1 基础介绍

1.1 概念介绍

在 Kubernetes 中,Job 是一种控制器用于在集群中运行一次性任务。Job 控制器会创建一个或多个 Pod,以运行指定的任务。

当任务完成后,Job 控制器将删除 Pod。

1.2 Job 的类型

在 Kubernetes 中,有两种类型的 Job:

  1. 单次 Job
  2. CronJob

1 单次 Job

单次 Job 用于运行一次性任务,例如在集群中运行一个批处理作业或者初始化数据库。

当任务完成后,Job 将自动终止。

特点:

  • 创建Pod运行特定任务,确保任务运行完成
  • 任务运行期间节点异常时会自动重新创建Pod
  • 支持并发创建Pod任务数和指定任务数

总之,单次 Job 是 Kubernetes 中用于运行一次性任务的一种控制器,通过简单的配置文件即可完成任务的运行和管理。

单次: 

 并发示意图:

2 CronJob

CronJob 类型的 Job 允许按照指定的时间表运行任务。

可以指定任务在每天、每周、每月或其他时间间隔内运行。CronJob 会创建一个 Job 来运行指定的任务,并在任务完成后终止该 Job。

特点:

  • 周期性:实现周期性计划任务
  • 调用Jobs控制器创建任务
  • CronJobs任务名称小于52个字符
  • 应用场景如:定期备份,周期性发送邮件

2 原理介绍

2.1 单次 Job实现原理

在 Kubernetes 中,单次 Job 的实现原理是通过控制器(Controller)的方式来实现的。控制器会监视 Kubernetes API 中的 Job 对象,并根据 Job 对象的定义创建、更新和删除 Pod

  1. 创建:创建 Job 时,控制器会根据 Job 对象的定义创建一个 Pod 模板。然后,控制器根据需要创建一个或多个 Pod 实例,并将 Pod 调度到集群中的节点上运行。
  2. 监视:在这个过程中,控制器会监视 Pod 的状态,并根据需要更新 Pod 或创建新的 Pod。当任务完成后,控制器会删除 Pod。
  3. 更新/删除:控制器还会监视 Job 的状态根据需要更新 Pod 或创建新的 Pod并更新 Job 对象的状态。例如,当任务完成后,控制器会将 Job 对象的状态设置为“完成”,控制器会删除 Pod。。

此外,控制器还支持一些选项,例如 backoffLimit、activeDeadlineSeconds、completions 和 parallelism。这些选项可以控制 Job 的行为,例如在任务失败后进行重试的次数。

总之,Kubernetes 单次 Job 的实现原理是通过控制器来实现的,控制器会根据 Job 对象的定义创建、更新和删除 Pod,并监视 Job 的状态。

这种方式使得 Kubernetes 可以方便地管理和运行一次性的任务。

2.2 CronJob 的实现原理

Kubernetes 中 CronJob 的实现原理大体上可以分为以下步骤:

  1. 创建 CronJob 对象。当创建一个 CronJob 对象时,Kubernetes API 服务器将存储 CronJob 的定义,并为其分配唯一的名称。

  2. 接收到任务触发时间。CronJob 控制器会定期检查 CronJob 对象的时间表以确定下一个任务的触发时间。当控制器检测到某个任务的触发时间已到达时,它将开始执行下一步操作。

  3. 创建 Job 对象。CronJob 控制器会根据 CronJob 对象的定义创建一个 Job 模板,并在需要的时候创建一个或多个 Job 实例。

  4. 创建 Pod 对象。在创建 Job 实例期间,CronJob 控制器会根据 Job 模板创建一个或多个 Pod 实例,并将它们调度到集群中的节点上运行。

  5. 监视 Pod 状态。CronJob 控制器会监视 Pod 的状态,并根据需要更新 Pod 或创建新的 Pod。

  6. 删除 Job 和 Pod 对象。一旦任务完成,CronJob 控制器会删除 Job 和 Pod 对象。如果 Job 是成功完成的,则 Pod 也将被删除。否则,控制器可根据需要重试任务。

  7. 更新 CronJob 对象状态。CronJob 控制器会监视 Job 的状态,并更新 CronJob 对象的状态。例如,当 Job 完成后,控制器会将 CronJob 对象的状态设置为“最近一次成功运行的时间”和“最近一次运行的状态”。

3单次job使用案例

详细讲解如何使用k8s的Job控制器运行一次性任务的示例。

3.1 创建一个容器镜像

首先,需要创建一个容器镜像,该镜像将包含要运行的任务。

例如,创建一个基于Ubuntu的镜像,并在其中安装Python和必要的依赖项。

Dockerfile示例:

FROM ubuntu:latest

RUN apt-get update && apt-get install -y python3 python3-pip

COPY requirements.txt /app/
RUN pip3 install --no-cache-dir -r /app/requirements.txt

COPY main.py /app/

CMD ["python3", "/app/main.py"]

在该镜像中,安装了Python3和pip3,并将应用程序的依赖项安装到容器中。还将应用程序的主要代码复制到容器中,并使用CMD指令指定容器启动时要运行的命令。

3.2 创建一个k8s Job

接下来,需要创建一个k8s Job来运行刚刚创建的容器镜像。

可以使用kubectl命令行工具或编写Python代码来创建Job。在这里,将展示如何使用Python Kubernetes客户端API创建Job。

from kubernetes import client, config

# 加载k8s集群配置
config.load_kube_config()

# 创建k8s API客户端
api_client = client.BatchV1Api()

# 定义Job对象
job_name = "my-job"
job_namespace = "default"

job = client.V1Job()
job.metadata = client.V1ObjectMeta(name=job_name, namespace=job_namespace)

# 定义Job的Pod模板
pod_template = client.V1PodTemplateSpec()
pod_template.metadata = client.V1ObjectMeta(labels={"app": job_name})
container = client.V1Container(name="my-container", image="my-image:latest")
pod_template.spec = client.V1PodSpec(containers=[container])

# 定义Job的规范
job.spec = client.V1JobSpec(template=pod_template, backoff_limit=0, ttl_seconds_after_finished=600)

# 创建Job
api_client.create_namespaced_job(namespace=job_namespace, body=job)

在这个例子中,

  1. 加载配置:加载k8s集群的配置,并创建一个BatchV1Api对象来与k8s API进行交互。
  2. 定义Job:定义一个V1Job对象,设置其元数据(包括名称和命名空间)。
  3. 定义Pod:定义Job的Pod模板,其中包含一个容器,该容器将运行刚刚创建的容器镜像。
  4. 定义Job的规范:包括Pod模板和一些其他属性,例如backoff_limit和ttl_seconds_after_finished。
  5. 创建Job:使用API客户端创建该Job。

3.3 查看Job的状态

一旦Job被创建,k8s将自动创建一个Pod并在其中运行对应的容器镜像。

可以使用kubectl命令行工具或编写Python代码来查看Job的状态。

kubectl命令行示例:

$ kubectl get jobs
NAME      COMPLETIONS   DURATION   AGE
my-job    1/1           1s         5m

Python代码示例:

from kubernetes import client, config

# 加载k8s集群配置
config.load_kube_config()

# 创建k8s API客户端
api_client = client.BatchV1Api()

# 获取Job状态
job_name = "my-job"
job_namespace = "default"
job = api_client.read_namespaced_job(name=job_name, namespace=job_namespace)
status = job.status

if status.succeeded == 1:
    print("Job completed successfully!")
else:
    print("Job failed or is still running.")

在这个示例中,使用Python Kubernetes客户端API获取Job的状态。

首先读取Job对象,然后检查其状态属性以确定Job的状态

如果Job已成功完成,将打印一条消息表示它已成功完成。否则,将打印一条消息表示Job失败或仍在运行。

3.4 小结:

介绍了如何使用k8s的Job控制器运行一次性任务。首先创建了一个容器镜像,并在其中安装了必要的依赖项和我们要运行的任务。然后,使用Python Kubernetes客户端API创建了一个k8s Job,并检查了Job的状态以确定任务是否已成功完成。

4 CronJob

下面将详细讲解如何使用k8s的CronJob控制器运行定期任务的示例。会讲2种示例:

  • Python代码实现
  • yaml配置实现

4.1 Python代码实现

1 创建一个容器镜像

首先,和job一样,需要创建一个容器镜像,直接用上一个镜像吧。

Dockerfile示例:

FROM ubuntu:latest

RUN apt-get update && apt-get install -y python3 python3-pip

COPY requirements.txt /app/
RUN pip3 install --no-cache-dir -r /app/requirements.txt

COPY main.py /app/

CMD ["python3", "/app/main.py"]

在该镜像中,安装了Python3和pip3,并将应用程序的依赖项安装到容器中。还将应用程序的主要代码复制到容器中,并使用CMD指令指定容器启动时要运行的命令。

2 创建k8s CronJob

接下来,需要创建一个k8s CronJob来运行刚刚的容器镜像。可以使用kubectl命令行工具或编写Python代码来创建CronJob。

在这里,将展示如何使用Python Kubernetes客户端API创建CronJob。

from kubernetes import client, config

# 加载k8s集群配置
config.load_kube_config()

# 创建k8s API客户端
api_client = client.BatchV1beta1Api()

# 定义CronJob对象
cron_job_name = "my-cronjob"
cron_job_namespace = "default"

cron_job = client.V1beta1CronJob()
cron_job.metadata = client.V1ObjectMeta(name=cron_job_name, namespace=cron_job_namespace)

# 定义CronJob的Pod模板
pod_template = client.V1PodTemplateSpec()
pod_template.metadata = client.V1ObjectMeta(labels={"app": cron_job_name})
container = client.V1Container(name="my-container", image="my-image:latest")
pod_template.spec = client.V1PodSpec(containers=[container])

# 定义CronJob的规范
cron_spec = client.V1beta1CronJobSpec(schedule="0 * * * *", job_template=client.V1beta1JobTemplateSpec(spec=pod_template))
cron_job.spec = cron_spec

# 创建CronJob
api_client.create_namespaced_cron_job(namespace=cron_job_namespace, body=cron_job)

在这个例子中,

  1. 加载k8s集群的配置,并创建一个BatchV1beta1Api对象来与k8s API进行交互。
  2. 定义一个V1beta1CronJob对象,设置其元数据(包括名称和命名空间)。
  3. 定义CronJob的Pod模板,其中包含一个容器,该容器将运行我们创建的容器镜像。
  4. 定义CronJob的规范,包括调度计划和作业模板规范。

在这个例子中,将CronJob调度计划设置为每小时运行一次。最后,使用API客户端创建该CronJob。

3 查看CronJob的状态

一旦CronJob被创建,k8s将按照定义的调度计划定期运行任务。可以使用kubectl命令行工具或编写Python代码来查看CronJob的状态。

kubectl命令行示例:

$ kubectl get cronjobs
NAME         SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
my-cronjob   0 * * * *   False     0        <none>          1h

Python Kubernetes客户端API示例:

from kubernetes import client, config

# 加载k8s集群配置
config.load_kube_config()

# 创建k8s API客户端
api_client = client.BatchV1beta1Api()

# 获取CronJob状态
cron_job_name = "my-cronjob"
cron_job_namespace = "default"
cron_job = api_client.read_namespaced_cron_job(name=cron_job_name, namespace=cron_job_namespace)
print(cron_job.status)

在这个例子中,使用API客户端读取CronJob的状态,并打印输出。

该状态包括:

  • 已运行的作业数
  • 最近一次运行的作业
  • 最近一次成功运行的作业

等信息。

4 小结:

上面,详细讲解了如何使用k8s的CronJob控制器运行定期任务的示例。创建了一个容器镜像,并使用Python Kubernetes客户端API创建了一个CronJob。最后,展示了如何使用kubectl命令行工具或Python Kubernetes客户端API查看CronJob的状态。

4.2 yaml配置实现

1 创建一个k8s CronJob

容器镜像就不创建了,直接用刚刚创建的那个dockerfile,接下来,讲解一下使用yaml文件来创建一个k8s CronJob,该文件将定义我们要运行的容器镜像、调度计划等参数。

apiVersion: batch/v1beta1
kind: CronJob #资源类型
metadata:
  name: my-cronjob
spec:
  schedule: "0 * * * *"
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            app: my-cronjob
        spec:
          containers:
          - name: my-container
            image: my-image:latest
            imagePullPolicy: Always
          restartPolicy: OnFailure

在这个yaml文件中,

  1. 定义了一个名为"my-cronjob"的CronJob,并设置了其调度计划为每小时运行一次
  2. 定义了作业模板,该模板包含一个Pod模板,其中包含一个容器,该容器将运行我们创建的容器镜像。
  3. 重启策略设置为"OnFailure",以便在作业失败时自动重新启动。

2 应用CronJob配置

定义好了CronJob的yaml文件,可以使用kubectl命令行工具或编写Python代码来将其应用到k8s集群中。

kubectl命令行示例:

from kubernetes import client, config, utils

# 加载k8s集群配置
config.load_kube_config()

# 应用yaml文件
utils.create_from_yaml(client.BatchV1beta1Api(), "my-cronjob.yaml")

在这个例子中,使用Python Kubernetes客户端API将CronJob的yaml文件应用到k8s集群中。

  1. 首先加载k8s集群的配置,
  2. 然后使用create_from_yaml()方法将yaml文件的内容传递给API客户端,以创建CronJob。

3 查看CronJob的状态

CronJob被创建之后,k8s将按照定义的调度计划定期运行任务。可以:

  • 使用kubectl命令行工具
  • 编写Python代码

来查看CronJob的状态

kubectl命令行示例:

$ kubectl get cronjobs
NAME         SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
my-cronjob   0 * * * *   False     0        <none>          1m

Python Kubernetes客户端API示例:

from kubernetes import client, config

# 加载k8s集群配置
config.load_kube_config()

# 获取CronJob列表
api_instance = client.BatchV1beta1Api()
cronjobs = api_instance.list_namespaced_cron_job(namespace="default")
for cj in cronjobs.items:
    print(f"{cj.metadata.name}: {cj.status.active}")

在这个例子中,

使用Python Kubernetes客户端API来获取CronJob列表,并打印每个CronJob的名称和活动状态。

  • 如果活动状态为0,则表示该CronJob没有运行任务。
  • 否则,它将显示CronJob正在运行任务。

4 小结

这是一个简单的示例,演示了如何使用k8s的CronJob控制器在k8s集群中运行定期任务。通过定义一个容器镜像和一个k8s CronJob,可以轻松地设置和管理定期任务。

在实际应用中,可以根据需要设置更复杂的调度计划和容器镜像来运行不同类型的任务

5 总结

k8s中的Job和CronJob是两种不同的控制器类型,用于在k8s集群中运行任务。我们总结一下它们的技术总结和使用场景总结。

5.1 单次Job

Job是k8s中用于运行一次性任务的控制器类型。当需要在k8s集群中运行一次性任务时,可以使用Job来创建一个任务,例如批处理作业、数据导入等

Job控制器确保任务只运行一次,如果任务失败,则可以自动重新启动任务。

Job的使用场景:

  • 在集群中运行一次性任务,例如批处理作业、数据导入等。
  • 任务需要确保只运行一次,并且可以自动重新启动任务。

5.2 定期CronJob

CronJob是k8s中用于运行定期任务的控制器类型。当需要定期运行任务时,可以使用CronJob来创建一个计划任务,例如备份、数据清理等。CronJob控制器使用类似于Linux的cron系统的语法来定义调度计划,例如每小时、每天或每周运行任务

CronJob的使用场景:

  • 在集群中定期运行任务,例如备份、数据清理等。
  • 任务需要按照一定的调度计划运行。

6 投票

 

 

有关【K8S系列】深入解析Job的更多相关文章

  1. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  2. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby - 用逗号、双引号和编码解析 csv - 2

    我正在使用ruby​​1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\

  5. ruby-on-rails - 使用一系列等级计算字母等级 - 2

    这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,

  6. ruby-on-rails - 我更新了 ruby​​ gems,现在到处都收到解析树错误和弃用警告! - 2

    简而言之错误:NOTE:Gem::SourceIndex#add_specisdeprecated,useSpecification.add_spec.Itwillberemovedonorafter2011-11-01.Gem::SourceIndex#add_speccalledfrom/opt/local/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:91./opt/local/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/rails/gem_dependency.rb:275:in`==':und

  7. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  8. 阿里云RDS——产品系列概述 - 2

    基础版云数据库RDS的产品系列包括基础版、高可用版、集群版、三节点企业版,本文介绍基础版实例的相关信息。RDS基础版实例也称为单机版实例,只有单个数据库节点,计算与存储分离,性价比超高。说明RDS基础版实例只有一个数据库节点,没有备节点作为热备份,因此当该节点意外宕机或者执行重启实例、变更配置、版本升级等任务时,会出现较长时间的不可用。如果业务对数据库的可用性要求较高,不建议使用基础版实例,可选择其他系列(如高可用版),部分基础版实例也支持升级为高可用版。基础版与高可用版的对比拓扑图如下所示。优势 性能由于不提供备节点,主节点不会因为实时的数据库复制而产生额外的性能开销,因此基础版的性能相对于

  9. ruby - 用 YAML.load 解析 json 安全吗? - 2

    我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("

  10. ruby - 如何使用 Nokogiri 解析纯 HTML 表格? - 2

    我想用Nokogiri解析HTML页面。页面的一部分有一个表,它没有使用任何特定的ID。是否可以提取如下内容:Today,3,455,34Today,1,1300,3664Today,10,100000,3444,Yesterday,3454,5656,3Yesterday,3545,1000,10Yesterday,3411,36223,15来自这个HTML:TodayYesterdayQntySizeLengthLengthSizeQnty345534345456563113003664354510001010100000344434113622315

随机推荐