iT邦幫忙

2023 iThome 鐵人賽

DAY 9
0
DevOps

第一次參賽就學 Kubernetes系列 第 9

[Day 09] ReplicaSet

  • 分享至 

  • xImage
  •  

如果今天應用程式掛掉、導致服務無法提供使用者存取,希望 k8s 可以即時將服務重新 run 起來、使服務不被中斷,這時候就要提到 k8s 中的 ReplicaSet。


當應用程式的使用者增加時,需要提升服務的高可用性 (Hign Availability, HA)、提升負載平衡,或者是為了因應服務異常中斷,需要在環境中部署多個 instances,也就是多個 pods。

在 k8s 中可以用 ReplicaSet 來對 Pods 進行管理與監控。

ReplicaSet

ReplicaSet 是監控 pod 的一個程序,確保受到管理的 pods(應用服務都是放在 pod 中) 狀態為正常運行(running)。

ReplicaSet 主要的功能:

  • 維持當前設定的 pods 數量,多一個或少一個 ReplicaSet 會自動做 pods 的增減。
  • 如果 pods 錯誤、刪除或停止時,ReplicaSet 會自動起新的 pod 來補上。

如何知道要管理哪些 Pods

為達成 HA 及負載平衡,在叢集中通常會部署多個 pods。透過先前在 YAML 設定檔中的 labels 屬性以及待會將提到的 selector 屬性來指定 ReplicaSet 要管理哪些 pods。

透過幫 pods 貼標籤 labels,並在 ReplicaSet 上定義 selector 指定要管理哪些 pods。

範例

https://ithelp.ithome.com.tw/upload/images/20230925/201625112zEHXcqabR.png

圖片來源: https://velog.io/@gentledev10/kubernetes-replicaset

底下是一個用來建立應用程式的 pod 範例 nginx-pod.yaml

apiVersion: v1
kind: Pod
metadata: nginx-pod
  name: nginx-pod
  labels:
    app: nginx-app
    tier: frontend
spec:
  containers:
  - name: nginx-container
    image: nginx
    ports:
    - containerPort: 80

底下是一個 ReplicaSet 範例 nginx-rs.yaml,假設希望在叢集中維持執行 3 個 pods。

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-app
  template:
    # 若是 pod 掛掉時,ReplicaSet 會按照以下內容來建立新的 pod
    metadata:
      name: nginx-pod
      labels:
        app: nginx-app
        tier: frontend
    spec:
      containers:
      - name: nginx-container
        image: nginx
        ports:
        - containerPort: 80

如同 pod 的定義一樣,有 apiVersionkindmetadataspec 屬性,不同的是在 spec 定義:

  • replicas:需要幾個 replica,這邊希望在叢集中跑三個 pods。
  • selector:定義要管理的 labels 有哪些,在 matchLabels 下填上標籤 app 其值為 nginx-app,表示要連結至有此標籤的所有 pods。可以將不是由設定檔建立的 pod 也納入 replicaSet 的管理。
  • template:pod 的詳細內容,其實就是把建立 pod 的設定檔底下的 metadataspec 兩個屬性的內容原封不動搬過來。
  • status:實際由 k8s 於執行時自動產生與更新,在定義時可不寫。

建立 ReplicaSet

執行 nginx-rs.yaml

kubectl create -f nginx-rs.yaml

replicaset.apps/nginx-rs created

查看建立的 pods。

kubectl get po

NAME             READY   STATUS    RESTARTS   AGE
nginx-rs-dpghz   1/1     Running   0          106s
nginx-rs-nrw5r   1/1     Running   0          106s
nginx-rs-qpt2v   1/1     Running   0          106s

也可以用 label 篩選 pods,先建立一個沒有 label 的 pod。

kubectl run nginx --image=nginx
kubectl get po

NAME             READY   STATUS    RESTARTS   AGE
nginx            1/1     Running   0          37s
nginx-rs-dpghz   1/1     Running   0          3m33s
nginx-rs-nrw5r   1/1     Running   0          3m33s
nginx-rs-qpt2v   1/1     Running   0          3m33s

篩選 labeltier=frontend 的 pod。

kubectl get po -l tier=frontend

NAME             READY   STATUS    RESTARTS   AGE
nginx-rs-dpghz   1/1     Running   0          4m43s
nginx-rs-nrw5r   1/1     Running   0          4m43s
nginx-rs-qpt2v   1/1     Running   0          4m43s

加上 -o wide 可以看到 ReplicaSet 的 selectorapp=nginx-app

kubectl get replicaset nginx-rs -o wide

NAME       DESIRED   CURRENT   READY   AGE     CONTAINERS        IMAGES   SELECTOR
nginx-rs   3         3         3       6m13s   nginx-container   nginx    app=nginx-app

刪掉 nginx pod。

kubectl delete po nginx

pod "nginx" deleted

查看該 ReplicaSet 的詳細資料。

kubectl describe replicaset nginx-rs

