赞
踩
Kubernetes 的业务可以分为两大类:在线业务和离线业务。
在上篇中我们也看到了,Kubernetes 基于 Pod 延伸出了很多表示各种业务的其他资源对象。那为什么不直接在 Pod 中添加功能来处理这些业务需求?
这篇笔记会简要阐述 Kubernetes 基于 Pod 的设计理念,也是上面问题的解答。下面先从 Kubernetes 最简单的两种对象 Job 和 CronJob 开始。
Kubernetes 使用 YAML 来描述资源,把业务简化成了一个个的对象,内部有属性,外部有联系,也需要互相协作,只不过我们不需要编程,完全由 Kubernetes 自动处理。
面向对象的设计有许多基本原则,其中有两条比较恰当地描述了 Kubernetes 对象设计思路,一个是单一职责
,另一个是组合优于继承
。
因为 Pod 已经是一个相对完善的对象,专门负责管理容器,那么我们就不应该再画蛇添足
地盲目为它扩充功能,而是要保持它的独立性,容器之外的功能就需要定义其他的对象,把 Pod 作为它的一个成员组合
进去。每种 Kubernetes 对象就可以只关注自己的业务领域,只做自己最擅长的事情,其他的工作交给其他对象来处理,既不缺位
也不越位
,既有分工又有协作。
“离线业务”也可以分为两种。一种是“临时任务”,运行完成就结束了,如果有需要可以再次安排;另一种是“定时任务”,可以按时按点周期运行,不需要过多干预。为了实现对离线业务的处理,Kubernetes 组合了 Pod 推出两种新的对象 Job
和 CronJob
,“临时任务”就是 API 对象 Job,“定时任务”就是 API 对象 CronJob
,使用这两个对象我们就能够在 Kubernetes 里调度管理任意的离线业务了。
YAML 文件的“头部”:
apiVersion: batch/v1
kind: Job
,这与对象的名字是一致的metadata:
里面仍要有 name
标记名字,也可以用 labels
添加任意的标签当然我们也可以用 kubectl create
来生成 YAML 模板:
$ kubectl create job echo-job --image=busybox --dry-run=client -o yaml
注意:想要生成 YAML 样板文件的话不能使用 kubectl run,因为 kubectl run 只能创建 Pod,要创建 Pod 以外的其他 API 对象,需要使用命令 kubectl create,再加上对象的类型名
下面是我们生成的 Job 对象的 YAML 文件(修改后的):
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"]
可以看出,Job
与 Pod
主要的区别就在 spec
字段里,多了一个 template
字段,然后又是一个 spec
。
它其实就是在 Job 对象里应用了组合模式,template
字段定义了一个“应用模板”,里面嵌入了一个 Pod,这样 Job 就可以从这个模板来创建出 Pod。
而这个 Pod 因为受 Job 的管理控制,不直接和 apiServer
打交道,也就没必要重复 apiVersion
等“头字段”,只需要定义好关键的 spec
,描述清楚容器相关的信息就可以了,可以说是一个“无头部”的 Pod
对象。
apiVersion 字段是 batch/v1,表明它不属于核心对象组(core group),而是属于批处理对象组(batch group)
这个 Pod 工作非常简单,在 containers 里写好名字和镜像,command 执行 /bin/echo
,输出“hello world”。
因为 Job 业务的特殊性,所以我们还要在 spec
里多加一个字段 restartPolicy
,确定Pod
运行失败时的策略,OnFailure
是失败原地重启容器,而Never
则是不重启容器,让 Job
去重新调度生成一个新的 Pod
。
使用下面的命令来创建 Job:
$ kubectl apply -f job.yml
job.batch/echo-job created
然后我们可以查看 Job、Pod 的状态:
$ kubectl get jobs
NAME COMPLETIONS DURATION AGE
echo-job 1/1 13s 26s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
echo-job-vr84n 0/1 Completed 0 29s
因为 Pod 被 Job 管理,它就不会反复重启报错了,而是会显示为 Completed 表示任务完成,而 Job 里也会列出运行成功的作业数量,这里只有一个作业,所以就是 1/1。Pod 被自动关联了一个名字,用的是 Job 的名字(echo-job)再加上一个随机字符串。
最后我们查看一下 Pod 的输出:
$ kubectl logs echo-job-vr84n
hello world
Job 在运行结束后,为了方便获取处理结果,不会立即删除。但是积累过多的已完成的 Job 也会消耗系统资源,我们可以使用 ttlSecondsAfterFinished 设置一个保留时限。参阅已完成 Job 的自动清理
上面我们操作了一个最简单的 Job,其实 Kubernetes 还支持在Job 级别、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
这里是几个控制离线作业的重要字段,其他更详细的信息可以参考 Job 文档
activeDeadlineSeconds
- 设置 Pod 运行的超时时间
backoffLimit
- 设置 Pod 的失败重试次数
completions
- Job 完成需要运行多少个 Pod,默认是 1 个
parallelism
- 它与 completions 相关,表示允许并发运行的 Pod 数量,避免过多占用资源
这 4 个字段并不在 template
字段下,而是在 spec
字段下,所以它们是属于 Job 级别的,用来控制模板里的 Pod 对象。
“声明式”的 Job
对象让离线业务的描述变得非常直观,简单的几个字段就可以很好地控制作业的并行度和完成数量,不需要我们去人工监控干预,Kubernetes 把这些都自动化实现了。
CronJob
是定时任务,在 Kubernetes 中简称CronJob
为 cj
(前面提到过可以通过 kubectl api-resources
命令查看)。下面我们使用命令来创建一个 CronJob
的 YAML 模板,因为是定时任务,在命令行里还需要指定参数 --schedule
这个参数就是用来定义哪个时间运行任务:
kubectl create cj echo-cj --image=busybox --schedule="" --dry-run=client -o yaml
然后稍微编辑一下,就生成一个描述 CronJob 对象的 YAML 文件:
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"]
除了名字不同,CronJob 和 Job 的用法几乎是一样的,使用 kubectl apply 创建 CronJob,使用 kubectl get cj、kubectl get pod 来查看状态:
$ kubectl apply -f cronjob.yml
$ kubectl get cj
$ kubectl get pod
这个 YAML 连续有三个 spec 嵌套层次:
除了定义 Job 对象的jobTemplate
字段之外,CronJob 还有一个新字段就是schedule
,用来定义任务周期运行的规则。它使用的是标准的 Cron 语法,指定分钟、小时、天、月、周
,和 Linux 上的 crontab 是一样的。
出于节约资源的考虑,CronJob 不会无限期地保留已经运行的 Job,它只会保留最近三个执行结果,当然我们也可以用successfulJobsHistoryLimit
改变保留的数量。参阅 使用 CronJob 运行自动化任务
其余的用法可以参考 CronJob 文档
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。