K8S中的Job和CronJob
Job
Job负责批量处理短暂的一次性任务 (short lived one-off tasks),即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。
Kubernetes支持以下几种Job:
- 非并行Job:通常创建一个Pod直至其成功结束
- 固定结束次数的Job:设置.spec.completions,创建多个Pod,直到.spec.completions个Pod成功结束
- 带有工作队列的并行Job:设置.spec.Parallelism但不设置.spec.completions,当所有Pod结束并且至少一个成功时,Job就认为是成功
根据.spec.completions和.spec.Parallelism的设置,可以将Job划分为以下几种pattern:
| Job类型 | 使用示例 | 行为 | completions | Parallelism |
|---|---|---|---|---|
| 一次性Job | 数据库迁移 | 创建一个Pod直至其成功结束 | 1 | 1 |
| 固定结束次数的Job | 处理工作队列的Pod | 依次创建一个Pod运行直至completions个成功结束 | 2+ | 1 |
| 固定结束次数的并行Job | 多个Pod同时处理工作队列 | 依次创建多个Pod运行直至completions个成功结束 | 2+ | 2+ |
| 并行Job | 多个Pod同时处理工作队列 | 创建一个或多个Pod直至有一个成功结束 | 1 | 2+ |
Job Controller
Job Controller负责根据Job Spec创建Pod,并持续监控Pod的状态,直至其成功结束。如果失败,则根据restartPolicy(只支持OnFailure和Never,不支持Always)决定是否创建新的Pod再次重试任务。

