1. 程式人生 > 其它 >k8s控制器--Replicaset和Deployment

k8s控制器--Replicaset和Deployment

k8s控制器--Replicaset和Deployment

一、Replicaset控制器

2.1、Replicaset概述

ReplicaSet是kubernetes中的一種副本控制器,簡稱rs,主要作用是控制由其管理的pod,使pod副本的數量始終維持在預設的個數。它的主要作用就是保證一定數量的Pod能夠在叢集中正常執行,它會持續監聽這些Pod的執行狀態,在Pod發生故障時重啟pod,pod數量減少時重新執行新的 Pod副本。官方推薦不要直接使用ReplicaSet,用Deployments取而代之,Deployments是比ReplicaSet更高階的概念,它會管理ReplicaSet並提供很多其它有用的特性,最重要的是Deployments支援宣告式更新,宣告式更新的好處是不會丟失歷史變更。所以Deployment控制器不直接管理Pod物件,而是由 Deployment 管理ReplicaSet,再由ReplicaSet負責管理Pod物件。

2.2、Replicaset工作原理

Replicaset核心作用在於使用者建立指定數量的pod副本,並確保pod副本一直處於滿足使用者期望的數量, 起到多退少補的作用,並且還具有自動擴容縮容等制。
Replicaset控制器主要由三個部分組成:
1、使用者期望的pod副本數:用來定義由這個控制器管控的pod副本有幾個
2、標籤選擇器:選定哪些pod是自己管理的,如果通過標籤選擇器選到的pod副本數量少於我們指定的數量,需要用到下面的元件
3、pod資源模板:如果叢集中現存的pod數量不夠我們定義的副本中期望的數量怎麼辦,需要新建pod,這就需要pod模板,新建的pod是基於模板來建立的。

2.3、Replicaset使用案例

#編寫一個ReplicaSet資源清單
[root@k8s-master1 ~]# cat replicaset.yaml 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: yecc/gcr.io-google_samples-gb-frontend:v3
        imagePullPolicy:  IfNotPresent

[root@k8s-master1 ~]# kubectl apply -f replicaset.yaml 
replicaset.apps/frontend created
[root@k8s-master1 ~]# kubectl get rs
NAME       DESIRED   CURRENT   READY   AGE
frontend   3         3         3       48s
[root@k8s-master1 ~]# kubectl get pods
NAME             READY   STATUS    RESTARTS   AGE
frontend-8p5lq   1/1     Running   0          54s
frontend-9hjr8   1/1     Running   0          54s
frontend-nt6kb   1/1     Running   0          54s

2.4、Replicaset管理pod

2.4.1、實現pod的動態擴縮容

方式一:修改yaml檔案的replicas值,重新apply

方式二:使用kubectl edit rs frontend動態修改

# 方式一
[root@k8s-master1 ~]# vim replicaset.yaml
replicas: 4

[root@k8s-master1 ~]# kubectl apply -f replicaset.yaml
replicaset.apps/frontend configured
[root@k8s-master1 ~]# kubectl get pods
NAME             READY   STATUS    RESTARTS   AGE
frontend-8p5lq   1/1     Running   0          22m
frontend-9hjr8   1/1     Running   0          22m
frontend-nt6kb   1/1     Running   0          22m
frontend-vhz2g   1/1     Running   0          5s

# 方式二
[root@k8s-master1 ~]# kubectl edit rs frontend

2.4.2、實現pod的版本更新

修改yaml檔案的image或者使用kubectl edit命令修改映象只會影響新生成的pod,對原先的pod沒有影響,只能刪除原先的pod才能完成版本更新。

生產環境如果升級,可以刪除一個pod,觀察一段時間之後沒問題再刪除另一個pod,但是這樣需要人工干預多次;實際生產環境一般採用藍綠髮布,原來有一個rs1,再建立一個rs2(控制器),通過修改service標籤,修改service可以匹配到rs2的控制器,這樣才是藍綠髮布,這個也需要我們精心的部署規劃,我們有一個控制器就是建立在rs之上完成的,叫做Deployment

二、Deployment控制器

Deployment官方文件:https://kubernetes.io/docs/concepts/workloads/controllers/deployment/

2.1、Deployment概述

