替换故障 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 的容器中创建新 shell。

    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

    在此新 shell 中,运行以下命令:

    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 副本节点的标识符。 例如 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 清单,该清单描述了一个用于恢复 etcd 数据而临时运行的实用程序 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