首頁>技術>

1. 深入學習控制器1.1 控制器概述

Pod是kubernetes所有執行應用或部署服務的基礎,可以看作是k8s中執行的機器人,應用單獨執行在Pod中不具備高階的特性,比如節點故障時Pod無法自動遷移,Pod多副本橫向擴充套件,應用滾動升級RollingUpdate等,因此Pod一般不會單獨使用,需要使用控制器來實現。

我們先看一個概念ReplicationController副本控制器,簡稱RC,副本控制是實現Pod高可用的基礎,其通過定義副本的副本數replicas,當執行的Pod數量少於replicas時RC會自動建立Pod,當Pod數量多於replicas時RC會自動刪除多餘的Pod,確保當前執行的Pod和RC定義的副本數保持一致。

副本控制器包括Deployment,ReplicaSet,ReplicationController,StatefulSet等。其中常用有兩個:Deployment和StatefulSet,Deployment用於無狀態服務,StatefulSet用於有狀態服務,ReplicaSet作為Deployment後端副本控制器,ReplicationController則是舊使用的副本控制器。

為了實現不同的功能,kubernetes中提供多種不同的控制器滿足不同的業務場景,可以分為四類:

Stateless application無狀態化應用,如Deployment,ReplicaSet,RC等;Stateful application有狀態化應用,需要儲存資料狀態,如資料庫,資料庫叢集;Node daemon節點支撐守護,適用於在所有或部分節點執行Daemon,如日誌,監控採集;Batch批處理任務,非長期執行服務,分為一次性執行Job和計劃執行CronJob兩種。

本文我們主要介紹無狀態服務副本控制器的使用,包括Deployment,ReplicaSet和ReplicationController。

1.2 Deployment

Deployment是實現無狀態應用副本控制器,其通過declarative申明式的方式定義Pod的副本數,Deployment的副本機制是通過ReplicaSet實現,replicas副本的管理通過在ReplicaSet中新增和刪除Pod,RollingUpdate通過新建ReplicaSet,然後逐步移除和新增ReplicaSet中的Pod數量,從而實現滾動更新,使用Deployment的場景如下:

滾動升級RollingUpdate,後臺通過ReplicaSet實現多副本replicas實現,增加副本(高負載)或減少副本(低負載)應用回滾Rollout,版本更新支援回退1.2.1 Deployment定義

1. 我們定義一個Deployment,副本數為3,Pod以模版Template的形式封裝在Deployment中,為了結合之前Pod學習內容,我們增加了resource和健康檢查的定義,具體實現參考前面介紹的文章。

[root@node-1 happylau]# cat deployment-demo.yaml apiVersion: apps/v1kind: Deploymentmetadata: #Deployment的元資料資訊,包含名字,標籤 name: deployment-nginx-demo labels: app: nginx rc: deployment annotations: kubernetes.io/replicationcontroller: Deployment kubernetes.io/description: "ReplicationController Deployment Demo"spec: replicas: 3 #副本數量,包含有3個Pod副本 selector: #標籤選擇器,選擇管理包含指定標籤的Pod matchLabels: app: nginx rc: deployment template: #如下是Pod的模板定義,沒有apiVersion,Kind屬性,需包含metadata定義 metadata: #Pod的元資料資訊,必須包含有labels labels: app: nginx rc: deployment spec: #spec指定容器的屬性資訊 containers: - name: nginx-deployment image: nginx:1.7.9 imagePullPolicy: IfNotPresent ports: #容器埠資訊 - name: http-80-port protocol: TCP containerPort: 80 resources: #資源管理,requests請求資源,limits限制資源 requests: cpu: 100m memory: 128Mi limits: cpu: 200m memory: 256Mi livenessProbe: #健康檢查器livenessProbe,存活檢查 httpGet: path: /index.html port: 80 scheme: HTTP initialDelaySeconds: 3 periodSeconds: 5 timeoutSeconds: 2 readinessProbe: #健康檢查器readinessProbe,就緒檢查 httpGet: path: /index.html port: 80 scheme: HTTP initialDelaySeconds: 3 periodSeconds: 5 timeoutSeconds: 2

