K8S動手教程3.1:ReplicationController

內容摘要

創建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資源也一樣。

結果如下圖:

K8S動手教程3.1:ReplicationController

說明:

1、DESIRED表示需要多少個副本,在rc中我們配置的是3個;

2、CURRENT表示啟動了多少個Pod;

3、READY表示可以使用的Pod數量;

查詢詳情,命令為:

kubectl describe rc rctest

結果如下:

K8S動手教程3.1:ReplicationController

說明:

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,結果如下:

K8S動手教程3.1:ReplicationController

說明:在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,如下圖:

K8S動手教程3.1:ReplicationController

從上面的結果可以看出,容器停止了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,結果如下:

K8S動手教程3.1:ReplicationController

出現了4個Pod。

原因在於:rc使用標籤和Pod匹配,如果Pod刪除了標籤,那麼和rc匹配的Pod數量少了1個,因此會啟動1個新Pod以達到rc要求的副本數量。

這種做法可以將Pod從rc控制器移出。

3、基於上面實驗,我們將刪除標籤的Pod添加上原有的標籤,觀察Pod數量的變化

K8S動手教程3.1:ReplicationController

可以看到,新建的Pod狀態變為Terminating,原因在於此時有4個Pod匹配rc的標籤,副本數量多了,因此要停止一個Pod。

4、給其中1個Pod,增加標籤,觀察Pod數量變化

增加標籤,命令為:

kubectl label pod rctest-lsjvr version=v1.0
K8S動手教程3.1:ReplicationController

可以看到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,結果如下:

K8S動手教程3.1:ReplicationController

所有pod的label沒有發生任何變化。

下面我們刪除最後一行的Pod,查詢結果如下:

K8S動手教程3.1:ReplicationController

新建了一個Pod,並且標籤發生了變化,增加了我們新增的標籤。

可見,在給rc的Pod模板增加標籤的時候,如果不新建Pod,那麼Pod不會發生變化。

7、刪除節點,觀察Pod變化

先查詢下Pod在哪些節點上,命令為:

kubectl get pod -o wide

結果如下:

K8S動手教程3.1:ReplicationController

注意NODE列,3個Pod全在worker節點上。

現在我們刪除該節點,觀察Pod的變化,命令為:

kubectl delete node worker

查詢Pod,結果如下:

K8S動手教程3.1:ReplicationController

可以看到,Pod重新在控制節點上運行起來了,NODE列顯示的是控制節點名稱。

實驗

1、創建rc;

2、將rc特性分析中的7個實驗自己做一遍;


分享到:


相關文章: