Kubernetes Controllers

环境准备

root@master30~ 11:14:15# kubectl create ns controllers
root@master30~ 11:15:36# kubectl config set-context --current --namespace controllers

Controllers (控制器)介绍

Controller 主要作用是确保所管理的资源处于用户期望的状态,通过不断地监控资源的状态,并根据实际状态与期望状态之间的差异执行相应的动作,来实现资源的自愈、自动扩展等功能。

先简单回顾一下:容器按照是否持续运行可分为两类。

  • 服务类容器: 一直运行任务,通常持续提供服务, 比如HTTP等。

  • 工作类容器:一次性任务, 比如批处理程序,完成后容器就退出。

Kubernetes 中用于管理服务类容器的控制器有 ReplicaSet 、Deployment 和 DaemonSet 等。

Kubernetes 中用于管理工作类容器的控制器有 Job 和 CronJob。

ReplicaSets

ReplicaSets 介绍

ReplicaSet,简称RS,是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合。 因此,它通常用来保证给定数量的、完全相同的 Pod 的可用性。它主要被 Deployment 用来作为一种编排 Pod 创建、删除及更新的机制。

ReplicaSet 工作原理

ReplicaSet 部分主要字段:

  • 一个用来识别可获得的 Pod 的集合的选择算符。
  • 一个用来标明应该维护的副本个数的数值。
  • 一个用来指定创建新 Pod 时要使用的 Pod 模板。

每个 ReplicaSet 根据 Pod 模板创建制定数量 Pod, 进而实现其存在价值。

  • 如果pod数量多于指定数量,则RS会终止额外的pod。
  • 如果pod数量少于指定数量,则RS会创建额外的pod。例如宿主机内核升级,在其他节点上创建新Pod。

ReplicaSet 使用

ReplicaSet 创建
root@master30~/controllers 11:20:08# vim rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx
spec:
  #期望副本数
  replicas: 3
  #选择器(核心关键):RS 通过标签匹配管理 Pod,只会管控所有带有 app=nginx 标签的 Pod。
  selector:
    matchLabels:
      app: nginx
  #Pod 模板
  template:
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: docker.io/library/nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
root@master30~/controllers 11:20:21# kubectl apply -f rs.yaml
replicaset.apps/nginx created
root@master30~/controllers 11:32:51# kubectl get rs
NAME    DESIRED   CURRENT   READY   AGE
nginx   3         3         3       4s
root@master30~/controllers 11:32:55# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
nginx-l7827   1/1     Running   0          30s
nginx-m8bbs   1/1     Running   0          30s
nginx-tcp45   1/1     Running   0          30s
root@master30~/controllers 11:33:48# kubectl describe pods nginx-l7827 | grep Controlled
Controlled By:  ReplicaSet/nginx
ReplicaSet 健壮性测试

测试1:删除单个副本

root@master30~/controllers 11:35:07# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
nginx-l7827   1/1     Running   0          2m22s
nginx-m8bbs   1/1     Running   0          2m22s
nginx-tcp45   1/1     Running   0          2m22s
root@master30~/controllers 11:35:13# kubectl delete pods nginx-l7827
pod "nginx-l7827" deleted
root@master30~/controllers 11:35:28# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
nginx-7c9qp   1/1     Running   0          9s
nginx-m8bbs   1/1     Running   0          2m45s
nginx-tcp45   1/1     Running   0          2m45s

Pod 的 metadata.ownerReferences 字段,显示所属主资源。 正是通过这一连接,ReplicaSet 知道它所维护的 Pod 集合的状态, 并据此计划其操作行为。

root@master30~/controllers 11:40:30# kubectl get pods nginx-m8bbs -o yaml | grep '^  ownerReferences' -A8
  ownerReferences:
  - apiVersion: apps/v1
    blockOwnerDeletion: true
    controller: true
    kind: ReplicaSet
    name: nginx
    uid: bf76c593-ae88-48f1-9f5f-52f582a7a382
  resourceVersion: "251909"
  uid: 3f947b43-08ad-4fc1-b4a2-8b3c0d324de1

ReplicaSet 使用 selector 获得 Pod 集合。如果某个 Pod 没有 OwnerReference 或者其 OwnerReference 不是一个控制器, 且其匹配到某 ReplicaSet 的选择算符,则该 Pod 立即被此 ReplicaSet 获得。

ReplicaSet 依靠 selector 标签匹配 Pod,管控符合标签的 Pod;

测试2:创建具有相同标签的pod

root@master30~/controllers 11:43:45# kubectl run nginx --image=docker.io/library/nginx:latest --labels app=nginx;kubectl get pods
pod/nginx created
NAME          READY   STATUS        RESTARTS   AGE
nginx         0/1     Terminating   0          0s
nginx-7c9qp   1/1     Running       0          8m41s
nginx-m8bbs   1/1     Running       0          11m
nginx-tcp45   1/1     Running       0          11m

具有相同标签的pod/nginx刚被创建出来就被Terminating

ReplicaSet 删除

删除RS控制器,会删除它管理的pods。

root@master30~/controllers 11:46:52# kubectl delete rs nginx ;kubectl get pods
replicaset.apps "nginx" deleted
NAME          READY   STATUS        RESTARTS   AGE
nginx-7c9qp   1/1     Terminating   0          12m
nginx-m8bbs   1/1     Terminating   0          14m
nginx-tcp45   1/1     Terminating   0          14m

使用**–cascade=orphan**选项,只删除RS,保留pod。

root@master30~/controllers 11:48:30# kubectl delete rs nginx --cascade=orphan
replicaset.apps "nginx" deleted
root@master30~/controllers 11:48:57# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
nginx-22wsj   1/1     Running   0          42s
nginx-drwf8   1/1     Running   0          42s
nginx-q54v7   1/1     Running   0          42s
root@master30~/controllers 11:52:24# kubectl delete rs -h | grep '^    --cascade' -A1
    --cascade='background':
        Must be "background", "orphan", or "foreground". Selects the deletion cascading strategy for the dependents (e.g. Pods created by a ReplicationController). Defaults to background.

