0. 前言:在线业务和离线业务
Kubernetes 的业务可以分为两大类:在线业务和离线业务。
-
在线业务:像 Nginx 、MySQL 这样长时间运行的业务,这些应用一旦运行起来,除非出错或者停止,它的容器进程会一直保持在 Running 状态
-
离线业务:短时间运行的业务,或者是定时任务,这种业务在计算完成后就直接退出了;它们一般不直接服务于外部用户,只对内部用户有意义,比如日志分析、数据建模、视频转码等等,虽然计算量很大,但只会运行一段时间;也就是说,它们的特点是必定会退出,因此我们需要考虑运行超时、状态检查、失败重试、获取计算结果等管理事项
在上篇中我们也看到了,Kubernetes 基于 Pod 延伸出了很多表示各种业务的其他资源对象。那为什么不直接在 Pod 中添加功能来处理这些业务需求?
这篇笔记会简要阐述 Kubernetes 基于 Pod 的设计理念,也是上面问题的解答。下面先从 Kubernetes 最简单的两种对象 Job
和 CronJob
开始。
1. 不扩展 Pod 功能背后的理念和原则
Kubernetes 使用 YAML 来描述资源,把业务简化成了一个个的对象,内部有属性,外部有联系,也需要互相协作,只不过我们不需要编程,完全由 Kubernetes 自动处理。
面向对象的设计有许多基本原则,其中有两条比较恰当地描述了 Kubernetes 对象设计思路,一个是“单一职责”,另一个是“组合优于继承”。
-
单一职责:对象应该只专注于做好一件事情,保持足够小的粒度才更方便复用和管理
-
组合优于继承:尽量让对象在运行时产生联系,保持松耦合,而不要用硬编码的方式固定对象的关系
因为 Pod 已经是一个相对完善的对象,专门负责管理容器,那么我们就不应该再“画蛇添足”地盲目为它扩充功能,而是要保持它的独立性,容器之外的功能就需要定义其他的对象,把 Pod 作为它的一个成员“组合”进去。每种 Kubernetes 对象就可以只关注自己的业务领域,只做自己最擅长的事情,其他的工作交给其他对象来处理,既不“缺位”也不“越位”,既有分工又有协作。
2. Job 和 CronJob
“离线业务”也可以分为两种。一种是“临时任务”,运行完成就结束了,如果有需要可以再次安排;另一种是“定时任务”,可以按时按点周期运行,不需要过多干预。为了实现对离线业务的处理,Kubernetes 组合了 Pod 推出两种新的对象 Job
和 CronJob
,“临时任务”就是 API 对象 Job
,“定时任务”就是 API 对象 CronJob
,使用这两个对象women 就能够在 Kubernetes 里调度管理任意的离线业务了。
2.1 使用 YAML 描述 Job
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:
creationTimestamp: null
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。
2.2 在 Kubernetes 里面操作 Job
使用下面的命令来创建 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
Job 在运行结束后,为了方便获取处理结果,不会立即删除。但是积累过多的已完成的 Job 也会消耗系统资源,我们可以使用 ttlSecondsAfterFinished
设置一个保留时限。参阅已完成 Job 的自动清理
2.3 几个离线作业的重要字段
上面我们操作了一个最简单的 Job,其实 Kubernetes 还支持在Job 级别、Pod 级别添加任意的字段来定制业务。
这里是几个控制离线作业的重要字段,其他更详细的信息可以参考 Job 文档
activeDeadlineSeconds
- 设置 Pod 运行的超时时间
backoffLimit
- 设置 Pod 的失败重试次数
completions
- Job 完成需要运行多少个 Pod,默认是 1 个
parallelism
- 它与 completions 相关,表示允许并发运行的 Pod 数量,避免过多占用资源
这 4 个字段并不在 template
字段下,而是在 spec
字段下,所以它们是属于 Job 级别的,用来控制模板里的 Pod 对象。
“声明式”的 Job 对象让离线业务的描述变得非常直观,简单的几个字段就可以很好地控制作业的并行度和完成数量,不需要我们去人工监控干预,Kubernetes 把这些都自动化实现了。
2.4 使用 YAML 描述 CronJob
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"]
这个 YAML 连续有三个 spec 嵌套层次:
-
第一个 spec 是 CronJob 自己的对象规格声明
-
第二个 spec 从属于“jobTemplate”,它定义了一个 Job 对象
-
第三个 spec 从属于“template”,它定义了 Job 里运行的 Pod
除了定义 Job 对象的“jobTemplate”字段之外,CronJob 还有一个新字段就是“schedule”,用来定义任务周期运行的规则。它使用的是标准的 Cron 语法,指定分钟、小时、天、月、周,和 Linux 上的 crontab 是一样的。
出于节约资源的考虑,CronJob 不会无限期地保留已经运行的 Job,它只会保留最近三个执行结果,当然我们也可以用 successfulJobsHistoryLimit
改变保留的数量。参阅 使用 CronJob 运行自动化任务
其余的用法可以参考 CronJob 文档
标签:CronJob,Kubernetes,对象,Job,Pod,spec From: https://www.cnblogs.com/joexu01/p/16740718.html