Pod控制器由master的控制器管理器(kube-controller-manager)組件提供,pod控制器的主要作用是對pod資源進行創建、創建、修改、刪除等操作。常見的pod控制器由Replication Controller、ReplicaSet、Deployment、DaemonSet、StatefulSet、Job和CronJob。
1、pod控制器與pod對象
(1)pod控制器
Pod控制器資源通過持續地監控集羣中運行着的pod資源對象來確保受其管控的資源嚴格符合用戶期望的狀態。一個pod控制器至少由標籤選擇器、期望的副本數量、pod模板三部分組成。
(2)pod控制器資源的定義
Pod控制器資源定義同pod資源的定義相同,也是通過apiVersion、kind、metadata、spec、status等五個字段及子字段組成,status爲當前狀態不需要再資源配置清單中定義。Spec字段通常要內嵌replicas、selector、template字段;而template爲pod模板的定義,該字段主要定義pod資源需要定義的metadata字段和spec字段,用法與自助式pod資源的定義相同。
2、ReplicaSet控制器
ReplicaSet控制器主要用於確保其管控的pod對象副本數在任一時刻都能精確滿足期望的數量。
(1)ReplicaSet控制器的主要功能
1)確保Pod資源對象的數量精確反應期望值
2)確保pod健康運行
3)彈性伸縮
(2)ReplicaSet的資源定義清單
ReplicaSet控制器資源的定義與pod資源定義類似,其spec字段嵌套的子字段及作用如下:
replicas:期望pod副本的數量
selector:當前控制器匹配Pod對象副本的標籤選擇器,支持matchLabels和matchExpressions兩種匹配機制
template:用於補充pod副本數量時使用的pod模板資源
minReadySeconds:新建的pod對象,在啓動後的多長時間內如果其容器未發生奔潰等異常情況則視爲就緒。默認0
# replicaset類型pod控制器資源定義清單
[root@master01 test02]# cat test01.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: test-replicaset
spec:
replicas: 2
selector:
matchLabels:
app: test-rep
template:
metadata:
labels:
app: test-rep
spec:
containers:
- name: repset-test
image: nginx:1.12
ports:
- name: http
containerPort: 80
# 創建replicaset控制器
[root@master01 test02]# kubectl apply -f test01.yaml
replicaset.apps/test-replicaset created
# 查看創建的控制器的狀態
[root@master01 test02]# kubectl get replicaset test-replicaset
NAME DESIRED CURRENT READY AGE
test-replicaset 2 2 2 3m16s
(3)replicaset對pod的管理
任何原因導致的pod副本缺失時都會有ReplicaSet控制器自動補充,多餘的則會被ReplicaSet控制器刪除。Pod資源的變動時間可通過“kubectl describe replicasets”命令查看。
# 查看replicaset控制器的狀態
[root@master01 test02]# kubectl describe replicasets test-replicaset
Name: test-replicaset
Namespace: default
. . . . . .
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 8m36s replicaset-controller Created pod: test-replicaset-gj5xx
Normal SuccessfulCreate 8m36s replicaset-controller Created pod: test-replicaset-25cpv
(4)更新replicaset控制器
replicaSet控制器的核心組成部分是標籤選擇器,副本數量及Pod模板,但更新操作一般是圍繞replicas和template兩個字段值進行的。
1)更改pod模板、升級應用
Replicaset控制器的模板可以隨時按需修改,但修改只會影響之後由其創建的pod對象。更新時我們先修改配置文件,然後可以一次性刪除控制器相關的所有的pod副本及相關的標籤或者分批刪除舊的副本或更改其標籤。
# 爲了使更新效果明顯,將配置中的nginx更改爲httpd
[root@master01 test02]# cat test01.yaml
. . . . . .
containers:
- name: repset-test
image: httpd:latest
. . . . . .
# 對清單配置文件執行”kubectl apply”或”kubectl replace”完成控制器資源的修改操作
[root@master01 test02]# kubectl replace -f test01.yaml
# 刪除該控制器下的所有pod副本
[root@master01 test02]# kubectl delete pods -l app=test-rep
# 再次查看時已經更新完成
[root@master01 test02]# kubectl get pods -l app=test-rep -w
NAME READY STATUS RESTARTS AGE
test-replicaset-6w977 1/1 Running 0 119s
test-replicaset-lw99r 1/1 Running 0 119s
2)replicaSet控制器的擴容與縮容
replicaSet控制器對pod數量的增加與縮減都可以通過修改資源的定義文件或者命令實現。通過修改定義文件的擴縮容都是實時的。
# 修改資源定義文件,將pod數量擴至5個
[root@master01 test02]# sed -i "s#replicas: 2#replicas: 5#g" test01.yaml
# 讓配置清單生效
[root@master01 test02]# kubectl replace -f test01.yaml
# 查看狀態
[root@master01 test02]# kubectl get replicaset test-replicaset
NAME DESIRED CURRENT READY AGE
test-replicaset 5 5 5 53m
# 通過命令將pod的數量縮減至3個
[root@master01 test02]# kubectl scale replicasets test-replicaset --replicas=3
replicaset.extensions/test-replicaset scaled
# 查看縮減後的pod
[root@master01 test02]# kubectl get pods -l app=test-rep
NAME READY STATUS RESTARTS AGE
test-replicaset-6w977 1/1 Running 0 17m
test-replicaset-lw99r 1/1 Running 0 17m
test-replicaset-x865r 1/1 Running 0 9m2s
“kubectl scale”命令還支持通過參數”—current-replicas”在現有pod副本數量符合指定的值時才執行擴展操作。
# 當pod數量爲2個時擴展爲6個,因爲pod數量部位兩個所以報錯
[root@master01 test02]# kubectl scale replicasets test-replicaset --current-replicas=2 --replicas=6
error: Expected replicas to be 2, was 3
# 當pod數量爲3個時擴展爲6個,
[root@master01 test02]# kubectl scale replicasets test-replicaset --current-replicas=3 --replicas=6
replicaset.extensions/test-replicaset scaled
(5)刪除replicaSet控制器資源
使用”kubectl delete”命令刪除replicaset對象時默認會一併刪除其管控的個pod對象,有時,這些pod資源可能不是該replicaset控制器創建的,此時可以使用”—cascade=false”選項,取消級聯,刪除相關的pod對象。
# 刪除名稱爲test-replicaset的replicaset控制器並取消與pod的級聯
[root@master01 test02]# kubectl delete replicasets test-replicaset --cascade=false
replicaset.extensions "test-replicaset" deleted
# 刪除控制器後查看pod
[root@master01 test02]# kubectl get pods -l app=test-rep
NAME READY STATUS RESTARTS AGE
test-replicaset-2kqw8 1/1 Running 0 2m54s
test-replicaset-6w977 1/1 Running 0 63m
test-replicaset-lw99r 1/1 Running 0 63m
test-replicaset-rmq4t 1/1 Running 0 2m54s
test-replicaset-rsxxb 1/1 Running 0 2m54s
test-replicaset-x865r 1/1 Running 0 54m
3、Deployment控制器
Deployment控制器是構建與ReplicaSet控制器之上,可爲Pod和ReplicaSet資源提供聲明式更新的一種控制器;Deployment控制器的主要作用還是爲了Pod資源的健康運行,但大部分功能可通過調用ReplicaSet控制器來實現,同時還添加了事件和狀態查看、回滾、版本記錄、暫停和啓動、多種自動更新方案等特性。
(1)創建Deployment控制器
Deployment控制器資源清單定義與replicaset控制器資源定義的方式基本相同。
# 定義deployment控制器的配置清單
[root@master01 test02]# cat test02.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-test
spec:
replicas: 2
selector:
matchLabels:
app: test-deploy
template:
metadata:
labels:
app: test-deploy
spec:
containers:
- name: test-deploy
image: nginx:1.12
ports:
- name: http
containerPort: 80
# 創建deployment
[root@master01 test02]# kubectl apply -f test02.yaml
# 查看創建的deployment控制器
[root@master01 test02]# kubectl get deployments deployment-test
NAME READY UP-TO-DATE AVAILABLE AGE
deployment-test 2/2 2 2 2m50s
deployment控制器創建完成後,該控制器會自動創建相關的replicaset控制器,並以deployment控制器名稱加hash值命名。
# 查看有replicaset控制器創建的deployment控制器
[root@master01 test02]# kubectl get replicasets -l app=test-deploy
NAME DESIRED CURRENT READY AGE
deployment-test-65b8b4f5b8 2 2 2 6m18s
(2)Deployment控制器的更新策略
相對於replicaset控制器,deployment控制器的更新只需要用於指定在Pod模板中需要修改的內容,剩下的步驟則由其自動完成。
Deployment控制器也支持兩種更新策略,重新創建和滾動更新,默認更新策略爲滾動更新。
1)重新創建(recreate):重新創建是先刪除現有的pod對象,然後由控制器基於新模板重新創建出新版本的資源對象。
2)滾動更新(rolling update):在刪除一部分舊版本pod的同時。補充新建一部分新版本pod對象;使更新的過程中業務不中斷,但要求應用程序能夠支持新舊版本同時工作的情形。
滾動更新時,應用升級期間還要確保可用的pod對象數量不低於閾值以確保應用能夠正常處理請求,變動的方式和pod對象的數量通過spec.strategy.rollingUpdate.maxSurge和spec.strategy.rollingUpdate.maxUnavailable兩個字段協同定義,他們的值都可以是一個期望值的百分比,他們的作用如下:
1)maxSurge:指定升級期間存在的pod對象數量最多可超出期望值的個數。
2)maxUnavilable:指定升級期間正常可用的pod副本數量最多不能低於期望值的個數。
更新時,還可以使用deployment.spec.minReadySecondsz字段控制應用升級的速度,該字段能夠定義在新的pod對象創建後至少需要等多久才能將其視爲就緒,再次期間,更新操作將會被阻塞。
Deployment也支持用戶保留其滾動更新歷史中的舊ReplicaSet對象版本;可保存的歷史版本數量由spec.revisionHistoryLimit屬性定義;而只有保存在revision歷史中的ReplicaSet版本可用於回滾。爲了保存歷史版本可在創建deployment對象時使用”--record”選項。
(3)升級deployment
由於deployment控制的資源定義是聲明式的配置,因此修改配置更適合使用”apply”和”patch”命令進行;如果只是修改容器鏡像,則使用”set image”命令更適合。
# 通過打補丁的方式設置更新速度爲10s,更新時的pod數量最多隻能比定義的數量多1個,最少只能比定義的數量少一個。
[root@master01 ~]# kubectl patch deployments deployment-test -p '{"spec":{"minReadySeconds":10,"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":1}}}}'
deployment.extensions/deployment-test patched
# 更換鏡像
[root@master01 test02]# kubectl set image deployments deployment-test test-deploy=httpd
deployment.extensions/deployment-test image updated
# 更新pod的數量爲5個
[root@master01 test02]# kubectl patch deployments deployment-test -p '{"spec":{"replicas":5}}'
deployment.extensions/deployment-test patched
# 監控更新過程
[root@master01 test02]# kubectl get deployments deployment-test --watch
NAME READY UP-TO-DATE AVAILABLE AGE
deployment-test 5/5 5 5 19h
(4)金絲雀發佈
Deployment控制器還支持自定義控制更新過程中的滾動節奏,如“暫停”或“繼續”等更新操作。
金絲雀發佈是在更新的過程,第一批新的pod資源更新完成後立即暫停更新過程,然後帥選出小部分的請求路由至新版本的pod中,並觀察新版本的pod是否穩定並按預期的方式運行,待觀察沒問題後繼續完成餘下pod資源的滾動更新;有問題則立刻回滾更新操作。
# 設置maxSurge爲1,設置maxUnavailable爲0
[root@master01 test02]# kubectl patch deployments deployment-test -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'
deployment.extensions/deployment-test patched
# 更改pod中容器鏡像,在第一批新版本pod對象創建完成後轉爲暫停
[root@master01 test02]# kubectl set image deployments deployment-test test-deploy=tomcat && kubectl rollout pause deployments deployment-test
deployment.extensions/deployment-test paused
# 查看跟新過程中的狀態信息
[root@master01 test02]# kubectl rollout status deployments deployment-test
Waiting for deployment "deployment-test" rollout to finish: 2 out of 5 new replicas have been updated...
# 繼續之前的更新過程
[root@master01 ~]# kubectl rollout resume deployments deployment-test
deployment.extensions/deployment-test resumed
(5)回滾deployment控制器應用的發佈
在更新的過程中,如果更新失敗或更新無法繼續進行時,需要將應用回滾到之前的版本或指定的歷史記錄中的版本。
# 將更新回滾到上一個版本
[root@master01 ~]# kubectl rollout undo deployments deployment-test
deployment.extensions/deployment-test rolled back
# 查看歷史版本
[root@master01 ~]# kubectl rollout history deployments deployment-test
deployment.extensions/deployment-test
REVISION CHANGE-CAUSE
1 <none>
3 <none>
4 <none>
# 回滾到指定的歷史版本
[root@master01 ~]# kubectl rollout undo deployments deployment-test --to-revision=3
deployment.extensions/deployment-test rolled back
在回滾的過程中,如果此前的滾動更新狀態處於“暫停”狀態,那麼回滾操作就需要先將pod模板的版本改回到之前的版本,然後繼續更新,否則,一直將處於“暫停”狀態無法回滾。
4、Daemonset控制器
Daemonset控制器用於在集羣中的全部節點上同時運行一份指定的pod資源的副本,後續加入集羣的節點也會自動創建該pod副本;管理員可以使用節點選擇器及節點標籤在指定的節點上運行指定的pod對象。Daemonset控制器通常用於運行執行系統及操作任務的應用。
(1)定義DaemonSet控制器
DaemonSet控制器的資源定義方法同前面兩種控制器的定義方法相同,但不支持replicas字段。
# 定義daemonset控制器資源配置文件
[root@master01 test02]# cat test03.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: test-daemonset
labels:
app: filebeat
spec:
selector:
matchLabels:
app: filebeat
template:
metadata:
name: filebeat
labels:
app: filebeat
spec:
containers:
- name: filebeat
image: fluent/fluentd:v1.3
# 創建daemonset控制器
[root@master01 test02]# kubectl apply -f test03.yaml
daemonset.apps/test-daemonset created
# 查看daemonset控制器的運行狀態
[root@master01 test02]# kubectl get daemonsets
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
test-daemonset 2 2 2 2 2 <none> 3m36s
(2)daemonset更新
Daemonset控制器也支持滾動更新(RollingUpdata)和刪除時更新(OnDelete)兩種更新策略,默認爲滾動更新;同時也支持使用maxUnavilabe屬性設置最大不可用pod資源數,也可使用minReadySeconds字段控制更新節奏。刪除更新是刪除相應節點pod後重建並更新爲新版本,滾動更新策略是一次刪除一個工作節點上的pod資源,待其新版本pod資源重建完成後再開始操作另外一個節點的pod資源。
# 更新鏡像
[root@master01 test02]# kubectl set image daemonsets test-daemonset filebeat=fluent/fluentd
daemonset.extensions/test-daemonset image updated
5、job控制器
Job控制器用於調配pod對象運行一次性任務,容器中的進程在正常運行結束後不會對其進行重啓操作,而是將pod對象置於“Completed”狀態。
Job控制器的對象有兩種分別是單工作隊列的串行job和多工作隊列的並行式job。
(1)定義創建job控制器
Job控制器spec字段內嵌的必要字段僅爲templte;並且job控制器屬於API羣組”batch/v1”內。
# 定義一個job
[root@master01 test02]# cat test04.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: test-job
spec:
template:
spec:
containers:
- name: test-job
image: alpine
command: ["/bin/sh","-c","sleep 120"]
restartPolicy: Never
# 創建job控制器
[root@master01 test02]# kubectl apply -f test04.yaml
job.batch/test-job created
# 查看job控制器
[root@master01 test02]# kubectl get job test-job
NAME COMPLETIONS DURATION AGE
test-job 0/1 11s 11s
(2)並行式job
將job.spec.parallelism字段屬性值設置爲1,並設置任務數字段” job.spec.completions”屬性值,便能夠讓pod控制器以串行方式運行多任務;如果設置job.spec.parallelism屬性值大於等於2,且job.spec.completions的屬性值爲1,則爲並行任務,job.spec.completions的屬性值大於等於2則爲串行多任務。
# 定義一個串行多任務的job控制器
[root@master01 test02]# cat test05.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: test-job2
spec:
parallelism: 3
completions: 5
template:
spec:
containers:
- name: test-job2
image: alpine
command: ["/bin/sh","-c","sleep 120"]
restartPolicy: Never
(3)job控制器擴容
Job控制器的job.spec.parallelism字段屬性值表示同時運行的pod的對象數,此屬性值支持運行時調整來改變運行的pod數量,實現擴容和縮容。
# 對job控制器控制的pod進行縮容
[root@master01 test02]# kubectl scale jobs test-job2 --replicas=1
kubectl scale job is DEPRECATED and will be removed in a future version.
job.batch/test-job2 scaled
(4)刪除job
Job控制器控制的pod運行結束後,用戶可根據自己需求刪除或保留;如果,某些控制器的應用無法正常結束運行,restartPolicy又定義爲重啓(值爲OnFailure或者Always)。對此job控制器提供了兩個屬性用於抑制這種情況發生:
job.spec.activeDeadlineSeconds:用於爲其指定最大活動時間的長度,超出將被終止
job.spec.backoffLimit:將作業標記爲失敗狀態之前的重試次數,默認爲6
6、CronJob控制器
CronJob控制器用於管理Job控制器資源的運行時間,CronJob控制器可以控制pod週期性的執行一些任務,有點類似於linux定時任務。
創建CronJob控制器時spec字段可嵌套的主要字段有:
1)jobTemplate:必選字段;Job控制器模板,用於爲CronJob控制器生成Job對象。
2)schedule:必選字段,爲cron格式的作業調度運行的時間點。
3)concurrencyPolicy:併發執行策略,定義前一次作業運行未完成時是否以及如何運行後一次作業,值有”Allow”和”Forbid”。
4)failedJobHistoryLimit:爲失敗的任務執行保留的歷史記錄數
5)successfulJobHistoryLimit:爲成功的任務執行保留的歷史記錄數。
6)startingDeadlineSeconds:因各種原因缺乏執行作業的時間點所導致的啓動作業錯誤的超長時間,會被記入錯誤的歷史記錄
7)suspend:是否掛起後續的任務執行,默認爲false
# cronjob控制器資源定義
[root@master01 test02]# cat test06.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: test-cronjob
labels:
app: cronjob
spec:
schedule: "*/3 * * * *"
jobTemplate:
metadata:
labels:
app: cronjob-test
spec:
parallelism: 3
template:
spec:
containers:
- name: testcronjob
image: alpine
command:
- /bin/sh
- -c
- date; echo hello k8s; sleep 30
restartPolicy: OnFailure
# 創建crontab控制器並查看其運行狀態
[root@master01 test02]# kubectl apply -f test06.yaml
cronjob.batch/test-cronjob created
[root@master01 test02]# kubectl get cronjobs test-cronjob
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
test-cronjob */3 * * * * False 0 <none> 18s
查看狀態時各字段的含義如下:SCHEDULE爲調度的時間點,SUSPEND代表後續任務是否處於掛起狀態,ACTIVE表示活動狀態的job對象的數量,LAST SCHEDULE表示上次調度運行至此刻的時長。
7、Pod中斷預算
Pod中斷預算(PBD)類型的資源用於爲自願的中斷做好預算方案,限制可自願中斷的最大Pod副本數量或確保最少可用的Pod副本數,以確保服務的高可用。
自願中斷:由於用戶特地執行的管理操作導致的pod中斷
非自願中斷:由不可控外界因素導致的Pod中斷退出的操作。
部署在在kubernetes的每個應用程序都可以創建一個對應的PDB對象以限制自願中斷時最大可以中斷的副本數量或最少應該保持可用的副本數量,從而保證應用自身的高可用。支持PDB的pod控制器類型主要包括Deployment,ReplicaSet和statefulSet等。
定義PDB資源時,其spec字段主要嵌套的字段有:
1)Select:當前PDB對象使用的標籤選擇器,一般與相關的pod控制器使用同一個選擇器。
2)minAvailabel:Pod自願中斷的場景中,至少要保證可用的Pod對象數量或比例。
3)maxUnavailable:Pod自願中斷場景中,最多可轉化爲不可用狀態的pod對象數量或比例。
# 定義一個pdb資源對象,對deployment控制器test-deploy創建的pod對象設置中斷預算。
[root@master01 test02]# cat test07.yaml
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: test-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: test-deploy
# 創建並查看創建的pdb
[root@master01 test02]# kubectl apply -f test07.yaml
poddisruptionbudget.policy/test-pdb created
[root@master01 test02]# kubectl get pdb
NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
test-pdb 2 N/A 3 20s