Deployment是kubernetes中最常用的資源物件,為ReplicaSet和Pod的建立提供了一種宣告式的定義方法,在Deployment物件中描述一個期望的狀態,Deployment控制器就會按照一定的控制速率把實際狀態改成期望狀態,通過定義一個Deployment控制器會建立一個新的ReplicaSet控制器,通過ReplicaSet建立pod,刪除Deployment控制器,也會刪除Deployment控制器下對應的ReplicaSet控制器和pod資源

使用Deployment而不直接建立ReplicaSet是因為Deployment物件擁有許多ReplicaSet沒有的特性,例如滾動升級和回滾

宣告式定義:指直接修改資源清單yaml檔案,然後通過kubectl apply -f 資源清單yaml檔案,就可以更改資源

Deployment控制器是建立在rs之上的一個控制器,可以管理多個rs,每次更新映象版本,都會生成一個新的rs,把舊的rs替換掉,多個rs同時存在,但是隻有一個rs執行。

rs v1控制三個pod,刪除一個pod,在rs v2上重新建立一個,依次類推,直到全部都是由rs v2控制,如果rs v2有問題,還可以回滾,Deployment是建構在rs之上的,多個rs組成一個Deployment,但是隻有一個rs處於活躍狀態.

2.2、Deployment工作原理

Deployment可以使用宣告式定義,直接在命令列通過純命令的方式完成對應資源版本的內容的修改,也就是通過打補丁的方式進行修改;Deployment能提供滾動式自定義自控制的更新;對Deployment來講,我們在實現更新時還可以實現控制更新節奏和更新邏輯。

更新節奏和更新邏輯

​ 比如說Deployment控制5個pod副本,pod的期望值是5個,但是升級的時候需要額外多幾個pod,那我們控制器可以控制在5個pod副本之外還能再增加幾個pod副本;比方說能多一個,但是不能少,那麼升級的時候就是先增加一個,再刪除一個,增加一個刪除一個,始終保持pod副本數是5個;還有一種情況,最多允許多一個,最少允許少一個,也就是最多6個,最少4個,第一次加一個,刪除兩個,第二次加兩個,刪除兩個,依次類推,可以自己控制更新方式,這種滾動更新需要加readinessProbe和livenessProbe探測,確保pod中容器裡的應用都正常啟動了才刪除之前的pod。
啟動第一步,剛更新第一批就暫停了也可以;假如目標是5個,允許一個也不能少,允許最多可以10個,那一次加5個即可;這就是我們可以自己控制節奏來控制更新的方法。

通過Deployment物件,你可以輕鬆的做到以下事情:

  1. 建立ReplicaSet和Pod
  2. 滾動升級(不停止舊服務的狀態下升級)和回滾應用(將應用回滾到之前的版本)
  3. 平滑地擴容和縮容
  4. 暫停和繼續Deployment

2.3、Deployment使用案例

[root@k8s-master1 ~]# cat deploy-demo.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-v1
spec:
  replicas: 2
  selector:
   matchLabels:
    app: myapp
    version: v1
  template:
   metadata:
    labels:
     app: myapp
     version: v1
   spec:
    containers:
    - name: myapp
      image: janakiramm/myapp:v1
      imagePullPolicy: IfNotPresent
      ports:
      - containerPort: 80
      
[root@k8s-master1 ~]# kubectl apply -f deploy-demo.yaml
deployment.apps/myapp-v1 created
[root@k8s-master1 ~]# kubectl get deploy
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
myapp-v1   2/2     2            2           5s
[root@k8s-master1 ~]# kubectl get rs
NAME                  DESIRED   CURRENT   READY   AGE
myapp-v1-67fd9fc9c8   2         2         2       10s
[root@k8s-master1 ~]# kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
myapp-v1-67fd9fc9c8-6fw6v   1/1     Running   0          16s
myapp-v1-67fd9fc9c8-pndjj   1/1     Running   0          16s

2.4、Deployment管理pod

2.4.1、實現Pod擴縮容

方式一:修改yaml檔案,然後kubectl apply

方式二:使用kubectl edit deploy修改副本數

2.4.2、實現滾動升級及回滾

滾動升級:

  • 方式一:修改yaml檔案,然後kubectl apply
  • 方式二:使用kubectl edit deploy修改映象版本

回滾:

