【k8s所有的服务是否都可以集成在一个个pod里?】
pod里,已经可以直接调度其内部所有的容器,来一起提供一个整体的应用。为什么k8s还有其他额外的对象来做k8s的其他服务呢,直接都集成在pod里不是更好么?这里可以参考k8s对自己API对象的设计思路来理解:1)单一职责:每个对象尽力做好一件事儿,不贪大求全,小粒度更好管理和复用;2)组合优于集成:尽量让对象只是在运行时再产生联系,而不是用硬编码的方式直接固定对象之间的关系。
所以,pod本身既然已经是一个相对完善的对象,专门负责管理容器,那么基于第一条设计思路,就不应该继续给他扩充其它的功能了,同时,可基于上述第二条规则,在需要pod能力的时候,把pod作为一个成员,组合进去。这样既有分工,又有协作,为k8s高效又灵活的运作奠定了基础。
【为什么要有Job/CronJob】
pod里的业务,可以分为两大类:
1、长时间运行的“在线业务”(如nginx、mysql等)。特点是永远在线,是常驻业务;
2、短时间运行的“离线业务”(如busybox等)。特点是仅仅服务于内部用户,比如日志分析、视频转码等,虽然计算量大,但只运行短短的一下就一定会退出。根据运行的方式,又可以分为临时任务和定时任务。
对于长时间 运行的业务,其实没有太多的调度策略。但是对于短时间运行的业务,调度策略就需要比较细致了,需要基于运行超时、状态检查、失败重试、获取计算结果等来做区分。而这些由于具体业务的不同,导致的调度分别,让pod来进行管理细化,就不太合适了,pod更多应该是基于应用需要,做好容器的编排运行。所以,这样的功能,我们使用其他的对象来进行管理。上面说,离线业务里面,又分了临时和定时任务。这里临时任务就是API对象Job,定时任务,就是API对象CronJob。使用这两个对象,就可以帮助Pod细化任务调度的工作了。
【如何使用YAML描述Job】
定义:YAML中,必要的格式,在YAML和pod的笔记中已经有了描述,这里只记录对于Job特别关注的部分。想不起的部分,可以用kubectl explain job来看字段说明。但要生成YAML样板不能用kubtctl run,因为run只能创建pod,创建pod以外的其他API对象,要用命令kubectl create,再加对象名。
- apiversion:不是v1,是batch/v1;
- kind:Job;
- metadata:需要有name,lables做好标记。
示例:使用busybox创建一个“echo-job”,命令如下:
这里我第一次输入错了create,少写了一个e,所以有了如下报错,但这个报错,根本理解不到是我写错名字了,写到这里大家一起注意。所以注意经常用tab键来补齐输入,虽然有些单词你觉得很简单想直接输入:
关于这个YAML的理解,还有几个要点:
1、相对于Pod的“spec”字段,Job的spec里,多了一个 template 字段,然后里面又有一个“spec”。这是因为job对象里,应用了组合模式,template是一个应用模板,里面可以又嵌入一个pod,所以又会有一个spec,这样,job就可以创建一个pod出来。那么可能又会想,pod的yaml,完整的不应该是有apiversion,kind等么,这里只有一个spec呀。这是有因为这个pod是job管理的,不直接和apiserver联系,所以apiversion等头字段,就不用写了,只要定义好关键的spec就可以了,job自己会理解这个pod怎么用。结合下图就很好理解了,这里的 Pod 工作非常简单,在 containers 里写好名字和镜像,command 执行 /bin/echo,输出“hello world”:
2、因为 Job 业务的特殊性,所以我们还要在 spec 里多加一个字段 restartPolicy,确定 Pod 运行失败时的策略,OnFailure 是失败原地重启容器,而 Never 则是不重启容器,让 Job 去重新调度生成一个新的 Pod。
【如何在k8s里操作Job】
1、创建一个job对象:
2、查看job和pod的状态。创建之后 Kubernetes 就会从 YAML 的模板定义中提取 Pod,在 Job 的控制下运行 Pod,你可以用 kubectl get job、kubectl get pod 来分别查看 Job 和 Pod 的状态。因为 Pod 被 Job 管理,它就不会反复重启报错了,而是会显示为 Completed 表示任务完成,而 Job 里也会列出运行成功的作业数量,这里只有一个作业,所以就是 1/1:
另外,Pod 被自动关联了一个名字,用的是 Job 的名字(echo-job)再加上一个随机字符串(lln8x),这是 Job 管理时,直接帮忙给pod起的名字,这样我们就可以使用命令 kubectl logs 来获取 Pod 的运行结果:
【Job里如何灵活调度Pod】
通过YAML描述对象的框架,增加了很多的灵活性。如下 4 个字段是离线作业中常用的几个,它们并不在 template 字段下,而是在 spec 字段下,所以它们是属于 Job 级别的,用来控制模板里的 Pod 对象:
- activeDeadlineSeconds:设置 Pod 运行的超时时间;
- backoffLimit:设置 Pod 的失败重试次数;
- completions:Job 完成需要运行多少个 Pod,默认是 1 个;
- parallelism:它与 completions 相关,表示允许并发运行的 Pod 数量,避免过多占用资源。
示例:如下YAML描述了一个job对象,名字叫“sleep-job”,它随机睡眠一段时间再退出,模拟运行时间较长的作业(比如 MapReduce)。Job 的参数设置成 15 秒超时,最多重试 2 次,总共需要运行完 4 个 Pod,但同一时刻最多并发 2 个 Pod:
使用kubectl apply 创建job后,用get pod -w来实时观察pod状态,看到pod不断被排队、创建、运行的过程:
等到 4 个 Pod 都completed,用 kubectl get 来看看 Job 和 Pod 的状态。就会看到 Job 的完成数量如同我们预期的是 4,而 4 个 Pod 也都是完成状态:
“声明式”的 Job 对象让离线业务的描述变得非常直观,简单的几个字段就可以很好地控制作业的并行度和完成数量,不需要我们去人工监控干预,Kubernetes 把这些都自动化实现了。
【如何使用YAML描述CronJob】
“临时任务”使用 Job 对象,“定时任务”使用 CronJob 对象描述。这一节可以类比job的部分来理解。
create的时候,有几个要点要注意:
1、因为 CronJob 的名字有点长,所以 Kubernetes 提供了简写 cj,这个简写也可以使用命令 kubectl api-resources 看到;
2、CronJob 需要定时运行,所以我们在命令行里还需要指定参数 --schedule:
关于这个YAML,有几个点要注意
1、观察spec有三个,这个套娃结构,可以参考下面的截图:
1)第一个 spec: 是 CronJob 自己的对象规格声明;
2)第二个 spec: 从属于“jobTemplate”,它定义了一个 Job 对象;
3)第三个 spec: 从属于“template”,它定义了 Job 里运行的 Pod。
2、CronJob 还有一个新字段就是“schedule”,用来定义任务周期运行的规则。它使用的是标准的 Cron 语法,指定分钟、小时、天、月、周,和 Linux 上的 crontab 是一样的。像在这里我就指定每分钟运行一次,格式具体的含义你可以课后参考 Kubernetes 官网文档。
【如何在k8s里操作CronJob】
CronJob 和 Job 的用法几乎是一样的,使用 kubectl apply 创建 CronJob,使用 kubectl get cj、kubectl get pod 来查看状态。
标签:CronJob,kubernetes,chrono,job,spec,Job,pod,Pod From: https://www.cnblogs.com/1234roro/p/16914758.html