Deployment欄位說明:

deployment基本屬性,包括apiVersion,Kind,metadata和spec,其中,deployment.metdata指定名稱和標籤內容,deployment.spec指定部署組的屬性資訊;deployment屬性資訊包含有replicas,Selector和template,其中replicas指定副本數目,Selector指定管理的Pod標籤,template為定義Pod的模板,Deployment通過模板建立Pod;deployment.spec.template為Pod定義的模板,和Pod定義不太一樣,template中不包含apiVersion和Kind屬性,要求必須有metadata,deployment.spec.template.spec為容器的屬性資訊,其他定義內容和Pod一致。

2. 生成Deployment,建立時加一個--record引數,會在annotation中記錄deployment.kubernetes.io/revision版本

[root@node-1 happylau]# kubectl apply -f deployment-demo.yaml --recorddeployment.apps/deployment-nginx-demo created

3. 檢視Deployment列表,執行時自動下載映象,如下已運行了3個副本

[root@node-1 happylau]# kubectl get deployments deployment-nginx-demo NAME READY UP-TO-DATE AVAILABLE AGEdeployment-nginx-demo 3/3 3 3 2m37sNAME代表名稱,metadata.name欄位定義READY代表Pod的健康狀態,前面值是readiness,後面是livenessUP-TO-DATE代表更新,用於滾動升級AVAILABLE代表可用AGE建立至今執行的時長

4. 檢視Deployment的詳情,可以看到Deployment通過一個deployment-nginx-demo-866bb6cf78 replicaset副本控制器控制Pod的副本數量

Deployment詳情資訊

5. 檢視replicaset的詳情資訊,通過Events可檢視到deployment-nginx-demo-866bb6cf78建立了三個Pod

ReplicaSet詳情資訊

6. 檢視Pod詳情,最終通過Pod定義的模版建立container,資源定義,健康檢查等包含在Pod定義的模版中

Pod詳情資訊

通過上面的實戰演練我們可得知Deployment的副本控制功能是由replicaset實現,replicaset生成Deployment中定義的replicas副本的數量,即建立多個副本,如下圖所示:

Deployment建立結構示意圖

1.2.2 Deployment擴容

當業務比較繁忙時可以通過增加副本數,增加副本數是通過yaml檔案中的replicas控制的,當設定了replias後,Deployment控制器會自動根據當前副本數目建立所需的Pod數,這些pod會自動加入到service中實現負載均衡,相反減少副本數,這些pod會自動從service中刪除。

Deployment擴容

1. 將deployment的副本數擴容至4個,可通過修改yaml檔案的replicas個數或者通過scale命令擴充套件。

[root@node-1 ~]# kubectl scale --replicas=4 deployment deployment-nginx-demo deployment.extensions/deployment-nginx-demo scaled

2. 檢視Deployment副本數量,已增加至4個副本

[root@node-1 ~]# kubectl get deploymentsNAME READY UP-TO-DATE AVAILABLE AGEdeployment-nginx-demo 4/4 4 4 77m

3. 副本的擴容是如何實現的呢?我們檢視replicaset的詳情資訊觀察,增加副本的個數是通過replicaset來擴容,通過模版複製新的Pod

Deployment擴充套件

4. 副本縮容

[root@node-1 ~]# kubectl scale --replicas=2 deployment deployment-nginx-demo deployment.extensions/deployment-nginx-demo scaled[root@node-1 ~]# kubectl get deployments deployment-nginx-demo NAME                    READY   UP-TO-DATE   AVAILABLE   AGEdeployment-nginx-demo   2/2     2            2           7h41m

Deployment減少副本

通過上面的操作演練我們可以得知:Deployment的擴容是通過ReplicaSet的模版建立Pod或刪除Pod實現,scale是手動擴充套件實現副本的機制,kubernetes還提供了另外一種副本自動擴容機制horizontalpodautoscalers(Horizontal Pod Autoscaling),即通過定義CPU的利用率實現自動的橫向擴充套件,由於需要依賴於監控元件,後續我們再做介紹。

