內容摘要
創建rc
分析rc特性
在上一章講解Pod時曾提到Pod重啟機制,由於健康檢查由節點上的Kubelet控制,因此當節點出問題時,Pod不能重啟。要克服這一問題,必須使用K8S的副本控制器,K8S有多種控制器資源,ReplicationController是比較典型的一種。為了方便,簡稱rc。rc可以控制Pod的重啟,如果Pod所在節點出問題,它會在其他節點創建新的Pod,從而大大提高容器可用性。
下面我們通過實驗來學習該控制器。
測試環境
構建兩節點K8S集群。
kubeadm join 172.18.152.19:6443 --token j8xjt9.mdvgkhbte5inx8cg --discovery-token-ca-cert-hash sha256:6a913bc97e1750e0267dcc8ca8166d5954a04c97a67e2253fcb42f379f7e2f73
構建測試鏡像
Dockerfile內容如下:
FROM node:7 ADD app.js /app.js ENTRYPOINT ["node", "app.js"]
app.js文件內容如下:
const http = require('http'); const os = require('os'); console.log("rc server starting..."); var handler = function(request, response) { console.log("Received request from " + request.connection.remoteAddress); response.writeHead(200); response.end("You've hit " + os.hostname() + "\n"); }; var www = http.createServer(handler); www.listen(8080);
構建鏡像,名稱為rc_image,並上傳到倉庫中。
創建第1個rc
創建rc配置文件,內容如下:
apiVersion: v1 kind: ReplicationController metadata: name: rctest spec: replicas: 3 selector: app: rc template: metadata: labels: app: rc spec: containers: - name: rcimage image: huqianakls/rc_image:latest ports: - containerPort: 8080
說明:
1、kind為ReplicationController,Replication中文就是副本的意思,它是K8S中的資源,和Pod一樣;
2、第1個spec下的replicas為3,表示要啟動3個Pod,replicas參數指定副本數量;
3、第1個spec下的selector是標籤選擇器,用於匹配rc控制的Pod,凡是具有該標籤的Pod受到rc的控制;
4、template是Pod的模板,下面的metadata是元數據,labels就是Pod的標籤,該標籤和selector下的標籤一致。實際上selector不用設置標籤選擇器也可以,K8S會自動提取template下的標籤設置到標籤選擇器中;
5、template下的spec描述的是容器配置,其實就是Pod的配置;
下面創建該rc,命令仍然是 kubectl create -f。為了快速創建,可以先使用docker pull在工作節點中拉取rc文件中用到的鏡像。
創建成功後查詢該rc,命令為:
kubectl get rc
查詢方法和Pod基本一樣,只需要把查詢的資源類型修改為rc即可,其他K8S資源也一樣。
結果如下圖:
說明:
1、DESIRED表示需要多少個副本,在rc中我們配置的是3個;
2、CURRENT表示啟動了多少個Pod;
3、READY表示可以使用的Pod數量;
查詢詳情,命令為:
kubectl describe rc rctest
結果如下:
說明:
1、Pods Status行說明了受該rc控制的Pod狀態;
2、Events屬性可以看出創建了3個Pod;
使用另一種方式查詢詳情,結果如下:
[root@docker ~]# kubectl get rc rctest -o yaml apiVersion: v1 kind: ReplicationController metadata: creationTimestamp: 2019-09-26T07:16:35Z generation: 1 labels: app: rc name: rctest namespace: default resourceVersion: "3192" selfLink: /api/v1/namespaces/default/replicationcontrollers/rctest uid: 93285219-e02d-11e9-b790-00163e0cba89 spec: replicas: 3 selector: app: rc template: metadata: creationTimestamp: null labels: app: rc spec: containers: - image: huqianakls/rc_image:latest imagePullPolicy: Always name: rcimage ports: - containerPort: 8080 protocol: TCP resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 status: availableReplicas: 3 fullyLabeledReplicas: 3 observedGeneration: 1 readyReplicas: 3 replicas: 3 [root@docker ~]#
說明:
注意status下的屬性,availableReplicas表示可用副本數量;readyReplicas表示準備好的副本數量;
查詢Pod,結果如下:
說明:在NAME列,可以看到有3個POD,以rc名字開頭,後面使用隨機字符串。
選一個Pod查詢詳情,結果如下:
[root@docker ~]# kubectl get pod rctest-b976d -o yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: 2019-09-26T07:16:35Z generateName: rctest- labels: app: rc name: rctest-b976d namespace: default ownerReferences: - apiVersion: v1 blockOwnerDeletion: true controller: true kind: ReplicationController name: rctest uid: 93285219-e02d-11e9-b790-00163e0cba89 resourceVersion: "3191" selfLink: /api/v1/namespaces/default/pods/rctest-b976d uid: 932a0d34-e02d-11e9-b790-00163e0cba89 spec: containers: - image: huqianakls/rc_image:latest imagePullPolicy: Always name: rcimage ports: - containerPort: 8080 protocol: TCP resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: default-token-zr4wn readOnly: true dnsPolicy: ClusterFirst nodeName: worker restartPolicy: Always schedulerName: default-scheduler securityContext: {} serviceAccount: default serviceAccountName: default terminationGracePeriodSeconds: 30 tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 300 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 300 volumes: - name: default-token-zr4wn secret: defaultMode: 420 secretName: default-token-zr4wn status: conditions: - lastProbeTime: null lastTransitionTime: 2019-09-26T07:16:35Z status: "True" type: Initialized - lastProbeTime: null lastTransitionTime: 2019-09-26T07:16:49Z status: "True" type: Ready - lastProbeTime: null lastTransitionTime: 2019-09-26T07:16:35Z status: "True" type: PodScheduled containerStatuses: - containerID: docker://fba728bc118d3576d507f7ecc2f91e241730581787b928f225c6346011985a91 image: huqianakls/rc_image:latest imageID: docker-pullable://huqianakls/rc_image@sha256:585a53a3a8a13362920f7e6691779ee23ae3c8aec26e3ee41d2c1a3754d571f2 lastState: {} name: rcimage ready: true restartCount: 0 state: running: startedAt: 2019-09-26T07:16:49Z hostIP: 172.18.152.20 phase: Running podIP: 192.168.171.67 qosClass: BestEffort startTime: 2019-09-26T07:16:35Z
說明:注意generateName屬性,該屬性和rc名字一樣;
rc特性分析
下面通過實驗分析下rc的相關特性:
1、刪除其中一個Pod,觀察是否會啟動新的Pod
上面rc創建了三個Pod,現在刪除名稱為rctest-b976d的Pod,命令為:
kubectl delete pod rctest-b976d
刪除後查詢Pod,如下圖:
從上面的結果可以看出,容器停止了rctest-b976d Pod,啟動另一個Pod rctest-lsjvr。在一段時間內出現了4個Pod,最終Pod數量還是變為3個。
2、修改其中1個Pod的標籤,觀察是否會啟動新的Pod
我們修改前面實驗啟動的Pod: rctest-lsjvr,將metadata下的labels屬性刪除,命令為:
kubectl edit pod rctest-lsjvr
查詢Pod,結果如下:
出現了4個Pod。
原因在於:rc使用標籤和Pod匹配,如果Pod刪除了標籤,那麼和rc匹配的Pod數量少了1個,因此會啟動1個新Pod以達到rc要求的副本數量。
這種做法可以將Pod從rc控制器移出。
3、基於上面實驗,我們將刪除標籤的Pod添加上原有的標籤,觀察Pod數量的變化
可以看到,新建的Pod狀態變為Terminating,原因在於此時有4個Pod匹配rc的標籤,副本數量多了,因此要停止一個Pod。
4、給其中1個Pod,增加標籤,觀察Pod數量變化
增加標籤,命令為:
kubectl label pod rctest-lsjvr version=v1.0
可以看到Pod數量沒有發生變化,而且也沒有出現Pod停止和啟動行為。
可見,新增標籤不會影響rc,rc只關心自己在Pod選擇器中使用的標籤。
5、修改rc中的Pod選擇器,觀察Pod的變化
這個結果顯而易見,由於先前的Pod和rc無法匹配,rc會啟動3個Pod,先前的Pod不再受rc的約束。
6、在rc中的template屬性下增加新的Pod標籤,觀察Pod是否有變化
使用kubectl edit rc命令修改rctest,使用--show-labels參數查詢Pod,結果如下:
所有pod的label沒有發生任何變化。
下面我們刪除最後一行的Pod,查詢結果如下:
新建了一個Pod,並且標籤發生了變化,增加了我們新增的標籤。
可見,在給rc的Pod模板增加標籤的時候,如果不新建Pod,那麼Pod不會發生變化。
7、刪除節點,觀察Pod變化
先查詢下Pod在哪些節點上,命令為:
kubectl get pod -o wide
結果如下:
注意NODE列,3個Pod全在worker節點上。
現在我們刪除該節點,觀察Pod的變化,命令為:
kubectl delete node worker
查詢Pod,結果如下:
可以看到,Pod重新在控制節點上運行起來了,NODE列顯示的是控制節點名稱。
實驗
1、創建rc;
2、將rc特性分析中的7個實驗自己做一遍;