K8S 工作负载(3)
概述
前两章我们介绍了 K8S 下 Pod,Deployment,ReplicaSet以及StatefulSet 这四种工作负载,这其中后三者属于工作负载资源。在实际操作中,通过使用 Deployment 和 StatefulSet 可以实现大部分我们想要的效果,但是在一些场景下,例如,需要搜集当前集群下所有节点的监控数据,或者节点出现增删的情况下,如何优雅的自动完成服务的扩缩容以及如何进行定时任务或者单次任务的执行。由此,引出我们本章介绍的三种工作负载资源: DasmonSet, Job以及 CronJob。
DaemonSet
DaemonSet是这样一种对象(守护进程集),它在集群的每个节点上运行一个Pod,且保证只有一个Pod,这非常适合一些系统层面的应用,例如日志收集、资源监控等,这类应用需要每个节点都运行,且不需要太多实例,比如我们收集节点信息信息的 node-exporter。
DaemonSet 的一些典型用法:
- 在每个节点上运行集群守护进程
- 在每个节点上运行日志收集守护进程
- 在每个节点上运行监控守护进程
整体架构图如下:
创建 DaemonSet
下面的 daemonset.yaml 文件描述的是一个监控节点磁盘信息的服务
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: disk-exporter
namespace: monitoring
labels:
app.kubernetes.io/name: disk-exporter
app.kubernetes.io/instance: disk-exporter
app.kubernetes.io/version: "1.0.1"
spec:
minReadySeconds: 10
selector:
matchLabels:
app.kubernetes.io/name: disk-exporter
app.kubernetes.io/instance: disk-exporter
template:
metadata:
labels:
app.kubernetes.io/name: disk-exporter
app.kubernetes.io/instance: disk-exporter
spec:
nodeSelector: # 节点选择,当节点拥有disk-info=need时才在节点上创建Pod。若需要在所有节点部署,则不需要加上nodeSelector
disk-info: need
containers:
- name: disk-exporter
securityContext:
privileged: true
image: "disk-exporter:v1.0.0"
imagePullPolicy: IfNotPresent
ports:
- name: metrics
containerPort: 9945
protocol: TCP
resources:
limits:
cpu: "2.0"
memory: 2.0Gi
requests:
cpu: "1"
memory: 1Gi
command:
- bash
- -c
- "/disk-exporter/bin/disk-exporter"
我们可以看到,上述的文件中,没有出现 deployment 和 statefulset 中的 replicas 这个参数,这是因为每个节点都固定一个。
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
disk-exporter 3 3 3 3 3 <none> 5m
Job 和 CronJob
Job和CronJob是负责批量处理短暂的一次性任务(short lived one-off tasks),即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。
- Job:是Kubernetes用来控制批处理型任务的资源对象。批处理业务与长期处理业务(Deployment、Statefulset)的主要区别是批处理业务的运行有头有尾,而长期处理业务在用户不停止的情况下永远运行。Job管理的Pod根据用户的设置把任务成功完成就自动退出(Pod自动删除)。
- CronJob:是基于时间的Job,就类似于Linux系统的crontab文件中的一行,在指定的时间周期运行指定的Job。
创建 Job
下面我们创建一个简单的job,计算π到2000位并打印输出。Job结束需要运行50个Pod,这个示例中就是打印π 50次,并行运行5个Pod,Pod如果失败最多重试5次。
apiVersion: batch/v1
kind: Job
metadata:
name: pi-with-timeout
spec:
completions: 50 # 运行的次数,即Job结束需要成功运行的Pod个数
parallelism: 5 # 并行运行Pod的数量,默认为1
backoffLimit: 5 # 表示失败Pod的重试最大次数,超过这个次数不会继续重试。
activeDeadlineSeconds: 10 # 表示Pod超期时间,一旦达到这个时间,Job及其所有的Pod都会停止。
template: # Pod定义
spec:
containers:
- name: pi
image: perl
command:
- perl
- "-Mbignum=bpi"
- "-wle"
- print bpi(2000)
restartPolicy: Never
根据completions和parallelism的设置,可以将Job划分为以下几种类型。\
Job 类型 | 说明 | 使用示例 |
---|---|---|
一次性Job | 创建一个Pod直至其成功结束 | 数据库创建 |
固定结束次数的Job | 依次创建一个Pod运行直至completions个成功结束 | 处理工作队列的 Pod |
固定结束次数的并行Job | 依次创建多个Pod运行直至completions个成功结束 | 多个Pod同时处理工作队列 |
并行Job | 创建一个或多个Pod直至有一个成功结束 | 多个Pod同时处理工作队列 |
创建 CronJob
CronJob 用于执行排期操作,例如备份、生成报告等。
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "* * * * *" # 定时相关配置
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox:1.28
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
CronJob的格式从前到后就是:
- Minute
- Hour
- Day of month
- Month
- Day of week
输入 | 描述 | 相当于 |
---|---|---|
@yearly | 每年 1 月 1 日的午夜运行一次 | 0 0 1 1 * |
@monthly | 每月第一天的午夜运行一次 | 0 0 1 * * |
@weekly | 每周的周日午夜运行一次 | 0 0 * * 0 |
@daily | 每天午夜运行一次 | 0 0 * * * |
@hourly | 每小时的开始一次 | 0 * * * * |
注意有时候我们定时任务,涉及到时区的问题。可以参考官方文档