1.2.3 滾動更新

Deployment支援滾動更新,預設建立Deployment後會增加滾動更新的策略,通過逐步替代replicas中的pod實現更新無服務中斷(需要結合service),如下圖所示:將一個deployment副本數為3的應用更新,先更新10.0.0.6 pod,更新pod應用,替換新的ip,然後加入到service中,以此類推再繼續更新其他pod,從而實現滾動更新,不影響服務的升級。

滾動更新

通過型別為:RollingUpdate,每次更新最大的數量maxSurge是replicas總數的25%,最大不可用的數量maxUnavailable為25%,如下是通過kubectl get deployments deployment-nginx-demo -o yaml檢視滾動更新相關的策略。

spec: progressDeadlineSeconds: 600 replicas: 3 revisionHistoryLimit: 10 selector: matchLabels: app: nginx rc: deployment strategy: #strategy定義的是升級的策略,型別為RollingUpdate rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate

1. 滾動更新是當pod.template中定義的相關屬性變化,如下將映象更新到1.9.1,通過--record會記錄操作命令

[root@node-1 ~]# kubectl set image deployments deployment-nginx-demo nginx-deployment=nginx:1.9.1 --recorddeployment.extensions/deployment-nginx-demo image updated

2. 檢視滾動升級的狀態(由於第一次nginx的映象寫錯了,容器下載映象失敗,寫成nignx,導致修改後有兩次record)

[root@node-1 happylau]# kubectl rollout status deployment deployment-nginx-demo deployment "deployment-nginx-demo" successfully rolled out檢視滾動升級版本,REVSISION代表版本號:[root@node-1 happylau]# kubectl rollout history deployment deployment-nginx-demo deployment.extensions/deployment-nginx-demo REVISION CHANGE-CAUSE1 <none>2 kubectl set image deployments deployment-nginx-demo nginx-deployment=nignx:1.9.1 --record=true3 kubectl set image deployments deployment-nginx-demo nginx-deployment=nignx:1.9.1 --record=true

3. 觀察Deployment的升級過程,新建立一個RS deployment-nginx-demo-65c8c98c7b,逐漸將舊RS中的pod替換,直至舊的RS deployment-nginx-demo-866bb6cf78上的副本數為0.

滾動升級原理

4. 檢視RS的列表,可以看到新的RS的副本數為2,其他RS副本數為0

[root@node-1 ~]# kubectl get replicasets NAME DESIRED CURRENT READY AGEdeployment-nginx-demo-65c8c98c7b 2 2 2 21m #新的RS,REVSION為3deployment-nginx-demo-6cb65f58c6 0 0 0 22m #映象寫錯的RS,REVISON為2deployment-nginx-demo-866bb6cf78 0 0 0 40m #舊的RS,對應REVSION為1

5. 測試版本升級是否成功