Name:         nginx-rs
Namespace:    default
Selector:     app=nginx-app
Labels:       <none>
Annotations:  <none>
Replicas:     3 current / 3 desired
Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=nginx-app
           tier=frontend
  Containers:
   nginx-container:
    Image:        nginx
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age    From                   Message
  ----    ------            ----   ----                   -------
  Normal  SuccessfulCreate  7m22s  replicaset-controller  Created pod: nginx-rs-nrw5r
  Normal  SuccessfulCreate  7m22s  replicaset-controller  Created pod: nginx-rs-dpghz
  Normal  SuccessfulCreate  7m22s  replicaset-controller  Created pod: nginx-rs-qpt2v

觀察 selectorlabelsReplicasPods Status 和底下的 Events(建立 pod 的事件紀錄)。

Scale up & Scale down

若想要修改 ReplicaSet,例如把其中的 replicas 修改為其他數量,有三種修改方式:

  1. 修改設定檔 nginx-rs.yaml 內的內容
  2. 使用 kubectl scale 指令
  3. 使用 kubectl edit 指令

先來看第 1 種直接修改 nginx-rs.yaml

kubectl replace -f nginx-rs.yaml

replicaset.apps/nginx-rs replaced

修改其中的 replicas 為 2。

vi nginx-rs.yaml

查看 ReplicaSet。

kubectl get rs nginx-rs

NAME       DESIRED   CURRENT   READY   AGE
nginx-rs   2         2         2       6m4s

查看 pods running 變為 2 個。

kubectl get po

NAME             READY   STATUS    RESTARTS   AGE
nginx-rs-jcq5h   1/1     Running   0          6m42s
nginx-rs-whmw6   1/1     Running   0          6m42s

第 2 種使用 scale 設定 replicas 為 6。

kubectl scale replicaset nginx-rs --replicas=6

replicaset.apps/nginx-rs scaled

查看當前 ReplicaSet。

kubectl get rs nginx-rs

NAME       DESIRED   CURRENT   READY   AGE
nginx-rs   6         6         6       18m

查看 pods running 變為 6 個。

kubectl get po -o wide
NAME             READY   STATUS    RESTARTS   AGE    IP            NODE       NOMINATED NODE   READINESS GATES
nginx-rs-6825z   1/1     Running   0          2m4s   10.244.0.15   minikube   <none>           <none>
nginx-rs-dpghz   1/1     Running   0          19m    10.244.0.11   minikube   <none>           <none>
nginx-rs-g94bm   1/1     Running   0          2m4s   10.244.0.13   minikube   <none>           <none>
nginx-rs-l2zp5   1/1     Running   0          2m4s   10.244.0.14   minikube   <none>           <none>
nginx-rs-nrw5r   1/1     Running   0          19m    10.244.0.10   minikube   <none>           <none>
nginx-rs-qpt2v   1/1     Running   0          19m    10.244.0.9    minikube   <none>           <none>

第 3 種是使用 edit,把 replicas 改回 3。

# k8s 會提供一個暫時的 file 可以修改,若儲存後則 apply 這個版本的 replicaset
kubectl edit replicaset nginx-rs

replicaset.apps/nginx-rs edited

查看當前 ReplicaSet 跟 pods,scale down 後變為 3。

kubectl get rs,po

NAME                       DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-rs   3         3         3       27m

NAME                 READY   STATUS    RESTARTS   AGE
pod/nginx-rs-dpghz   1/1     Running   0          27m
pod/nginx-rs-nrw5r   1/1     Running   0          27m
pod/nginx-rs-qpt2v   1/1     Running   0          27m

注意:使用第 2 種(kubectl scale)與第 3 種(kubectl edit)方式並不會自動修改 nginx-rs.yaml 設定檔裡的內容,下次再執行時 replicas 依然是原本的 3。

刪除 ReplicaSet

同時刪除所有在設定檔中建立與管理的 pods,也就是 labels 有對應到的 pods。

kubectl delete replicaset nginx-rs

replicaset.apps "nginx-rs" deleted 

查看 ReplicaSet。

kubectl get replicaset

No resources found in default namespace.

ReplicaSet 的 status 屬性

status 屬性是由 k8s 自動產生與變動的,在執行 kubectl create -f nginx-rs.yaml 或異動 ReplicaSet 後,k8s 會去 etcd 取得叢集中 status 的資料,並比對當前叢集的狀態、設定檔中的狀態有沒有一致。

例如修改 nginx-rs.yamlreplicas 為 2。

vi nginx-rs.yaml

kubectl replace -f nginx-rs.yaml
replicaset.apps/nginx-rs replaced

可以透過 kubectl edit 來觀察。

kubectl edit replicaset nginx-rs

# 省略部分 ...
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-app
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx-app
        tier: frontend
      name: nginx-pod
    spec:
      containers:
      - image: nginx
        imagePullPolicy: Always
        name: nginx-container
        ports:
        - containerPort: 80
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 2
  fullyLabeledReplicas: 2
  observedGeneration: 2
  readyReplicas: 2
  replicas: 2

如上可以看到 status 屬性。

參考來源

  1. Kubernetes Kubernetes: Getting Started
  2. Kubernetes YAML File Explained - Deployment and Service | Kubernetes Tutorial 19

上一篇
[Day 08] YAML 設定檔
下一篇
[Day 10] Deployment (上篇)
系列文
第一次參賽就學 Kubernetes30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言