Kubernetes学习笔记(二):Pod控制器详解:资源元信息、ReplicaSet、Deployment、DaemonSet、Job、CronJob
1、資源元信息
Kubernetes的資源對象組成:主要包括了Spec、Status兩部分。其中Spec部分用來描述期望的狀態(tài),Status部分用來描述觀測到的狀態(tài)
Kubernetes的元數(shù)據(jù)部分。該部分主要包括了用來識別資源的標簽:Label;用來描述資源的注解:Annotation;用來描述多個資源之間相互關系的OwnerReference
1)、Label
Label是Kubernetes系統(tǒng)中的一個重要概念。它的作用就是在資源上添加標識,用來對它們進行區(qū)分和選擇
Label的特點:
- 一個Label會以key/value鍵值對的形式附加到各種對象上,如Node、Pod、Service等等
- 一個資源對象可以定義任意數(shù)量的Label,同一個Label也可以被添加到任意數(shù)量的資源對象上去
- Label通常在資源對象定義時確定,當然也可以在對象創(chuàng)建后動態(tài)添加或者刪除
可以通過Label實現(xiàn)資源的多維度分組,以便靈活、方便地進行資源分配、調(diào)度、配置、部署等管理工作
一些常用的Label示例如下:
- 版本標簽:“version”:“release”,“version”:“stable”
- 環(huán)境標簽:“environment”:“dev”,“environment”:“test”,“environment”:“pro”
- 架構標簽:“tier”:“frontend”,“tier”:“backend”
標簽定義完畢之后,還要考慮到標簽的選擇,這就要使用到Label Selector,即:
-
Label用于給某個資源對象定義標識
-
Label Selector用于查詢和篩選擁有某些標簽的資源對象
當前有兩種Label Selector:
-
基于等式的Label Selector
name = slave:選擇所有包含Label中key="name"且value="slave"的對象
env != production:選擇所有包括Label中的key="env"且value不等于"production"的對象
-
基于集合的Label Selector
name in (master, slave):選擇所有包含Label中的key="name"且value="master"或"slave"的對象
name not in (frontend):選擇所有包含Label中的key="name"且value不等于"frontend"的對象
標簽的選擇條件可以使用多個,此時將多個Label Selector進行組合,使用逗號","進行分隔即可。例如:
name = slave, env != production
name not in (frontend), env != production
1)命令方式
創(chuàng)建pod-label.yaml文件,內(nèi)容如下:
apiVersion: v1 kind: Pod metadata:name: pod-labelnamespace: dev spec:containers:- image: nginx:1.17.1name: podports:- name: nginx-portcontainerPort: 80protocol: TCP # 創(chuàng)建Pod [root@k8s-master ~]# kubectl create -f pod-label.yaml pod/pod-label created# 為pod資源打標簽 [root@k8s-master ~]# kubectl label pod pod-label version=1.0 -n dev pod/pod-label labeled [root@k8s-master ~]# kubectl get pod pod-label -n dev --show-labels NAME READY STATUS RESTARTS AGE LABELS pod-label 1/1 Running 0 78s version=1.0# 為pod資源更新標簽 [root@k8s-master ~]# kubectl label pod pod-label version=2.0 -n dev --overwrite pod/pod-label labeled [root@k8s-master ~]# kubectl get pod pod-label -n dev --show-labels NAME READY STATUS RESTARTS AGE LABELS pod-label 1/1 Running 0 2m4s version=2.0# 篩選標簽 [root@k8s-master ~]# kubectl get pod -n dev -l version=2.0 --show-labels NAME READY STATUS RESTARTS AGE LABELS pod-label 1/1 Running 0 2m46s version=2.0# 刪除標簽 [root@k8s-master ~]# kubectl label pod pod-label version- -n dev pod/pod-label labeled [root@k8s-master ~]# kubectl get pod pod-label -n dev --show-labels NAME READY STATUS RESTARTS AGE LABELS pod-label 1/1 Running 0 3m29s <none>2)配置方式
修改pod-label.yaml文件,修改后內(nèi)容如下:
apiVersion: v1 kind: Pod metadata:name: pod-labelnamespace: devlabels:version: "3.0" env: "test" spec:containers:- image: nginx:1.17.1name: podports:- name: nginx-portcontainerPort: 80protocol: TCP # 更新Pod [root@k8s-master ~]# kubectl apply -f pod-label.yaml pod/pod-label configured[root@k8s-master ~]# kubectl get pod pod-label -n dev --show-labels NAME READY STATUS RESTARTS AGE LABELS pod-label 1/1 Running 0 5m17s env=test,version=3.02)、Annotation
Annotations一般是系統(tǒng)或者工具用來存儲資源的非標示性信息,可以用來擴展資源的spec/status的描述
3)、Ownereference
Ownereference一般就是指集合類的資源,比如說Pod集合,就有replicaset、statefulset
集合類資源的控制器會創(chuàng)建對應的歸屬資源。比如:replicaset控制器在操作中會創(chuàng)建Pod,被創(chuàng)建Pod的Ownereference就指向了創(chuàng)建Pod的replicaset,Ownereference使得用戶可以方便地查找一個創(chuàng)建資源的對象,另外,還可以用來實現(xiàn)級聯(lián)刪除的效果
2、Pod控制器介紹
Pod是Kubernetes的最小管理單元,在Kubernetes中,按照Pod的創(chuàng)建方式可以將其分為兩類:
- 自主式Pod:Kubernetes直接創(chuàng)建出來的Pod,這種Pod刪除后就沒有了,也不會重建
- 控制器創(chuàng)建的Pod:Kubernetes通過控制器創(chuàng)建的Pod,這種Pod刪除了之后還會自動重建
什么是Pod控制器?
Pod控制器是管理Pod的中間層,使用Pod控制器之后,只需要告訴Pod控制器,想要多少個什么樣的Pod就可以了,它會創(chuàng)建出滿足條件的Pod并確保每一個Pod資源處于用戶期望的目標狀態(tài)。如果Pod資源在運行中出現(xiàn)故障,它會基于指定策略重新編排Pod
在Kubernetes中,有很多類型的Pod控制器,每種都有自己的適合的場景,常見的有下面這些:
- ReplicationController:比較原始的Pod控制器,已經(jīng)被廢棄,由ReplicaSet替代
- ReplicaSet:保證副本數(shù)量一直維持在期望值,并支持Pod數(shù)量擴縮容,鏡像版本升級
- Deployment:通過控制ReplicaSet來控制Pod,并支持滾動升級、回退版本
- DaemonSet:在集群中的指定Node上運行且僅運行一個副本,一般用于守護進程類的任務
- Job:它創(chuàng)建出來的Pod只要完成任務就立即退出,不需要重啟或重建,用于執(zhí)行一次性任務
- CronJob:它創(chuàng)建的Pod負責周期性任務控制,不需要持續(xù)后臺運行
- StatefulSet:管理有狀態(tài)應用
3、ReplicaSet(RS)
1)、ReplicaSet定義
ReplicaSet的主要作用是保證一定數(shù)量的Pod正常運行,它會持續(xù)監(jiān)聽這些Pod的運行狀態(tài),一旦Pod發(fā)生故障,就會重啟或重建。同時它還支持對pod數(shù)量的擴縮容和鏡像版本的升降級
ReplicaSet的資源清單文件:
apiVersion: apps/v1 # 版本號 kind: ReplicaSet # 類型 metadata: # 元數(shù)據(jù)name: # rs名稱 namespace: # 所屬命名空間 labels: # 標簽controller: rs spec: # 詳情描述replicas: 3 # 副本數(shù)量selector: # 選擇器,通過它指定該控制器管理哪些podmatchLabels: # Labels匹配規(guī)則app: nginx-podmatchExpressions: # Expressions匹配規(guī)則- {key: app, operator: In, values: [nginx-pod]}template: # 模板,當副本數(shù)量不足時,會根據(jù)下面的模板創(chuàng)建pod副本metadata:labels:app: nginx-podspec:containers:- name: nginximage: nginx:1.17.1ports:- containerPort: 80在這里面,需要新了解的配置項就是spec下面幾個選項:
-
replicas:指定副本數(shù)量,其實就是當前RS創(chuàng)建出來的Pod的數(shù)量,默認為1
-
selector:選擇器,它的作用是建立Pod控制器和Pod之間的關聯(lián)關系,采用的Label Selector機制,在Pod模板上定義Label,在控制器上定義選擇器,就可以表明當前控制器能管理哪些Pod了
-
template:模板,就是當前控制器創(chuàng)建Pod所使用的模板,就是Pod的定義
2)、創(chuàng)建ReplicaSet
創(chuàng)建pc-replicaset.yaml文件,內(nèi)容如下:
apiVersion: apps/v1 kind: ReplicaSet metadata:name: pc-replicasetnamespace: dev spec:replicas: 3selector: matchLabels:app: nginx-podtemplate:metadata:labels:app: nginx-podspec:containers:- name: nginximage: nginx:1.17.1 # 創(chuàng)建rs [root@k8s-master ~]# kubectl create -f pc-replicaset.yaml replicaset.apps/pc-replicaset created# 查看rs # DESIRED:期望副本數(shù)量 # CURRENT:當前副本數(shù)量 # READY:已經(jīng)準備好提供服務的副本數(shù)量 [root@k8s-master ~]# kubectl get rs pc-replicaset -n dev -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR pc-replicaset 3 3 3 25s nginx nginx:1.17.1 app=nginx-pod# 查看當前控制器創(chuàng)建出來的pod # 這里發(fā)現(xiàn)控制器創(chuàng)建出來的pod的名稱是在控制器名稱后面拼接了-xxxxx隨機碼 [root@k8s-master ~]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE pc-replicaset-8hjrb 1/1 Running 0 58s pc-replicaset-jx8zb 1/1 Running 0 58s pc-replicaset-r56fn 1/1 Running 0 58s3)、擴縮容
# 編輯rs的副本數(shù)量,修改spec:replicas: 6即可 [root@k8s-master ~]# kubectl edit rs pc-replicaset -n dev replicaset.apps/pc-replicaset edited# 查看pod [root@k8s-master ~]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE pc-replicaset-2tnmm 1/1 Running 0 12s pc-replicaset-8hjrb 1/1 Running 0 6m4s pc-replicaset-jx8zb 1/1 Running 0 6m4s pc-replicaset-lqv6z 1/1 Running 0 12s pc-replicaset-q8p5w 1/1 Running 0 12s pc-replicaset-r56fn 1/1 Running 0 6m4s# 使用scale命令實現(xiàn)擴縮容,后面--replicas=n直接指定目標數(shù)量即可 [root@k8s-master ~]# kubectl scale rs pc-replicaset --replicas=2 -n dev replicaset.apps/pc-replicaset scaled# 命令運行完畢,立即查看,發(fā)現(xiàn)已經(jīng)有4個開始準備退出了 [root@k8s-master ~]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE pc-replicaset-2tnmm 0/1 Terminating 0 76s pc-replicaset-8hjrb 0/1 Terminating 0 7m8s pc-replicaset-jx8zb 0/1 Terminating 0 7m8s pc-replicaset-lqv6z 0/1 Terminating 0 76s pc-replicaset-q8p5w 1/1 Running 0 76s pc-replicaset-r56fn 1/1 Running 0 7m8s# 稍等片刻,就只剩下2個了 [root@k8s-master ~]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE pc-replicaset-q8p5w 1/1 Running 0 101s pc-replicaset-r56fn 1/1 Running 0 7m33s4)、鏡像更新
# 編輯rs的容器鏡像 - image: nginx:1.17.2 [root@k8s-master ~]# kubectl edit rs pc-replicaset -n dev replicaset.apps/pc-replicaset edited# 再次查看,發(fā)現(xiàn)鏡像版本已經(jīng)變更了 [root@k8s-master ~]# kubectl get rs -n dev -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR pc-replicaset 2 2 2 36m nginx nginx:1.17.2 app=nginx-pod# kubectl set image rs rs名稱 容器=鏡像版本 -n namespace [root@k8s-master ~]# kubectl set image rs pc-replicaset nginx=nginx:1.17.1 -n dev replicaset.apps/pc-replicaset image updated# 再次查看,發(fā)現(xiàn)鏡像版本已經(jīng)變更了 [root@k8s-master ~]# kubectl get rs -n dev -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR pc-replicaset 2 2 2 37m nginx nginx:1.17.1 app=nginx-pod5)、刪除ReplicaSet
# 使用kubectl delete命令會刪除此rs以及它管理的pod # 在Kubernetes刪除rs前,會將rs的replicas調(diào)整為0,等待所有的pod被刪除后,在執(zhí)行rs對象的刪除 [root@k8s-master ~]# kubectl delete rs pc-replicaset -n dev replicaset.apps "pc-replicaset" deleted[root@k8s-master ~]# kubectl get pod -n dev No resources found in dev namespace. # 如果希望僅僅刪除RS對象(保留Pod),可以使用kubectl delete命令時添加--cascade=false選項(不推薦) [root@k8s-master ~]# kubectl delete rs pc-replicaset -n dev --cascade=false replicaset.apps "pc-replicaset" deleted [root@k8s-master ~]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE pc-replicaset-dmhbh 1/1 Running 0 2m35s pc-replicaset-mr9l8 1/1 Running 0 2m35s pc-replicaset-pj6mp 1/1 Running 0 2m35s # 也可以使用yaml直接刪除(推薦) [root@k8s-master ~]# kubectl delete -f pc-replicaset.yaml replicaset.apps "pc-replicaset" deleted4、Deployment(Deploy)
1)、Deployment定義
為了更好的解決服務編排的問題,Kubernetes在V1.2版本開始,引入了Deployment控制器。Deployment控制器并不直接管理Pod,而是通過管理ReplicaSet來簡介管理Pod,即:Deployment管理ReplicaSet,ReplicaSet管理Pod。所以Deployment比ReplicaSet功能更加強大
Deployment主要功能有下面幾個:
- 支持ReplicaSet的所有功能
- 支持發(fā)布的停止、繼續(xù)
- 支持滾動升級和回滾版本
Deployment的資源清單文件:
apiVersion: apps/v1 # 版本號 kind: Deployment # 類型 metadata: # 元數(shù)據(jù)name: # rs名稱 namespace: # 所屬命名空間 labels: # 標簽controller: deploy spec: # 詳情描述replicas: 3 # 副本數(shù)量revisionHistoryLimit: 3 # 保留歷史版本paused: false # 暫停部署,默認是falseprogressDeadlineSeconds: 600 # 部署超時時間(s),默認是600strategy: # 策略type: RollingUpdate # 滾動更新策略rollingUpdate: # 滾動更新maxSurge: 30% # 最大額外可以存在的副本數(shù),可以為百分比,也可以為整數(shù)maxUnavailable: 30% # 最大不可用狀態(tài)的Pod的最大值,可以為百分比,也可以為整數(shù)selector: # 選擇器,通過它指定該控制器管理哪些podmatchLabels: # Labels匹配規(guī)則app: nginx-podmatchExpressions: # Expressions匹配規(guī)則- {key: app, operator: In, values: [nginx-pod]}template: # 模板,當副本數(shù)量不足時,會根據(jù)下面的模板創(chuàng)建pod副本metadata:labels:app: nginx-podspec:containers:- name: nginximage: nginx:1.17.1ports:- containerPort: 802)、控制器模型
Kubernetes所有的控制器都遵循一個通用編排模式,即:控制循環(huán)(control loop),這里有一段Go語言風格的偽代碼,描述這個控制循環(huán):
for {實際狀態(tài) := 獲取集群中對象X的實際狀態(tài)(Actual State)期望狀態(tài) := 獲取集群中對象X的期望狀態(tài)(Desired State)if 實際狀態(tài) == 期望狀態(tài){什么都不做} else {執(zhí)行編排動作,將實際狀態(tài)調(diào)整為期望狀態(tài)} }在具體實現(xiàn)中,實際狀態(tài)往往來自于Kubernetes集群本身。比如,kubectl通過心跳匯報的容器狀態(tài)和節(jié)點狀態(tài),或者監(jiān)控系統(tǒng)中保存的應用監(jiān)控數(shù)據(jù),或者控制器主動收集的它自己感興趣的信息,這些都是常見實際狀態(tài)的來源
而期望狀態(tài)一般來自于用戶提交的YAML文件。比如,Deployment對象中Replicas字段的值,這些信息往往都保存在Etcd中
以Deployment為例,描述下它對控制器模型的實現(xiàn):
類似Deployment這樣的一個控制器,實際上都是由上半部分的控制器定義(包括期望狀態(tài)),加上下半部分的被控制對象的模板組成的
控制器對象本身,負責定義被管理對象的期望狀態(tài)。比如,Deployment里的replicas=2這個字段
而被控制對象的定義,則來自于一個模板。比如,Deployment里的template字段。可以看到,Deployment這個template字段里的內(nèi)容,跟一個標準的Pod對象的API定義絲毫不差。而所有被這個Deployment管理的Pod實例,其實都是根據(jù)這個template字段的內(nèi)容創(chuàng)建出來的
3)、創(chuàng)建Deployment
創(chuàng)建pc-deployment.yaml,內(nèi)容如下:
apiVersion: apps/v1 kind: Deployment metadata:name: pc-deploymentnamespace: dev spec: replicas: 3selector:matchLabels:app: nginx-podtemplate:metadata:labels:app: nginx-podspec:containers:- name: nginximage: nginx:1.17.1上面pc-deployment定義的Pod副本個數(shù)是3(spec.replicas=3)。在具體的實現(xiàn)上,這個Deployment與ReplicaSet以及Pod的關系如下圖:
Deployment控制器實際操縱的是ReplicaSet對象,而不是Pod對象。對于一個Deployment所管理的Pod,它的ownerReference是ReplicaSet
一個定義了replicas=3的Deployment,與它的ReplicaSet以及Pod的關系,實際上是一種層層控制的關系
其中,ReplicaSet負責通過控制器模式保證系統(tǒng)中Pod的個數(shù)永遠等于指定的個數(shù)(比如3個)。這也正是Deployment只允許容器的restartPolicy=Always的主要原因:只有在容器能保證自己始終是Running狀態(tài)的前提下,ReplicaSet調(diào)整Pod的個數(shù)才有意義
而在此基礎上,Deployment同樣通過控制器模式,來操作ReplicaSet的個數(shù)和屬性,進而實現(xiàn)水平擴展/收縮和滾動更新這兩個編排動作
# 創(chuàng)建deployment [root@k8s-master ~]# kubectl create -f pc-deployment.yaml --record deployment.apps/pc-deployment created--record參數(shù)的作用是記錄下你每次操作所執(zhí)行的命令,以方便后面查看
# 查看deployment # READY 已經(jīng)準備好提供服務的副本數(shù)量 # UP-TO-DATE 最新版本的pod的數(shù)量 # AVAILABLE 當前可用的pod的數(shù)量 [root@k8s-master ~]# kubectl get deploy pc-deployment -n dev NAME READY UP-TO-DATE AVAILABLE AGE pc-deployment 3/3 3 3 25s在返回結果中,我們可以看到四個狀態(tài)字段,它們的含義如下:
- DESIRED:用戶期望的Pod副本個數(shù)(spec.replicas的值)
- CURRENT:當前處于Running狀態(tài)的Pod的個數(shù)
- UP-TO-DATE:當前處于最新版本的Pod的個數(shù),所謂最新版本指的是Pod的Spec部分與Deployment里Pod模板里定義的完全一致
- AVAILABLE:當前已經(jīng)可用的Pod的個數(shù),即:既是Running狀態(tài),又是最新版本,并且已經(jīng)處于Ready(健康檢查正確)狀態(tài)的Pod的個數(shù)
只有這個AVAILABLE字段,描述的才是用戶所期望的最終狀態(tài)
# 查看rs # 發(fā)現(xiàn)rs的名稱是在原來deployment的名字后面添加了一個10位數(shù)的隨機串 [root@k8s-master ~]# kubectl get rs -n dev NAME DESIRED CURRENT READY AGE pc-deployment-858db84f89 3 3 3 42s在用戶提交了一個Deployment對象后,Deployment Controller就會立即創(chuàng)建一個Pod副本個數(shù)為3的ReplicaSet。這個ReplicaSet的名字,則是由Deployment的名字和一個隨機字符串共同組成
這個隨機字符串叫作pod-template-hash,ReplicaSet會把這個隨機字符串加在它所控制的所有Pod的標簽里,從而保證這些Pod不會與集群里的其他Pod混淆
而ReplicaSet的DESIRED、CURRENT和READY字段的含義,和Deployment中是一致的。所以,相比之下,Deployment只是在ReplicaSet的基礎上,添加了UP-TO-DATE這個跟版本有關的狀態(tài)字段
# 查看pod [root@k8s-master ~]# kubectl get pod -n dev --show-labels NAME READY STATUS RESTARTS AGE LABELS pc-deployment-858db84f89-74rr9 1/1 Running 0 68s app=nginx-pod,pod-template-hash=858db84f89 pc-deployment-858db84f89-bzsmh 1/1 Running 0 68s app=nginx-pod,pod-template-hash=858db84f89 pc-deployment-858db84f89-jgxw4 1/1 Running 0 68s app=nginx-pod,pod-template-hash=858db84f894)、擴縮容
# 變更副本數(shù)量為5個 [root@k8s-master ~]# kubectl scale deploy pc-deployment --replicas=5 -n dev deployment.apps/pc-deployment scaled# 查看deployment [root@k8s-master ~]# kubectl get deploy pc-deployment -n dev NAME READY UP-TO-DATE AVAILABLE AGE pc-deployment 5/5 5 5 142m# 查看pod [root@k8s-master ~]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE pc-deployment-858db84f89-74rr9 1/1 Running 0 143m pc-deployment-858db84f89-bns84 1/1 Running 0 108s pc-deployment-858db84f89-bzsmh 1/1 Running 0 143m pc-deployment-858db84f89-cx6dk 1/1 Running 0 108s pc-deployment-858db84f89-jgxw4 1/1 Running 0 143m# 編輯deployment的副本數(shù)量,修改spec:replicas: 4即可 [root@k8s-master ~]# kubectl edit deploy pc-deployment -n dev deployment.apps/pc-deployment edited# 查看pod [root@k8s-master ~]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE pc-deployment-858db84f89-74rr9 1/1 Running 0 144m pc-deployment-858db84f89-bzsmh 1/1 Running 0 144m pc-deployment-858db84f89-cx6dk 1/1 Running 0 3m3s pc-deployment-858db84f89-jgxw4 1/1 Running 0 144m5)、鏡像更新
Deployment支持兩種更新策略:重建更新和滾動更新,可以通過strategy指定策略類型
strategy:type: # 指定策略類型,支持兩種策略Recreate: # 重建更新,在創(chuàng)建出新的Pod之前會先殺掉所有已存在的PodRollingUpdate: # 滾動更新,就是殺死一部分,就啟動一部分,在更新過程中,存在兩個版本PodrollingUpdate: # 當type為RollingUpdate時生效,用于為RollingUpdate設置參數(shù),支持兩個屬性maxUnavailable: # 用來指定在升級過程中不可用Pod的最大數(shù)量,默認為25%maxSurge: # 用來指定在升級過程中可以超過期望的Pod的最大數(shù)量,默認為25%1)重建更新
編輯pc-deployment.yaml,在spec節(jié)點下添加更新策略,修改后內(nèi)容如下:
apiVersion: apps/v1 kind: Deployment metadata:name: pc-deploymentnamespace: dev spec: replicas: 3strategy: # 策略type: Recreate # 重建更新 selector:matchLabels:app: nginx-pod template:metadata:labels:app: nginx-podspec:containers:- name: nginximage: nginx:1.17.1 # 更新deployment [root@k8s-master ~]# kubectl apply -f pc-deployment.yaml deployment.apps/pc-deployment configured# 更新鏡像 [root@k8s-master ~]# kubectl set image deployment pc-deployment nginx=nginx:1.17.2 -n dev deployment.apps/pc-deployment image updated# 觀察升級過程 [root@k8s-master ~]# kubectl get pod -n dev -w NAME READY STATUS RESTARTS AGE pc-deployment-858db84f89-8sdvp 1/1 Running 0 22s pc-deployment-858db84f89-d7cr8 1/1 Running 0 22s pc-deployment-858db84f89-jhlf7 1/1 Running 0 22spc-deployment-858db84f89-jhlf7 1/1 Terminating 0 57s pc-deployment-858db84f89-d7cr8 1/1 Terminating 0 57s pc-deployment-858db84f89-8sdvp 1/1 Terminating 0 57spc-deployment-6c78d7875b-wphf8 0/1 Pending 0 0s pc-deployment-6c78d7875b-jthvj 0/1 Pending 0 0s pc-deployment-6c78d7875b-dtgz5 0/1 Pending 0 0spc-deployment-6c78d7875b-wphf8 0/1 ContainerCreating 0 0s pc-deployment-6c78d7875b-jthvj 0/1 ContainerCreating 0 1s pc-deployment-6c78d7875b-dtgz5 0/1 ContainerCreating 0 1spc-deployment-6c78d7875b-dtgz5 1/1 Running 0 3s pc-deployment-6c78d7875b-wphf8 1/1 Running 0 3s pc-deployment-6c78d7875b-jthvj 1/1 Running 0 3s# 在創(chuàng)建出新的Pod之前會先殺掉所有已存在的Pod2)滾動更新
編輯pc-deployment.yaml,在spec節(jié)點下修改更新策略,修改后內(nèi)容如下:
apiVersion: apps/v1 kind: Deployment metadata:name: pc-deploymentnamespace: dev spec: replicas: 3strategy: # 策略type: RollingUpdate # 滾動更新策略rollingUpdate:maxSurge: 25% maxUnavailable: 25% selector:matchLabels:app: nginx-pod template:metadata:labels:app: nginx-podspec:containers:- name: nginximage: nginx:1.17.1 # 更新deployment [root@k8s-master ~]# kubectl apply -f pc-deployment.yaml deployment.apps/pc-deployment configured# 更新鏡像 [root@k8s-master ~]# kubectl set image deployment pc-deployment nginx=nginx:1.17.3 -n dev deployment.apps/pc-deployment image updated# 觀察升級過程 [root@k8s-master ~]# kubectl get pod -n dev -w NAME READY STATUS RESTARTS AGE pc-deployment-858db84f89-cg7bn 1/1 Running 0 24s pc-deployment-858db84f89-n6pqb 1/1 Running 0 20s pc-deployment-858db84f89-x7jks 1/1 Running 0 22spc-deployment-57df6f8b8c-jsr9z 0/1 Pending 0 0s pc-deployment-57df6f8b8c-jsr9z 0/1 ContainerCreating 0 0s pc-deployment-57df6f8b8c-jsr9z 1/1 Running 0 51s pc-deployment-858db84f89-x7jks 0/1 Terminating 0 83spc-deployment-57df6f8b8c-jkphn 0/1 Pending 0 0s pc-deployment-57df6f8b8c-jkphn 0/1 ContainerCreating 0 0s pc-deployment-57df6f8b8c-jkphn 1/1 Running 0 2s pc-deployment-858db84f89-n6pqb 0/1 Terminating 0 83spc-deployment-57df6f8b8c-xfr9f 0/1 Pending 0 0s pc-deployment-57df6f8b8c-xfr9f 0/1 ContainerCreating 0 1s pc-deployment-57df6f8b8c-xfr9f 1/1 Running 0 1s pc-deployment-858db84f89-cg7bn 0/1 Terminating 0 89s# 至此,新版本的Pod創(chuàng)建完畢,舊版本的Pod銷毀完畢 # 中間過程是滾動進行的,也就是邊銷毀邊創(chuàng)建# 查看rs,發(fā)現(xiàn)原來的rs的依舊存在,只是pod數(shù)量變?yōu)榱?,而后又新產(chǎn)生了一個rs,pod數(shù)量為3 # 其實這就是deployment能夠進行版本回退的奧妙所在,后面會詳細解釋 [root@k8s-master ~]# kubectl get rs -n dev NAME DESIRED CURRENT READY AGE pc-deployment-57df6f8b8c 3 3 3 8m15s pc-deployment-6c78d7875b 0 0 0 16m pc-deployment-858db84f89 0 0 0 171m滾動更新過程如下圖:
在上面這個Deployment的例子中,它有3個Pod副本,那么控制器在滾動更新的過程中永遠都會確保至少有2個Pod處于可用狀態(tài),至多只有4個Pod同時存在于集群中
如上所示,Deployment的控制器實際上控制的是ReplicaSet的數(shù)目,以及每個ReplicaSet的屬性
而一個應用的版本對應的正是一個ReplicaSet;這個版本應用的Pod數(shù)量,則由ReplicaSet通過它自己的控制器(ReplicaSet Controller)來保證。通過這樣的多個ReplicaSet對象,Kubernetes項目就實現(xiàn)了對多個應用版本的描述
6)、版本回退
Deployment支持版本升級過程中的暫停、繼續(xù)功能以及版本回退等諸多功能,下面具體來看
kubectl rollout:版本升級相關功能,支持下面的選項:
- status:顯示當前升級狀態(tài)
- history:顯示升級歷史記錄
- pause:暫停版本升級過程
- resume:繼續(xù)已經(jīng)暫停的版本升級過程
- restart:重啟版本升級過程
- undo:回滾到上一級版本(可以使用--to-revision回滾到指定版本)
重新創(chuàng)建Deployment,并進行兩次鏡像升級:
# 重新創(chuàng)建deployment [root@k8s-master ~]# kubectl delete -f pc-deployment.yaml deployment.apps "pc-deployment" deleted[root@k8s-master ~]# kubectl create -f pc-deployment.yaml --record deployment.apps/pc-deployment created[root@k8s-master ~]# kubectl get deploy,rs,pod -n dev NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/pc-deployment 3/3 3 3 12sNAME DESIRED CURRENT READY AGE replicaset.apps/pc-deployment-858db84f89 3 3 3 12sNAME READY STATUS RESTARTS AGE pod/pc-deployment-858db84f89-4kj4h 1/1 Running 0 12s pod/pc-deployment-858db84f89-glvff 1/1 Running 0 12s pod/pc-deployment-858db84f89-mw297 1/1 Running 0 12s[root@k8s-master ~]# kubectl get deploy -n dev -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR pc-deployment 3/3 3 3 15s nginx nginx:1.17.1 app=nginx-pod# 進行鏡像升級 [root@k8s-master ~]# kubectl set image deployment pc-deployment nginx=nginx:1.17.2 -n dev deployment.apps/pc-deployment image updated[root@k8s-master ~]# kubectl get deploy,rs,pod -n dev NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/pc-deployment 3/3 3 3 54sNAME DESIRED CURRENT READY AGE replicaset.apps/pc-deployment-6c78d7875b 3 3 3 27s replicaset.apps/pc-deployment-858db84f89 0 0 0 54sNAME READY STATUS RESTARTS AGE pod/pc-deployment-6c78d7875b-dqts7 1/1 Running 0 25s pod/pc-deployment-6c78d7875b-s64ld 1/1 Running 0 23s pod/pc-deployment-6c78d7875b-xffh2 1/1 Running 0 27s[root@k8s-master ~]# kubectl get deploy -n dev -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR pc-deployment 3/3 3 3 110s nginx nginx:1.17.2 app=nginx-pod# 再進行鏡像升級 [root@k8s-master ~]# kubectl set image deployment pc-deployment nginx=nginx:1.17.3 -n dev deployment.apps/pc-deployment image updated[root@k8s-master ~]# kubectl get deploy,rs,pod -n dev NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/pc-deployment 3/3 3 3 4m59sNAME DESIRED CURRENT READY AGE replicaset.apps/pc-deployment-57df6f8b8c 3 3 3 38s replicaset.apps/pc-deployment-6c78d7875b 0 0 0 4m32s replicaset.apps/pc-deployment-858db84f89 0 0 0 4m59sNAME READY STATUS RESTARTS AGE pod/pc-deployment-57df6f8b8c-7vmpg 1/1 Running 0 34s pod/pc-deployment-57df6f8b8c-mqlwx 1/1 Running 0 36s pod/pc-deployment-57df6f8b8c-qrs7w 1/1 Running 0 38s[root@k8s-master ~]# kubectl get deploy -n dev -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR pc-deployment 3/3 3 3 5m10s nginx nginx:1.17.3 app=nginx-pod # 查看當前升級版本的狀態(tài) [root@k8s-master ~]# kubectl rollout status deploy pc-deployment -n dev deployment "pc-deployment" successfully rolled out# 查看升級歷史記錄 [root@k8s-master ~]# kubectl rollout history deploy pc-deployment -n dev deployment.apps/pc-deployment REVISION CHANGE-CAUSE 1 kubectl create --filename=pc-deployment.yaml --record=true 2 kubectl create --filename=pc-deployment.yaml --record=true 3 kubectl create --filename=pc-deployment.yaml --record=true# 版本回滾 # 這里直接使用--to-revision=1回滾到了1版本(nginx:1.17.1),如果省略這個選項,就是回退到上個版本,就是2版本(nginx:1.17.2) [root@k8s-master ~]# kubectl rollout undo deployment pc-deployment --to-revision=1 -n dev deployment.apps/pc-deployment rolled back# 查看發(fā)現(xiàn),通過nginx鏡像版本可以發(fā)現(xiàn)到了1版本 [root@k8s-master ~]# kubectl get deploy -n dev -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR pc-deployment 3/3 3 3 9m6s nginx nginx:1.17.1 app=nginx-pod# 查看rs,發(fā)現(xiàn)第一個rs中有3個pod運行,后面兩個版本的rs中pod為0 # 其實deployment之所以可是實現(xiàn)版本的回滾,就是通過記錄下歷史rs來實現(xiàn)的 # 一旦想回滾到哪個版本,只需要將當前版本pod數(shù)量降為0,然后將回滾版本的pod提升為目標數(shù)量就可以了 [root@k8s-master ~]# kubectl get rs -n dev -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES pc-deployment-57df6f8b8c 0 0 0 5m13s nginx nginx:1.17.3 pc-deployment-6c78d7875b 0 0 0 9m7s nginx nginx:1.17.2 pc-deployment-858db84f89 3 3 3 9m34s nginx nginx:1.17.17)、金絲雀發(fā)布
Deployment控制器支持控制更新過程中的控制,如暫停(pause)或繼續(xù)(resume)更新操作
比如有一批新的Pod資源創(chuàng)建完成后立即暫停更新過程,此時,僅存在一部分新版本的應用,主體部分還是舊的版本。然后,再篩選一小部分的用戶請求路由到新版本的Pod應用,繼續(xù)觀察能否穩(wěn)定地按期望的方式運行。確定沒問題之后再繼續(xù)完成余下的Pod資源滾動更新,否則立即回滾更新操作。這就是所謂的金絲雀發(fā)布
# 更新deployment的版本,并配置暫停deployment [root@k8s-master ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.4 -n dev && kubectl rollout pause deployment pc-deployment -n dev deployment.apps/pc-deployment image updated deployment.apps/pc-deployment paused# 觀察更新狀態(tài) [root@k8s-master ~]# kubectl rollout status deploy pc-deployment -n dev Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated...[root@k8s-master ~]# kubectl get rs -n dev -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES pc-deployment-57df6f8b8c 0 0 0 15m nginx nginx:1.17.3 pc-deployment-6c78d7875b 0 0 0 19m nginx nginx:1.17.2 pc-deployment-849d4778f4 1 1 0 14s nginx nginx:1.17.4 pc-deployment-858db84f89 3 3 3 20m nginx nginx:1.17.1# 監(jiān)控更新的過程,可以看到已經(jīng)新增了一個資源,但是并未按照預期的狀態(tài)去刪除一個舊的資源,就是因為使用了pause暫停命令# 繼續(xù)更新 [root@k8s-master ~]# kubectl rollout resume deploy pc-deployment -n dev deployment.apps/pc-deployment resumed[root@k8s-master ~]# kubectl get rs -n dev -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES pc-deployment-57df6f8b8c 0 0 0 20m nginx nginx:1.17.3 pc-deployment-6c78d7875b 0 0 0 24m nginx nginx:1.17.2 pc-deployment-849d4778f4 3 3 3 5m16s nginx nginx:1.17.4 pc-deployment-858db84f89 0 0 0 25m nginx nginx:1.17.15、DaemonSet(DS)
1)、DaemonSet定義
DaemonSet類型的控制器可以保證在集群中的每一臺(或指定)節(jié)點上都運行一個副本。一般適用于日志收集、節(jié)點監(jiān)控等場景。也就是說,如果一個Pod提供的功能是節(jié)點級別的(每個節(jié)點都需要且只需要一個),那么這類Pod就適合使用DaemonSet類型的控制器創(chuàng)建
DaemonSet創(chuàng)建的Pod有如下三個特征:
- 這個Pod運行在Kubernetes集群里的每一個節(jié)點(Node)上
- 每個節(jié)點上只有一個這樣的Pod實例
- 當有新的節(jié)點加入Kubernetes集群后,該Pod會自動地在新節(jié)點上被創(chuàng)建出來;而當舊節(jié)點被刪除后,它上面的Pod也相應地會被回收掉
DaemonSet的資源清單文件:
apiVersion: apps/v1 # 版本號 kind: DaemonSet # 類型 metadata: # 元數(shù)據(jù)name: # rs名稱 namespace: # 所屬命名空間 labels: # 標簽controller: daemonset spec: # 詳情描述revisionHistoryLimit: 3 # 保留歷史版本updateStrategy: # 更新策略type: RollingUpdate # 滾動更新策略rollingUpdate: # 滾動更新maxUnavailable: 1 # 最大不可用狀態(tài)的Pod的最大值,可以為百分比,也可以為整數(shù)selector: # 選擇器,通過它指定該控制器管理哪些podmatchLabels: # Labels匹配規(guī)則app: nginx-podmatchExpressions: # Expressions匹配規(guī)則- {key: app, operator: In, values: [nginx-pod]}template: # 模板,當副本數(shù)量不足時,會根據(jù)下面的模板創(chuàng)建pod副本metadata:labels:app: nginx-podspec:containers:- name: nginximage: nginx:1.17.1ports:- containerPort: 802)、創(chuàng)建DaemonSet
創(chuàng)建pc-daemonset.yaml,內(nèi)容如下:
apiVersion: apps/v1 kind: DaemonSet metadata:name: pc-daemonsetnamespace: dev spec: selector:matchLabels:app: nginx-podtemplate:metadata:labels:app: nginx-podspec:containers:- name: nginximage: nginx:1.17.1 # 創(chuàng)建daemonset [root@k8s-master ~]# kubectl create -f pc-daemonset.yaml --record daemonset.apps/pc-daemonset created# 查看daemonset [root@k8s-master ~]# kubectl get ds -n dev -o wide NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR pc-daemonset 2 2 2 2 2 <none> 15s nginx nginx:1.17.1 app=nginx-pod# 查看pod,發(fā)現(xiàn)在每個Node上都運行一個pod [root@k8s-master ~]# kubectl get pod -n dev -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pc-daemonset-gbzw8 1/1 Running 0 23s 10.244.1.35 k8s-node2 <none> <none> pc-daemonset-h6zfz 1/1 Running 0 23s 10.244.2.74 k8s-node1 <none> <none>3)、DaemonSet實現(xiàn)原理
DaemonSet如何保證每個Node上有且只有一個被管理的Pod呢?
DaemonSet Controller首先從Etcd里獲取所有的Node列表,然后遍歷所有的Nod,然后去檢查,當前這個Node上是不是有一個攜帶了app: nginx-pod標簽的Pod在運行
檢查結果可能有這么三種情況:
- 沒有這種Pod,那么就意味著要在這個Node上創(chuàng)建這樣一個Pod
- 有這種Pod,但是數(shù)量大于1,那就說明要把多余的Pod從這個Node上刪除掉
- 正好只有一個這種Pod,那說明這個節(jié)點是正常的
DaemonSet是如何在指定的Node上創(chuàng)建新Pod呢?
通過kubectl edit來看下DaemonSet創(chuàng)建Pod的詳細信息:
[root@k8s-master ~]# kubectl edit pod pc-daemonset-pq6n7 -n dev spec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution: # Node節(jié)點必須滿足指定的所有規(guī)則才可以,相當于硬限制nodeSelectorTerms:- matchFields:- key: metadata.nameoperator: Invalues:- k8s-node1上面定義的nodeAffinity的含義是:這里Pod只允許運行在metadata.name是k8s-node1的節(jié)點上
DaemonSet Controller會在創(chuàng)建Pod的時候,自動在這個Pod的API對象里,加上這樣一個nodeAffinity定義。其中,需要綁定的節(jié)點名字,正是當前正在遍歷的這個Node
此外,DaemonSet還會給這個Pod自動加上另外一個與調(diào)度相關的字段,叫作tolerations。這個字段意味著這個Pod,會容忍(Toleration)某些Node的污點(Taint)
spec: tolerations:- effect: NoSchedulekey: node.kubernetes.io/unschedulableoperator: Exists上面定義的tolerations的含義是:容忍所有被標記為unschedulable污點的Node;容忍的效果是允許調(diào)度
而在正常情況下,被標記了unschedulable污點的Node,是不會有任何Pod被調(diào)度上去的(effect: NoSchedule)。可是,DaemonSet自動地給被管理的Pod加上了這個特殊的tolerations,就使得這些Pod可以忽略這個限制,繼而保證每個節(jié)點上都會被調(diào)度一個Pod。當然,如果這個節(jié)點有故障的話,這個Pod可能會啟動失敗,而DaemonSet則會始終嘗試下去,直到Pod啟動成功
DaemonSet創(chuàng)建的Pod自動添加的tolerations配置如下:
spec: tolerations:- effect: NoExecutekey: node.kubernetes.io/not-readyoperator: Exists- effect: NoExecutekey: node.kubernetes.io/unreachableoperator: Exists- effect: NoSchedulekey: node.kubernetes.io/disk-pressureoperator: Exists- effect: NoSchedulekey: node.kubernetes.io/memory-pressureoperator: Exists- effect: NoSchedulekey: node.kubernetes.io/pid-pressureoperator: Exists- effect: NoSchedulekey: node.kubernetes.io/unschedulableoperator: Exists如果這個DaemonSet是一個網(wǎng)絡插件的Agent組件,這個時候整個Kubernetes集群里還沒有可用的容器網(wǎng)絡,所有Worker節(jié)點的狀態(tài)都是NotReady(NetworkReady=false)。但因為DaemonSet創(chuàng)建的Pod會容忍所有被標記為not-ready污點的Node,所以即使在所有Worker節(jié)點的狀態(tài)都是NotReady時,DaemonSet創(chuàng)建的Pod依然能被調(diào)度
4)、鏡像更新與版本回退
# 鏡像更新 [root@k8s-master ~]# kubectl set image daemonset pc-daemonset nginx=nginx:1.17.2 -n dev daemonset.apps/pc-daemonset image updated[root@k8s-master ~]# kubectl get ds -n dev -o wide NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR pc-daemonset 2 2 2 2 2 <none> 2m8s nginx nginx:1.17.2 app=nginx-pod# 查看升級歷史記錄 [root@k8s-master ~]# kubectl rollout history ds pc-daemonset -n dev daemonset.apps/pc-daemonset REVISION CHANGE-CAUSE 1 kubectl create --filename=pc-daemonset.yaml --record=true 2 kubectl create --filename=pc-daemonset.yaml --record=trueDeployment管理這些版本,靠的是一個版本對應一個ReplicaSet對象。可是,DaemonSet控制器操作的直接就是Pod,不可能有ReplicaSet這樣的對象參與其中。那么,它的這些版本又是如何維護的呢?
Kubernetes v1.7之后添加了一個API對象,名叫ControllerRevision,專門用來記錄某種Controller對象的版本。比如,可以通過如下命令查看pc-daemonset對應的ControllerRevision:
[root@k8s-master ~]# kubectl get controllerrevision -n dev NAME CONTROLLER REVISION AGE pc-daemonset-6c78d7875b daemonset.apps/pc-daemonset 2 107s pc-daemonset-858db84f89 daemonset.apps/pc-daemonset 1 2m30s使用kubectl describe查看這個ControllerRevision對象:
[root@k8s-master ~]# kubectl describe controllerrevision pc-daemonset-6c78d7875b -n dev Name: pc-daemonset-6c78d7875b Namespace: dev Labels: app=nginx-podcontroller-revision-hash=6c78d7875b Annotations: deprecated.daemonset.template.generation: 2kubernetes.io/change-cause: kubectl create --filename=pc-daemonset.yaml --record=true API Version: apps/v1 Data:Spec:Template:$patch: replaceMetadata:Creation Timestamp: <nil>Labels:App: nginx-podSpec:Containers:Image: nginx:1.17.2Image Pull Policy: IfNotPresentName: nginxResources:Termination Message Path: /dev/termination-logTermination Message Policy: FileDns Policy: ClusterFirstRestart Policy: AlwaysScheduler Name: default-schedulerSecurity Context:Termination Grace Period Seconds: 30 ...... Revision: 2 Events: <none>這個ControllerRevision對象實際上是在Data字段保存了該版本對應的完整的DaemonSet的API對象。并且,在Annotation字段保存了創(chuàng)建這個對象所使用的kubectl命令
# 版本回滾 [root@k8s-master ~]# kubectl rollout undo ds pc-daemonset --to-revision=1 -n dev daemonset.apps/pc-daemonset rolled back# 查看發(fā)現(xiàn),通過nginx鏡像版本可以發(fā)現(xiàn)到了1版本 [root@k8s-master ~]# kubectl get ds -n dev -o wide NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR pc-daemonset 2 2 1 1 1 <none> 6m11s nginx nginx:1.17.1 app=nginx-pod# 查看升級歷史記錄 [root@k8s-master ~]# kubectl rollout history ds pc-daemonset -n dev daemonset.apps/pc-daemonset REVISION CHANGE-CAUSE 2 kubectl create --filename=pc-daemonset.yaml --record=true 3 kubectl create --filename=pc-daemonset.yaml --record=true這個kubectl rollout undo操作,實際上相當于讀取到了Revision=1的ControllerRevision對象保存的Data字段。而這個Data字段里保存的信息,就是Revision=1時這個DaemonSet的完整API對象
所以,現(xiàn)在DaemonSet Controller就可以使用這個歷史API對象,對現(xiàn)有的DaemonSet做一次PATCH操作(等價于執(zhí)行一次kubectl apply -f “舊的DaemonSet對象”),從而把這個DaemonSet更新到一個舊版本
所以,在執(zhí)行完這次回滾完成后,DaemonSet的Revision并不會從Revision=2退回到1,而是會增加成Revision=3。這是因為,一個新的 ControllerRevision被創(chuàng)建了出來
6、Job
1)、Job定義
Job主要用于負責**批量處理(一次要處理指定數(shù)量任務)短暫的一次性(每個任務僅運行一次就結束)**任務。Job特點如下:
- 當Job創(chuàng)建的pod執(zhí)行成功結束時,Job將記錄成功結束的pod數(shù)量
- 當成功結束的pod達到指定的數(shù)量時,Job將完成執(zhí)行
Job的資源清單文件:
apiVersion: batch/v1 # 版本號 kind: Job # 類型 metadata: # 元數(shù)據(jù)name: # rs名稱 namespace: # 所屬命名空間 labels: # 標簽controller: job spec: # 詳情描述completions: 1 # 指定job需要成功運行Pods的次數(shù)。默認值:1parallelism: 1 # 指定job在任一時刻應該并發(fā)運行Pods的數(shù)量。默認值:1activeDeadlineSeconds: 30 # 指定job可運行的時間期限,超過時間還未結束,系統(tǒng)將會嘗試進行終止backoffLimit: 6 # 指定job失敗后進行重試的次數(shù)。默認是6manualSelector: true # 是否可以使用selector選擇器選擇pod,默認是falseselector: # 選擇器,通過它指定該控制器管理哪些podmatchLabels: # Labels匹配規(guī)則app: counter-podmatchExpressions: # Expressions匹配規(guī)則- {key: app, operator: In, values: [counter-pod]}template: # 模板,當副本數(shù)量不足時,會根據(jù)下面的模板創(chuàng)建pod副本metadata:labels:app: counter-podspec:restartPolicy: Never # 重啟策略只能設置為Never或者OnFailurecontainers:- name: counterimage: busybox:1.30command: ["bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 2;done"]關于重啟策略設置的說明:
- 如果指定為OnFailure,則job會在pod出現(xiàn)故障時重啟容器,而不是創(chuàng)建pod,failed次數(shù)不變
- 如果指定為Never,則job會在pod出現(xiàn)故障時創(chuàng)建新的pod,并且故障pod不會消失,也不會重啟,failed次數(shù)加1
- 如果指定為Always的話,就意味著一直重啟,意味著job任務會重復去執(zhí)行了,當然不對,所以不能設置為Always
2)、創(chuàng)建Job
創(chuàng)建pc-job.yaml,內(nèi)容如下:
apiVersion: batch/v1 kind: Job metadata:name: pc-jobnamespace: dev spec:template:spec:containers:- name: piimage: resouer/ubuntu-bc command: ["sh", "-c", "echo 'scale=10000; 4*a(1)' | bc -l "]restartPolicy: NeverbackoffLimit: 4上面定義了計算π值的Pod,輸出到小數(shù)點后10000位
跟其他控制器不同的是,Job控制器并不要求定義一個spec.selector來描述要控制哪些Pod
# 創(chuàng)建job [root@k8s-master ~]# kubectl create -f pc-job.yaml job.batch/pc-job created# 查看job詳情 [root@k8s-master ~]# kubectl describe job pc-job -n dev Name: pc-job Namespace: dev Selector: controller-uid=85b24167-0e3f-465d-bc8d-ac10aa5df734 Labels: controller-uid=85b24167-0e3f-465d-bc8d-ac10aa5df734job-name=pc-job Annotations: <none> Parallelism: 1 Completions: 1 Start Time: Wed, 09 Feb 2022 22:32:11 +0800 Pods Statuses: 1 Running / 0 Succeeded / 0 Failed Pod Template:Labels: controller-uid=85b24167-0e3f-465d-bc8d-ac10aa5df734job-name=pc-jobContainers:pi:Image: resouer/ubuntu-bcPort: <none>Host Port: <none>Command:sh-cecho 'scale=10000; 4*a(1)' | bc -l Environment: <none>Mounts: <none>Volumes: <none> ......這個Job對象在創(chuàng)建后,它的Pod模板,被自動加上了一個controller-uid=< 一個隨機字符串 >這樣的Label。而這個Job對象本身,則被自動加上了這個Label對應的Selector,從而保證了Job與它所管理的Pod之間的匹配關系。而Job Controller之所以要使用這種攜帶了UID的Label,就是為了避免不同Job對象所管理的Pod發(fā)生重合
# pod進入Running狀態(tài),意味著它正在計算π的值 [root@k8s-master ~]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE pc-job-vc25v 1/1 Running 0 19s# 幾分鐘后計算結束,這個pod就會進入Completed狀態(tài) [root@k8s-master ~]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE pc-job-vc25v 0/1 Completed 0 2m13s這也是需要在Pod模板中定義restartPolicy=Never的原因:離線計算的Pod永遠都不應該被重啟,否則它們會再重新計算一遍
事實上,restartPolicy在Job對象里只允許被設置為Never和OnFailure;而在Deployment對象里,restartPolicy則只允許被設置為Always
3)、Job并行控制
在Job對象中,負責并行控制的參數(shù)有兩個:
- spec.parallelism:它定義的是一個Job在任意時間最多可以啟動多少個Pod同時運行
- spec.completions:它定義的是Job至少要完成的Pod數(shù)目,即Job的最小完成數(shù)
修改pc-job.yaml,修改后內(nèi)容如下:
apiVersion: batch/v1 kind: Job metadata:name: pc-jobnamespace: dev spec:parallelism: 2completions: 4template:spec:containers:- name: piimage: resouer/ubuntu-bccommand: ["sh", "-c", "echo 'scale=10000; 4*a(1)' | bc -l "]restartPolicy: NeverbackoffLimit: 4指定了這個Job最大的并行數(shù)是2,而最小的完成數(shù)是4
# 重新創(chuàng)建job [root@k8s-master ~]# kubectl delete job pc-job -n dev job.batch "pc-job" deleted [root@k8s-master ~]# kubectl create -f pc-job.yaml job.batch/pc-job created[root@k8s-master ~]# kubectl get job -n dev NAME COMPLETIONS DURATION AGE pc-job 0/4 23s 23s# job首先創(chuàng)建了兩個并行運行的pod來計算π [root@k8s-master ~]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE pc-job-cjlvf 1/1 Running 0 38s pc-job-jkf2r 1/1 Running 0 38s# 前兩個pod完成計算后,進入Completed狀態(tài) # job第二次創(chuàng)建出來的兩個并行的pod進入了Running狀態(tài) [root@k8s-master ~]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE pc-job-brd6n 1/1 Running 0 26s pc-job-cjlvf 0/1 Completed 0 2m34s pc-job-czbp8 1/1 Running 0 10s pc-job-jkf2r 0/1 Completed 0 2m34s[root@k8s-master ~]# kubectl get job -n dev NAME COMPLETIONS DURATION AGE pc-job 2/4 2m52s 2m52s# 所有的pod均已經(jīng)成功退出 [root@k8s-master ~]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE pc-job-brd6n 0/1 Completed 0 5m53s pc-job-cjlvf 0/1 Completed 0 8m1s pc-job-czbp8 0/1 Completed 0 5m37s pc-job-jkf2r 0/1 Completed 0 8m1s# job執(zhí)行完成 [root@k8s-master ~]# kubectl get job -n dev NAME COMPLETIONS DURATION AGE pc-job 4/4 4m18s 8m5s7、CronJob(CJ)
1)、CronJob定義
CronJob控制器以Job控制器資源為其管控對象,并借助它管理Pod資源對象,Job控制器定義的作業(yè)任務在其控制器資源創(chuàng)建之后便會立即執(zhí)行,但CronJob可以以類似于Linux操作系統(tǒng)的周期性任務作業(yè)計劃的方式控制其運行時間點及重復運行的方式。也就是說,CronJob可以在特定的時間點(反復的)去運行Job任務
CronJob的資源清單文件:
apiVersion: batch/v1beta1 # 版本號 kind: CronJob # 類型 metadata: # 元數(shù)據(jù)name: # rs名稱 namespace: # 所屬命名空間 labels: # 標簽controller: cronjob spec: # 詳情描述schedule: # cron格式的作業(yè)調(diào)度運行時間點,用于控制任務在什么時間執(zhí)行concurrencyPolicy: # 并發(fā)執(zhí)行策略,用于定義前一次作業(yè)運行尚未完成時是否以及如何運行后一次的作業(yè)failedJobHistoryLimit: # 為失敗的任務執(zhí)行保留的歷史記錄數(shù),默認為1successfulJobHistoryLimit: # 為成功的任務執(zhí)行保留的歷史記錄數(shù),默認為3startingDeadlineSeconds: # 啟動作業(yè)錯誤的超時時長jobTemplate: # job控制器模板,用于為cronjob控制器生成job對象;下面其實就是job的定義metadata:spec:completions: 1parallelism: 1activeDeadlineSeconds: 30backoffLimit: 6manualSelector: trueselector:matchLabels:app: counter-podmatchExpressions: 規(guī)則- {key: app, operator: In, values: [counter-pod]}template:metadata:labels:app: counter-podspec:restartPolicy: Never containers:- name: counterimage: busybox:1.30command: ["bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 20;done"]需要重點解釋的幾個選項:
schedule: cron表達式,用于指定任務的執(zhí)行時間
*/1 * * * *<分鐘> <小時> <日> <月份> <星期>分鐘值從0到59小時值從0到23日值從1到31月值從1到12星期值從0到6,0代表星期日多個時間可以用逗號隔開,范圍可以用連字符給出,*可以作為通配符,/表示每...concurrencyPolicy:
- Allow:允許Jobs并發(fā)運行(默認)
- Forbid:禁止并發(fā)運行,如果上一次運行尚未完成,則跳過下一次運行
- Replace:替換,取消當前正在運行的作業(yè)并用新作業(yè)替換它
2)、創(chuàng)建CronJob
創(chuàng)建pc-cronjob.yaml,內(nèi)容如下:
apiVersion: batch/v1beta1 kind: CronJob metadata:name: pc-cronjobnamespace: devlabels:controller: cronjob spec:schedule: "*/1 * * * *"jobTemplate:metadata:spec:template:spec:restartPolicy: Nevercontainers:- name: counterimage: busybox:1.30command: ["bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1; do echo $i;sleep 3;done"]每分鐘執(zhí)行一次
# 創(chuàng)建cronjob [root@k8s-master ~]# kubectl create -f pc-cronjob.yaml cronjob.batch/pc-cronjob created# 查看cronjob [root@k8s-master ~]# kubectl get cj -n dev NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE pc-cronjob */1 * * * * False 0 <none> 17s[root@k8s-master ~]# kubectl get job -n dev NAME COMPLETIONS DURATION AGE pc-cronjob-1644420420 1/1 29s 2m8s pc-cronjob-1644420480 1/1 29s 68s pc-cronjob-1644420540 0/1 8s 8s# 查看pod [root@k8s-master ~]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE pc-cronjob-1644420420-jv2v6 0/1 Completed 0 2m12s pc-cronjob-1644420480-s7chz 0/1 Completed 0 72s pc-cronjob-1644420540-mwk76 1/1 Running 0 12s# 刪除cronjob [root@k8s-master ~]# kubectl delete cj pc-cronjob -n dev cronjob.batch "pc-cronjob" deleted參考:
Kubernetes(K8S) 入門進階實戰(zhàn)完整教程,黑馬程序員K8S全套教程(基礎+高級)
極客時間 《深入剖析Kubernetes》
云原生技術公開課
總結
以上是生活随笔為你收集整理的Kubernetes学习笔记(二):Pod控制器详解:资源元信息、ReplicaSet、Deployment、DaemonSet、Job、CronJob的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python温度转换_一步一步教会你,详
- 下一篇: php农历生日计算,阴历-农历-转换类