障害が発生した etcd レプリカを置き換える

このドキュメントでは、Google Distributed Cloud の高可用性(HA)ユーザー クラスタで、失敗した etcd レプリカを置き換える方法について説明します。

ここで説明する手順は、kubeception を使用する HA ユーザー クラスタに適用されます。つまり、Controlplane V2 が有効になっていないユーザー クラスタです。Controlplane V2 が有効になっているユーザー クラスタで etcd レプリカを置き換える必要がある場合は、Cloud カスタマーケアにお問い合わせください

始める前に

  • 管理クラスタが正常に機能していることを確認します。

  • ユーザー クラスタ内の他の 2 つの 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 の 16 進数のメンバー ID です。

    2. 失敗したレプリカノードと同じ名前とピア URL で、新しいメンバーを追加します。

      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. etcd データを復元するために一時的に実行するユーティリティ Pod を記述する Pod マニフェストを作成します。現在のディレクトリの次の 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