Job Spec格式
- spec.template格式同Pod
- RestartPolicy仅支持Never或OnFailure
- 单个Pod时,默认Pod成功运行后Job即结束
- .spec.completions标志Job结束需要成功运行的Pod个数,默认为1
- .spec.parallelism标志并行运行的Pod的个数,默认为1
- spec.activeDeadlineSeconds标志失败Pod的重试最大时间,超过这个时间不会继续重试
一个简单的例子:
[root@k8s-master mnt]# cat job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
metadata:
name: pi
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
[root@k8s-master mnt]#
[root@k8s-master mnt]# kubectl create -f job.yaml
job.batch/pi created
[root@k8s-master mnt]# kubectl get pod
NAME READY STATUS RESTARTS AGE
deamonset-example-vdzjp 1/1 Running 0 19m
deamonset-example-xxt2z 1/1 Running 0 20m
pi-7s4vx 0/1 ContainerCreating 0 5s
[root@k8s-master mnt]# kubectl get pod
NAME READY STATUS RESTARTS AGE
deamonset-example-vdzjp 1/1 Running 0 19m
deamonset-example-xxt2z 1/1 Running 0 20m
pi-7s4vx 0/1 ContainerCreating 0 7s
[root@k8s-master mnt]# kubectl describe pod pi-7s4vx
Name: pi-7s4vx
Namespace: default
Priority: 0
Node: k8s-node02/192.168.180.136
Start Time: Mon, 23 Dec 2019 20:21:25 +0800
Labels: controller-uid=51af6eb5-9166-49eb-9328-8f5c6bcfe18f
job-name=pi
Annotations: <none>
Status: Pending
IP:
IPs: <none>
Controlled By: Job/pi
Containers:
pi:
Container ID:
Image: perl
Image ID:
Port: <none>
Host Port: <none>
Command:
perl
-Mbignum=bpi
-wle
print bpi(2000)
State: Waiting
Reason: ContainerCreating
Ready: False
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-6wcrh (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
default-token-6wcrh:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-6wcrh
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned default/pi-7s4vx to k8s-node02
Normal Pulling 19s kubelet, k8s-node02 Pulling image "perl"
[root@k8s-master mnt]# kubectl get job
NAME COMPLETIONS DURATION AGE
pi 0/1 26s 26s
[root@k8s-master mnt]# kubectl get job
NAME COMPLETIONS DURATION AGE
pi 0/1 31s 31s
[root@k8s-master mnt]# kubectl describe pod pi-7s4vx
Name: pi-7s4vx
Namespace: default
Priority: 0
Node: k8s-node02/192.168.180.136
Start Time: Mon, 23 Dec 2019 20:21:25 +0800
Labels: controller-uid=51af6eb5-9166-49eb-9328-8f5c6bcfe18f
job-name=pi
Annotations: <none>
Status: Pending
IP:
IPs: <none>
Controlled By: Job/pi
Containers:
pi:
Container ID:
Image: perl
Image ID:
Port: <none>
Host Port: <none>
Command:
perl
-Mbignum=bpi
-wle
print bpi(2000)
State: Waiting
Reason: ContainerCreating
Ready: False
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-6wcrh (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
default-token-6wcrh:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-6wcrh
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned default/pi-7s4vx to k8s-node02
Normal Pulling 2m11s kubelet, k8s-node02 Pulling image "perl"
[root@k8s-master mnt]# kubectl get pod
NAME READY STATUS RESTARTS AGE
deamonset-example-vdzjp 1/1 Running 0 28m
deamonset-example-xxt2z 1/1 Running 0 29m
pi-7s4vx 0/1 Completed 0 9m7s
[root@k8s-master mnt]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deamonset-example-vdzjp 1/1 Running 0 28m 10.244.2.22 k8s-node01 <none> <none>
deamonset-example-xxt2z 1/1 Running 0 29m 10.244.1.23 k8s-node02 <none> <none>
pi-7s4vx 0/1 Completed 0 9m15s 10.244.1.24 k8s-node02 <none> <none>
[root@k8s-master mnt]# kubectl logs pi-7s4vx
3.141592653589793238462643383279502884197169399375105820974944592307816678316527120190914564856692346034
固定结束次数的Job示例
apiVersion: batch/v1
kind: Job
metadata:
name: busybox
spec:
completions: 3
template:
metadata:
name: busybox
spec:
containers:
- name: busybox
image: busybox
command: ["echo", "hello"]
restartPolicy: Never
CronJob
CronJob即定时任务,就类似于Linux系统的crontab,在指定的时间周期运行指定的任务。在Kubernetes 1.5,使用CronJob需要开启batch/v2alpha1 API,即–runtime-config=batch/v2alpha1。
CronJob Spec
- .spec.schedule指定任务运行周期,格式同Cron
- .spec.jobTemplate指定需要运行的任务,格式同Job
- .spec.startingDeadlineSeconds指定任务开始的截止期限
- .spec.concurrencyPolicy指定任务的并发策略,支持Allow、Forbid和Replace三个选项
[root@k8s-master mnt]# cat cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
[root@k8s-master mnt]#
[root@k8s-master mnt]# vim cronjob.yaml
[root@k8s-master mnt]# kubectl create -f cronjob.yaml
cronjob.batch/hello created
[root@k8s-master mnt]# kubectl get cronjob
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * False 0 <none> 16s
[root@k8s-master mnt]# kubectl get job
NAME COMPLETIONS DURATION AGE
hello-1577105220 0/1 2s 2s
pi 1/1 5m23s 25m
[root@k8s-master mnt]# kubectl get pod
NAME READY STATUS RESTARTS AGE
deamonset-example-vdzjp 1/1 Running 0 45m
deamonset-example-xxt2z 1/1 Running 0 47m
hello-1577105220-9vjjn 0/1 Completed 0 50s
pi-7s4vx 0/1 Completed 0 26m
[root@k8s-master mnt]# kubectl logs pod hello-1577105220-9vjjn
Error from server (NotFound): pods "pod" not found
[root@k8s-master mnt]# kubectl logs hello-1577105220-9vjjn
Mon Dec 23 12:47:14 UTC 2019
Hello from the Kubernetes cluster
[root@k8s-master mnt]# kubectl get job -w
NAME COMPLETIONS DURATION AGE
hello-1577105220 1/1 9s 2m4s
hello-1577105280 1/1 8s 64s
hello-1577105340 0/1 4s 4s
pi 1/1 5m23s 27m
hello-1577105340 1/1 6s 6s
hello-1577105400 0/1 0s
hello-1577105400 0/1 0s 0s
hello-1577105400 1/1 5s 5s
^Z
[1]+ 已停止 kubectl get job -w
[root@k8s-master mnt]# kubectl delete -f cronjob.yaml
cronjob.batch "hello" deleted
[root@k8s-master mnt]# kubectl delete -f job.yaml
job.batch "pi" deleted
[root@k8s-master mnt]#
K8S中的Job和CronJob的更多相关文章
- k8s中yaml文常见语法
在k8s中,所有的配置都是 json格式的.但为了读写方便,通常将这些配置写成yaml 格式,其运行的时候,还是会靠yaml引擎将其转化为json,apiserver 也仅接受json的数据类型. y ...
- 如何在K8S中优雅的使用私有镜像库 (Docker版)
前言 在企业落地 K8S 的过程中,私有镜像库 (专用镜像库) 必不可少,特别是在 Docker Hub 开始对免费用户限流之后, 越发的体现了搭建私有镜像库的重要性. 私有镜像库不但可以加速镜像的拉 ...
- k8s 中 Pod 的控制器
k8s 中 Pod 的控制器 前言 Replication Controller ReplicaSet Deployment 更新 Deployment 回滚 deployment StatefulS ...
- 新版的K8S中的flannel.yaml文件中要注意的细节
部署flannel作为k8s中的网络插件,yaml文件都大小同异. 但在要注意以下细节. 以前,只需要前面master判断. 现在也需要有not-ready状态了. tolerations: - ke ...
- 转 docker创建私有仓库和k8s中使用私有镜像
docker私有仓库建立 环境说明我们选取192.168.5.2做私有仓库地址yum install docker -y1.启动docker仓库端口服务 docker run -d -p 5000:5 ...
- K8S中如何跨namespace 访问服务?为什么ping不通ClusterIP?
1.K8S中如何跨namespace 访问服务? 2.在Pod中为什么ping不通ClusterIP? 简述: Rancher2.0中的一个用户,在K8S环境中,创建两个namespace,对应用进行 ...
- 从harbor部署到在k8s中使用
一.概述 harbor是什么呢?英文单词的意思是:港湾.港湾用来存放集装箱(货物的),而docker的由来正是借鉴了集装箱的原理,所以harbor是用于存放docker的镜像,作为镜像仓库使用.官方的 ...
- 在k8s中搭建可解析hostname的DNS服务
2016-01-25更新 上篇文章总结k8s中搭建hbase时,遇到Pod中hostname的DNS解析问题,本篇将通过修改kube2sky源码来解决这个问题. 1 前言 kube2sky在Githu ...
- 【Kubernetes】在K8s中创建StatefulSet
在K8s中创建StatefulSet 遇到的问题: 使用Deployment创建的Pod是无状态的,当挂在Volume之后,如果该Pod挂了,Replication Controller会再run一个 ...
随机推荐
- 安装consul-client+registrator
安装registrator 下载镜像这里必须要注意:registrator的lastest版本已经2年没更新了,他的最新主板本是master,一定要注意,因为旧的版本无法发现跟自己不是同一个网络的容器 ...
- 深入理解计算机系统 第十章 系统级I/O 第二遍
了解 Unix I/O 的好处 了解 Unix I/O 将帮助我们理解其他的系统概念 I/O 是系统操作不可或缺的一部分,因此,我们经常遇到 I/O 和其他系统概念之间的循环依赖.例如,I/O 在进程 ...
- windows server 2008 R2 Enterprise 防火墙开启允许远程桌面登录
解决方法: 开始------ > 运行 ----- > gpedit.msc 打开“本地组策略编辑器”,按如下设置:计算机配置----->管理模板----->网络-----&g ...
- hdu 4632区间dp 回文字串计数问题
Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65535 K (Java/ ...
- JS基础_属性名和属性值
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- sccrapy 爬虫框架网数据库储存时去重的问题
from scrapy.exceptions import DropItem #导入异常处理模块 class Baidu03Pipeline(object): def __init__(self): ...
- 使用spring的test时,当配置文件不在classpath下,而在WEB-INF下
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/applicationContext.xml"})
- JavaScript中变量声明效率问题
1 var theString1 = "字符串1"; var theString2 = "字符串1"; var theString3 = "字符串1& ...
- 完美解决Uncaught SyntaxError: Unexpected end of input
Unexpected end of input 的英文意思是“意外的终止输入” 他通常表示我们浏览器在读取我们的js代码时,碰到了不可预知的错误,导致浏览器 无语进行下面的读取 通常造成这种错误的原 ...
- Java注解【五、注解实战】
需求: 1.表:用户ID,用户名,年龄,邮箱. 2.实现方法,传入实体,打印sql. 实现: 1.表: package Annotation; @Table("user") pub ...