kubernetes入門到實戰(九)Stateless控制器詳解

1. 深刻學習控制器

1.1 控制器概述

Pod是kubernetes全部運行應用或部署服務的基礎,能夠看做是k8s中運行的機器人,應用單獨運行在Pod中不具有高級的特性,好比節點故障時Pod沒法自動遷移,Pod多副本橫向擴展,應用滾動升級RollingUpdate等,所以Pod通常不會單獨使用,須要使用控制器來實現。html

kubernetes入門到實戰(九)Stateless控制器詳解

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

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

爲了實現不一樣的功能,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的場景以下:api

  • 滾動升級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/v1
kind: Deployment
metadata:            #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字段說明:app

  • 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一致。
  1. 生成Deployment,建立時加一個--record參數,會在annotation中記錄deployment.kubernetes.io/revision版本
[root@node-1 happylau]# kubectl apply -f deployment-demo.yaml --record
deployment.apps/deployment-nginx-demo created
  1. 查看Deployment列表,運行時自動下載鏡像,以下已運行了3個副本
[root@node-1 happylau]# kubectl get deployments deployment-nginx-demo 
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment-nginx-demo   3/3     3            3           2m37s

NAME表明名稱,metadata.name字段定義
READY表明Pod的健康狀態,前面值是readiness,後面是liveness
UP-TO-DATE表明更新,用於滾動升級
AVAILABLE表明可用
AGE建立至今運行的時長
  1. 查看Deployment的詳情,能夠看到Deployment經過一個deployment-nginx-demo-866bb6cf78 replicaset副本控制器控制Pod的副本數量

Deployment詳情信息

  1. 查看replicaset的詳情信息,經過Events可查看到deployment-nginx-demo-866bb6cf78建立了三個Pod

ReplicaSet詳情信息

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

Pod詳情信息

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

Deployment建立結構示意圖

1.2.2 Deployment擴容

當業務比較繁忙時能夠經過增長副本數,增長副本數是經過yaml文件中的replicas控制的,當設置了replias後,Deployment控制器會自動根據當前副本數目建立所需的Pod數,這些pod會自動加入到service中實現負載均衡,相反減小副本數,這些pod會自動從service中刪除。less

Deployment擴容

  1. 將deployment的副本數擴容至4個,可經過修改yaml文件的replicas個數或者經過scale命令擴展。
[root@node-1 ~]# kubectl scale --replicas=4 deployment deployment-nginx-demo 
deployment.extensions/deployment-nginx-demo scaled
  1. 查看Deployment副本數量,已增長至4個副本
[root@node-1 ~]# kubectl get deployments
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment-nginx-demo   4/4     4            4           77m
  1. 副本的擴容是如何實現的呢?咱們查看replicaset的詳情信息觀察,增長副本的個數是經過replicaset來擴容,經過模版複製新的Pod

Deployment擴展

  1. 副本縮容
[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   AGE
deployment-nginx-demo   2/2     2            2           7h41m

Deployment減小副本

經過上面的操做演練咱們能夠得知:Deployment的擴容是經過ReplicaSet的模版建立Pod或刪除Pod實現,scale是手動擴展實現副本的機制,kubernetes還提供了另一種副本自動擴容機制horizontalpodautoscalers(Horizontal Pod Autoscaling),即經過定義CPU的利用率實現自動的橫向擴展,因爲須要依賴於監控組件,後續咱們再作介紹。curl

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 --record
deployment.extensions/deployment-nginx-demo image updated
  1. 查看滾動升級的狀態(因爲第一次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-CAUSE
1         <none>
2         kubectl set image deployments deployment-nginx-demo nginx-deployment=nignx:1.9.1 --record=true
3         kubectl set image deployments deployment-nginx-demo nginx-deployment=nignx:1.9.1 --record=true
  1. 觀察Deployment的升級過程,新建立一個RS deployment-nginx-demo-65c8c98c7b,逐漸將舊RS中的pod替換,直至舊的RS deployment-nginx-demo-866bb6cf78上的副本數爲0.

滾動升級原理

  1. 查看RS的列表,能夠看到新的RS的副本數爲2,其餘RS副本數爲0
[root@node-1 ~]# kubectl get replicasets 
NAME                               DESIRED   CURRENT   READY   AGE
deployment-nginx-demo-65c8c98c7b   2         2         2       21m  #新的RS,REVSION爲3
deployment-nginx-demo-6cb65f58c6   0         0         0       22m  #鏡像寫錯的RS,REVISON爲2
deployment-nginx-demo-866bb6cf78   0         0         0       40m  #舊的RS,對應REVSION爲1
  1. 測試版本升級是否成功
[root@node-1 ~]# kubectl get pods -o wide 
NAME                                     READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
deployment-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 OK
Server: nginx/1.9.1 #鏡像的版本成功更新
Date: Mon, 28 Oct 2019 15:28:49 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 26 May 2015 15:02:09 GMT
Connection: keep-alive
ETag: "55648af1-264"
Accept-Ranges: bytes

1.2.4 版本回退

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

  1. 執行回滾,回退到REVISON版本爲1
[root@node-1 ~]# kubectl rollout undo deployment deployment-nginx-demo --to-revision=1
deployment.extensions/deployment-nginx-demo rolled back
  1. 查看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-CAUSE
2         kubectl set image deployments deployment-nginx-demo nginx-deployment=nignx:1.9.1 --record=true
3         kubectl set image deployments deployment-nginx-demo nginx-deployment=nignx:1.9.1 --record=true
4         <none>
  1. 查看Deployment的詳情,能夠看到RS已經會退到原始的RS了

版本回退

  1. 測試nginx的版本
[root@node-1 ~]# kubectl get pods -o wide 
NAME                                     READY   STATUS    RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES
deployment-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 OK
Server: nginx/1.7.9 #回退到1.7.9版本
Date: Mon, 28 Oct 2019 15:36:07 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 23 Dec 2014 16:25:09 GMT
Connection: keep-alive
ETag: "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/v1beta1
kind: ReplicaSet
metadata:
  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
  1. 建立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   AGE
replicaset-demo   3         3         3       15s
  1. 擴展副本數至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   AGE
replicaset-demo   4         4         4       76s
  1. 減小副本數至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   AGE
replicaset-demo   2         2         2       114s
  1. 鏡像版本升級,驗證得知不具有版本升級的能力
[root@node-1 happylau]# kubectl set image replicasets replicaset-demo nginx-replicaset-demo=nginx:1.9.1
replicaset.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
  1. 生成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   AGE
rc-demo   3         3         3       103s

#查看詳情
[root@node-1 happylau]# kubectl describe replicationcontrollers rc-demo 
Name:         rc-demo
Namespace:    default
Selector:     controller=replicationcontroller
Labels:       controller=replicationcontroller
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"v1","kind":"ReplicationController","metadata":{"annotations":{"kubernetes.io/description":"Kubernetes Replication Controlle...
              kubernetes.io/description: Kubernetes Replication Controller Replication
Replicas:     3 current / 3 desired
Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod 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   AGE
rc-demo   4         4         4       3m23s
  1. 副本縮容至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   AGE
rc-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/

相關文章
相關標籤/搜索