iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 11
0
Software Development

K8S - 30天從擦槍到提槍上陣學習筆記。系列 第 11

day 11 Pod Controller(1) - ReplicaSet

Pod and Pod Controller

每個工作節點上負責監控Pod存活性的角色是kubelet, 它會在主容器發生錯誤時進行自我修復, 但它只能監控主容器, 其餘的項目發生錯誤時需要依靠Pod設定的存活性探測機制來得知,
但是在工作節點自身發生錯誤的時候kubelet也不能再使用了, 此時Master無法得知工作節點的狀態, Pod也無法再重啟; 這時候就需要透過工作節點之外的Controller來監控, Controller是K8s Master的 kube-controller-manager上的一個組件, kube-controller-manager的任務是要確保object的status要符合object部署的spec, 它會不斷的進行statusspec的和解reconciliation來確保Pod的狀態, 常見的controller有 Namespace Controller, Deployment Controller, Service Controller...等, 可以將 Pod Controller視為一個監督者的角色, 它位在Pod工作節點外的上一層, 負責確保Pod有依照用戶設定的內容運作。

https://ithelp.ithome.com.tw/upload/images/20200915/20129656zLA4lj5L5W.png

圖片參考書:【Kubernetes 進階實踐】

PodTemplate

Pod模板是Controller拿來創建或管理Pod的參考規範,Pod spec通常都必須具備replicas,selector,template, 模板就是spec中的 template字段; 由於template是要嵌入Controller中使用, 所以不會有apiVersion, kind字段,
修改或更新template並不會更新已存在的Pod, 而是由Controller偵測到spec更新而創建一個新的Pod, 同時檢查Pod的狀態是否符合spec, 不符合spec的pod 將會被終止。

ReplicaSet

ReplicaSet 是用來確保Pod的運作狀態要符合pod spec配置的一種實現, 它啟動後會在cluster中匹配和 label selector 相符的object, 並反覆確認pod個數是否符合spec期望, 如果有多會刪除, 有少則會透過 PodTemplate 創建Pod補足, 等到狀態符合期望之後, ReplicaSet 會再進入下一個循環。
https://ithelp.ithome.com.tw/upload/images/20200915/20129656MIRWNoNwTy.png

圖片參考書:【Kubernetes 進階實踐】

創建 ReplicaSet

配置 ReplicaSet spec 一樣需要 apiVersion, kind, metadata, spec, 針對 spec 底下還有幾個屬性:
* replicas : 期望的pod數量
* selector : Controller匹配Pod數量的label selector, 支援 matchLabelsmatchExpressions
* template : 用來補足Pod數量時所用的Pod模板
* minReadySeconds : 新建的Pod在啟動後多長時間內未發生錯誤即視為Ready, 預設0秒。

### 創建範例 YAML

apiVersion: apps/v1
kind: ReplicaSet
  metadata:
    name: rs-example
  spec:
    replicas: 2
    selector:
      matchLabels:
        app: rs-demo
    template:
      metadata:
        labels:
          app: rs-demo
      spec:
        containers:
        - name: rs-hello
          image: nginx:latest
          ports:
          - name: http
            containerPort: 80
    minReadySeconds: 5

創建過程

  • 執行

    -> % kubectl apply -f replica-demo.yaml
    replicaset.apps/rs-example configured
    
  • 查看狀態

    -> % kubectl get pods -l app=rs-demo
    NAME               READY   STATUS              RESTARTS   AGE
    rs-example-44nhn   0/1     ContainerCreating   0          4s
    rs-example-mgjcr   0/1     ContainerCreating   0          4s
    
  • 第一次key錯image, 查看狀態時回應如下

    -> % kubectl get pods -l app=rs-demo
    NAME               READY   STATUS         RESTARTS   AGE
    rs-example-44nhn   0/1     ErrImagePull   0          11s
    rs-example-mgjcr   0/1     ErrImagePull   0          11s
    
  • 修改image來源之後查看狀態還是不成功(因為replicaSet的YAML修改只對新建的pod生效)

    -> % kubectl get pods -l app=rs-demo
    NAME               READY   STATUS             RESTARTS   AGE
    rs-example-44nhn   0/1     ImagePullBackOff   0          28s
    rs-example-mgjcr   0/1     ImagePullBackOff   0          28s
    
  • 此時操作刪除Pod讓它自動重新建立

    kubectl delete pod rs-example-mgjcr
    kubectl delete pod rs-example-44nhn
    
  • 載入修改後image的pod狀態已是Running

    -> % kubectl get pods -l app=rs-demo
    NAME               READY   STATUS    RESTARTS   AGE
    rs-example-nvwqp   1/1     Running   0          9s
    rs-example-tcckz   1/1     Running   0          18s
    

    Pod創建後, ReplicaSet就不會再去檢查pod spec內容, 所以除了修改pod副本個數之外, 其餘的變動都要在下一個新的pod創建時才會生效。ReplicaSet 可以確保Pod數量精確符合期望值, 發現Pod不健康時會自動請求創建Pod副本以及隨著設定彈性伸縮pod規模。

