第四章 Controller 控制器
- 控制器是什么
- 常见的控制器
- Deployment
- StatefulSet
- DaemonSet
- Job
- CronJob
1 控制器
1.1 定义
在 Kubernetes (k8s) 中,控制器 (Controller) 是负责维护集群状态并确保集群内的实际状态与期望状态一致的一类组件。控制器通过观察集群的当前状态并将其与用户定义的期望状态进行对比,做出相应的调整来实现状态的一致性。
1.2 作用
控制器的主要作用可以概括为以下几点:
- 自动化管理:控制器自动执行许多运维任务,如副本管理、负载均衡、滚动更新、回滚等,减少手动干预和运维负担。
- 确保高可用性:通过监控和调节,确保应用程序和服务在出现故障时能够自动恢复,保持高可用性。
- 集群状态调和:控制器不断地监控集群状态,并采取行动将集群状态调整到期望状态,确保一致性和稳定性。
1.3 工作原理
控制器的工作原理通常包括以下几个步骤:
- 观察状态:控制器定期查询 Kubernetes API 服务器,以获取集群的当前状态。
- 对比状态:控制器将实际状态与用户定义的期望状态进行对比,确定是否需要进行调整。
- 执行操作:如果实际状态与期望状态不符,控制器会执行相应的操作,如创建、更新或删除 Pod,调整副本数等,以将实际状态调和为期望状态。
1.4 常见的控制器
1.5 关联 pod
在 Kubernetes 中,控制器通过标签选择器 (Label Selector) 与 Pod 关联。标签选择器允许控制器根据特定的标签匹配策略来选择和管理 Pod。不熟悉标签的可以先阅读下之前的章节。接下来将一一对k8s 常见的几种控制器类型展开赘述。
2 Deployment
Deployment 控制器是一种用于管理应用部署的高级工具。它提供滚动更新、回滚和扩展等功能,使用户能够轻松地更新应用版本,并在更新过程中保持服务的高可用性。通过 Deployment,用户只需声明目标状态,Deployment 控制器会自动对 ReplicaSet 进行操作,以确保集群达到期望的状态。
2.1 创建 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3 # 期望的 pod 副本数量
selector: # 选择器 通过它指定管理哪些pod
matchLabels:
app: nginx
template: # 模版 根据模版创建pod副本
metadata:
labels: # pod 的标签
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
2.2 查看 Deployment
# 部署应用
$ kubectl apply -f deployment.yml
# 查看 deployment
$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 57s
# 查看 deployment 详情
$ kubectl describe deployment nginx-deployment
Type Reason Age From Message
Normal ScalingReplicaSet 5m15s deployment-controller Scaled up replica set nginx-deployment-5b979d57d5 to 3
# 查看 pod 详情
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE
nginx-deployment-5b979d57d5-bmvbm 1/1 Running 0 2m35s
nginx-deployment-5b979d57d5-fb6cx 1/1 Running 0 2m35s
nginx-deployment-5b979d57d5-zm7d9 1/1 Running 0 2m35s
# 输出到文件
$ kubectl get deployment nginx-deployment -o yaml >> test.yaml
参数详解
-
NAME
列出指定命名空间内(默认default)Deployment 的名称 -
READY
显示应用程序的可用的副本数。显示的模式是“就绪个数/期望个数”。 -
UP-TO-DATE
已经更新的副本数。 -
AVAILABLE
显示应用可供使用的副本数。 -
AGE
显示应用程序运行的时间。
2.3 扩缩 Deployment
# 查询副本数量
$ kubectl get replicaset|rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-5b979d57d5 3 3 3 3m10s
# 扩缩副本数量 直接指定replicas 参数的值即可
$ kubectl scale deployment nginx-deployment --replicas=5
deployment.apps/nginx-deployment scaled
# 为 Deployment 设置自动缩放器,并基于现有 Pod 的 CPU 利用率选择要运行的 Pod 个数下限和上限。
$ kubectl autoscale deployment/nginx-deployment --min=10 --max=15 --cpu-percent=80
参数详解
DESIRED
期望的 Pod 副本数量,即用户在 ReplicaSet 配置中指定的spec.replicas
数量。CURRENT
当前实际存在的 Pod 副本数量。包括所有状态的 Pod(正在创建、运行、终止等)。READY
当前处于就绪状态的 Pod 副本数量。Pod 只有在通过所有健康检查后才被视为就绪。AGE
ReplicaSet 已存在的时间。
2.4 回滚 Deployment
Deployment 被触发上线时,系统就会创建 Deployment 的新的修订版本。 这意味着仅当 Deployment 的 Pod 模板(.spec.template
)发生更改时,才会创建新修订版本 – 例如,模板的标签或容器镜像发生变化。 其他更新,如 Deployment 的扩缩容操作不会创建 Deployment 修订版本。 这是为了方便同时执行手动缩放或自动缩放。 换言之,当你回滚到较早的修订版本时,只有 Deployment 的 Pod 模板部分会被回滚。
# 查看线上与行状态
$ kubectl rollout status deployment/nginx-deployment
deployment "nginx-deployment" successfully rolled out
# 例 修改下镜像版本
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
deployment.apps/nginx-deployment image updated
# 查看历史 发现此时有两个版本
$ kubectl rollout history deployment nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
# 查看某次历史的详细信息
$ kubectl rollout history deployment/nginx-deployment --revision=2
deployment.apps/nginx-deployment with revision #2
Pod Template:
Labels: app=nginx
pod-template-hash=595dff4fdb
Containers:
nginx:
Image: nginx:1.16.1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
# 回到上个版本
$ kubectl rollout undo deployment nginx-deployment
deployment.apps/nginx-deployment rolled back
# 回到指定版本
$ kubectl rollout undo deployment nginx-deployment --to-revision=2
2.5 暂停恢复 Deployment
# 暂停上线 暂停后修改不会立马生效
$ kubectl rollout pause deployment/nginx-deployment
deployment.apps/nginx-deployment paused
# 修改镜像版本
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.18.1
# 注意此时时没有新的上线触发
$ kubectl rollout history deployment/nginx-deployment
# 恢复之后 版本才会生效
kubectl rollout resume deployment nginx-deployment
2.6 删除 Deployment
# 删除 Deployment
$ kubectl delete -f deployment.yml(apply时的名称) 推荐
$ kubectl delete deployment nginx-deployment(deployment名称)
# 太多了的话也能一次性删除 删除当前目录下的所有 yml 启动的
$ kubectl delete -f .
# 删除命名空间下的所有资源
$ kubectl delete all --all
pod "nginx-deployment-5b979d57d5-9mgbn" deleted
pod "nginx-deployment-5b979d57d5-nt62w" deleted
pod "nginx-deployment-5b979d57d5-tng27" deleted
service "kubernetes" deleted
2.7 Deployment 状态
Deployment 的生命周期中会有许多状态。上线新的 ReplicaSet 期间可能处于 Progressing(进行中),可能是 Complete(已完成),也可能是 Failed(失败)以至于无法继续进行。
2.7.1 进行中的 Deployment
当上线过程进入Progressing状态时,Deployment 控制器会向 Deployment 的 .status.conditions
中添加包含下面属性的状况条目:
type: Progressing
status: "True"
reason: NewReplicaSetCreated
|reason: FoundNewReplicaSet
|reason: ReplicaSetUpdated
# kubectl describe deployment/nginx-deployment 详情
Name: nginx-deployment
Namespace: default
CreationTimestamp: Sun, 04 Aug 2024 03:03:54 +0000
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 4
Selector: app=nginx
Replicas: 3 desired | 1 updated | 4 total | 3 available | 1 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.18.1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True ReplicaSetUpdated
OldReplicaSets: nginx-deployment-5b979d57d5 (3/3 replicas created), nginx-deployment-595dff4fdb (0/0 replicas created)
NewReplicaSet: nginx-deployment-66cfddf444 (1/1 replicas created)
2.7.2 完成的 Deployment
当上线过程进入Complete状态时,Deployment 控制器会向 Deployment 的 .status.conditions
中添加包含下面属性的状况条目:
type: Progressing
status: "True"
reason: NewReplicaSetAvailable
2.7.3 失败的 Deployment
当上线过程进入Failed状态时,Deployment 控制器会向 Deployment 的 .status.conditions
中添加包含下面属性的状况条目:
type: Progressing
status: "False"
reason: ProgressDeadlineExceeded
3 StatefulSet
3.1 定义
StatefulSet 是用来管理有状态应用的工作负载 API 对象。
StatefulSet 用来管理某 Pod集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符。
和 Deployment 类似, StatefulSet 管理基于相同容器规约的一组 Pod。但和 Deployment 不同的是, StatefulSet 为它们的每个 Pod 维护了一个有粘性的 ID。这些 Pod 是基于相同的规约来创建的, 但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。
如果希望使用存储卷为工作负载提供持久存储,可以使用 StatefulSet 作为解决方案的一部分。 尽管 StatefulSet 中的单个 Pod 仍可能出现故障, 但持久的 Pod 标识符使得将现有卷与替换已失败 Pod 的新 Pod 相匹配变得更加容易。
3.2 特点
StatefulSet 对于需要满足以下一个或多个需求的应用程序很有价值:
- 稳定的、唯一的网络标识符。
- 稳定的、持久的存储。
- 有序的、优雅的部署和扩缩。
- 有序的、自动的滚动更新。
在上面描述中,“稳定的”意味着 Pod 调度或重调度的整个过程是有持久性的。 如果应用程序不需要任何稳定的标识符或有序的部署、删除或扩缩, 则应该使用由一组无状态的副本控制器提供的工作负载来部署应用程序,比如 Deployment或者 ReplicaSet可能更适用于你的无状态应用部署需要。
3.3 限制
- 给定 Pod 的存储必须由 PersistentVolume Provisioner 基于所请求的
storage class
来制备,或者由管理员预先制备。 - 删除或者扩缩 StatefulSet 并不会删除它关联的存储卷。 这样做是为了保证数据安全,它通常比自动清除 StatefulSet 所有相关的资源更有价值。
- StatefulSet 当前需要无头服务来负责 Pod 的网络标识。你需要负责创建此服务。
- 当删除一个 StatefulSet 时,该 StatefulSet 不提供任何终止 Pod 的保证。 为了实现 StatefulSet 中的 Pod 可以有序且体面地终止,可以在删除之前将 StatefulSet 缩容到 0。
- 在默认 Pod 管理策略(
OrderedReady
) 时使用滚动更新, 可能进入需要人工干预才能修复的损坏状态。
3.4 为什么需要 Storage Class
在一个大规模的Kubernetes集群里,可能有成千上万个PVC,这就意味着运维人员必须实现创建出这个多个PV,此外,随着项目的需要,会有新的PVC不断被提交,那么运维人员就需要不断的添加新的,满足要求的PV,否则新的Pod就会因为PVC绑定不到PV而导致创建失败.而且通过 PVC 请求到一定的存储空间也很有可能不足以满足应用对于存储设备的各种需求,而且不同的应用程序对于存储性能的要求可能也不尽相同,比如读写速度、并发性能等,为了解决这一问题,Kubernetes 又为我们引入了一个新的资源对象:StorageClass,通过 StorageClass 的定义,管理员可以将存储资源定义为某种类型的资源,比如快速存储、慢速存储等,用户根据 StorageClass 的描述就可以非常直观的知道各种存储资源的具体特性了,这样就可以根据应用的特性去申请合适的存储资源了。
下面就来搭建DFS共享存储。
3.5 搭建 DFS
参考这篇博客
3.5.1 搭建 DFS 服务
#安装nfs-utils rpcbind
ubuntu
$ apt install -y nfs-kernel-server rpcbind
centos
$ yum install -y nfs-utils rpcbind
# 创建 nfs 服务
$ mkdir /root/nfsdata
# 授权
echo "/root/nfsdata *(insecure,rw,sync,no_root_squash)" >> /etc/exports
# 启动相关服务
centos
$ systemctl start nfs-server
ubuntu
$ systemctl start nfs-kernel-server
$ systemctl start rpcbind
# 挂载 地址记得修改
$ mount -t nfs 192.168.0.1:/root/nfsda ta /root/nfsdata
3.5.2 创建 rabc 授权
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: kube-system
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
namespace: kube-system
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
namespace: kube-system
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: kube-system
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
3.5.3 创建StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client
namespace: kube-system
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
reclaimPolicy: Retain
3.5.4 创建 nfs-client-provider
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
labels:
app: nfs-client-provisioner
namespace: kube-system
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: chronolaw/nfs-subdir-external-provisioner:v4.0.2
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
value: 192.168.0.1 # 搭建的nfs 服务的ip地址
- name: NFS_PATH
value: /root/nfsdata
volumes:
- name: nfs-client-root
nfs:
server: 192.168.0.1 # 搭建的nfs 服务的ip地址
path: /root/nfsdata
3.6 使用 StatefulSet
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # 必须匹配 .spec.template.metadata.labels
serviceName: "nginx"
replicas: 3 # 默认值是 1
minReadySeconds: 10 # 默认值是 0
template:
metadata:
labels:
app: nginx # 必须匹配 .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: registry.k8s.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteMany" ]
storageClassName: "xxx" # 这个就是创建的sc对应的名字
resources:
requests:
storage: 1Gi
4 DaemonSet
4.1 定义
DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod 。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
DaemonSet 的一些典型用法:
- 在每个节点上运行集群守护进程
- 在每个节点上运行日志收集守护进程
- 在每个节点上运行监控守护进程
一种简单的用法是为每种类型的守护进程在所有的节点上都启动一个 DaemonSet。 一个稍微复杂的用法是为同一种守护进程部署多个 DaemonSet;每个具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求。
4.2 使用 DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
# 这些容忍度设置是为了让该守护进程集在控制平面节点上运行
# 如果你不希望自己的控制平面节点运行 Pod,可以删除它们
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
# 可能需要设置较高的优先级类以确保 DaemonSet Pod 可以抢占正在运行的 Pod
# priorityClassName: important
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
5 Job
5.1 定义
Job 会创建一个或者多个 Pod,并将继续重试 Pod 的执行,直到指定数量的 Pod 成功终止。 随着 Pod 成功结束,Job 跟踪记录成功完成的 Pod 个数。 当数量达到指定的成功个数阈值时,任务(即 Job)结束。 删除 Job 的操作会清除所创建的全部 Pod。 挂起 Job 的操作会删除 Job 的所有活跃 Pod,直到 Job 被再次恢复执行。
一种简单的使用场景下,你会创建一个 Job 对象以便以一种可靠的方式运行某 Pod 直到完成。 当第一个 Pod 失败或者被删除(比如因为节点硬件失效或者重启)时,Job 对象会启动一个新的 Pod。
你也可以使用 Job 以并行的方式运行多个 Pod
5.2 使用job
# 负责计算 π 到小数点后 2000 位,并将结果打印出来。 此计算大约需要 10 秒钟完成
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4 # 最大重试次数
# 查看pod 状态为 Completed
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
pi-p5fzz 0/1 Completed 0 64s
# 查看日志
$ kubectl logs jobs/pi
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275901
5.3 Job 的终止与清理
Job 完成时不会再创建新的 Pod,不过已有的 Pod 通常也不会被删除。 保留这些 Pod 使得你可以查看已完成的 Pod 的日志输出,以便检查错误、警告或者其它诊断性输出。 Job 完成时 Job 对象也一样被保留下来,这样你就可以查看它的状态。 在查看了 Job 状态之后删除老的 Job 的操作留给了用户自己。
# 可以使用这两种方式手动删除
$ kubectl delete jobs/pi
$ kubectl delete -f ./job.yaml
默认情况下,Job 会持续运行,除非某个 Pod 失败(restartPolicy=Never
) 或者某个容器出错退出(restartPolicy=OnFailure
)。 这时,Job 基于前述的 spec.backoffLimit
来决定是否以及如何重试。 一旦重试次数到达 .spec.backoffLimit
所设的上限,Job 会被标记为失败, 其中运行的 Pod 都会被终止。
终止 Job 的另一种方式是设置一个活跃期限。 你可以为 Job 的 .spec.activeDeadlineSeconds
设置一个秒数值。 该值适用于 Job 的整个生命期,无论 Job 创建了多少个 Pod。 一旦 Job 运行时间达到 activeDeadlineSeconds
秒,其所有运行中的 Pod 都会被终止, 并且 Job 的状态更新为 type: Failed
及 reason: DeadlineExceeded
。
注意 Job 的 .spec.activeDeadlineSeconds
优先级高于其 .spec.backoffLimit
设置。 因此,如果一个 Job 正在重试一个或多个失效的 Pod,该 Job 一旦到达 activeDeadlineSeconds
所设的时限即不再部署额外的 Pod, 即使其重试次数还未达到 backoffLimit
所设的限制。
apiVersion: batch/v1
kind: Job
metadata:
name: pi-with-timeout
spec:
backoffLimit: 5
activeDeadlineSeconds: 100
template:
spec:
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
5.4 自动清理完成的Job
自动清理已完成 Job (状态为 Complete
或 Failed
)的另一种方式是使用由 TTL 控制器所提供的 TTL 机制。 通过设置 Job 的 .spec.ttlSecondsAfterFinished
字段,可以让该控制器清理掉已结束的资源。
TTL 控制器清理 Job 时,会级联式地删除 Job 对象。 换言之,它会删除所有依赖的对象,包括 Pod 及 Job 本身。 注意,当 Job 被删除时,系统会考虑其生命周期保障。
apiVersion: batch/v1
kind: Job
metadata:
name: pi-with-ttl
spec:
ttlSecondsAfterFinished: 100 # 结束 100 秒之后,可以成为被自动删除的对象
template:
spec:
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
6 CronJob
Kubernetes 中的 CronJob 允许你在特定时间间隔执行任务。这对于定期执行的任务(例如备份、报告生成、数据清理等)非常有用。
6.1 创建 CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *" # 每分钟运行一次
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure # 如果任务失败则重启容器
6.2 查看CronJob
# 查看
$ kubectl get cronjob
NAME SCHEDULE TIMEZONE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * <none> False 0 12s 30s
# CronJob 创建的每个任务实际上是一个 Job 查看job
$ kubectl get jobs
hello-28712708 Complete 1/1 4s 2m11s
hello-28712709 Complete 1/1 4s 71s
hello-28712710 Complete 1/1 4s 11s
# 查看 CronJob 的事件日志:
$ kubectl describe cronjob hello
# 查看 Job 和 Pod 的日志
$ kubectl logs hello-28712710-9mn7n(pod-name)
Sun Aug 4 09:10:01 UTC 2024
Hello from the Kubernetes cluster
6.3 Cron 时间表语法
# ┌───────────── 分钟 (0 - 59)
# │ ┌───────────── 小时 (0 - 23)
# │ │ ┌───────────── 月的某天 (1 - 31)
# │ │ │ ┌───────────── 月份 (1 - 12)
# │ │ │ │ ┌───────────── 周的某天 (0 - 6)(周日到周六)
# │ │ │ │ │ 或者是 sun,mon,tue,web,thu,fri,sat
# │ │ │ │ │
# │ │ │ │ │
# * * * * *
以下是一些常见的调度表达式示例:
* * * * *
:每分钟运行一次。0 * * * *
:每小时的第 0 分钟运行一次。0 0 * * *
:每天的午夜运行一次。0 0 * * 0
:每周日的午夜运行一次。0 0 1 * *
:每月的第一天的午夜运行一次。
6.4 删除cronjob
$ kubectl delete cronjob hello
至此k8s 常见的控制器已讲解完毕。后面章节将继续学习服务(Service)、存储
、配置等内容。持续更新中,觉得有帮助的可以点赞关注下,谢谢!