[root@k8s-master1 ~]# kubectl get deploy
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
myapp-v1   2/2     2            2           29m
[root@k8s-master1 ~]# kubectl get rs
NAME                  DESIRED   CURRENT   READY   AGE
myapp-v1-67fd9fc9c8   0         0         0       29m
myapp-v1-75fb478d6c   2         2         2       13s
# 檢視myapp-v1這個控制器的歷史版本
[root@k8s-master1 ~]# kubectl rollout history deployment myapp-v1
deployment.apps/myapp-v1 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

# 回滾
[root@k8s-master1 ~]# kubectl rollout undo deployment myapp-v1 --to-revision=1
deployment.apps/myapp-v1 rolled back
[root@k8s-master1 ~]# kubectl get rs
NAME                  DESIRED   CURRENT   READY   AGE
myapp-v1-67fd9fc9c8   2         2         2       30m
myapp-v1-75fb478d6c   0         0         0       84s
[root@k8s-master1 ~]# kubectl rollout history deployment myapp-v1
deployment.apps/myapp-v1 
REVISION  CHANGE-CAUSE
2         <none>
3         <none>

2.4.3、自定義滾動更新策略

maxSurgemaxUnavailable用來控制滾動更新的更新策略

# 取值範圍
數值:兩者不能同時為0。
1. maxUnavailable: [0, 副本數]
2. maxSurge: [0, 副本數]
比例:兩者不能同時為0。
1. maxUnavailable: [0%, 100%] 向下取整,比如10個副本,5%的話==0.5個,但計算按照0個;
2. maxSurge: [0%, 100%] 向上取整,比如10個副本,5%的話==0.5個,但計算按照1個;

# 建議配置
1. maxUnavailable == 0
2. maxSurge == 1
這是我們生產環境提供給使用者的預設配置。即“一上一下,先上後下”最平滑原則:1個新版本pod ready(結合readiness)後,才銷燬舊版本pod。此配置適用場景是平滑更新、保證服務平穩,但也有缺點,就是“太慢”了。

# 總結:
maxUnavailable:和期望的副本數比,不可用副本數最大比例(或最大值),這個值越小,越能保證服務穩定,更新越平滑;
maxSurge:和期望的副本數比,超過期望副本數最大比例(或最大值),這個值調的越大,副本更新速度越快。

自定義策略示例

# 修改更新策略:maxUnavailable=1,maxSurge=1 
[root@k8s-master1 ~]# kubectl patch deployment myapp-v1 -p '{"spec":{"strategy":{"rollingUpdate": {"maxSurge":1,"maxUnavailable":1}}}}' -n blue-green

# 檢視myapp-v1這個控制器的詳細資訊
[root@k8s-master1 ~]# kubectl describe deployment myapp-v1 -n blue-green
RollingUpdateStrategy:  1 max unavailable, 1 max surge

# 這個rollingUpdate更新策略變成了剛才設定的,因為我們設定的pod副本數是3,1和1表示最少不能少於2個pod,最多不能超過4個pod ,這個就是通過控制RollingUpdateStrategy這個欄位來設定滾動更新策略的

2.5、Deployment配置模板

apiVersion: apps/v1
kind: Deployment 
metadata:
  name: portal
  namespace: test 
spec:
  replicas: 1
  selector:
    matchLabels:
      project: ms
      app: portal
  template:
    metadata:
      labels:
        project: ms 
        app: portal
    spec:
      containers:
      - name: portal
        image:  xianchao/portal:v1
        imagePullPolicy: Always
        ports:
          - protocol: TCP
            containerPort: 8080 
        resources:  #資源配額
          limits:  #資源限制,最多可用的cpu和記憶體
            cpu: 1
            memory: 1Gi
          requests: #最少需要多少資源才可以執行Pod
            cpu: 0.5
            memory: 1Gi
        readinessProbe:
          tcpSocket:
            port: 8080
          initialDelaySeconds: 60
          periodSeconds: 10
        livenessProbe:
          tcpSocket:
            port: 8080
          initialDelaySeconds: 60
          periodSeconds: 10
作者:Lawrence 出處:http://www.cnblogs.com/hujinzhong/

-------------------------------------------

個性簽名:獨學而無友,則孤陋而寡聞。做一個靈魂有趣的人!

掃描上面二維碼關注我 如果你真心覺得文章寫得不錯,而且對你有所幫助,那就不妨幫忙“推薦"一下,您的“推薦”和”打賞“將是我最大的寫作動力! 本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線.