先说下一次性任务,在K8s中它叫job,直接来实战,先准备yaml配置
我们不知道yaml怎么写,可以直接写kubectl create job -h您可以看到命令行创建示例,然后根据创建的服务资源导出它yaml配置为my-job.yaml
apiVersion: batch/v1 # 1. batch/v1 是当前 Job 的 apiVersion kind: Job # 2. 指出当前资源类型为 Job metadata: name: my-job spec: template: metadata: spec: containers: - image: busybox name: my-job command: ["echo","Hello, boge."] restartPolicy: Never # 3. restartPolicy 在指定的情况下需要重启容器。 Job,只能设置为 Never 或者 OnFailure
创建它查看结果
# kubectl apply -f my-job.yaml job.batch/my-job created # kubectl get jobs.batch NAME COMPLETIONS DURATION AGE my-job 1/1 2s 73s # COMPLETIONS 已完成的 # DURATION 这个job运行时间 # AGE 这个job资源自创建至今已有时间 # job会生成一个pod,任务完成后会是Completed的状态 # kubectl get pod NAME READY STATUS RESTARTS AGE my-job-7h6fb 0/1 Completed 0 31s # 看下这个job生成的pod日志 # kubectl logs my-job-7h6fb Hello, boge.
ob失败会发生什么?
我们编辑这个job的yaml,把执行命令改成不存在的命令,看看会发生什么
apiVersion: batch/v1 # 1. batch/v1 是当前 Job 的 apiVersion kind: Job # 2. 指出当前资源类型为 Job metadata: name: my-job spec: template: metadata: spec: containers: - image: busybox name: my-job command: ["echoaaa","Hello, boge."] restartPolicy: Never # 3. restartPolicy 在指定的情况下需要重启容器。 Job,只能设置为 Never 或者 OnFailure
创建它
# kubectl apply -f my-job.yaml # 可以观察到这一点job而且restartPolicy重启模式是Never它的job状态还没有完成,所以它将继续创造新的pod,直到COMPLETIONS为1/1,显然它永远不会为我们的例子成功 # kubectl get pod NAME READY STATUS RESTARTS AGE my-job-9fcbm 0/1 StartError 0 47s my-job-bt2kd 0/1 StartError 0 54s my-job-mlnzz 0/1 StartError 0 37s my-job-mntdp 0/1 StartError 0 17s # kubectl get job NAME COMPLETIONS DURATION AGE my-job 0/1 15s 15s # 找一个pod看事件描述,会清楚地指出命令不存在 # kubectl describe pod my-job-9fcbm Name: my-job-9fcbm Namespace: default ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 44s default-scheduler Successfully assigned default/my-job-9fcbm to 10.0.0.204 Normal Pulling 43s kubelet Pulling image "busybox" Normal Pulled 36s kubelet Successfully pulled image "busybox" in 7.299038719s Normal Created 36s kubelet Created container my-job Warning Failed 36s kubelet Error: failed to create containerd task: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: span class="token string">"echoaaa": executable file not found in $PATH: unknown
# 删除掉这个job,不然那创建的pod数量可有够多的了
# kubectl delete job my-job
# 试试把restartPolicy重启模式换成OnFailure观察看看
# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-job-gs95h 0/1 CrashLoopBackOff 3 84s
# 可以看到它不会创建新的pod,而是会尝试重启自身,以期望恢复正常,这里看到已经重启了3次,还会持续增加到5,然后会被K8s给删除以尝试,因为这里只是job而不是deployment,它不会自己再启动一个新的pod,所以这个job等于就没有了,这里说明OnFailure是生效的,至少不会有那么多错误的pod出现了
并行执行job
准备好yaml配置
apiVersion: batch/v1
kind: Job
metadata:
name: my-job
spec:
parallelism: 2 # 并行执行2个job
template:
metadata:
name: my-job
spec:
containers:
- image: busybox
name: my-job
command: ["echo","Hello, boge."]
restartPolicy: OnFailure
创建并查看结果
# kubectl apply -f my-job.yaml
job.batch/my-job created
# job一共启动了2个pod,并且它们的AGE一样,可见是并行创建的
# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-job-fwf8l 0/1 Completed 0 7s
my-job-w2fxd 0/1 Completed 0 7s
再来个组合测试下并行完成定制的总任务数量
apiVersion: batch/v1
kind: Job
metadata:
name: myjob
spec:
completions: 6 # 此job完成pod的总数量
parallelism: 2 # 每次并发跑2个job
template:
metadata:
name: myjob
spec:
containers:
- name: hello
image: busybox
command: ["echo"," hello boge! "]
restartPolicy: OnFailure
创建并查看结果
# 可以看到是每次并发2个job,完成6个总量即停止
# kubectl get pod
NAME READY STATUS RESTARTS AGE
myjob-54wmk 0/1 Completed 0 11s
myjob-fgtmj 0/1 Completed 0 15s
myjob-fkj5l 0/1 Completed 0 7s
myjob-hsccm 0/1 Completed 0 7s
myjob-lrpsr 0/1 Completed 0 15s
myjob-ppfns 0/1 Completed 0 11s
# 符合预期
# kubectl get job
NAME COMPLETIONS DURATION AGE
myjob 6/6 14s 34s
# 测试完成后删掉这个资源
kubectl delete job myjob
到此,job的内容就讲完了,在生产中,job比较适合用在CI/CD流水线中,作完一次性任务使用,我在生产中基本没怎么用这个资源。 cronjob
上面的job是一次性任务,那我们需要定时循环来执行一个任务可以吗?答案肯定是可以的,就像我们在linux系统上面用crontab一样,在K8s上用cronjob的另一个好处就是它是分布式的,执行的pod可以是在集群中的任意一台NODE上面(这点和cronsun有点类似)
让我们开始实战吧,先准备一下cronjob的yaml配置为my-cronjob.yaml
apiVersion: batch/v1beta1 # <--------- 当前 CronJob 的 apiVersion
kind: CronJob # <--------- 当前资源的类型
metadata:
name: hello
spec:
schedule: "* * * * *" # <--------- schedule 指定什么时候运行 Job,其格式与 Linux crontab 一致,这里 * * * * * 的含义是每一分钟启动一次
jobTemplate: # <--------- 定义 Job 的模板,格式与前面 Job 一致
spec:
template:
spec:
containers:
- name: hello
image: busybox
command: ["echo","boge like cronjob."]
restartPolicy: OnFailure
正常创建后,我们过几分钟来看看运行结果
# 这里会显示cronjob的综合信息
# kubectl get cronjobs.batch
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello * * * * * False 0 66s 2m20s
# 可以看到它每隔一分钟就会创建一个pod来执行job任务
# kubectl get pod
NAME READY STATUS RESTARTS AGE
hello-1610267460-9b6hp 0/1 Completed 0 2m5s
hello-1610267520-fm427 0/1 Completed 0 65s
hello-1610267580-v8g4h 0/1 ContainerCreating 0 5s
# 测试完成后删掉这个资源
# kubectl delete cronjobs.batch hello
cronjob.batch "hello" deleted
cronjob定时任务在生产中的用处很多,这也是为什么上面job我说用得很少的缘故,我们可以把一些需要定时定期运行的任务,在K8s上以cronjob运行,依托K8s强大的资源调度以及服务自愈能力,我们可以放心的把定时任务交给它执行。