[root@node-1 ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESdeployment-nginx-demo-65c8c98c7b-bzql9 1/1 Running 0 25m 10.244.1.58 node-2 <none> <none>deployment-nginx-demo-65c8c98c7b-vrjhp 1/1 Running 0 25m 10.244.2.72 node-3 <none> <none>[root@node-1 ~]# curl -I http://10.244.2.72 HTTP/1.1 200 OKServer: nginx/1.9.1 #映象的版本成功更新Date: Mon, 28 Oct 2019 15:28:49 GMTContent-Type: text/htmlContent-Length: 612Last-Modified: Tue, 26 May 2015 15:02:09 GMTConnection: keep-aliveETag: "55648af1-264"Accept-Ranges: bytes1.2.4 版本回退

如果版本不符合預期,kubernetes提供回退的功能,和滾動更新一樣,回退的功能Deployment將替換到原始的RS上,即逐步將Pod的副本替換到舊的RS上.

1. 執行回滾,回退到REVISON版本為1

[root@node-1 ~]# kubectl rollout undo deployment deployment-nginx-demo --to-revision=1deployment.extensions/deployment-nginx-demo rolled back

2. 檢視Deployment的回退狀態和歷史版本

[root@node-1 ~]# kubectl rollout status deployment deployment-nginx-demo deployment "deployment-nginx-demo" successfully rolled out[root@node-1 ~]# kubectl rollout history deployment deployment-nginx-demo deployment.extensions/deployment-nginx-demo REVISION CHANGE-CAUSE2 kubectl set image deployments deployment-nginx-demo nginx-deployment=nignx:1.9.1 --record=true3 kubectl set image deployments deployment-nginx-demo nginx-deployment=nignx:1.9.1 --record=true4 <none>

3. 檢視Deployment的詳情,可以看到RS已經會退到原始的RS了

版本回退

4. 測試nginx的版本

[root@node-1 ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESdeployment-nginx-demo-866bb6cf78-9thtn 1/1 Running 0 3m42s 10.244.1.59 node-2 <none> <none>deployment-nginx-demo-866bb6cf78-ws2hx 1/1 Running 0 3m48s 10.244.2.73 node-3 <none> <none>#測試版本[root@node-1 ~]# curl -I http://10.244.1.59 HTTP/1.1 200 OKServer: nginx/1.7.9 #回退到1.7.9版本Date: Mon, 28 Oct 2019 15:36:07 GMTContent-Type: text/htmlContent-Length: 612Last-Modified: Tue, 23 Dec 2014 16:25:09 GMTConnection: keep-aliveETag: "54999765-264"Accept-Ranges: bytes

小結:通過上面的操作演練可知,Deployment是通過ReplicaSet實現Pod副本數的管理(擴容或減少副本數),滾動更新是通過新建RS,將Pod從舊的RS逐步更新到新的RS上;相反,回滾版本將會退到指定版本的ReplicaSet上。

1.3 ReplicaSet

ReplicaSet副本集簡稱RS,用於實現副本數的控制,通過上面的學習我們可以知道Deployment實際是呼叫ReplicaSet實現副本的控制,RS不具備滾動升級和回滾的特性,一般推薦使用Deployment,ReplicaSet的定義和Deployment差不多,如下:

1. 定義ReplicaSet

[root@node-1 happylau]# cat replicaset-demo.yaml apiVersion: extensions/v1beta1kind: ReplicaSetmetadata: name: replicaset-demo labels: controller: replicaset annotations: kubernetes.io/description: "Kubernetes Replication Controller Replication"spec: replicas: 3 #副本數 selector: #Pod標籤選擇器 matchLabels: controller: replicaset template: #建立Pod的模板 metadata: labels: controller: replicaset spec: #容器資訊 containers: - name: nginx-replicaset-demo image: nginx:1.7.9 imagePullPolicy: IfNotPresent ports: - name: http-80-port protocol: TCP containerPort: 80

2. 建立RS並檢視RS列表

[root@node-1 happylau]# kubectl apply -f replicaset-demo.yaml replicaset.extensions/replicaset-demo created[root@node-1 happylau]# kubectl get replicasets replicaset-demo NAME DESIRED CURRENT READY AGEreplicaset-demo 3 3 3 15s

3. 擴充套件副本數至4個

[root@node-1 happylau]# kubectl scale --replicas=4 replicaset replicaset-demo replicaset.extensions/replicaset-demo scaled[root@node-1 happylau]# kubectl get replicasets replicaset-demo NAME DESIRED CURRENT READY AGEreplicaset-demo 4 4 4 76s

4. 減少副本數至2個

[root@node-1 happylau]# kubectl scale --replicas=2 replicaset replicaset-demo replicaset.extensions/replicaset-demo scaled[root@node-1 happylau]# kubectl get replicasets replicaset-demo NAME DESIRED CURRENT READY AGEreplicaset-demo 2 2 2 114s

5. 映象版本升級,驗證得知不具備版本升級的能力

[root@node-1 happylau]# kubectl set image replicasets replicaset-demo nginx-replicaset-demo=nginx:1.9.1replicaset.extensions/replicaset-demo image updated #命令執行成功了

ReplicaSet驗證版本更新

ReplicaSet小結:通過上面的演示可以知道,RS定義和Deployment類似,能實現副本的控制,擴充套件和縮減,Deployment是更高層次的副本控制器,ReplicaSet主要為Deployment的副本控制器和滾動更新機制,ReplicaSet本身無法提供滾動更新的能力。

1.4 ReplicationController

ReplicationController副本控制器簡稱RC,是kubernetes中最早的副本控制器,RC是ReplicaSet之前的版本,ReplicationController提供副本控制能力,其定義方式和Deployment,ReplicaSet相類似,如下:

1. 定義ReplicationController

[root@node-1 happylau]# cat rc-demo.yaml apiVersion: v1 kind: ReplicationController metadata:  name: rc-demo   labels:    controller: replicationcontroller   annotations:    kubernetes.io/description: "Kubernetes Replication Controller Replication"spec:  replicas: 3  selector:     #不能使用matchLables字符集模式    controller: replicationcontroller   template:    metadata:      labels:        controller: replicationcontroller       spec:      containers:      - name: nginx-rc-demo         image: nginx:1.7.9        imagePullPolicy: IfNotPresent        ports:        - name: http-80-port          protocol: TCP          containerPort: 80

2. 生成RC並檢視列表

[root@node-1 happylau]# kubectl apply -f rc-demo.yaml replicationcontroller/rc-demo created[root@node-1 happylau]# kubectl get replicationcontrollers NAME      DESIRED   CURRENT   READY   AGErc-demo   3         3         3       103s#檢視詳情[root@node-1 happylau]# kubectl describe replicationcontrollers rc-demo Name:         rc-demoNamespace:    defaultSelector:     controller=replicationcontrollerLabels:       controller=replicationcontrollerAnnotations:  kubectl.kubernetes.io/last-applied-configuration:                {"apiVersion":"v1","kind":"ReplicationController","metadata":{"annotations":{"kubernetes.io/description":"Kubernetes Replication Controlle...              kubernetes.io/description: Kubernetes Replication Controller ReplicationReplicas:     3 current / 3 desiredPods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 FailedPod Template:  Labels:  controller=replicationcontroller  Containers:   nginx-rc-demo:    Image:        nginx:1.7.9    Port:         80/TCP    Host Port:    0/TCP    Environment:  <none>    Mounts:       <none>  Volumes:        <none>Events:  Type    Reason            Age   From                    Message  ----    ------            ----  ----                    -------  Normal  SuccessfulCreate  113s  replication-controller  Created pod: rc-demo-hm8s9  Normal  SuccessfulCreate  113s  replication-controller  Created pod: rc-demo-xnfht  Normal  SuccessfulCreate  113s  replication-controller  Created pod: rc-demo-lfhc9

3.副本擴容至4個

[root@node-1 happylau]# kubectl scale --replicas=4 replicationcontroller rc-demo replicationcontroller/rc-demo scaled[root@node-1 happylau]# kubectl get replicationcontrollers NAME      DESIRED   CURRENT   READY   AGErc-demo   4         4         4       3m23s 

4. 副本縮容至2個

[root@node-1 happylau]# kubectl scale --replicas=2 replicationcontroller rc-demo replicationcontroller/rc-demo scaled[root@node-1 happylau]# kubectl get replicationcontrollers NAME      DESIRED   CURRENT   READY   AGErc-demo   2         2         2       3m51s
寫在最後

本文介紹了kubernetes中三個副本控制器:Deployment,ReplicaSet和ReplicationController,當前使用最廣泛的是Deployment,ReplicaSet為Deployment提供滾動更新機制,RC當前是舊版的副本控制器,當前已廢棄,推薦使用Deployment控制器,具備副本控制器,擴充套件副本,縮減副本,滾動升級和回滾等高階能力。

參考文獻

Deployment:https://kubernetes.io/docs/concepts/workloads/controllers/deployment/

ReplicaSet:https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/

ReplicationController:https://kubernetes.io/docs/concepts/workloads/controllers/

當你的才華撐不起你的野心時,你就應該靜下心來學習

最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 開源專案:通過WP外掛搭建h5+應用檢測更新服務