# 1.background(默认)
#后台级联删除:主资源(如 RS)先标记为删除,API 立即返回;控制器后台异步清理下属 Pod。
# 2.foreground
#前台级联删除:先删除所有下属 Pod,全部清理完毕后,再删除主资源 RS,命令会阻塞等待全部删完。
# 3.orphan
#孤儿模式:只删除 RS 本身,保留所有关联 Pod,Pod 失去控制器管理,不会被一同删掉。

ReplicationController

ReplicationController,简称RC,功能与ReplicaSets类似。 ReplicaSet 是 RC 的升级版, 支持新的基于集合的标签选择算符

Deployment

Deployment 介绍

Deployment,简称 deploy,为 PodReplicaSet 提供声明式的更新能力。

ReplicaSet 能确保运行指定数量的pod。Deployment能管理ReplicaSets,并提供对pod的更新等功能。因此,我们建议你使用Deployment来管理ReplicaSets,除非你需要自定义更新编排。这意味着你可能永远不需要操作ReplicaSet对象,而是使用Deployment替代管理 。

Deployment 用例

以下是 Deployments 的典型用例:

Deployment 管理

Deployment (你创建和操作的对象)
    └── 管理着 → ReplicaSet (由Deployment自动创建)
                    └── 管理着 → Pod (实际运行应用容器的实例)

当你创建一个 Deployment 时:

  1. Deployment 会创建一个 ReplicaSet
  2. 这个 ReplicaSet 负责创建和管理指定数量的 Pod
  3. 当你更新 Deployment(如更换镜像版本)时,Deployment 会创建一个新的 ReplicaSet,并逐步将 Pod 从旧 ReplicaSet 迁移到新 ReplicaSet

Deployment = ReplicaSet + 滚动更新 + 版本回滚 + 声明式管理

✅ 推荐:始终使用 Deployment

创建
命令行方式
root@master30~/controllers 14:01:58# kubectl create deployment web --image=docker.io/library/nginx:1.27 --replicas=2
root@master30~/controllers 14:05:21# kubectl get all
NAME                       READY   STATUS    RESTARTS   AGE
pod/web-768f99776c-fxcqn   1/1     Running   0          3m21s
pod/web-768f99776c-ks9p7   1/1     Running   0          3m21s

NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/web   2/2     2            2           3m21s

