前言在上文Kubernetes Pod操作篇介紹了kubernetes的核心組件Pod,本文繼續(xù)介紹kubernetes的副本機(jī)制,正是因?yàn)楦北緳C(jī)制你的部署能自動(dòng)保待運(yùn)行,并且保持健康,無(wú)須任何手動(dòng)干預(yù)。 探針kubernetes可以通過(guò)存活探針(liveness probe)檢查容器是否還在運(yùn)行??梢詾閜od中的每個(gè)容器單獨(dú)指定存活探針;如果探測(cè)失敗,kubernetes將定期執(zhí)行探針并重新啟動(dòng)容器; kubernetes有以下三種探測(cè)容器的機(jī)制: - HTTP GET探針對(duì)容器的IP地址執(zhí)行HTTP GET請(qǐng)求;
- TCP套接字探針嘗試與容器指定端口建立TCP連接;
- Exec探針在容器內(nèi)執(zhí)行任意命令,并檢查命令的退出狀態(tài)碼。
1.準(zhǔn)備鏡像 1.1 準(zhǔn)備App.js 為了測(cè)試探針的作用,需要準(zhǔn)備新的鏡像;在之前的服務(wù)中稍作改動(dòng),在第五個(gè)請(qǐng)求之后,給每個(gè)請(qǐng)求返回HTTP狀態(tài)碼500(Internal Server Error),app.js做如下改動(dòng): const http = require('http');const os = require('os');console.log("kubia server is starting...");var requestCount = 0;var handler = function(request,response){ console.log("Received request from " + request.connection.remoteAddress); requestCount++; if (requestCount > 5) { response.writeHead(500); response.end("I'm not well. Please restart me!"); return; } response.writeHead(200); response.end("You've hit " + os.hostname()+"\n");};var www = http.createServer(handler);www.listen(8080);
requestCount記錄請(qǐng)求的次數(shù),大于5次直接返回500狀態(tài)碼,這樣探針可以捕獲狀態(tài)碼進(jìn)行服務(wù)器重啟; 1.2 構(gòu)建鏡像 [root@localhost unhealthy]# docker build -t kubia-unhealthy .Sending build context to Docker daemon 3.584kBStep 1/3 : FROM node:7 ---> d9aed20b68a4Step 2/3 : ADD app.js /app.js ---> e9e1b44f8f54Step 3/3 : ENTRYPOINT ["node","app.js"] ---> Running in f58d6ff6bea3Removing intermediate container f58d6ff6bea3 ---> d36c6390ec66Successfully built d36c6390ec66Successfully tagged kubia-unhealthy:latest
通過(guò)docker build構(gòu)建kubia-unhealthy鏡像 1.3 推送鏡像 [root@localhost unhealthy]# docker tag kubia-unhealthy ksfzhaohui/kubia-unhealthy[root@localhost unhealthy]# docker loginAuthenticating with existing credentials...WARNING! Your password will be stored unencrypted in /root/.docker/config.json.Configure a credential helper to remove this warning. Seehttps://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded[root@localhost unhealthy]# docker push ksfzhaohui/kubia-unhealthyThe push refers to repository [docker.io/ksfzhaohui/kubia-unhealthy]40d9e222a827: Pushed ......latest: digest: sha256:5fb3ebeda7f98818bc07b2b1e3245d6a21014a41153108c4dcf52f2947a4dfd4 size: 2213
首先給鏡像附加標(biāo)簽,然后登錄docker hub,最后推送到docker hub:
2.探針實(shí)戰(zhàn) 2.1 Http探針YAML文件 創(chuàng)建YAML描述文件,指定了一個(gè)Http Get存活探針,告訴Kubernetes定期在端口路徑下執(zhí)行Http Get請(qǐng)求,以確定容器是否健康; apiVersion: v1kind: Podmetadata: name: kubia-livenessspec: containers: - image: ksfzhaohui/kubia-unhealthy name: kubia livenessProbe: httpGet: path: / port: 8080
2.2 創(chuàng)建Pod [d:\k8s]$ kubectl create -f kubia-liveness-probe.yamlpod/kubia-liveness created[d:\k8s]$ kubectl get podsNAME READY STATUS RESTARTS AGEkubia-liveness 0/1 ContainerCreating 0 3s
創(chuàng)建名稱為kubia-liveness的Pod,查看的RESTARTS為0,隔一段時(shí)間再次觀察: [d:\k8s]$ kubectl get podsNAME READY STATUS RESTARTS AGEkubia-liveness 1/1 Running 2 4m
觀察可以發(fā)現(xiàn)此時(shí)的RESTARTS=2,表示重啟了2次,因?yàn)槊看翁綔y(cè)都會(huì)發(fā)送http請(qǐng)求,而服務(wù)在接收5次請(qǐng)求之后會(huì)返回500狀態(tài)碼,Kubernetes探測(cè)之后就會(huì)重啟容器; 2.3 Pod探針描述 [d:\k8s]$ kubectl describe po kubia-livenessName: kubia-liveness...... State: Running Started: Mon, 23 Dec 2019 15:42:45 +0800 Last State: Terminated Reason: Error Exit Code: 137 Started: Mon, 23 Dec 2019 15:41:15 +0800 Finished: Mon, 23 Dec 2019 15:42:42 +0800 Ready: True Restart Count: 2 Liveness: http-get http://:8080/ delay=0s timeout=1s period=10s #success=1 #failure=3......Events: Type Reason Age From Message ---- ------ ---- ---- ------- ...... Warning Unhealthy 85s (x9 over 5m5s) kubelet, minikube Liveness probe failed: HTTP probe failed with statuscode: 500 Normal Killing 85s (x3 over 4m45s) kubelet, minikube Container kubia failed liveness probe, will be restarted......
State:當(dāng)前狀態(tài)是運(yùn)行中; Last State:最后的狀態(tài)是終止,原因是出現(xiàn)了錯(cuò)誤,退出代碼為137有特殊的含義:表示該進(jìn)程由外部信號(hào)終止,數(shù)字137是兩個(gè)數(shù)字的總和:128+x, 其中x是終止進(jìn)程的信號(hào)編號(hào),這里x=9是SIGKILL的信號(hào)編號(hào),意味著這個(gè)進(jìn)程被強(qiáng)行終止; Restart Count:重啟的次數(shù); Liveness:存活探針的附加信息,delay(延遲)、timeout(超時(shí))、period(周期);大致意思就是開(kāi)始探測(cè)延遲為0秒,探測(cè)超時(shí)時(shí)間為1秒,每隔10秒檢測(cè)一次,探測(cè)連續(xù)失敗三次重啟容器;定義探針時(shí)可以自定義這些參數(shù),比如initialDelaySeconds設(shè)置初始延遲等; Events:列出了發(fā)生的事件,比如探測(cè)到失敗,殺進(jìn)程,重啟容器等; 3.探針總結(jié) 首先生產(chǎn)環(huán)境運(yùn)行的pod一定要配置探針;其次探針一定要檢查程序的內(nèi)部,不受外部因數(shù)影響比如外部服務(wù),數(shù)據(jù)庫(kù)等;最后就是探針應(yīng)該足夠輕量。 以上方式創(chuàng)建的pod,kubernetes在使用探針發(fā)現(xiàn)服務(wù)不可能就會(huì)重啟服務(wù),這項(xiàng)任務(wù)由承載pod的節(jié)點(diǎn)上的Kubelet執(zhí)行,在主服務(wù)器上運(yùn)行的Kubernetes Control Plane組件不會(huì)參與此過(guò)程;但如果節(jié)點(diǎn)本身崩潰,由于Kubelet本身運(yùn)行在節(jié)點(diǎn)上,所以如果節(jié)點(diǎn)異常終止,它將無(wú)法執(zhí)行任何操作,這時(shí)候就需要ReplicationController或類似機(jī)制管理pod。 ReplicationControllerReplicationController是一種kubernetes資源,可確保它的pod始終保持運(yùn)行狀態(tài);如果pod因任何原因消失(包括節(jié)點(diǎn)崩潰),則ReplicationController會(huì)重新創(chuàng)建Pod; ReplicationController會(huì)持續(xù)監(jiān)控正在運(yùn)行的pod列表,是確保pod的數(shù)量始終與其標(biāo)簽選擇器匹配,一個(gè)ReplicationController有三個(gè)主要部分: - label selector(標(biāo)簽選擇器),用于確定ReplicationController作用域中有哪些pod;
- replica count(副本個(gè)數(shù)),指定應(yīng)運(yùn)行的pod數(shù)量;
- pod template(pod模板),用于創(chuàng)建新的pod副本。
以上三個(gè)屬性可以隨時(shí)修改,但是只有副本個(gè)數(shù)修改對(duì)當(dāng)前pod會(huì)有影響,比如當(dāng)前副本數(shù)量減少了,那當(dāng)前pod有可能會(huì)被刪除;ReplicationController提供的好處: - 確保一個(gè)pod(或多個(gè)pod副本)持續(xù)運(yùn)行,失敗重啟新pod;
- 集群節(jié)點(diǎn)發(fā)生故障時(shí),它將為故障節(jié)點(diǎn)上運(yùn)行的所有pod創(chuàng)建副本;
- 輕松實(shí)現(xiàn)pod的水平伸縮。
1.創(chuàng)建ReplicationController apiVersion: v1kind: ReplicationControllermetadata: name: kubiaspec: replicas: 3 selector: app: kubia template: metadata: labels: app: kubia spec: containers: - name: kubia image: ksfzhaohui/kubia ports: - containerPort: 8080
指定了類型為ReplicationController,名稱為kubia;replicas設(shè)置副本為3,selector為標(biāo)簽選擇器,template為pod創(chuàng)建的模版,三個(gè)要素都指定了,執(zhí)行創(chuàng)建命令: [d:\k8s]$ kubectl create -f kubia-rc.yamlreplicationcontroller/kubia created[d:\k8s]$ kubectl get podsNAME READY STATUS RESTARTS AGEkubia-dssvz 1/1 Running 0 73skubia-krlcr 1/1 Running 0 73skubia-tg29c 1/1 Running 0 73s
創(chuàng)建完之后等一會(huì)執(zhí)行獲取pod列表可以發(fā)現(xiàn)創(chuàng)建了三個(gè)容器,刪除其中一個(gè),再次觀察: [d:\k8s]$ kubectl delete pod kubia-dssvzpod "kubia-dssvz" deleted[d:\k8s]$ kubectl get podsNAME READY STATUS RESTARTS AGEkubia-dssvz 1/1 Terminating 0 2m2skubia-krlcr 1/1 Running 0 2m2skubia-mgz64 1/1 Running 0 11skubia-tg29c 1/1 Running 0 2m2s
被刪除的pod結(jié)束中,新的pod已經(jīng)啟動(dòng),獲取有關(guān)ReplicationController的信息: [d:\k8s]$ kubectl get rcNAME DESIRED CURRENT READY AGEkubia 3 3 3 4m20s
期望3個(gè)副本,當(dāng)前3個(gè)副本,準(zhǔn)備好的也是3個(gè),更詳細(xì)的可以使用describe命令: [d:\k8s]$ kubectl describe rc kubiaName: kubiaNamespace: defaultSelector: app=kubiaLabels: app=kubiaAnnotations: Replicas: 3 current / 3 desiredPods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 FailedPod Template:......Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulCreate 5m20s replication-controller Created pod: kubia-dssvz Normal SuccessfulCreate 5m20s replication-controller Created pod: kubia-tg29c Normal SuccessfulCreate 5m20s replication-controller Created pod: kubia-krlcr Normal SuccessfulCreate 3m29s replication-controller Created pod: kubia-mgz64 Normal SuccessfulCreate 75s replication-controller Created pod: kubia-vwnmf
Replicas顯示副本期望數(shù)和當(dāng)前數(shù),Pods Status顯示每種狀態(tài)下的副本數(shù),最后的Events為發(fā)生的事件,測(cè)試一共刪除2個(gè)pod,可以看到一個(gè)創(chuàng)建了5個(gè)pod; 注:因?yàn)槭褂玫氖荕inikube,只有一個(gè)節(jié)點(diǎn)同時(shí)充當(dāng)主節(jié)點(diǎn)和工作節(jié)點(diǎn),節(jié)點(diǎn)故障無(wú)法模擬。 2.修改標(biāo)簽 通過(guò)更改pod的標(biāo)簽,可以將它從ReplicationController的作用域中添加或刪除: [d:\k8s]$ kubectl get pods --show-labelsNAME READY STATUS RESTARTS AGE LABELSkubia-mgz64 1/1 Running 0 27m app=kubiakubia-tg29c 1/1 Running 0 28m app=kubiakubia-vwnmf 1/1 Running 0 24m app=kubia[d:\k8s]$ kubectl label pod kubia-mgz64 app=foo --overwritepod/kubia-mgz64 labeled[d:\k8s]$ kubectl get pods --show-labelsNAME READY STATUS RESTARTS AGE LABELSkubia-4dzw8 0/1 ContainerCreating 0 2s app=kubiakubia-mgz64 1/1 Running 0 27m app=fookubia-tg29c 1/1 Running 0 29m app=kubiakubia-vwnmf 1/1 Running 0 25m app=kubia
可以發(fā)現(xiàn)初始創(chuàng)建的是三個(gè)Pod標(biāo)簽都是app=kubia,當(dāng)把kubia-mgz64的標(biāo)簽設(shè)置為foo之后就脫離了當(dāng)前ReplicationController的控制,這樣ReplicationController控制的副本就變成了2個(gè),所以會(huì)里面重新創(chuàng)建一個(gè)Pod;脫離控制的Pod還是照常運(yùn)行,除非我們手動(dòng)刪除; [d:\k8s]$ kubectl delete pod kubia-mgz64pod "kubia-mgz64" deleted[d:\k8s]$ kubectl get pods --show-labelsNAME READY STATUS RESTARTS AGE LABELSkubia-4dzw8 1/1 Running 0 20h app=kubiakubia-tg29c 1/1 Running 0 21h app=kubiakubia-vwnmf 1/1 Running 0 21h app=kubia
3.修改Pod模版 ReplicationController的pod模板可以隨時(shí)修改: [d:\k8s]$ kubectl edit rc kubia......replicationcontroller/kubia edited
使用如上命令即可,會(huì)彈出文本編輯器,修改Pod模版標(biāo)簽,如下所示: template: metadata: creationTimestamp: null labels: app: kubia type: special
添加新的標(biāo)簽type:special,保存退出即可;修改Pod模版之后并不影響現(xiàn)有的pod,只會(huì)影響重新創(chuàng)建的pod: [d:\k8s]$ kubectl get pods --show-labelsNAME READY STATUS RESTARTS AGE LABELSkubia-4dzw8 1/1 Running 0 21h app=kubiakubia-tg29c 1/1 Running 0 21h app=kubiakubia-vwnmf 1/1 Running 0 21h app=kubia[d:\k8s]$ kubectl delete pod kubia-4dzw8pod "kubia-4dzw8" deleted[d:\k8s]$ kubectl get pods --show-labelsNAME READY STATUS RESTARTS AGE LABELSkubia-6qrxj 1/1 Running 0 2m12s app=kubia,type=specialkubia-tg29c 1/1 Running 0 21h app=kubiakubia-vwnmf 1/1 Running 0 21h app=kubia
刪除一個(gè)pod,重新創(chuàng)建的pod有了新的標(biāo)簽; 4.水平縮放pod 通過(guò)文本編輯器來(lái)修改副本數(shù),修改spec.replicas為5 [d:\k8s]$ kubectl edit rc kubiareplicationcontroller/kubia edited[d:\k8s]$ kubectl get pods --show-labelsNAME READY STATUS RESTARTS AGE LABELSkubia-6qrxj 1/1 Running 0 9m49s app=kubia,type=specialkubia-9crmf 0/1 ContainerCreating 0 4s app=kubia,type=specialkubia-qpwbl 0/1 ContainerCreating 0 4s app=kubia,type=specialkubia-tg29c 1/1 Running 0 21h app=kubiakubia-vwnmf 1/1 Running 0 21h app=kubia
可以發(fā)現(xiàn)自動(dòng)創(chuàng)建了2個(gè)Pod,達(dá)到副本數(shù)5;通過(guò)kubectl scale重新修改為3: [d:\k8s]$ kubectl scale rc kubia --replicas=3replicationcontroller/kubia scaled[d:\k8s]$ kubectl get pods --show-labelsNAME READY STATUS RESTARTS AGE LABELSkubia-6qrxj 1/1 Running 0 15m app=kubia,type=specialkubia-tg29c 1/1 Running 0 22h app=kubiakubia-vwnmf 1/1 Running 0 21h app=kubia
5.刪除ReplicationController 通過(guò)kubectl delete刪除ReplicationController時(shí)默認(rèn)會(huì)刪除pod,但是也可以指定不刪除: [d:\k8s]$ kubectl delete rc kubia --cascade=falsereplicationcontroller "kubia" deleted[d:\k8s]$ kubectl get pods --show-labelsNAME READY STATUS RESTARTS AGE LABELSkubia-6qrxj 1/1 Running 0 103m app=kubia,type=specialkubia-tg29c 1/1 Running 0 23h app=kubiakubia-vwnmf 1/1 Running 0 23h app=kubia[d:\k8s]$ kubectl get rc kubiaError from server (NotFound): replicationcontrollers "kubia" not found
--cascade=false可以不刪除pod,只刪除ReplicationController ReplicaSetReplicaSet是新一代ReplicationController,將完全替代ReplicationController;ReplicaSet的行為與ReplicationController完全相同,但pod選擇器的表達(dá)能力更強(qiáng); 1.創(chuàng)建ReplicaSet apiVersion: apps/v1kind: ReplicaSetmetadata: name: kubiaspec: replicas: 3 selector: matchLabels: app: kubia template: metadata: labels: app: kubia spec: containers: - name: kubia image: ksfzhaohui/kubia
apiVersion指定為apps/v1:apps表示API組,v1表示實(shí)際的API版本;如果是在核心的API組中,API是可以不用指定的,比如之前的ReplicationController只需要指定v1; 其他定義基本和ReplicationController類似,除了在selector下使用了matchLabels選擇器; [d:\k8s]$ kubectl create -f kubia-replicaset.yamlreplicaset.apps/kubia created[d:\k8s]$ kubectl get pods --show-labelsNAME READY STATUS RESTARTS AGE LABELSkubia-6qrxj 1/1 Running 0 150m app=kubia,type=specialkubia-tg29c 1/1 Running 0 24h app=kubiakubia-vwnmf 1/1 Running 0 24h app=kubia[d:\k8s]$ kubectl get rsNAME DESIRED CURRENT READY AGEkubia 3 3 3 49s
創(chuàng)建完ReplicaSet之后,重新接管了原來(lái)的3個(gè)pod;更詳細(xì)的可以使用describe命令: [d:\k8s]$ kubectl describe rsName: kubiaNamespace: defaultSelector: app=kubiaLabels: Annotations: Replicas: 3 current / 3 desiredPods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 FailedPod Template: Labels: app=kubia Containers: kubia: Image: ksfzhaohui/kubia Port: Host Port: Environment: Mounts: Volumes: Events:
可以看到Events事件列表為空,當(dāng)前的3個(gè)pod都是接管的原來(lái)已經(jīng)創(chuàng)建的pod; 2.ReplicaSet標(biāo)簽選擇器 ReplicaSet相對(duì)于ReplicationController的主要改進(jìn)是它更具表達(dá)力的標(biāo)簽選擇器; selector: matchExpressions: - key: app operator: In values: - kubia
ReplicaSet除了可以使用matchLabels,還可以使用功能更強(qiáng)大的matchExpressions;每個(gè)表達(dá)式都必須包含一個(gè)key、一個(gè)operator(運(yùn)算符)、可能還有一個(gè)values的列表,運(yùn)算符可以有: - In:Label的值必須與其中一個(gè)指定的values匹配;
- Notln:Label的值與任何指定的values不匹配;
- Exists:pod必須包含一個(gè)指定名稱的標(biāo)簽,使用此運(yùn)算符時(shí),不應(yīng)指定values字段;
- DoesNotExist:pod不得包含有指定名稱的標(biāo)簽,不應(yīng)指定values字段;
3.刪除ReplicaSet [d:\k8s]$ kubectl delete rs kubiareplicaset.apps "kubia" deleted[d:\k8s]$ kubectl get pods --show-labelsNo resources found in default namespace.
刪除ReplicaSet的同時(shí)會(huì)刪除其管理的pod; DaemonSetReplicationcontroller和ReplicaSet都用于在kubernetes集群上運(yùn)行部署特定數(shù)量的pod;而DaemonSet可以在所有集群節(jié)點(diǎn)上運(yùn)行一個(gè)pod,比如希望在每個(gè)節(jié)點(diǎn)上運(yùn)行日志收集器和資源監(jiān)控器;當(dāng)然也可以通過(guò)節(jié)點(diǎn)選擇器控制只有哪些節(jié)點(diǎn)運(yùn)行pod; 1.創(chuàng)建DaemonSet apiVersion: apps/v1kind: DaemonSetmetadata: name: ssd-monitorspec: selector: matchLabels: app: ssd-monitor template: metadata: labels: app: ssd-monitor spec: nodeSelector: disk: ssd containers: - name: main image: ksfzhaohui/kubia
準(zhǔn)備如上創(chuàng)建DaemonSet的YAML文件,以上屬性基本和ReplicaSet類似,除了nodeSelector也就是節(jié)點(diǎn)選擇器,指定了選擇disk=ssd標(biāo)簽; 的節(jié)點(diǎn)標(biāo)簽; [d:\k8s]$ kubectl create -f ssd-monitor-daemonset.yamldaemonset.apps/ssd-monitor created[d:\k8s]$ kubectl get dsNAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGEssd-monitor 0 0 0 0 0 disk=ssd 24s[d:\k8s]$ kubectl get pods --show-labelsNo resources found in default namespace.
創(chuàng)建完之后,并沒(méi)有給當(dāng)前節(jié)點(diǎn)創(chuàng)建pod,因?yàn)楫?dāng)前節(jié)點(diǎn)沒(méi)有指定disk=ssd標(biāo)簽; [d:\k8s]$ kubectl get nodeNAME STATUS ROLES AGE VERSIONminikube Ready master 8d v1.17.0[d:\k8s]$ kubectl label node minikube disk=ssdnode/minikube labeled[d:\k8s]$ kubectl get node --show-labelsNAME STATUS ROLES AGE VERSION LABELSminikube Ready master 8d v1.17.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disk=ssd,gpu=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=minikube,kubernetes.io/os=linux,node-role.kubernetes.io/master=[d:\k8s]$ kubectl get pods --show-labelsNAME READY STATUS RESTARTS AGE LABELSssd-monitor-84hxd 1/1 Running 0 31s app=ssd-monitor,controller-revision-hash=5dc77f567d,pod-template-generation=1
首先獲取當(dāng)前節(jié)點(diǎn)名稱為minikube,然后設(shè)置標(biāo)簽disk=ssd,這時(shí)候會(huì)自動(dòng)在當(dāng)前節(jié)點(diǎn)創(chuàng)建一個(gè)pod,因?yàn)樵趍inikube中只有一個(gè)節(jié)點(diǎn)不好在多個(gè)節(jié)點(diǎn)上模擬; 2.刪除pod和DaemonSet [d:\k8s]$ kubectl label node minikube disk=hdd --overwritenode/minikube labeled[d:\k8s]$ kubectl get pods --show-labelsNo resources found in default namespace.
修改節(jié)點(diǎn)minkube的標(biāo)簽,可以發(fā)現(xiàn)節(jié)點(diǎn)上的pod會(huì)自動(dòng)刪除,因?yàn)椴粷M足節(jié)點(diǎn)選擇器; [d:\k8s]$ kubectl delete ds ssd-monitordaemonset.apps "ssd-monitor" deleted[d:\k8s]$ kubectl get dsNo resources found in default namespace.
刪除DaemonSet也會(huì)一起刪除這些pod; JobReplicationController、ReplicaSet和DaemonSet會(huì)持續(xù)運(yùn)行任務(wù),永遠(yuǎn)達(dá)不到完成態(tài),這些pod中的進(jìn)程在退出時(shí)會(huì)重新啟動(dòng);kubernetes通過(guò)Job資源允許你運(yùn)行一種pod, 該pod在內(nèi)部進(jìn)程成功結(jié)束時(shí),不重啟容器,一旦任務(wù)完成,pod就被認(rèn)為處千完成狀態(tài); 在發(fā)生節(jié)點(diǎn)故障時(shí),該節(jié)點(diǎn)上由Job管理的pod,重新安排到其他節(jié)點(diǎn);如果進(jìn)程本身異常退出,可以將Job配置為重新啟動(dòng)容器; 1.創(chuàng)建Job 在創(chuàng)建Job前先準(zhǔn)備一個(gè)構(gòu)建在busybox的鏡像,該容器將調(diào)用sleep 命令兩分鐘: FROM busyboxENTRYPOINT echo "$(date) Batch job starting"; sleep 120; echo "$(date) Finished succesfully"
此鏡像已經(jīng)推送到docker hub:
apiVersion: batch/v1kind: Jobmetadata: name: batch-jobspec: template: metadata: labels: app: batch-job spec: restartPolicy: OnFailure containers: - name: main image: ksfzhaohui/batch-job
Job屬于batch API組,其中重要的屬性是restartPolicy默認(rèn)為Always表示無(wú)限期運(yùn)行,其他選項(xiàng)還有OnFailure或Never,表示進(jìn)程失敗重啟和不重啟; [d:\k8s]$ kubectl create -f exporter.yamljob.batch/batch-job created[d:\k8s]$ kubectl get jobNAME COMPLETIONS DURATION AGEbatch-job 0/1 7s 8s[d:\k8s]$ kubectl get podNAME READY STATUS RESTARTS AGEbatch-job-7sw68 1/1 Running 0 25s
創(chuàng)建Job,會(huì)自動(dòng)創(chuàng)建一個(gè)pod,pod中的進(jìn)程運(yùn)行2分鐘后會(huì)結(jié)束: [d:\k8s]$ kubectl get podNAME READY STATUS RESTARTS AGEbatch-job-7sw68 0/1 Completed 0 3m1s[d:\k8s]$ kubectl get jobNAME COMPLETIONS DURATION AGEbatch-job 1/1 2m11s 3m12s
可以發(fā)現(xiàn)pod狀態(tài)為Completed,同樣job的COMPLETIONS同樣為完成; 2.Job中運(yùn)行多個(gè)pod實(shí)例 作業(yè)可以配置為創(chuàng)建多個(gè)pod實(shí)例,并以并行或串行方式運(yùn)行它們;可以通過(guò)設(shè)置completions和parallelism屬性來(lái)完成; 2.1 順序運(yùn)行Job pod apiVersion: batch/v1kind: Jobmetadata: name: multi-completion-batch-jobspec: completions: 3 template: metadata: labels: app: multi-completion-batch-job spec: restartPolicy: OnFailure containers: - name: main image: ksfzhaohui/batch-job
completions設(shè)置為3,一個(gè)一個(gè)的運(yùn)行3個(gè)pod,所有完成整個(gè)job完成; [d:\k8s]$ kubectl get podNAME READY STATUS RESTARTS AGEmulti-completion-batch-job-h75j8 0/1 Completed 0 2m19smulti-completion-batch-job-wdhnj 1/1 Running 0 15s[d:\k8s]$ kubectl get jobNAME COMPLETIONS DURATION AGEmulti-completion-batch-job 1/3 2m28s 2m28s
可以看到完成一個(gè)pod之后會(huì)啟動(dòng)第二pod,所有都運(yùn)行完之后如下所示: [d:\k8s]$ kubectl get podNAME READY STATUS RESTARTS AGEmulti-completion-batch-job-4vjff 0/1 Completed 0 2m7smulti-completion-batch-job-h75j8 0/1 Completed 0 6m16smulti-completion-batch-job-wdhnj 0/1 Completed 0 4m12s[d:\k8s]$ kubectl get jobNAME COMPLETIONS DURATION AGEmulti-completion-batch-job 3/3 6m13s 6m18s
2.2 并行運(yùn)行Job pod apiVersion: batch/v1kind: Jobmetadata: name: multi-completion-parallel-batch-jobspec: completions: 3 parallelism: 2 template: metadata: labels: app: multi-completion-parallel-batch-job spec: restartPolicy: OnFailure containers: - name: main image: ksfzhaohui/batch-job
同時(shí)設(shè)置了completions和parallelism,表示job可以同時(shí)運(yùn)行兩個(gè)pod,其中任何一個(gè)執(zhí)行完成可以運(yùn)行第三個(gè)pod: [d:\k8s]$ kubectl create -f multi-completion-parallel-batch-job.yamljob.batch/multi-completion-parallel-batch-job created[d:\k8s]$ kubectl get podNAME READY STATUS RESTARTS AGEmulti-completion-parallel-batch-job-f7wn8 0/1 ContainerCreating 0 3smulti-completion-parallel-batch-job-h9s29 0/1 ContainerCreating 0 3s
2.3 限制Job pod完成任務(wù)的時(shí)間 在pod配置中設(shè)置activeDeadlineSeconds屬性,可以限制pod的時(shí)間;如果pod運(yùn)行時(shí)間超過(guò)此時(shí)間,系統(tǒng)將嘗試終止pod, 并將Job標(biāo)記為失??; apiVersion: batch/v1kind: Jobmetadata: name: time-limited-batch-jobspec: activeDeadlineSeconds: 30 template: metadata: labels: app: time-limited-batch-job spec: restartPolicy: OnFailure containers: - name: main image: ksfzhaohui/batch-job
指定activeDeadlineSeconds為30秒,超過(guò)30秒自動(dòng)失?。?/p> [d:\k8s]$ kubectl create -f time-limited-batch-job.yamljob.batch/time-limited-batch-job created[d:\k8s]$ kubectl get jobNAME COMPLETIONS DURATION AGEtime-limited-batch-job 0/1 3s 3s[d:\k8s]$ kubectl get podNAME READY STATUS RESTARTS AGEtime-limited-batch-job-jgmm6 1/1 Running 0 29s[d:\k8s]$ kubectl get podNAME READY STATUS RESTARTS AGEtime-limited-batch-job-jgmm6 1/1 Terminating 0 30s[d:\k8s]$ kubectl get podNo resources found in default namespace.[d:\k8s]$ kubectl get jobNAME COMPLETIONS DURATION AGEtime-limited-batch-job 0/1 101s 101s
可以觀察AGE標(biāo)簽下面的時(shí)間表示已經(jīng)運(yùn)行的時(shí)間,30秒之后pod狀態(tài)變成Terminating; 2.4 Job定期運(yùn)行 job也支持定期執(zhí)行,有點(diǎn)像quartz,也支持類似的quartz表達(dá)式: apiVersion: batch/v1beta1kind: CronJobmetadata: name: corn-batch-jobspec: schedule: "0-59 * * * *" jobTemplate: spec: template: metadata: labels: app: corn-batch-job spec: restartPolicy: OnFailure containers: - name: main image: ksfzhaohui/batch-job
指定schedule用來(lái)表示表達(dá)式分別是:分鐘,小時(shí),每個(gè)月中的第幾天,月,星期幾;以上配置表示每分鐘運(yùn)行一個(gè)job; [d:\k8s]$ kubectl create -f cronjob.yamlcronjob.batch/corn-batch-job created[d:\k8s]$ kubectl get podNAME READY STATUS RESTARTS AGEcorn-batch-job-1577263560-w2fq2 0/1 Completed 0 3m3scorn-batch-job-1577263620-92pc7 1/1 Running 0 2m2scorn-batch-job-1577263680-tmr8p 1/1 Running 0 62scorn-batch-job-1577263740-jmzqk 0/1 ContainerCreating 0 2s[d:\k8s]$ kubectl get jobNAME COMPLETIONS DURATION AGEcorn-batch-job-1577263560 1/1 2m5s 3m48scorn-batch-job-1577263620 1/1 2m4s 2m47scorn-batch-job-1577263680 0/1 107s 107scorn-batch-job-1577263740 0/1 47s 47s
每個(gè)一分鐘就運(yùn)行一個(gè)job,可以刪除CronJob [d:\k8s]$ kubectl delete CronJob corn-batch-jobcronjob.batch "corn-batch-job" deleted
總結(jié)本文繼續(xù)在閱讀Kubernetes in Action過(guò)程中,實(shí)際操作的筆記;主要介紹了相關(guān)的副本機(jī)制探針,ReplicationController,ReplicaSet,DaemonSet以及Job相關(guān)知識(shí)點(diǎn)。 參考Kubernetes in Action 博客地址https://github.com/ksfzhaohui/blog |