異動 ReplicaSet

ReplicaSet 是按照 label selector 來匹配pod數量, 如果手動去修改 label 也會觸發 ReplicaSet 自動創建的機制

  • 查看目前的pod
-> % kubectl get pods  -L app
NAME                            READY   STATUS              RESTARTS   AGE     APP
rs-example-cwn9x                1/1     Running             0          4m14s   rs-demo
rs-example-jbm28                1/1     Running             0          4m14s   rs-demo
  • 修改 rs-example-cwn9x , 拿掉 label
-> % kubectl label pods rs-example-cwn9x app= --overwrite


pod/rs-example-cwn9x labeled
  • 查看結果
-> % kubectl get pods  -L app
NAME                                READY   STATUS    RESTARTS   AGE     APP
rs-example-cwn9x                    1/1     Running   0          5m26s
rs-example-jbm28                    1/1     Running   0          4m59s   rs-demo
rs-example-v94sf                    1/1     Running   0          13s     rs-demo

原本的 rs-example-cwn9x 因為強制更新了label 所以ReplicaSet檢查的時候不會計算它, 為了達到期望的2個, 於是創建了一個新的 rs-example-v94sf

  • 修改 rs-example-cwn9x , 加上 label rs-demo
-> % kubectl label pods rs-example-cwn9x app=rs-demo --overwrite


pod/rs-example-cwn9x labeled
  • 查看結果
-> % kubectl get pods  -L app
NAME                                READY   STATUS        RESTARTS   AGE     APP
rs-example-cwn9x                    1/1     Running       0          9m28s   rs-demo
rs-example-jbm28                    1/1     Running       0          9m1s    rs-demo
rs-example-v94sf                    0/1     Terminating   0          4m15s   rs-demo

因為 rs-example 只能有兩個pod, 當 label掃到有三個pod的時候, 會把其中一個pod刪除, 所以 rs-example-v94sf 狀態為 Terminating

伸縮與擴充

kubectl 提供了一個指令可以實現 ReplicaSet 的伸縮

kubectl scale replicasets [LABEL] --replicas=<integer>
  • 先查看目前的狀態
-> % kubectl get replicasets
NAME                          DESIRED   CURRENT   READY   AGE
rs-example                    2         2         2       50m
  • 執行擴充
-> % kubectl scale replicasets rs-example --replicas=3
replicaset.apps/rs-example scaled
  • 查看結果
-> % kubectl get replicasets
NAME                          DESIRED   CURRENT   READY   AGE
rs-example                    3         3         3       51m

另外kubectl 還提供參數 --current-replicas 可以依照現在pod數量判斷擴充條件

  • 目前 replicasets 有3個, 假設執行語法如下, 因為不符合--current-replicas條件所以不會執行
-> % kubectl scale replicasets rs-example --current-replicas=2 --replicas=3
 error: Expected replicas to be 2, was 3
  • 調整一下條件, 改執行
-> % kubectl scale replicasets rs-example --current-replicas=3 --replicas=5
replicaset.apps/rs-example scaled
  • 查看結果
-> % kubectl get replicasets
NAME                          DESIRED   CURRENT   READY   AGE
rs-example                    5         5         5       57m

刪除

預設刪除ReplicaSet 時會一併刪除下層的pod, kubectl 有提供參數 --cascade=false 供使用, 可以只刪除 replicaset

今日小結

由於replicaset不支援滾動更新,所以大多建議使用deployment,下一篇會研究看看deployment。


上一篇
day 10 Pod(3)-生命週期, 容器探測
下一篇
day 12 Pod Controller(2) - Deployment
系列文
K8S - 30天從擦槍到提槍上陣學習筆記。30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言