NAME                             DESIRED   CURRENT   READY   AGE
replicaset.apps/web-768f99776c   2         2         2       3m21s
root@master30~/controllers 14:06:24# kubectl describe deployments.apps web
Name:                   web
Namespace:              controllers
CreationTimestamp:      Sun, 28 Jun 2026 14:03:03 +0800
Labels:                 app=web
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=web
Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=web
  Containers:
   nginx:
    Image:         docker.io/library/nginx:1.27
    Port:          <none>
    Host Port:     <none>
    Environment:   <none>
    Mounts:        <none>
  Volumes:         <none>
  Node-Selectors:  <none>
  Tolerations:     <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   web-768f99776c (2/2 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  3m57s  deployment-controller  Scaled up replica set web-768f99776c to 2
# ReplicaSet与Deployment关系
root@master30~/controllers 14:07:00# kubectl describe rs web-768f99776c | grep Controlled
Controlled By:  Deployment/web
# 指明ReplicaSet是由Deployment/web创建的。

# pod与ReplicaSet关系
root@master30~/controllers 14:10:29# kubectl describe pod web-768f99776c-fxcqn | grep Controlled
Controlled By:  ReplicaSet/web-768f99776c
# 指明pod是由ReplicaSet/web-b78cbd74b创建的
yaml 文件方式
root@master30~/controllers 14:12:05# kubectl create deployment web --image=docker.io/library/nginx:1.27 --replicas=2 --dry-run=client -o yaml > deployment-web.yaml
root@master30~/controllers 14:23:16# cat deployment-web.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web
  name: web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web
    spec:
      containers:
      - image: docker.io/library/nginx:1.27
        name: nginx
        resources: {}
status: {}

格式说明:

① apiVersion,是当前配置格式的版本。
② kind,是要创建的资源类型, 这里是Deployment。
③ metadata,是该资源的元数据, name是必需的元数据项。
④ spec,是该Deployment的规格说明。
⑤ spec.replicas,指明副本数量, 默认为1。
⑥ spec.template,定义Pod的模板, 这是配置文件的重要部分。
⑦ spec.template.metadata,定义Pod的元数据, 至少要定义一个label。 label的key和value可以任意指定。
⑧ spec.template.spec,描述Pod的规格, 此部分定义Pod中每一个容器的属性,name和image是必需的。

创建方式进行比较

  • 基于命令行的方式:
    • 简单、 直观、 快捷, 上手快。
    • 适合临时测试或实验。
  • 基于配置文件的方式:
    • 配置文件描述了What, 即应用最终要达到的状态。
    • 配置文件提供了创建资源的模板, 能够重复部署。
    • 可以像管理代码一样管理部署。
    • 适合正式的、 跨环境的、 规模化部署。
    • 这种方式要求熟悉配置文件的语法, 有一定难度。

**kubectl apply **命令不但能够创建Kubernetes资源, 也能对资源进行更新, 非常方便。

编辑
# 方法1:命令行直接修改
root@master30~/controllers 14:25:11# kubectl edit deployments.apps web

# 方法2:编辑资源文件,然后apply应用

# 方法3:命令行修改,例如修改deployment副本数
# scale用于修改spec.replicas,即修改副本数
root@master30~/controllers 14:25:25# kubectl scale deployment web --replicas=4
deployment.apps/web scaled
root@master30~/controllers 14:26:15# kubectl get deployments.apps
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web    4/4     4            4           23m
删除

删除deployments时,默认会删除deployments管理的子资源。

root@master30~/controllers 14:26:22# kubectl delete deployments.apps web
deployment.apps "web" deleted
root@master30~/controllers 14:26:52# kubectl get all
No resources found in controllers namespace.

使用**–cascade=orphan选项**删除deployments,不会删除deployments管理的子资源。

# 只删除deployment不删除资源
root@master30~/controllers 14:27:28# kubectl delete deployments.apps web --cascade=orphan
deployment.apps "web" deleted
root@master30~/controllers 14:27:45# kubectl get all
NAME                       READY   STATUS    RESTARTS   AGE
pod/web-768f99776c-d87qb   1/1     Running   0          27s
pod/web-768f99776c-msbbz   1/1     Running   0          27s

NAME                             DESIRED   CURRENT   READY   AGE
replicaset.apps/web-768f99776c   2         2         2       27s
#手动删除资源
root@master30~/controllers 14:27:50# kubectl delete all -l app=web
pod "web-768f99776c-d87qb" deleted
pod "web-768f99776c-msbbz" deleted
replicaset.apps "web-768f99776c" deleted
水平伸缩
root@master30~/controllers 14:29:36# kubectl create deployment web --image=docker.io/library/nginx:1.27 --replicas=2
deployment.apps/web created
root@master30~/controllers 14:31:11# kubectl get all
NAME                       READY   STATUS    RESTARTS   AGE
pod/web-768f99776c-jjq9v   1/1     Running   0          9s
pod/web-768f99776c-t92xq   1/1     Running   0          9s

NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/web   2/2     2            2           9s

NAME                             DESIRED   CURRENT   READY   AGE
replicaset.apps/web-768f99776c   2         2         2       9s
root@master30~/controllers 14:31:20# kubectl scale deployment web --replicas=3
deployment.apps/web scaled
root@master30~/controllers 15:24:18# kubectl get all
NAME                       READY   STATUS    RESTARTS   AGE
pod/web-768f99776c-jjq9v   1/1     Running   0          53m
pod/web-768f99776c-t92xq   1/1     Running   0          53m
pod/web-768f99776c-xh5xb   1/1     Running   0          5s

NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/web   3/3     3            3           53m

NAME                             DESIRED   CURRENT   READY   AGE
replicaset.apps/web-768f99776c   3         3         3       53m

#或者
root@master30~/controllers 15:24:23# kubectl edit deployments.apps web

#或者
root@master30~/controllers 15:30:18# kubectl get deployments.apps web -o yaml > web.yaml
root@master30~/controllers 15:30:50# vim web.yaml
健壮性测试

关闭 worker 节点,测试pod重建。

root@master30~/controllers 15:31:42# kubectl get pods -o wide
NAME                   READY   STATUS    RESTARTS   AGE     IP              NODE                 NOMINATED NODE   READINESS GATES
web-768f99776c-jjq9v   1/1     Running   0          60m     10.224.128.48   worker31.hgq.cloud   <none>           <none>
web-768f99776c-t92xq   1/1     Running   0          60m     10.224.96.244   worker32.hgq.cloud   <none>           <none>
web-768f99776c-xh5xb   1/1     Running   0          7m32s   10.224.128.49   worker31.hgq.cloud   <none>           <none>

# 关闭 worker32
root@worker32~ 15:32:03# init 0
# 等待一段时间(5分钟), Kubernetes 判定 worker32不可用, 将worker32上的Pod标记为Unknown状态, 并在worker31上重建Pod,维持总副本数为3
# 当worker32恢复后, Unknown的Pod会被删除, 已经运行的Pod不会重新调度回worker32。

K8s 判断节点宕机,要经过 3 个阶段

  1. Node 节点上kubelet 默认 每 10s 发一次心跳上报自身状态(kubelet → kube-apiserver)

  2. Master 上 controller-manager5 秒检查一次心跳,连续 40s 没收到 Node节点心跳,判定 Node 节点不健康,b标记为 NotReady

    参数:node-monitor-period=5snode-monitor-grace-period=40s

    该参数属于 kube-controller-manager 组件,该组件以静态 Pod 形式运行在 master 节点,路径:

    /etc/kubernetes/manifests/kube-controller-manager.yaml
    

    编辑静态 Pod 配置文件,找到 command 段,添加或修改 --pod-eviction-timeout 参数,保存文件,触发静态 Pod 重启。

  3. 节点 NotReady 持续满 5 分钟,开始把 Pod 驱逐到别的节点。

    参数:pod-eviction-timeout=300s

    该参数也属于 kube-controller-manager 组件,该组件以静态 Pod 形式运行在 master 节点。修改方法同上。

更新镜像
root@master30~/controllers 15:38:59# kubectl describe pods web-768f99776c-jjq9v | grep '^    Image:'
    Image:          docker.io/library/nginx:1.27

# 设置 deployment 的 image 为 docker.io/library/nginx:1.28
# 获取容器名称
root@master30~/controllers 15:56:20# kubectl get deployments.apps web -o wide | awk '{print $7}'
IMAGES
docker.io/library/nginx:1.27

# 更新镜像为docker.io/library/nginx:1.28
root@master30~/controllers 16:00:39# kubectl edit deployments.apps web
deployment.apps/web edited

# 新增了一个replicaset,用于创建新的pod
root@master30~/controllers 16:01:00# kubectl get rs
NAME             DESIRED   CURRENT   READY   AGE
web-768f99776c   3         3         3       89m
web-7f7967f9f4   1         1         0       8s

# 查看镜像版本
root@master30~/controllers 16:02:42# kubectl get deployments.apps web -o wide | awk '{print$7}'
IMAGES
docker.io/library/nginx:1.28

# 查看Pod
root@master30~/controllers 16:01:52# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
web-7f7967f9f4-d24xm   1/1     Running   0          21s
web-7f7967f9f4-kjmz9   1/1     Running   0          40s
web-7f7967f9f4-pzp8c   1/1     Running   0          58s
版本控制

使用 kubectl rollout 命令控制deployment版本。

root@master30~/controllers 16:02:45# kubectl rollout -h
Manage the rollout of one or many resources.

 Valid resource types include:

  *  deployments
  *  daemonsets
  *  statefulsets

Examples:
  # Rollback to the previous deployment
  kubectl rollout undo deployment/abc

  # Check the rollout status of a daemonset
  kubectl rollout status daemonset/foo

  # Restart a deployment
  kubectl rollout restart deployment/abc

  # Restart deployments with the 'app=nginx' label
  kubectl rollout restart deployment --selector=app=nginx

Available Commands:
  history       View rollout history
  pause         Mark the provided resource as paused
  restart       Restart a resource
  resume        Resume a paused resource
  status        Show the status of the rollout
  undo          Undo a previous rollout

Usage:
  kubectl rollout SUBCOMMAND [options]

Use "kubectl rollout <command> --help" for more information about a given
command.
Use "kubectl options" for a list of global command-line options (applies to all
commands).

示例:

root@master30~/controllers 16:35:17# kubectl set image deployment/web nginx=docker.io/library/nginx:1.28 --record
  • kubectl set image

    核心子命令:修改控制器内容器镜像,支持 Deployment / StatefulSet / DaemonSet / ReplicaSet。

  • deployment/web

    代表操作对象:名为 web 的 Deployment

  • nginx=docker.io/library/nginx:1.28

    格式:容器名=新镜像地址

  • --record

    把本次执行的命令记录保存到 Deployment 的注解 kubernetes.io/change-cause,方便后续回滚、查看变更记录。

#查看更新记录
root@master30~/controllers 16:39:13# kubectl rollout history deployment web
deployment.apps/web
REVISION  CHANGE-CAUSE
3         <none>
4         kubectl set image deployment/web nginx=docker.io/library/nginx:1.28 --record=true

# 回滚
root@master30~/controllers 16:39:35# kubectl rollout undo deployment web --to-revision=3
deployment.apps/web rolled back
root@master30~/controllers 16:40:57# kubectl get deployments.apps -o wide
NAME   READY   UP-TO-DATE   AVAILABLE   AGE    CONTAINERS   IMAGES                         SELECTOR
web    3/3     3            3           129m   nginx        docker.io/library/nginx:1.27   app=web
root@master30~/controllers 16:41:05# kubectl rollout history deployment web
deployment.apps/web
REVISION  CHANGE-CAUSE
4         kubectl set image deployment/web nginx=docker.io/library/nginx:1.28 --record=true
5         <none>
  • kubectl rollout
    • 专门管理有状态滚动更新的子命令,仅支持:Deployment / StatefulSet / DaemonSet。
    • 常用子操作:status(查看进度)、history(历史版本)、undo(回滚)、restart(重启 Pod)。
  • --to-revision
    • 回滚到版本几
滚动更新

Kubernetes提供了两个参数maxSurge和maxUnavailable来精细控制Pod的替换数量 。

  • **maxSurge,此参数控制滚动更新过程中副本总数超过 DESIRED 的上限的数量。**maxSurge可以是具体的整数(比如3) , 也可以是百分百, 向上取整。 maxSurge默认值为25%。

    例如, DESIRED为10, 那么副本总数的最大值为 roundUp(10 + 10 * 25%) =13, 所以我们看到 CURRENT 就是13。

  • maxUnavailable,此参数控制滚动更新过程中不可用的副本相占DESIRED的最大比例。 maxUnavailable可以是具体的整数(比如3), 也可以是百分百, 向下取整。 maxUnavailable默认值为25%。

    例如, DESIRED为10, 那么可用的副本数至少要为10 - roundDown(10 * 25%)= 8, 所以我们看到AVAILABLE是8。

总结:

  • maxSurge 值越大, 初始创建的新副本数量就越多。
  • **maxUnavailable **值越大, 初始销毁的旧副本数量就越多,更新初期造成不可用副本数量越多。

理想情况下, 我们这个案例滚动更新的过程应该是这样的:

  1. 创建3个新副本,此时Running副本数为10,maxSurge副本总数达到13。
  2. 销毁2个旧副本,同时再创建2个新副本。此时Running副本数为8。如果之前创建的3个副本状态没有变更为Running,则ContainerCreating副本数为5,maxSurge副本总数仍为13。
  3. 当新副本状态变更为Running, 例如之前创建的5个新副本在同一时刻状态变为running。当然这是一种理想情况。
  4. 此时running状态副本为13个,那么此时可以一次性销毁5个旧副本,同时又可以一次性创建5个新副本,使running副本数回到8。
  5. 这个过程会持续进行, 直到所有的旧副本被新副本替换,滚动更新完成。

**实践:**更新deployment镜像,并使用以下脚本监控:

root@master30~/controllers 16:45:21# vim monitor_pod_numbers
root@master30~/controllers 16:45:48# chmod +x monitor_pod_numbers
root@master30~/controllers 16:54:58# ./monitor_pod_numbers &
[2] 196868
root@master30~/controllers 16:56:20# tail -f output.log
#!/bin/bash
while true
do
  echo '===================' >> output.log
  kubectl get pods --no-headers |awk '{print $3}' |sort | uniq -c |sed -r 's/^ +//'>> output.log
  sleep 0.5
done

日志内容类似:

===================
10 Running
===================
5 ContainerCreating
8 Running
2 Terminating
===================
5 ContainerCreating
8 Running
2 Terminating
===================
5 ContainerCreating
8 Running
===================
5 ContainerCreating
8 Running
===================
3 ContainerCreating
1 Pending
9 Running
4 Terminating
===================
5 ContainerCreating
8 Running
5 Terminating
===================
5 ContainerCreating
8 Running
5 Terminating
===================
5 ContainerCreating
8 Running
3 Terminating
===================
10 Running
4 Terminating
===================
10 Running
2 Terminating
===================
10 Running
===================
10 Running
===================

DaemonSet

学习参考:DaemonSet

DaemonSet 介绍

DaemonSet,简写DS,确保全部(或者某些)节点上运行一个 Pod 的副本。 当有新节点加入集群时, 也会在新节点上新增一个 Pod 。 当有节点从集群移除时,移除节点上的 Pod 也会被回收。

DaemonSet 用例

DaemonSet 的一些典型用例:

  • 在每个节点上运行集群守护进程,例如存储守护进程 glusterd 和 ceph。
  • 在每个节点上运行日志收集守护进程, 例如 flunentd或logstash。
  • 在每个节点上运行监控守护进程,例如 Prometheus Node Exporter或 collectd。

DaemonSet 用法

简单的用法:为每种类型的守护进程在所有的节点上都启动一个 DaemonSet。

复杂的用法:为同一种守护进程部署多个 DaemonSet;每个具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求。

DaemonSet 使用

DaemonSet 创建
root@master30~/controllers 16:58:16# vim daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
 name: busybox
spec:
 selector:
   matchLabels:
    app: busybox
 template:
  metadata:
   labels:
    app: busybox
  spec:
    containers:
    - name: busybox
      image: docker.io/library/busybox
      imagePullPolicy: IfNotPresent
      command:
      - sleep
      - "36000"
root@master30~/controllers 17:05:29# kubectl apply -f daemonset.yaml
daemonset.apps/busybox created
DaemonSet 查看
root@master30~/controllers 17:19:26# kubectl apply -f daemonset.yaml
daemonset.apps/busybox created

#基础总数由集群符合调度条件的节点数量决定
root@master30~/controllers 17:20:52# kubectl get pods -o wide
NAME            READY   STATUS    RESTARTS   AGE    IP              NODE                 NOMINATED NODE   READINESS GATES
busybox-f7zsk   1/1     Running   0          105s   10.224.96.255   worker32.hgq.cloud   <none>           <none>
busybox-k4jm8   1/1     Running   0          105s   10.224.128.2    worker31.hgq.cloud   <none>           <none>

root@master30~/controllers 17:19:34# kubectl get ds busybox
NAME      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
busybox   2         2         2       2            2           <none>          72s
DaemonSet 调度
# master节点默认是不可调度节点
# 查看完整污点
root@master30~/controllers 17:21:14# kubectl describe node master30.hgq.cloud | grep Taints
Taints:             node-role.kubernetes.io/control-plane:NoSchedule
#污点格式:key=value:effect或者key:effect,其中effect分为三类,即NoSchedule、PreferNoSchedule、NoExecute
#key:node-role.kubernetes.io/control-plane
#value:这里为空(省略了)
#effect:NoSchedule

# 设置master节点为可调度
root@master30~/controllers 17:23:44# kubectl taint node master30.hgq.cloud node-role.kubernetes.io/control-plane-
node/master30.hgq.cloud untainted
root@master30~/controllers 18:14:17# kubectl get ds
NAME      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
busybox   3         3         3       3            3           <none>          58m

# 设置master节点不可调度
root@master30~/controllers 18:18:43# kubectl taint node master30.hgq.cloud node-role.kubernetes.io/control-plane:NoSchedule
node/master30.hgq.cloud tainted
root@master30~/controllers 18:19:24# kubectl get ds
NAME      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
busybox   2         2         2       2            2           <none>          59m
root@master30~/controllers 18:19:28# kubectl get pods
NAME            READY   STATUS    RESTARTS   AGE
busybox-f7zsk   1/1     Running   0          60m
busybox-hhhck   1/1     Running   0          54m
busybox-k4jm8   1/1     Running   0          60m
# pod数量为2个,但是master节点上的busybox pod不会自动删除,也不会计数到这里。
  • -:删除污点

  • 不加 -:新增 / 覆盖污点

示例对比:

# 删除污点
kubectl taint node master30 node-role.kubernetes.io/control-plane-
# 添加污点
kubectl taint node master30 node-role.kubernetes.io/control-plane:NoSchedule
DaemonSet 健壮性
# 删除其中一个Pod
root@master30~/controllers 18:21:28# kubectl delete pods busybox-f7zsk
pod "busybox-f7zsk" deleted

#自动创建新的Pod
root@master30~/controllers 18:22:12# kubectl get pods
NAME            READY   STATUS    RESTARTS   AGE
busybox-dvllq   1/1     Running   0          8s
busybox-k4jm8   1/1     Running   0          62m
DaemonSet 删除

删除 DaemonSet 时,默认会删除它创建的所有 Pod,使用**–cascade=orphan**选项,将保留DaemonSet 创建 Pod。

root@master30~/controllers 18:22:20# kubectl delete ds busybox
daemonset.apps "busybox" deleted
root@master30~/controllers 18:22:52# kubectl get pods
NAME            READY   STATUS        RESTARTS   AGE
busybox-dvllq   1/1     Terminating   0          45s
busybox-k4jm8   1/1     Terminating   0          63m

K8s 集群中 DS

  1. Kubernetes 使用 DaemonSet 控制器运行系统组件,例如kube-proxy、calico-node。
root@master30~/controllers 18:23:34# kubectl get daemonsets.apps --namespace kube-system
NAME          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
calico-node   3         3         3       3            3           kubernetes.io/os=linux   5d1h
kube-proxy    3         3         3       3            3           kubernetes.io/os=linux   5d1h
  1. 分析calico-node 的yaml文件:
kind: DaemonSet
apiVersion: apps/v1
metadata:
  name: calico-node
  namespace: kube-system
  labels:
    k8s-app: calico-node
spec:
  selector:
    matchLabels:
      k8s-app: calico-node
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  template:
    metadata:
      labels:
        k8s-app: calico-node
      annotations:
        scheduler.alpha.kubernetes.io/critical-pod: ''
    spec:
      nodeSelector:
        kubernetes.io/os: linux
      hostNetwork: true
      containers:
        - name: calico-node
          image: hub.laoma.cloud/calico/node:v3.28.0

注意: 完整配置文件内容要更复杂一些, 为了方便学习DaemonSet, 这里只保留了最重要的内容。

生产级示例

采集节点日志-Fluent Bit
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluent-bit-ds
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: fluent-bit
  template:
    metadata:
      labels:
        app: fluent-bit
    spec:
      containers:
      - name: fluent-bit
        image: cr.fluentbit.io/fluent/fluent-bit:latest
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
采集节点监控指标-Node Exporter
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter-ds
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: node-exporter
  template:
    metadata:
      labels:
        app: node-exporter
    spec:
      containers:
      - name: node-exporter
        image: prom/node-exporter:latest
        ports:
        - containerPort: 9100
        volumeMounts:
        - name: proc
          mountPath: /host/proc
          readOnly: true
        - name: sys
          mountPath: /host/sys
          readOnly: true
      volumes:
      - name: proc
        hostPath:
          path: /proc
      - name: sys
        hostPath:
          path: /sys

Job

Job 介绍

  • Job 用于运行一次性任务。
  • 如果pod运行任务失败,则创建新的pod继续运行任务,直到任务运行完成,也就是pod中任务退出代码为0, Job结束。
  • 在job运行过程中,如果托管pod的节点发生故障,Job pod将被自动重新安排到另一个节点。
  • 删除 Job 的操作会清除所创建的全部 Pod。
  • 挂起 Job 的操作会删除 Job 的所有活跃 Pod,直到 Job 被再次恢复执行。

Job 用例

简单的使用场景:

  • 执行数据库清理
  • 备份 Kubernetes 集群

Job 使用

Job 基本管理
root@master30~/controllers 18:26:20# kubectl create job -h |grep ^Usage -A1
Usage:
  kubectl create job NAME --image=image [--from=cronjob/name] -- [COMMAND] [args...] [options]

示例1:

命令行创建:

root@master30~/controllers 18:28:19# kubectl create job myjob --image=docker.io/library/busybox -- echo hello k8s job!
job.batch/myjob created
root@master30~/controllers 18:28:29# kubectl get all
NAME              READY   STATUS      RESTARTS   AGE
pod/myjob-9h7ld   0/1     Completed   0          6s

NAME              STATUS    COMPLETIONS   DURATION   AGE
job.batch/myjob   Running   0/1           6s         6s
root@master30~/controllers 18:28:35# kubectl logs myjob-9h7ld
hello k8s job!

# 删除 Job 的操作会清除所创建的全部 Pod
# 使用--cascade=orphan选项,可以保留job创建的pod
root@master30~/controllers 18:29:06# kubectl delete jobs.batch myjob
job.batch "myjob" deleted

通过 yaml 文件创建job。

root@master30~/controllers 18:29:29# vim job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: myjob
spec:
  template:
    metadata:
      name: myjob
    spec:
      containers:
      - name: hello
        image: hub.laoma.cloud/library/busybox
        imagePullPolicy: IfNotPresent
        command: ["echo", "hello k8s job! "]
      restartPolicy: Never
root@master30~/controllers 18:30:14# kubectl apply -f job.yaml
job.batch/myjob created

**示例2:**计算pi,保留小数点200位。

root@master30~/controllers 18:31:59# vim job-pi.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: hub.laoma.cloud/library/perl
        imagePullPolicy: IfNotPresent
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(200)"]
      restartPolicy: Never
  backoffLimit: 4
root@master30~/controllers 18:32:16# kubectl apply -f job-pi.yaml
job.batch/pi created
root@master30~/controllers 18:32:36# kubectl get jobs.batch
NAME   STATUS     COMPLETIONS   DURATION   AGE
pi     Complete   1/1           6s         6s
root@master30~/controllers 18:32:42# kubectl get pods
NAME       READY   STATUS      RESTARTS   AGE
pi-lfnsz   0/1     Completed   0          18s
root@master30~/controllers 18:32:54# kubectl logs pi-lfnsz
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303820
restartPolicy

restart 策略只能是:

  • Never:只要任务没有完成,就会创建新的 pod,直到 job 完成,所以有可能会产生多个pod。
  • OnFailure:只要任务没有完成,就会重启 pod,直到job完成。

我们做个试验, 修改job.yaml, 故意引入一个错误 :echo 修改为 echoxxx


apiVersion: batch/v1
kind: Job
metadata:
  name: myjob
spec:
  template:
    metadata:
      name: myjob
    spec:
      containers:
      - name: hello
        image: hub.laoma.cloud/library/busybox
        imagePullPolicy: IfNotPresent
        command: ["echoxxx", "hello k8s job! "]
      restartPolicy: Never

再次应用,验证。

root@master30~/controllers 18:37:09# kubectl apply -f job.yaml
job.batch/myjob created

# 可以看到有多个Pod, 状态均不正常。 
root@master30~/controllers 18:37:29# kubectl get all
NAME              READY   STATUS       RESTARTS   AGE
pod/myjob-6ljmv   0/1     StartError   0          4s
pod/myjob-t8nlh   0/1     StartError   0          15s

NAME              STATUS    COMPLETIONS   DURATION   AGE
job.batch/myjob   Running   0/1           15s        15s

# 查看某个 pod 详细信息
root@master30~/controllers 18:37:45# kubectl describe pods myjob-6ljmv | grep ^Events -A100
Events:
  Type     Reason     Age    From               Message
  ----     ------     ----   ----               -------
  Normal   Scheduled  2m39s  default-scheduler  Successfully assigned controllers/myjob-6ljmv to worker31.hgq.cloud
  Normal   Pulled     2m39s  kubelet            Container image "hub.laoma.cloud/library/busybox" already present on machine
  Normal   Created    2m39s  kubelet            Created container hello
  Warning  Failed     2m39s  kubelet            Error: failed to create containerd task: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "echoxxx": executable file not found in $PATH: unknown

日志显示没有可执行程序, 符合预期。

问题现象: 为什么会看到这么多失败的Pod?

解释: 当第一个Pod启动时, 容器失败退出, 根据 restartPolicy: Never, 此失败容器不会被重启, 但 Job 默认预期完成的Pod数量是1, 目前COMPLETIONS为0, 不满足, 所以 Job 会创建新的Pod, 直到 COMPLETIONS 为1。 对于我们这个例子, SUCCESSFUL 永远也到不了1, 所以Job 会一直创建新的Pod。 为了终止这个行为, 我们删除Job 。

清理 job

root@master30~/controllers 18:40:19# kubectl delete jobs.batch myjob

如果将 restartPolicy 设置为 OnFailure 会怎么样?

apiVersion: batch/v1
kind: Job
metadata:
  name: myjob
spec:
  template:
    metadata:
      name: myjob
    spec:
      containers:
      - name: hello
        image: hub.laoma.cloud/library/busybox
        imagePullPolicy: IfNotPresent
        command: ["echoxxxx", "hello k8s job! "]
      restartPolicy: OnFailure

再次应用,验证。

root@master30~/controllers 18:41:57# kubectl apply -f job.yaml
root@master30~/controllers 18:42:10# kubectl get all
NAME              READY   STATUS             RESTARTS     AGE
pod/myjob-w4jxr   0/1     CrashLoopBackOff   1 (8s ago)   10s

NAME              STATUS    COMPLETIONS   DURATION   AGE
job.batch/myjob   Running   0/1           10s        10s
# pod执行失败后,会重启。
# pod 数量总是1,RESTARTS数值不断增加。
backoffLimit

如果Job执行失败,我们可以指定job执行失败最大次数。

apiVersion: batch/v1
kind: Job
metadata:
  name: myjob
spec:
  backoffLimit: 2
  template:
    metadata:
      name: myjob
    spec:
      containers:
      - name: hello
        image: hub.laoma.cloud/library/busybox
        imagePullPolicy: IfNotPresent
        command: ["echoxx", "hello k8s job! "]
      restartPolicy: Never

测试结果:最多重建2次。

root@master30~/controllers 18:44:50# kubectl get all
NAME              READY   STATUS       RESTARTS   AGE
pod/myjob-9pdx5   0/1     StartError   0          29s
pod/myjob-cxx9j   0/1     StartError   0          40s
pod/myjob-h6kvn   0/1     StartError   0          9s

NAME              STATUS   COMPLETIONS   DURATION   AGE
job.batch/myjob   Failed   0/1           40s        40s
completions

我们还可以通过 completions 指定 Pod 执行完成多少次,才算Job执行完成。

apiVersion: batch/v1
kind: Job
metadata:
  name: myjob
spec:
  completions: 2
  template:
    metadata:
      name: myjob
    spec:
      containers:
      - name: hello
        image: hub.laoma.cloud/library/busybox
        imagePullPolicy: IfNotPresent
        command: ["echo", "hello k8s job! "]
      restartPolicy: Never

上面配置的含义是: Job 需要累计成功完成 2 个 Pod 才算任务结束

root@master30~/controllers 18:46:37# kubectl apply -f job.yaml
job.batch/myjob created
root@master30~/controllers 18:46:47# kubectl get all
NAME              READY   STATUS      RESTARTS   AGE
pod/myjob-bscfc   0/1     Completed   0          5s
pod/myjob-ghk66   0/1     Completed   0          9s

NAME              STATUS     COMPLETIONS   DURATION   AGE
job.batch/myjob   Complete   2/2           7s         9s

如果不指定completions, 默认值均为1。

parallelism

有时我们希望Job同时运行多个Pod, 提高Job的执行效率,通过parallelism设置并行Pod数量 。

apiVersion: batch/v1
kind: Job
metadata:
  name: myjob
spec:
  completions: 6
  parallelism: 2
  template:
    metadata:
      name: myjob
    spec:
      containers:
      - name: hello
        image: hub.laoma.cloud/library/busybox
        imagePullPolicy: IfNotPresent
        command: ["echo", "hello k8s job! "]
      restartPolicy: Never
root@master30~/controllers 18:51:06# kubectl apply -f job.yaml
job.batch/myjob created

root@master30~/controllers 18:51:14# kubectl get all
NAME              READY   STATUS      RESTARTS   AGE
pod/myjob-6wd56   0/1     Completed   0          12s
pod/myjob-pb7cq   0/1     Completed   0          16s
pod/myjob-pkrvr   0/1     Completed   0          9s
pod/myjob-qd524   0/1     Completed   0          16s
pod/myjob-r6mk5   0/1     Completed   0          12s
pod/myjob-zfdgw   0/1     Completed   0          8s

NAME              STATUS     COMPLETIONS   DURATION   AGE
job.batch/myjob   Complete   6/6           12s        16s

效果: 每次运行2个Pod, 直到总共有6个Pod成功完成。

如果不指定parallelism, 默认值均为1。

上面的例子只是为了演示Job的并行特性, 实际用途不大。 不过现实中确实存在很多需要并行处理的场景。 比如批处理程序, 每个副本(Pod) 都会从任务池中读取任务并执行, 副本越多, 执行时间就越短, 效率就越高。这种类似的场景都可以用Job来实现。

activeDeadlineSeconds

一旦 Job 运行时间达到该值,其所有运行中的 Pod 都会被终止,并且 Job 的状态更新为 type: Failedreason: DeadlineExceeded。该值适用于 Job 的整个生命期,无论 Job 创建了多少个 Pod。

apiVersion: batch/v1
kind: Job
metadata:
  name: pi-with-timeout
spec:
  backoffLimit: 5
  activeDeadlineSeconds: 10
  template:
    spec:
      containers:
      - name: pi
        image: hub.laoma.cloud/library/perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

Job 的 .spec.activeDeadlineSeconds 优先级高于其 .spec.backoffLimit 设置。 因此,如果一个 Job 正在重试一个或多个失效的 Pod,该 Job 一旦到达 activeDeadlineSeconds 所设的时限即不再部署额外的 Pod,即使其重试次数还未达到 backoffLimit 所设的限制。

ttlSecondsAfterFinished

通过设置 Job 的 .spec.ttlSecondsAfterFinished 字段,可以让该控制器清理掉已结束的资源。

TTL 控制器清理 Job 时,会级联式地删除 Job 对象。 换言之,它会删除所有依赖的对象,包括 Pod 及 Job 本身。 注意,当 Job 被删除时,系统会考虑其生命周期保障,例如其 Finalizers。

例如:

apiVersion: batch/v1
kind: Job
metadata:
  name: pi-with-ttl
spec:
  ttlSecondsAfterFinished: 100
  template:
    spec:
      containers:
      - name: pi
        image: hub.laoma.cloud/library/perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

Job pi-with-ttl 在结束 100 秒之后,可以成为被自动删除的对象。

如果该字段设置为 0,Job 在结束之后立即成为可被自动删除的对象。 如果该字段没有设置,Job 不会在结束之后被 TTL 控制器自动清除。

注意这种 TTL 机制仍然是一种 Alpha 状态的功能特性,需要配合 TTLAfterFinished 特性门控使用。有关详细信息,可参考 TTL 控制器的文档。

CronJob

CronJob 介绍

Linux中有cron程序定时执行任务, Kubernetes的CronJob提供了类似的功能, 用于周期性地执行Job,例如备份、生成报告等。

CronJob 创建新的 Job 和(间接)Pod 时,CronJob 的 .metadata.name 是命名这些 Pod 的部分基础。 CronJob 的名称必须是一个合法的 DNS 子域值, 但这会对 Pod 的主机名产生意外的结果。为获得最佳兼容性,名称应遵循更严格的 DNS 标签规则。 即使名称是一个 DNS 子域,它也不能超过 52 个字符。这是因为 CronJob 控制器将自动在你所提供的 Job 名称后附加 11 个字符,并且存在 Job 名称的最大长度不能超过 63 个字符的限制。

CronJob 使用

#查看帮助
root@master30~/controllers 18:54:05# kubectl create cronjob -h

示例:

root@master30~/controllers 18:54:20# kubectl create cronjob mycronjob --image=docker.io/library/busybox --schedule='*/2 * * * *' -- echo hello k8s job!

crontab 格式说明:

*  *  *  * * 
分 时 日 月 周
故*/2表示每2分钟触发一次

等效的配置文件:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: mycronjob
spec:
  schedule: "*/2 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: hub.laoma.cloud/library/busybox
            command: ["echo", "hello k8s job! "]
          restartPolicy: Never

等待一段时间,最多创建3个job。

root@master30~/controllers 18:59:13# kubectl get all
NAME                           READY   STATUS      RESTARTS   AGE
pod/mycronjob-29710736-tgkzq   0/1     Completed   0          3m14s
pod/mycronjob-29710738-jmd4j   0/1     Completed   0          74s

NAME                      SCHEDULE      TIMEZONE   SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/mycronjob   */2 * * * *   <none>     False     0        74s             3m33s

NAME                           STATUS     COMPLETIONS   DURATION   AGE
job.batch/mycronjob-29710736   Complete   1/1           4s         3m14s
job.batch/mycronjob-29710738   Complete   1/1           4s         74s

CronJob 参数

Cron 时间表

.spec.schedule 字段是必需的,格式遵循 Cron 语法。

# ┌───────────── 分钟 (0 - 59)
# │ ┌───────────── 小时 (0 - 23)
# │ │ ┌───────────── 月的某天 (1 - 31)
# │ │ │ ┌───────────── 月份 (1 - 12)
# │ │ │ │ ┌───────────── 周的某天 (0 - 6)(周日到周一;在某些系统上,7 也是星期日)
# │ │ │ │ │                          或者是 sun,mon,tue,web,thu,fri,sat
# │ │ │ │ │
# │ │ │ │ │
# * * * * *

例如 0 0 13 * 5 表示此任务必须在每个星期五的午夜以及每个月的 13 日的午夜开始。

任务模板

.spec.jobTemplate,为 CronJob 创建的 Job 定义模板,它是必需的。它和 Job 的语法完全一样, 只不过它是嵌套的,没有 apiVersionkind。 你可以为模板化的 Job 指定通用的元数据, 例如标签注解。 有关如何编写一个任务的 .spec, 请参考编写 Job 规约

任务延迟开始的最后期限

.spec.startingDeadlineSeconds 字段是可选的。 它表示任务如果由于某种原因错过了调度时间,开始该任务的截止时间的秒数。

  • 过了截止时间,CronJob 就不会开始该任务的实例(未来的任务仍在调度之中)。 例如,你每天运行两次备份任务,允许它最多延迟 8 小时开始,但不能更晚, 因为更晚进行的备份将变得没有意义:你宁愿等待下一次计划的运行。

  • 对于错过已配置的最后期限的 Job,Kubernetes 将其视为失败的任务。 如果你没有为 CronJob 指定 startingDeadlineSeconds,那 Job 就没有最后期限。

  • 如果 .spec.startingDeadlineSeconds 字段被设置(非空), CronJob 控制器将会计算从预期创建 Job 到当前时间的时间差。 如果时间差大于该限制,则跳过此次执行。例如,如果将其设置为 200,则 Job 控制器允许在实际调度之后最多 200 秒内创建 Job。

并发性规则

.spec.concurrencyPolicy 也是可选的。它声明了 CronJob 创建的任务执行时发生重叠如何处理。 仅能声明下列规则中的一种:

  • Allow(默认):CronJob 允许并发任务执行。
  • Forbid: CronJob 不允许并发任务执行;如果新任务的执行时间到了而老任务没有执行完,CronJob 会忽略新任务的执行。
  • Replace:如果新任务的执行时间到了而老任务没有执行完,CronJob 会用新任务替换当前正在运行的任务。

请注意,并发性规则仅适用于相同 CronJob 创建的任务。如果有多个 CronJob,它们相应的任务总是允许并发执行的。

任务历史限制

.spec.successfulJobsHistoryLimit.spec.failedJobsHistoryLimit 字段是可选的。 这两个字段指定应保留多少已完成和失败的任务。 默认设置分别为 3 和 1。将限制设置为 0 代表相应类型的任务完成后不会保留。

有关自动清理任务的其他方式, 参见自动清理完成的 Job

更多推荐