取代失敗的 etcd 備用資源

本文說明如何在 Google Distributed Cloud 的高可用性 (HA) 使用者叢集中,更換失敗的 etcd 副本。

本文說明適用於使用 kubeception 的高可用性使用者叢集,也就是未啟用Controlplane V2 的使用者叢集。如果需要更換已啟用 Controlplane V2 的使用者叢集中的 etcd 副本,請與 Cloud Customer Care 團隊聯絡

事前準備

  • 確認管理員叢集運作正常。

  • 確認使用者叢集中的其他兩個 etcd 成員運作正常。如果有多個 etcd 成員發生故障,請參閱「從 etcd 資料損毀或遺失中復原」。

取代失敗的 etcd 備用資源

  1. 備份 etcd PodDisruptionBudget (PDB) 的副本,以便稍後還原。

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG -n USER_CLUSTER_NAME get pdb kube-etcd-pdb -o yaml > PATH_TO_PDB_FILE

    其中:

    • ADMIN_CLUSTER_KUBECONFIG 是管理員叢集的 kubeconfig 檔案路徑。

    • USER_CLUSTER_NAME 是包含失敗 etcd 副本的使用者叢集名稱。

    • PATH_TO_PDB_FILE 是您要儲存 etcd PDB 檔案的路徑,例如 /tmp/etcpdb.yaml

  2. 刪除 etcd PodDisruptionBudget (PDB)。

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG -n USER_CLUSTER_NAME delete pdb kube-etcd-pdb
  3. 執行下列指令,在文字編輯器中開啟 kube-etcd StatefulSet

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG -n USER_CLUSTER_NAME edit statefulset kube-etcd

    --initial-cluster-state 旗標的值變更為 existing

    containers:
        - name: kube-etcd
          ...
          args:
            - --initial-cluster-state=existing
          ...
     
  4. 排空失敗的 etcd 備用資源節點。

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG drain NODE_NAME --ignore-daemonsets --delete-local-data

    其中 NODE_NAME 是失敗的 etcd 備用資源節點名稱。

  5. 在其中一個運作中的 kube-etcd Pod 容器中建立新殼層。

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG exec -it \
       KUBE_ETCD_POD --container kube-etcd --namespace USER_CLUSTER_NAME \
       -- bin/sh

    其中 KUBE_ETCD_POD 是工作 kube-etcd Pod 的名稱。例如:kube-etcd-0

    在這個新殼層中,執行下列指令:

    1. 從 etcd 叢集中移除失敗的 etcd 副本節點。

      首先,請列出 etcd 叢集的所有成員:

      etcdctl member list -w table

      輸出內容會顯示所有成員 ID。找出失敗副本的成員 ID。

      接著,移除失敗的副本:

      export ETCDCTL_CACERT=/etcd.local.config/certificates/etcdCA.crt
      export ETCDCTL_CERT=/etcd.local.config/certificates/etcd.crt
      export ETCDCTL_CERT=/etcd.local.config/certificates/etcd.crt
      export ETCDCTL_KEY=/etcd.local.config/certificates/etcd.key
      export ETCDCTL_ENDPOINTS=https://127.0.0.1:2379
      etcdctl member remove MEMBER_ID

      其中 MEMBER_ID 是失敗的 etcd 副本 Pod 的十六進位成員 ID。

    2. 新增與失敗副本節點同名和對等互連網址的成員。

      etcdctl member add MEMBER_NAME --peer-urls=https://MEMBER_NAME.kube-etcd:2380

      其中 MEMBER_NAME 是失敗的 kube-etcd 副本節點 ID。例如:kube-etcd-1kube-etcd2

  6. 列出管理使用者叢集 etcd 儲存空間的 etcd Pod。這些 Pod 會在管理叢集中執行:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG get pods --namespace USER_CLUSTER_NAME \
        --output wide | grep kube-etcd
    

    輸出內容會顯示 etcd Pod,以及執行 Pod 的節點。輸出內容中顯示的節點是管理員叢集中的節點,會做為使用者叢集的控制層:

    NAME              ...   NODE
    kube-etcd-0       ...   node-abc
    kube-etcd-1       ...   node-yyy
    kube-etcd-2       ...   node-zzz
    
  7. 請記下 Pod 名稱和控制平面節點名稱,以便在下一個步驟中建立 Pod 資訊清單時使用。

    請注意,每個 etcd Pod 的名稱都是 kube-etcd,並附加一個數字。 這個數字稱為 Pod 的「成員編號」。這個 Pod 是 etcd 叢集的特定成員,負責保存使用者叢集的物件資料。本指南使用預留位置 MEMBER_NUMBER 來指稱 etcd Pod 成員編號。

    另請注意,etcd 叢集中的每個 Pod 都會在自己的節點上執行。

  8. 建立 Pod 資訊清單,說明您暫時執行的公用程式 Pod,用於還原 etcd 資料。將下列 Pod 資訊清單儲存至目前目錄,並命名為 etcd-utility-MEMBER_NUMBER.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: etcd-utility-MEMBER_NUMBER
      namespace: USER_CLUSTER_NAME
    spec:
      containers:
      - command: ["/bin/sh"]
        args: ["-ec", "while :; do echo '.'; sleep 5 ; done"]
        image: gcr.io/gke-on-prem-release/etcd-util:GKE_ON_PREM_VERSION
        name: etcd-utility
        volumeMounts:
        - mountPath: /var/lib/etcd
          name: data
        - mountPath: /etcd.local.config/certificates
          name: etcd-certs
      nodeSelector:
        kubernetes.googleapis.com/cluster-name: USER_CLUSTER_NAME
        kubernetes.io/hostname: NODE_NAME
      tolerations:
      - effect: NoExecute
        key: node.kubernetes.io/not-ready
        operator: Exists
        tolerationSeconds: 300
      - effect: NoExecute
        key: node.kubernetes.io/unreachable
        operator: Exists
        tolerationSeconds: 300
      - effect: NoSchedule
        key: node.kubernetes.io/unschedulable
        operator: Exists
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: data-kube-etcd-MEMBER_NUMBER
      - name: etcd-certs
        secret:
          defaultMode: 420
          secretName: KUBE_ETCD_SECRET_NAME
    

    更改下列內容:

    • NODE_NAME:執行 kube-etcd-0 Pod 的節點。

    • USER_CLUSTER_NAME:使用者叢集名稱。

    • GKE_ON_PREM_VERSION:要執行 etcd 還原作業的叢集版本 (例如 1.31.100-gke.136)。

    • KUBE_ETCD_SECRET_NAME:使用者叢集中 etcd 使用的 Secret 名稱,開頭為 kube-etcd-certs

  9. 在管理員叢集中建立公用程式 Pod:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG apply -f etcd-utility-MEMBER_NUMBER.yaml
    
  10. 從公用程式 Pod 內清除 etcd 資料目錄。

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG exec -it -n USER_CLUSTER_NAME etcd-utility-MEMBER_NUMBER -- /bin/bash -c 'rm -rf /var/lib/etcd/*'
  11. 刪除公用程式 Pod。

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG delete pod -n USER_CLUSTER_NAME etcd-utility-MEMBER_NUMBER
  12. 取消限制失敗的節點。

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG uncordon NODE_NAME
  13. 在文字編輯器中開啟 kube-etcd StatefulSet。

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG -n USER_CLUSTER_NAME edit statefulset kube-etcd

    --initial-cluster-state 旗標的值變更為 new

    containers:
        - name: kube-etcd
          ...
          args:
            - --initial-cluster-state=new
          ...
     
  14. 還原在步驟 1 中刪除的 etcd PDB。

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG apply -f /path/to/etcdpdb.yaml