目錄
引言
一、Pod控制器概述
二、Pod控制器的種類
(一)ReplicaSet
(二)Deployment
(三)StatefulSet
(四)DaemonSet
(五)Job
三、使用POD控制器
(一)部署動態PV
(二)使用Deployment控制器
1.創建控制器
2.參考鏈接
(三)使用StatefulSet控制器
1.主要特性
2.控制器組件
2.1?無頭服務
2.2?存儲卷申請模板
2.3?StatefulSet
3.示例
3.1 安裝CoreDNS
3.2 創建service
3.3 創建StatefulSet
3.4 使用service訪問
3.5?刪除與創建
4.小結
(四)DaemonSet控制器
1.定義與功能
2.工作原理
3.示例
(五)Job控制器
1.創建job
2.追蹤查看執行狀況
3.Job的清理
3.應用場景
(六)CronJob控制器
1.基本定義
2.使用Cronjob
引言
在Kubernetes(K8s)的龐大生態系統中,Pod控制器是一個核心組件,它負責管理和控制Pod的生命周期。Pod是Kubernetes中最小的可部署計算單元,而Pod控制器則確保Pod按照預期的狀態運行,無論面臨何種挑戰。本文將深入探討Pod控制器的概念、種類以及它們是如何工作的。
一、Pod控制器概述
Pod控制器是Kubernetes中用于管理Pod生命周期的組件。它們通過監視和管理Pod的集合來確保Pod始終按照預期運行。當Pod因為某些原因(如節點故障、資源不足等)而失敗時,Pod控制器會嘗試重新創建Pod,以保持Pod集合的穩定性和可用性。
二、Pod控制器的種類
(一)ReplicaSet
ReplicaSet是Deployment的基礎,它直接管理Pod的副本數。ReplicaSet確保在任何時候都有指定數量的Pod副本在運行。它有以下幾個特點
1.用戶期望的pod副本數量
2.標簽選擇器,判斷哪個pod歸自己管理
3.現存的pod數量不足,會根據pod資源模板進行新建
它會幫助用戶管理無狀態的pod資源,精確反應用戶定義的目標數量,但是RelicaSet不是直接使用的控制器,而是使用Deployment
(二)Deployment
Deployment是最常用的Pod控制器之一,建立在ReplicaSet之上,它用于部署無狀態應用程序。Deployment定義了Pod的期望副本數,并通過滾動更新和回滾機制來管理Pod的升級和降級。
Deployment還提供了聲明式更新和版本控制功能,使得應用程序的升級和回滾變得簡單和可靠。
(三)StatefulSet
StatefulSet用于部署有狀態應用程序,如有狀態數據庫或分布式存儲系統。StatefulSet為Pod提供了一個穩定的網絡標識和持久化存儲,確保Pod在重新調度時能夠保持其狀態。
StatefulSet還提供了有序部署和擴展的功能,使得有狀態應用程序的升級和擴展變得更加容易。
(四)DaemonSet
DaemonSet確保在每個節點上運行一個Pod的副本。它通常用于運行守護進程,如系統監控代理、日志收集器等。
DaemonSet中的Pod通常具有節點級別的存儲和網絡需求,并且需要在每個節點上運行。
(五)Job
Job用于運行一次性任務,如批處理作業或短生命周期的應用程序。Job會創建Pod來執行任務,并在任務完成后刪除Pod。
Job還提供了重試和并行執行的選項,使得一次性任務的執行變得更加靈活和可靠。
三、使用POD控制器
(一)部署動態PV
首先部署動態PV,其目的主要是在部署StatefulSet控制器時,它常與 PersistentVolumeClaims一起使用
具體的部署方法,可以訪問:【云原生】Kubernetes----PersistentVolume(PV)與PersistentVolumeClaim(PVC)詳解-CSDN博客
進行查看
(二)使用Deployment控制器
主要用于管理POD,保證用戶的期望值,其建立在ReplicaSet的基礎之上
1.創建控制器
[root@master01 pod]#vim deployment.yaml
[root@master01 pod]#cat deployment.yaml
apiVersion: apps/v1 #指定API版本
kind: Deployment #指定創建資源類型為Deployment
metadata: #定義資源的元數據信息name: nginx-deployment #指定資源的名稱labels: #設置標簽app: nginx #標簽以鍵值表示,標簽鍵為app,標簽值為nginx
spec: #定義資源的規格replicas: 3 #指定創建pod數量為3個selector: #選擇由Deployment管理的Pod的標簽選擇器matchLabels: #指定用于匹配的標簽app: nginx #設置標簽需要與模板標簽一致template: #創建pod的模板,deployment管理的pod實例,都由此模板定義metadata: #模板的元數據信息labels: #定義pod的標簽app: nginx #此處需要與deployment管理pod的標簽選擇器一致spec: #pod的規格信息containers: #定義pod中運行的容器列表- name: nginx #指定容器名稱image: nginx:1.18.0 #指定鏡像版本ports: #定義端口- containerPort: 80 #定義容器內部的監聽端口
使用命令創建deployment控制器
[root@master01 pod]#kubectl apply -f deployment.yaml
deployment.apps/nginx-deployment created
[root@master01 pod]#kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-794bf7886f-85bwb 1/1 Running 0 4h18m
nginx-deployment-67dfd6c8f9-75cqk 1/1 Running 0 9s
nginx-deployment-67dfd6c8f9-8nnjr 1/1 Running 0 9s
nginx-deployment-67dfd6c8f9-n4rv8 1/1 Running 0 9s----------------------------------------------------------------------------------
第一個pod為基于nfs的動態創建PV的pod
下面三個pod為控制器管理的pod
創建deployment控制器后,會根據yaml文件定義的內容,創建三個pod實例
升級時,修改yaml文件,并重新加載即可完成升級
[root@master01 pod]#vim deployment.yaml
......spec:containers:- name: nginximage: nginx:1.20.2 #修改版本
[root@master01 pod]#kubectl apply -f deployment.yaml
deployment.apps/nginx-deployment configured
此控制器在之前的文章中也多次提到,可以訪問網站進行詳細查看
2.參考鏈接
官方網站:Deployments | Kubernetes
文章鏈接:【云原生】kubernetes聲明式管理-----YAML文件-CSDN博客
(三)使用StatefulSet控制器
StatefulSet 是 Kubernetes 中的一個資源控制器,它用于管理有狀態的應用。與 Deployment 和 ReplicaSet 這樣的無狀態工作負載不同,StatefulSet 為每個 Pod 提供了一個穩定的、唯一的標識符,并且能夠保證 Pod 的部署順序和終止順序。
1.主要特性
穩定的標識符:每個Pod都有一個唯一的、持久的標識符,這個標識符在 Pod 的整個生命周期中都是不變的。這使得即使 Pod 被重新調度,其標識符也會保持不變。這一功能常常基于Headless(無頭模式,即沒有Cluster IP的Service)實現
有序的部署和擴展:Pod 是按照特定的順序進行創建和擴展(0到N-1)的。這允許應用程序在部署時按照特定的順序進行初始化。
有序的終止和縮容:當縮容或刪除 StatefulSet 時,Pod 會按照相反的順序(N-1到0)進行終止。這允許應用程序在關閉時按照特定的順序進行清理。
持久化存儲:StatefulSet 常常與 PersistentVolumeClaims(PVCs)一起使用,以提供穩定的存儲。即使 Pod 被重新調度,其存儲卷也會被保留并重新附加到新的 Pod 上。
2.控制器組件
StatefulSet控制器,主要有以下三個組件
2.1?無頭服務
2.1.1 定義
Headless Service(無頭服務):用于為Pod資源標識符生成可解析的DNS記錄,它是一種特殊類型的Kubernetes服務,它不分配Cluster IP地址。
2.1.2 特點
無Cluster IP:無頭服務不分配Cluster IP,因此客戶端不能通過服務的Cluster IP地址訪問后端Pod,而是直接通過Pod的具體地址進行通信。
DNS解析:Kubernetes的DNS系統會為無頭服務生成一條特殊的DNS記錄,列出所有關聯Pod的IP地址,允許客戶端通過域名解析直接獲得Pod列表。
適用于狀態服務應用:特別適合那些需要直接與特定實例通信的應用場景,如分布式數據庫、消息隊列等有狀態服務。
2.1.3?DNS記錄生成
當在Kubernetes中創建一個無頭服務時,DNS系統會為該服務生成一條特殊的DNS記錄。
這條DNS記錄列出了所有與該服務相關聯的Pod的IP地址。
命名規則:對于無頭服務,Kubernetes會以<service-name>.<namespace>.svc.cluster-domain.example的形式為其分配一個DNS記錄。
其中,<service-name>是服務的名稱,<namespace>是服務所在的命名空間,svc.cluster-domain.example是集群的DNS后綴。
解析過程:當客戶端需要訪問無頭服務時,它會查詢DNS服務器以解析該服務的名稱。
DNS服務器會返回與該服務相關聯的所有Pod的IP地址列表。客戶端可以根據這個IP地址列表直接訪問到具體的Pod實例。
當Pod重啟后,Kubernetes的控制器會更新這個DNS記錄,將新的Pod IP地址添加到列表中
因此,客戶端只需要繼續解析該服務的DNS名稱,即可獲得最新的Pod IP地址列表。
應用場景:無頭服務的DNS解析方式特別適用于需要直接與Pod實例通信的場景,如有狀態應用(StatefulSet)、分布式數據庫集群、消息隊列等。
2.1.4 在控制器中的作用
Deployment控制器創建的pod一旦重新創建以后,它的IP地址與pod名稱都會發生改變,這樣當基于IP地址與端口號的訪問服務,就會因為地址改變而無法訪問,例如MySQL,這時,只需要給pod設定一個固定的pod名稱,service的cluster IP設置為None,service只與pod的固定名稱進行綁定,而后通過coreDNS去解析service,得到關聯的pod的IP地址,這里看不懂沒有關系,可以在下面結合示例進行理解
2.2?存儲卷申請模板
volumeClaimTemplates(存儲卷申請模板):基于靜態或動態PV供給方式為Pod資源提供專有的固定存儲
大部分有狀態副本集都會用到持久存儲,比如分布式系統來說,由于數據是不一樣的,每個節點都需要自己專用的存儲節點。而在 deployment中pod模板中創建的存儲卷是一個共享的存儲卷,多個pod使用同一個存儲卷,而statefulset定義中的每一個pod都不能使用同一個存儲卷,由此基于pod模板創建pod是不適應的,這就需要引入volumeClainTemplate,當在使用statefulset創建pod時,會自動生成一個PVC,從而請求綁定一個PV,從而有自己專用的存儲卷
其中包括:訪問模式、存儲大小,動態PV指定storageClassName名稱
2.3?StatefulSet
用于管控Pod資源
3.示例
[root@master01 pod]#kubectl delete deployments.apps nginx-deployment
deployment.apps "nginx-deployment" deleted
#刪除deployment 控制器
3.1 安裝CoreDNS
CoreDNS用于提供解析服務與自動發現,使K8S集群能夠自動關聯Service資源的“名稱”和“CLUSTER-IP”,從而達到服務被集群自動發現的目的
使用kubeadm安裝或其它一鍵安裝k8s集群的,會默認安裝CoreDNS,只有當使用二進制安裝的時候,需要手動去安裝CoreDNS
k8s集群二進制安裝鏈接:Kubernetes二進制集群部署_kubernetes集群啟動-CSDN博客
驗證DNS是否可以使用
[root@master01 pod]#kubectl run busybox --image=busybox:1.28 -- sleep 36000
pod/busybox created
#創建一個busybox的pod,該容器提供一些基本的命令,主要用于測試環境
[root@master01 pod]#kubectl get pod busybox
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 4s
[root@master01 pod]#kubectl exec -it busybox sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # nslookup kubernetes #測試svc能否正常解析,可以使用kubectl get svc查看有哪些svc
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.localName: kubernetes
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
#解析正常,解析kubernetes的地址為10.96.0.1
[root@master01 pod]#kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13d
mydb ClusterIP 10.96.50.193 <none> 80/TCP 5d17h
myservice ClusterIP 10.96.33.11 <none> 80/TCP 5d17h
nginx ClusterIP 10.96.222.66 <none> 80/TCP 3d20h
3.2 創建service
StatefulSet 資源依賴于無頭模式的service
[root@master01 pod]#vim service.yaml
[root@master01 pod]#cat service.yaml
apiVersion: v1 #指定API版本
kind: Service #創建資源類型為Service
metadata:name: headless-svc #指定service名稱labels:app: headless-svc #設置service標簽
spec:ports:- port: 80 #service端口name: web #端口名稱targetport: 80 #指定流量轉發的目標端口,與pod暴露的端口一致clusterIP: None #將clusterIP地址的值設置為None,表示無IP地址,即無頭模式selector: #選擇管理的標簽app: state #此標簽需要與StatefulSet控制器管理的pod模板中定義的標簽一致type: ClusterIP #設置類型為ClusterIP,此為默認設置,可以省略
創建service
[root@master01 pod]#kubectl apply -f service.yaml
service/headless-svc created
[root@master01 pod]#kubectl get svc headless-svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
headless-svc ClusterIP None <none> 80/TCP 10s
3.3 創建StatefulSet
[root@master01 pod]#vim statefulset.yaml
[root@master01 pod]#cat statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet #創建資源類型為StatefulSet
metadata:name: state #指定資源名稱
spec:serviceName: headless-svc #指定需要綁定的service名稱replicas: 3 #創建pod數量為三個selector: #標簽選擇器,指定StatefulSet要管理哪些podmatchLabels: #指定標簽名稱app: state #必須與service中selector定義的標簽一致。pod含有此標簽的,都會去管理template: #指定pod創建模板metadata:labels:app: state #設置pod標簽,與上面標簽選擇器相同,StatefulSet才會管理spec:containers: #定義pod中運行的容器- name: nginx-pod #應當設置有狀態的服務,在此以nginx為例,官方文檔有MySQL示例image: nginx:1.18.0 #定義鏡像ports:- containerPort: 80 #定義容器監聽端口name: web #端口名稱volumeMounts: #定義將存儲卷卷掛載到指定目錄- name: html #指定存儲卷名稱mountPath: /usr/share/nginx/html #掛載到此目錄,此目錄為nginx服務的站點目錄volumeClaimTemplates: #PVC的請求模板- metadata:name: html #定義PVC的名稱annotations:volume.beta.kubernetes.io/storage-class: nfs-client-storageclass
#用于指定存儲類的注解。該存儲類定義了用于動態卷供應的后端存儲類型spec:accessModes: ["ReadWriteOnce"] #指定訪問模式為RWOresources:requests:storage: 2Gi #指定存儲卷的使用大小
創建pod查看
[root@master01 pod]#kubectl apply -f statefulset.yaml
statefulset.apps/state created
[root@master01 pod]#kubectl get statefulsets.apps state
NAME READY AGE
state 2/3 14s
[root@master01 pod]#kubectl get statefulsets.apps state
NAME READY AGE
state 3/3 17s
[root@master01 pod]#kubectl get pod
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 40m
nfs-client-provisioner-794bf7886f-85bwb 1/1 Running 0 5h51m
state-0 1/1 Running 0 25s
state-1 1/1 Running 0 19s
state-2 1/1 Running 0 13s
#它會按照0到N-1的順序去指定pod名稱,一定建立,指定pod生命周期結束,否則IP地址改變,它的名稱也不會改變
創建完之后,查看一下PV與PVC
在NFS服務器上自定義web界面
[root@nfs k8s]#ls
default-html-state-0-pvc-0bffc66c-b29e-40cd-bef5-18c1abe250af #state-0的PV卷
default-html-state-1-pvc-1aaee76c-7c94-4a8d-abc3-0b4f804239bc #state-1的PV卷
default-html-state-2-pvc-f82bb183-c3d8-49b1-be39-c4ee96f7e076 #state-2的PV卷
[root@nfs k8s]#echo "this is state-0" > default-html-state-0-pvc-0bffc66c-b29e-40cd-bef5-18c1abe250af/index.html
[root@nfs k8s]#echo "this is state-1" > default-html-state-1-pvc-1aaee76c-7c94-4a8d-abc3-0b4f804239bc/index.html
[root@nfs k8s]#echo "this is state-2" > default-html-state-2-pvc-f82bb183-c3d8-49b1-be39-c4ee96f7e076/index.html
由于沒有ClusterIP地址,想要通過IP地址訪問,只能在k8s集群中直接訪問podIP
3.4 使用service訪問
此時,創建的service是可以進行解析的
[root@master01 pod]#kubectl exec -it busybox sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # nslookup headless-svc
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.localName: headless-svc
Address 1: 10.244.2.208 state-0.headless-svc.default.svc.cluster.local
Address 2: 10.244.1.189 state-1.headless-svc.default.svc.cluster.local
Address 3: 10.244.2.209 state-2.headless-svc.default.svc.cluster.local
#該service會通過endpoint關聯到后端的pod
由于pod的IP地址是k8s集群內部的IP地址,且并沒有clusterIP去綁定podIP,只有域名管理,宿主機的DNS解析,無法解析k8s集群內部的域名與地址,所以使用宿主機無法訪問pod。只能通過創建pod,在pod中進行訪問
可以看到,訪問的pod是隨機的,因為k8s內部的負載均衡方式,是通過資源的使用率進行分配的,它會將請求優先分配到資源使用率較少的pod上,可以使用壓測工具去測試,而后再進行訪問
3.5?刪除與創建
當pod刪除時,會按照N-1到0的順序,倒序刪除
[root@master01 pod]#kubectl delete -f statefulset.yaml
statefulset.apps "state" deleted
[root@master01 pod]#kubectl get pod -w
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 65m
centos 1/1 Running 0 9m12s
nfs-client-provisioner-794bf7886f-85bwb 1/1 Running 0 6h16m
state-0 1/1 Running 0 25m
state-1 1/1 Running 0 25m
state-2 1/1 Running 0 25m
state-2 1/1 Terminating 0 25m
state-1 1/1 Terminating 0 25m
state-0 1/1 Terminating 0 25m
state-2 0/1 Terminating 0 25m
state-1 0/1 Terminating 0 25m
state-0 0/1 Terminating 0 25m
state-2 0/1 Terminating 0 25m
state-1 0/1 Terminating 0 25m
state-0 0/1 Terminating 0 25m
重新創建的時候,數據會持久化 ,而且創建的順序還是按照0到N-1的順序創建
重新創建之后再次訪問,數據不會丟失
再次解析service的話,它的解析地址會發生改變
這就是無頭模式的作用,不論后端的IP地址如何變化,只通過DNS來解析service,從而綁定后端的IP地址,得到數據
4.小結
StatefulSet控制器的實現,是一個相對復雜的過程,需要大家在平時多練多學,在生成環境中才能避免出現問題,因為StatefulSet管理的都是一些有狀態的服務,一旦容器失敗,導致數據丟失,可能會造成不好的影響
deployment與statefulset的區別
4.1 應用場景
Deployment:主要用于部署無狀態服務,即服務實例之間可以相互替換且不需要保留特定的網絡標識或存儲數據。它適用于那些不需要關心Pod具體身份且可任意替換的彈性服務。
StatefulSet:適用于部署有狀態的服務,比如數據庫集群、消息隊列等。這些服務需要穩定的持久化存儲和唯一、有序的網絡標識。StatefulSet為Pod分配的網絡標識符和存儲都是穩定的,使得應用能夠維持跨重啟或再調度的持久狀態。
4.2 Pod管理
Deployment:通過ReplicaSet確保指定數量的Pod副本始終運行,提供水平擴展和滾動更新能力。Pod由Deployment創建時,雖然可以自定義名稱,但通常由系統生成,并在重建或擴展時可能會發生變化。
StatefulSet:Pods在創建、更新和刪除時按照順序進行,以滿足那些依賴于嚴格順序啟動或停止的應用場景需求。每個Pod都有一個固定的、唯一的網絡標識符,并且其持久卷聲明(PVC)會綁定到持久化的存儲,即使Pod被刪除后重新創建,存儲的數據也會保留。
4.3 存儲與網絡
Deployment:通常不直接管理Pod的存儲和網絡,而是依賴于其他Kubernetes資源(如PersistentVolume和Service)來實現這些功能。
StatefulSet:為Pod提供穩定的存儲和網絡標識,確保有狀態應用能夠正常運行。StatefulSet通常與Headless Service和volumeClaimTemplate一起使用,以提供可解析的DNS資源記錄和專有且固定的存儲。
4.4 升級與回滾
Deployment:支持多種升級策略,如滾動更新和回滾,確保服務在整個升級過程中具有高可用性。通過更新Deployment的PodTemplateSpec字段來聲明Pod的新狀態,并逐步替換舊的Pod。
StatefulSet:也支持有序而自動的滾動更新,但由于涉及到有狀態應用,更新過程可能更加復雜和嚴格。同時,StatefulSet也支持回滾到之前的版本。
4.5 擴展性
Deployment:可以根據系統負載進行水平擴展和縮容,通過調整ReplicaSet的副本數來實現。
StatefulSet:雖然也支持擴展和縮容操作,但由于涉及到有狀態應用和數據一致性等問題,擴展性可能相對較弱。
(四)DaemonSet控制器
1.定義與功能
定義:DaemonSet是Kubernetes中的一個API對象,用于確保集群中的每個節點(或某些特定節點)都運行一個Pod的副本。
功能:當節點加入集群時,DaemonSet會自動在該節點上啟動Pod;當節點從集群中移除時,DaemonSet也會自動刪除該節點上的Pod。
應用場景:
①集群存儲守護進程:在每個Node節點上運行。如glusterd、ceph等。
②日志收集守護進程:在每個Node節點上運行日志收集進程。如fluentd、logstash等。
③節點監控守護進程:在每個Node上運行監控。如Prometheus Node Exporter、collectd、Datadog agent等。
④網絡插件:在每個節點上運行如Calico、Cilium或Flannel等。
2.工作原理
監聽對象:DaemonSet控制器會監聽Kubernetes集群中的daemonset對象、pod對象、node對象。
syncLoop循環:當上述被監聽的對象發生變動時,DaemonSet控制器會觸發syncLoop循環,確保Kubernetes集群朝著daemonset對象描述的狀態進行演進
3.示例
[root@master01 pod]#vim daemonset.yaml
[root@master01 pod]#cat daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet #創建資源類型為DaemonSet
metadata:name: nginx-daemonsetlabels:app: nginx
spec:selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.18.0ports:- containerPort: 80
創建DaemonSet控制器后,它會在每個節點上運行你指定的pod與定義的容器,它不是根據node節點的資源負載來決定在哪一個node上運行,它會在所有的節點上運行同一個副本
刪除DaemonSet控制器時,所有DaemonSet控制器管理的副本也會同時刪除
(五)Job控制器
Job控制器是Kubernetes中的一個核心組件,主要用于在集群中運行一次性或批處理任務。Job確保在集群中運行獨立的任務,并在任務成功完成后自動終止,不會重啟。
它的主要特點包括:
任務執行:Job控制器主要負責批量處理短暫的一次性任務。當任務執行完畢后,Job會自動將Pod的可用數設置為0,并將Pod的狀態置為Complete。
任務記錄:當Job創建的Pod成功執行完任務后,Job會記錄成功結束的Pod數量。當成功結束的Pod數量達到指定的數量時,Job完成執行。
任務重試:Job支持定義任務的重試策略,通過backoffLimit字段指定Job失敗后進行重試的次數。
并行任務:Job允許定義多個并行執行的任務,通過parallelism字段指定在任一時刻應該并發運行的Pod數量
[root@master01 pod]#vim job.yaml
[root@master01 pod]#cat job.yaml
apiVersion: batch/v1 #Batch API的第一個穩定版本
kind: Job #指定創建的資源類型是Job
metadata:name: job #資源名稱
spec:completions: 5 #指定Job需要成功完成多少個Podparallelism: 3 #并發執行的最大數量,也就是同時運行幾個podbackoffLimit: 2 #設置job失敗后進行重試的次數template: #定義創建模板spec: #定義job的規格信息restartPolicy: Never #指定重啟策略為Never,表示不重啟containers:- name: busybox #容器名稱image: busybox:1.28 #鏡像名稱command: ["/bin/sh","-c","for i in 1 2 3 4 5 6 7 8 9;do echo $i ;done"]
#容器內執行的程序,使用for循環打印1-9的數字,此命令執行完畢后,一次性任務結束,退出容器----------------------------------------------------------------------------------
completions:表示執行完指定的pod數量后,job這個一次性計劃任務就結束了
parallelism:表示同時運行的pod數量
backoffLimit:用于設置job失敗后進行重試的次數,默認值為6。默認情況下,除非Pod失敗或容器異常退出Job任務將不間斷的重試。一旦達到backoffLimit的值,作業將被標記為失敗
restartPolicy:在Job中只能將此屬性設置為OnFailure或Never,否則Job將不間斷運行
1.創建job
[root@master01 pod]#kubectl apply -f job.yaml
job.batch/job created
[root@master01 pod]#kubectl get job
NAME COMPLETIONS DURATION AGE
job 5/5 4s 8s--------------------------------------------------------------
NAME:Job的名稱。
COMPLETIONS:這個字段顯示了Job的完成情況。它由兩部分組成:已完成的Pod數量:表示已經有5個Pod成功完成了任務。期望完成的Pod數量:表示這個Job期望有5個Pod成功完成。
DURATION:Job從開始到結束所花費的時間。表示Job在4秒內完成了所有的任務。
AGE:Job創建到現在的時間
[root@master01 pod]#kubectl get pod
NAME READY STATUS RESTARTS AGE
job-5pcrc 0/1 Completed 0 98s
job-6wwtm 0/1 Completed 0 100s
job-cd8jq 0/1 Completed 0 100s
job-gdgbq 0/1 Completed 0 98s
job-rlpsr 0/1 Completed 0 100s
#執行完完畢之后,Completed正常退出
2.追蹤查看執行狀況
使用logs參數,查看執行結果
3.Job的清理
當你的 Job 已結束時,將 Job 保留在 API 中(而不是立即刪除 Job)很有用, 這樣你就可以判斷 Job 是成功還是失敗。
可以手動清理job資源,使用kubectl delete命令刪除
[root@master01 pod]#kubectl get job
NAME COMPLETIONS DURATION AGE
job 5/5 4s 28m
[root@master01 pod]#kubectl delete -f job.yaml
job.batch "job" deleted
[root@master01 pod]#kubectl get job
No resources found in default namespace.
[root@master01 pod]#kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-794bf7886f-85bwb 1/1 Running 1 12h
Kubernetes TTL-after-finished?控制器提供了一種 TTL 機制來限制已完成執行的 Job 對象的生命期
ttlSecondsAfterFinished 字段在 Kubernetes 1.21 版本中作為 alpha 特性被引入。在 kube-apiserver 的啟動參數中設置
?
[root@master01 pod]#vim /etc/kubernetes/manifests/kube-apiserver.yaml
......
spec:containers:- command:- kube-apiserver- --feature-gates=TTLAfterFinished=true
......
[root@master01 ~]#kubectl explain job.spec.ttlSecondsAfterFinished
KIND: Job
VERSION: batch/v1FIELD: ttlSecondsAfterFinished <integer>DESCRIPTION:ttlSecondsAfterFinished limits the lifetime of a Job that has finishedexecution (either Complete or Failed). If this field is set,ttlSecondsAfterFinished after the Job finishes, it is eligible to beautomatically deleted. When the Job is being deleted, its lifecycleguarantees (e.g. finalizers) will be honored. If this field is unset, theJob won't be automatically deleted. If this field is set to zero, the Jobbecomes eligible to be deleted immediately after it finishes. This field isalpha-level and is only honored by servers that enable the TTLAfterFinishedfeature.
----------------------------------------------------------------------------------
ttlSecondsAfterFinished 是 Kubernetes Job 資源中的一個可選字段,用于指定 Job 在完成
后(無論是成功完成還是失敗)可以保留的時間長度(以秒為單位)。這個字段允許你設置一個時間限制
,在該時間限制之后,Kubernetes 系統會自動刪除已完成的 Job。具體來說:
如果ttlSecondsAfterFinished字段被設置了,那么在Job完成后,經過指定的秒數,該Job會成為自動刪除的候選對象。
當Kubernetes系統刪除Job時,會尊重Job的生命周期保證(例如finalizers)。
如果ttlSecondsAfterFinished字段未設置,那么Job將不會自動刪除。
如果ttlSecondsAfterFinished字段被設置為0,那么Job會在完成后立即成為自動刪除的候選對象
使用TTL清理,使用1.28版本的k8s集群
[root@master01 opt]#kubectl version
Client Version: v1.28.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.28.2
[root@master01 opt]#vim job.yaml
[root@master01 opt]#cat job.yaml
apiVersion: batch/v1
kind: Job
metadata:name: busybox
spec:template:spec:containers:- name: busyboximage: busybox:1.28command: ["/bin/sh", "-c", "sleep 10;date;exit"]restartPolicy: NeverbackoffLimit: 2ttlSecondsAfterFinished: 10 #容器不論是失敗還是成功,10秒鐘之后刪除
[root@master01 opt]#kubectl apply -f job.yaml
job.batch/busybox created
[root@master01 opt]#kubectl get job -w
NAME COMPLETIONS DURATION AGE
busybox 0/1 5s 5s
busybox 0/1 13s 13s
busybox 0/1 14s 14s
busybox 1/1 14s 14s
busybox 1/1 14s 24s
busybox 1/1 14s 24s
追蹤pod查看
[root@master01 opt]#kubectl get pod -w
NAME READY STATUS RESTARTS AGE
busybox-llg27 0/1 Pending 0 0s
busybox-llg27 0/1 Pending 0 0s
busybox-llg27 0/1 ContainerCreating 0 0s
busybox-llg27 0/1 ContainerCreating 0 1s
busybox-llg27 1/1 Running 0 1s
busybox-llg27 0/1 Completed 0 12s
busybox-llg27 0/1 Completed 0 14s
busybox-llg27 0/1 Completed 0 14s
busybox-llg27 0/1 Completed 0 14s
busybox-llg27 0/1 Completed 0 14s
busybox-llg27 0/1 Terminating 0 24s #退出后10秒鐘后進行刪除
busybox-llg27 0/1 Terminating 0 24s
[root@master01 opt]#kubectl get pod
No resources found in default namespace.
[root@master01 opt]#kubectl get job
No resources found in default namespace.
3.應用場景
Job常用于運行那些僅需要執行一次的任務
批處理作業
Kubernetes Job主要被用于執行一次性批處理作業,如每日數據分析、事務處理等。
數據遷移和清理
Job可以用來定時遷移大量數據,以及維護數據庫
后臺任務
Job可以用來執行后臺任務,如計算任務、日志采集等
日志打包和壓縮
例如按時間段打包日志文件、將多個日志文件壓縮成一個文件等。
備份和恢復操作
例如備份數據庫、配置文件等,并將其存儲到云存儲服務中以便后續恢復
其它應用場景
kube-bench掃描、離線數據處理,視頻解碼等業務
(六)CronJob控制器
1.基本定義
在Kubernetes中,CronJob控制器用于運行定時任務,例如備份、生成報告等。這些任務在指定的時間周期上自動執行。一個 CronJob 對象就像 Unix 系統上的 crontab(cron table)文件中的一行,使用Cron格式進行編寫, 并周期性地在給定的調度時間執行Job。它在Kubernetes集群上運行的,可以管理多個Pod。
一個CronJob對象包含以下主要部分:
metadata:包含CronJob的名稱、命名空間、標簽和注解等。
spec:定義CronJob的規格。
????????schedule:一個符合cron格式的字符串,指定任務運行的時間表。與Linux系統中的crontab類似。* * * * *,表示分、時、日、月、周??
????????jobTemplate:描述要運行的Job的模板。Job模板中的spec字段與標準的Job資源中的spec字段非常相似。
????????startingDeadlineSeconds(可選):如果由于某種原因(例如,由于系統資源不足)而錯過了預定的啟動時間,則此字段指定在開始失敗之前允許錯過的秒數。
????????concurrencyPolicy(可選):定義當多個Job同時被觸發時應該如何處理。可以是"Allow"(允許同時運行)、"Forbid"(禁止同時運行,并跳過后續運行)或"Replace"(取消當前正在運行的Job并開始新的一個)。
????????suspend(可選):如果設置為true,則不會按照時間表啟動新的Job
????????successfulJobsHistoryLimit?和?failedJobsHistoryLimit(可選):分別指定要保留的成功和失敗Job的歷史記錄的最大數量。
2.使用Cronjob
[root@master01 pod]#vim cronjob.yaml
[root@master01 pod]#cat cronjob.yaml
apiVersion: batch/v1beta1 #設置版本為v1beta1
kind: CronJob #指示這是一個CronJob資源
metadata:name: cronjob #CronJob的名稱
spec:schedule: "*/1 * * * *" #定義執行周期,此處表示每一分鐘執行一次jobTemplate: #定義Job模板spec:template: #Pod模板spec:containers: #定義容器列表- name: echo #定義容器名稱image: busybox:1.28command: #定義容器啟動后要執行的命令 - /bin/sh- -c- date; echo this is busybox1.28 #在容器內執行date命令后,并輸出指定信息restartPolicy: OnFailure #容器重啟策略,非0狀態則會重啟,正常退出不重啟----------------------------------------------------------------------------------
Kubernetes集群版本較舊,并且不支持batch/v1 API版本,需要使用batch/v1beta1 API版本
指定文件創建Cronjob后,Kubernetes將創建一個名為cronjob的CronJob,并且每分鐘都會按照定義運行一個新的Job
[root@master01 pod]#kubectl apply -f cronjob.yaml
cronjob.batch/cronjob created
[root@master01 pod]#kubectl get cronjobs
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob */1 * * * * False 0 <none> 3s
[root@master01 pod]#kubectl get jobs -w
NAME COMPLETIONS DURATION AGE
cronjob-1717083300 0/1 0s
cronjob-1717083300 0/1 0s 0s
cronjob-1717083300 1/1 2s 2s
cronjob-1717083360 0/1 0s
cronjob-1717083360 0/1 0s 0s
cronjob-1717083360 1/1 2s 2s
cronjob-1717083420 0/1 0s
cronjob-1717083420 0/1 0s 0s
cronjob-1717083420 1/1 3s 3s
查看pod
[root@master01 pod]#kubectl get pod
NAME READY STATUS RESTARTS AGE
cronjob-1717083420-jw52p 0/1 Completed 0 2m30s
cronjob-1717083480-j87gz 0/1 Completed 0 89s
cronjob-1717083540-dz2hs 0/1 Completed 0 28s
nfs-client-provisioner-794bf7886f-85bwb 1/1 Running 3 13h
[root@master01 pod]#kubectl logs cronjob-1717083420-jw52p
Thu May 30 15:37:10 UTC 2024
this is busybox1.28
[root@master01 pod]#kubectl logs cronjob-1717083480-j87gz
Thu May 30 15:38:11 UTC 2024
this is busybox1.28
[root@master01 pod]#kubectl logs cronjob-1717083540-dz2hs
Thu May 30 15:39:12 UTC 2024
this is busybox1.28
#每隔一分鐘執行一次,可能會加一兩秒左右的容器創建時間
# 查看CronJob的狀態 ?
kubectl get cronjobs ?
??
# 查看CronJob的詳細信息 ?
kubectl describe cronjobs cronjob ?
??
# 查看由CronJob創建的Job列表 ?
kubectl get jobs ?
??
# 查看特定Job的詳細信息 ?
kubectl describe job <job-name>