替换故障 etcd 副本

本页面介绍如何替换 VMware 上的 Anthos 集群 (GKE On-Prem) 的高可用性 (HA) 用户集群中的故障 etcd 副本。

准备工作

  • 确保管理员集群正常运行。

  • 确保用户集群中的其他两个 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/etcdpdb.yaml

    其中:

    • ADMIN_CLUSTER_KUBECONFIG 是管理员集群的 kubeconfig 文件的路径。

    • USER_CLUSTER_NAME 是包含故障 etcd 副本的用户集群的名称。

  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 副本节点。

      ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etcd.local.config/certificates/etcdCA.crt --cert=/etcd.local.config/certificates/etcd.crt --key=/etcd.local.config/certificates/etcd.key --endpoints=https://127.0.0.1:2379 member remove MEMBER_ID

      其中 MEMBER_ID 是故障 etcd 副本节点的 ID。如需获取此 ID,请运行以下命令:

      ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etcd.local.config/certificates/etcdCA.crt --cert=/etcd.local.config/certificates/etcd.crt --key=/etcd.local.config/certificates/etcd.key member list -w fields

      上一命令会显示 etcd 集群的所有成员。输出类似于以下内容:

      sh-5.0# ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etcd.local.config/certificates/etcd.key member list -w fields
      
      "ClusterID" : 6963206042588294154
      "MemberID" : 4645269864592341793
      "Revision" : 0
      "RaftTerm" : 15
      "ID" : 2279696924967222455
      "Name" : "kube-etcd-2"
      "PeerURL" : "https://kube-etcd-2.kube-etcd:2380"
      "ClientURL" : "https://kube-etcd-2.kube-etcd:2379"
      "IsLearner" : false
      
      "ID" : 3728561467092418843
      "Name" : "kube-etcd-1"
      "PeerURL" : "https://kube-etcd-1.kube-etcd:2380"
      "ClientURL" : "https://kube-etcd-1.kube-etcd:2379"
      "IsLearner" : false
      
      "ID" : 4645269864592341793
      "Name" : "kube-etcd-0"
      "PeerURL" : "https://kube-etcd-0.kube-etcd:2380"
      "ClientURL" : "https://kube-etcd-0.kube-etcd:2379"
      "IsLearner" : false
      
      sh-5.0#
      

      上述输出中的 MemberID 是正常运行的 kube-etcd Pod 的成员 ID。接下来,获取失败的 etcd 副本节点的 ID。在前面的示例中 kube-etcd-0 具有 4645269864592341793IDkube-etcd-1 具有 3728561467092418843IDkube-etcd-2具有 2279696924967222455ID

      在创建 ID 成员后,请将其从十进制转换为十六进制,因为 member remove 命令接受十六进制成员 ID,而 member list 会返回小数。您可以使用 printf 进行转换。在此示例中,kube-etcd-2 将为:

      printf '%x\n' 2279696924967222455
      

      上述命令的输出是您需要用于 member remove 命令的 MEMBER_ID

    2. 添加名称和对等节点网址与失败副本节点相同的新成员。

      ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etcd.local.config/certificates/etcdCA.crt --cert=/etcd.local.config/certificates/etcd.crt --key=/etcd.local.config/certificates/etcd.key member add MEMBER_NAME --peer-urls=https://MEMBER_NAME.kube-etcd:2380

      其中 MEMBER_NAME 是故障 kube-etcd 副本节点的标识符。例如 kube-etcd-1kube-etcd-2

  6. 按照部署实用程序 Pod 的第 1-3 步,在管理员集群中创建实用程序 Pod。此 Pod 用于访问用户集群中故障 etcd 成员的 PersistentVolume (PV)。

  7. 从实用程序 Pod 中清理 etcd 数据目录。

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG exec -it -n USER_CLUSTER_NAME etcd-utility-MEMBER_NUMBER -- bash -c 'rm -rf /var/lib/etcd/*'
  8. 删除实用程序 pod。

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG delete pod -n USER_CLUSTER_NAME etcd-utility-MEMBER_NUMBER
  9. 取消封锁失败的节点。

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG uncordon NODE_NAME
  10. 在文本编辑器中打开 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
          ...
     
  11. 恢复第 1 步中删除的 etcd PDB。

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