备份和恢复用户集群

本文档介绍如何备份和恢复用户集群的 etcd 存储区。此页面还提供了一个脚本,您可以使用该脚本自动备份集群的 etcd 存储区。

您可以创建备份文件,以便从可能会损坏集群的 etcd 数据的不可预见的灾难中恢复。请将备份文件存储在集群外部且不依赖于集群操作的位置。

限制

  • 此过程不会备份应用特定的数据。

  • 此过程不会备份您的 PersistentVolume。

  • 创建备份后安排的工作负载不会随该备份一起恢复。

  • 升级失败后,您无法恢复集群。

  • 此过程不适用于恢复已删除的集群。

备份用户集群

用户集群备份是用户集群的 etcd 存储区的快照。 etcd 存储区包含管理集群状态所需的所有 Kubernetes 对象和自定义对象。快照包含重新创建集群组件和工作负载所需的数据。

您应遵循的备份步骤取决于用户集群是否启用了 Controlplane V2。启用 Controlplane V2 后,用户集群的控制平面会在用户集群本身上运行。未启用 Controlplane V2 时,用户集群的控制平面会在管理员集群中的一个或多个节点上运行,这称为 kubeception。

运行以下命令以确定集群是否已启用控制平面 V2:

kubectl get onpremuserclusters --kubeconfig USER_CLUSTER_KUBECONFIG \
  -n kube-system -o jsonpath='{.items[0].spec.enableControlplaneV2}' && echo

如果输出为 true,请按照 Controlplane V2 步骤备份集群。否则,请按照 Kubeception 步骤操作。除了密钥、证书和 etcd pod 名称的位置之外,备份步骤是相同的。

Kubeception

  1. 通过 shell 进入 kube-etcd 容器:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG exec -it \
     kube-etcd-0 -c kube-etcd -n USER_CLUSTER_NAME \
     -- /bin/sh
    

    其中:

    • ADMIN_CLUSTER_KUBECONFIG 是管理员集群的 kubeconfig 文件。
    • USER_CLUSTER_NAME 是用户集群的名称。
  2. 在 shell 的 /tmp 目录中,创建名为 snapshot.db 的备份:

    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 \
      snapshot save /tmp/snapshot.db
    
  3. 在 shell 中,输入 exit 以退出 shell。

  4. /tmp/snapshot.dbkube-etcd 容器复制到当前目录:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG cp \
      USER_CLUSTER_NAME/kube-etcd-0:/tmp/snapshot.db \
      --container kube-etcd snapshot.db
    

控制平面 V2

  1. 获取 etcd pod 的名称:

    kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get pods \
     -n kube-system -l component=etcd,tier=control-plane -ojsonpath='{$.items[*].metadata.name}{"\n"}'
    

    其中:

    • USER_CLUSTER_KUBECONFIG 是用户集群的 kubeconfig 文件。

    示例:

    NAME           READY   STATUS    RESTARTS   AGE
    etcd-uc1-cp1   1/1     Running   0          38m
    etcd-uc1-cp2   1/1     Running   0          37m
    etcd-uc1-cp3   1/1     Running   0          38m
    

    请注意,可以有多个 etcd Pod,例如,高可用性集群为 3 个。对于备份,任何 etcd Pod 都应正常运行。

  2. 通过 shell 进入 etcd 容器:

    kubectl --kubeconfig USER_CLUSTER_KUBECONFIG exec -it \
     POD_NAME -c etcd -n kube-system -- /bin/sh
    
    

    其中:

    • POD_NAME 是从上一步中获取的 etcd pod 的名称。
  3. 在 shell 中,创建一个名为 snapshot.db 的备份文件:

    ETCDCTL_API=3 etcdctl \
      --endpoints=https://127.0.0.1:2379 \
      --cacert=/etc/kubernetes/pki/etcd/ca.crt \
      --cert=/etc/kubernetes/pki/etcd/server.crt \
      --key=/etc/kubernetes/pki/etcd/server.key \
      snapshot save /tmp/snapshot.db
    
  4. 在 shell 中,输入 exit 以退出 shell。

  5. snapshot.dbetcd 容器复制到工作站主目录:

    kubectl --kubeconfig USER_CLUSTER_KUBECONFIG \
     cp POD_NAME:/tmp/snapshot.db ~/snapshot.db \
     -c etcd -n kube-system
    
  6. 从 PKI 目录复制 Secret:

    ssh -i NODE_NAME.key ubuntu@NODE_EXTERNAL_IP
    sudo chmod -R 0644 /etc/kubernetes/pki/*
    sudo chmod 0755 /etc/kubernetes/pki/etcd
    exit
    scp -ri NODE_NAME.key ubuntu@NODE_EXTERNAL_IP:/etc/kubernetes/pki ~/pki_NODE_NAME
    

    其中:

    • NODE_NAME 是包含控制平面节点的 ssh 密钥的文件
    • NODE_EXTERNAL_IP 是您要从中复制 Secret 的用户控制平面节点的 IP 地址,

从备份恢复用户集群(非 HA)

在使用备份文件恢复用户集群的 etcd 存储区之前,请先诊断集群并解决现有问题。使用备份来恢复有问题的集群可能会重新创建或加剧问题。请与 GKE on VMware 支持团队联系,获取有关恢复集群的更多帮助。

以下说明介绍了在集群的 etcd 数据已损坏且用户集群的 etcd pod 出现崩溃循环时,如何使用备份文件恢复用户集群。

Kubeception

您可以部署一个实用程序 pod(使用备份覆盖已损坏的数据)来恢复 etcd 数据。管理员集群的 API 服务器必须正在运行,并且管理员集群的调度器必须能够安排新的 pod。

  1. 在用户集群中查找 etcd 使用的 Secret 的名称:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG -n USER_CLUSTER_NAME \
       get secrets | grep kube-etcd-certs
    
  2. 将以下 pod 清单复制到名为 etcd-utility.yaml 的文件中。请替换以下内容:

    • NODE_NAME:运行 kube-etcd-0 pod 的节点。

    • ADMIN_CLUSTER_KUBECONFIG:管理员集群的 kubeconfig 文件。

    • USER_CLUSTER_NAME:用户集群的名称。

    • GKE_ON_PREM_VERSION:要在其中执行 etcd 恢复的集群版本(例如 1.5.0-gke.0)。

    • KUBE_ETCD_SECRET_NAME:用户集群中 etcd 使用的 Secret 的名称,以 kube-etcd-certs 开头。

    apiVersion: v1
    kind: Pod
    metadata:
     name: etcd-utility-0
     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-0
     - name: etcd-certs
       secret:
         defaultMode: 420
         secretName: KUBE_ETCD_SECRET_NAME
    
  3. 部署实用程序 pod:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG \
      create -f etcd-utility.yaml --namespace USER_CLUSTER_NAME
    
  4. snapshot.db 从当前目录复制到实用程序 pod 的根目录:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG cp snapshot.db \
      USER_CLUSTER_NAME/etcd-utility-0:snapshot.db --container etcd-utility
    
  5. 通过 shell 进入 etcd-utility 容器:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG exec it \
      etcd-utility-0 --container etcd-utility --namespace USER_CLUSTER_NAME \
      -- bin/sh
    
  6. 在 shell 的根目录中,运行以下命令创建一个包含备份的新文件夹:

    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 \
      snapshot restore snapshot.db
    
  7. 在 shell 中,删除旧的 etcd 数据:

    rm -r var/lib/etcd/*
    
  8. 在 shell 中,将恢复后的 etcd 数据复制到其永久位置:

    cp -r default.etcd/* var/lib/etcd/
    
  9. 在 shell 中,输入 exit 以退出 shell。

  10. 删除崩溃的 etcd pod:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG \
      delete pod kube-etcd-0 --namespace USER_CLUSTER_NAME
    
  11. 验证 etcd pod 是否不再崩溃。

  12. 删除实用程序 pod:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG \
      delete pod etcd-utility-0 --namespace USER_CLUSTER_NAME
  13. 从当前目录中移除 etcd-utility.yaml

    rm etcd-utility.yaml
    

控制平面 V2

您可以部署一个临时 etcd 容器以用备份覆盖损坏的数据,从而一次恢复一个 etcd 数据。

  1. 通过 shell 连接到用户控制平面节点:

    ssh -i NODE_NAME.key ubuntu@NODE_EXTERNAL_IP
    
  2. 在 shell 中,停止 Kubernetes API 服务器和 etcd 服务器:

    sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/etcd.yaml ~
    
  3. 在 shell 中,输入 exit 以退出 shell。

  4. 运行 scp 将备份文件 snapshot.db 和 Secret 复制到用户控制平面节点:

    scp -i NODE_NAME.key ~/snapshot.db ubuntu@NODE_EXTERNAL_IP:/tmp/
    
    chmod a+rw pki/
    scp -ri NODE_NAME.key ~/pki_NODE_NAME ubuntu@NODE_EXTERNAL_IP:/etc/kubernetes/pki
    
  5. 在 shell 中,使用 snapshot.db 恢复 etcd 数据:

    sudo docker run --rm -t \
    -v /opt/data/var/lib:/var/lib \
    -v /etc/kubernetes/pki/etcd:/etc/kubernetes/pki/etcd \
    -v /tmp:/tmp \
    --env ETCDCTL_API=3 \
    gcr.io/gke-on-prem-release/etcd-util:GKE_ON_PREM_VERSION etcdctl \
    --cacert=/etc/kubernetes/pki/etcd/ca.crt \
    --cert=/etc/kubernetes/pki/etcd/server.crt \
    --key=/etc/kubernetes/pki/etcd/server.key \
    --data-dir=/opt/data/var/lib/etcd \
    --name=NODE_NAME \
    --initial-advertise-peer-urls=https://NODE_IP_ADDRESS:2380 \
    --initial-cluster=NODE_NAME=https://NODE_IP_ADDRESS:2380 \
    snapshot restore /tmp/snapshot.db
    

    其中:

    • GKE_ON_PREM_VERSION 是用作映像标记的 GKE Enterprise 版本
    • NODE_NAME 是要执行恢复的节点的名称
    • NODE_IP_ADDRESS 是上述节点的 IP
  6. 在 etcd 清单文件中的容器命令下添加标志 - --initial-cluster-state=new

    示例:

    containers:
          - command:
            - etcd
            ...
            - --initial-cluster-state=new
            ...

  7. 在 shell 中,启动 kube-apiserver 和 etcd 服务器:

    sudo mv etcd.yaml kube-apiserver.yaml /etc/kubernetes/manifests/
    
  8. 在 shell 中,输入 exit 以退出 shell。

从备份恢复用户集群 (HA)

Kubeception

本部分介绍如何为高可用性 (HA) 用户集群恢复 etcd 数据。

对于高可用性用户集群,管理员集群中有三个节点作为用户集群的控制层面。这些节点中的每个节点都运行一个 etcd pod,该 pod 维护存储卷上的 etcd 数据。

如果有两个 etcd pod 运行状况良好,并且关联存储卷上的数据保持不变,则无需使用备份文件。这是因为您仍然有一个 etcd 仲裁。

在极少数情况下,如果两个 etcd 存储卷中的数据都损坏,则您需要使用备份文件来恢复 etcd 数据。

如需执行本部分中的步骤,您必须已创建 snapshot.db 文件,如备份用户集群中所述。

列出您的 etcd pod 和节点

  1. 列出管理您的用户集群的 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       ...   xxx
    kube-etcd-1       ...   yyy
    kube-etcd-2       ...   zzz
    
  2. 记下 Pod 名称和控制层面节点名称以备后续使用。

    请注意,每个 etcd pod 都会以 kube-etcd 后跟数字的形式来命名。 此数字称为 pod 的“成员编号”。它会将 pod 标识为容纳用户集群对象数据的 etcd 集群的特定成员。本指南使用占位符 MEMBER_NUMBER 来指代 etcd pod 成员编号。

    另请注意,etcd 集群中的每个 pod 都在各自的节点上运行。

准备部署实用程序 pod

  1. 为用户集群的 Kubernetes API 服务器保存 PodDisruptionBudget (PDB) 清单。然后删除 PDB。

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG get pdb --namespace USER_CLUSTER_NAME \
    kube-apiserver-pdb --output yaml > kube-apiserver-pdb.yaml
    
    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG delete pdb --namespace USER_CLUSTER_NAME \
    kube-apiserver-pdb
    
  2. 停止 Kubernetes API 服务器和 etcd 维护 Deployment。这样可以确保在恢复期间没有组件使用 etcd:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG --namespace USER_CLUSTER_NAME \
    scale --replicas 0 statefulset kube-apiserver
    
    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG --namespace USER_CLUSTER_NAME \
    scale --replicas 0 deployment gke-master-etcd-maintenance
    
  3. 回调您的 etcd pod 的容器映像的名称。

部署实用程序 pod

  1. 回调 etcd pod 的名称和运行 pod 的节点的名称。

  2. 在当前目录中将以下 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

上述清单描述了您为了恢复 etcd 数据而临时运行的实用程序 Pod。

  1. 在管理员集群中创建实用程序 pod:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG apply -f etcd-utility-MEMBER_NUMBER.yaml
    
  2. 将备份文件 snapshot.db 复制到实用程序 pod 的根目录中:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG cp snapshot.db \
    USER_CLUSTER_NAME/etcd-utility-MEMBER_NUMBER:snapshot.db
    
  3. 通过 shell 进入实用程序 pod 中的 etcd-utility 容器:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG exec -it --namespace USER_CLUSTER_NAME \
    etcd-utility-MEMBER_NUMBER --container etcd-utility -- bin/sh
    
  4. 在 shell 的根目录中,使用 snapshot.db 来恢复 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 \
    --name=kube-etcd-MEMBER_NUMBER \
    --initial-cluster=kube-etcd-0=https://kube-etcd-0.kube-etcd:2380,kube-etcd-1=https://kube-etcd-1.kube-etcd:2380,kube-etcd-2=https://kube-etcd-2.kube-etcd:2380 \
    --initial-cluster-token=etcd-cluster-1 \
    --initial-advertise-peer-urls=https://kube-etcd-MEMBER_NUMBER.kube-etcd:2380 \
    snapshot restore snapshot.db
    

    上述命令将 etcd 数据存储在 /kube-etcd-MEMBER_NUMBER.etcd 目录中。

  5. 在 shell 中,删除旧的 etcd 数据:

    rm -r var/lib/etcd/*
    
  6. 在 shell 中,将恢复后的 etcd 数据复制到其永久位置:

    cp -r kube-etcd-MEMBER_NUMBER.etcd/* var/lib/etcd/
    
  7. 在 shell 中,移除临时 etcd 目录和备份文件:

    rm -R kube-etcd-MEMBER_NUMBER.etcd/
    rm snapshot.db
    
  8. 在 shell 中,输入 exit 以退出 shell。

  9. 删除实用程序 pod:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG delete pod \
    --namespace USER_CLUSTER_NAME etcd-utility-MEMBER_NUMBER
    

重启组件

现在您已部署和删除了实用程序 pod,接下来需要重启一些集群组件。

  1. kube-etcd StatefulSet 中重启 pod:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG rollout restart statefulset \
    --namespace USER_CLUSTER_NAME kube-etcd
    
  2. 为您的用户集群启动 Kubernetes API 服务器:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG scale statefulset --replicas 3 \
    --namespace USER_CLUSTER_NAME kube-apiserver
    
  3. 为您的用户集群启动 etcd 维护 Deployment:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG scale deployment --replicas 1 \
    --namespace=USER_CLUSTER_NAME  gke-master-etcd-maintenance
    
  4. 为 Kubernetes API 服务器恢复 PDB:

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG apply -f kube-apiserver-pdb.yaml
    

控制平面 V2

本部分介绍如何为高可用性 (HA) 用户集群恢复 etcd 数据。

对于高可用性用户集群,用户集群中有三个节点用作用户集群的控制平面。这些节点中的每个节点都运行一个 etcd pod,该 pod 维护存储卷上的 etcd 数据。

如果有两个 etcd pod 运行状况良好,并且关联存储卷上的数据保持不变,则无需使用备份文件。这是因为您仍然有一个 etcd 仲裁。

在极少数情况下,如果两个 etcd 存储卷中的数据都损坏,则您需要使用备份文件来恢复 etcd 数据。

要执行本部分中的步骤,您必须已按照备份用户集群中的说明创建了一个 snapshot.db 文件。

列出您的 etcd pod 和节点

  1. 列出 etcd Pod 及其各自的节点:

    kubectl get pod --kubeconfig USER_CLUSTER_KUBECONFIG \
     -n kube-system -l component=etcd,tier=control-plane -o wide
    

    输出结果会显示 etcd pod 和 pod 运行的节点。输出中显示的节点是管理员集群中作为用户集群控制层面的节点:

    NAME           ...   NODE
    etcd-xxx       ...   xxx
    etcd-yyy       ...   yyy
    etcd-zzz       ...   zzz
    
  2. 记下 Pod 名称和控制层面节点名称以备后续使用。

    请注意,每个 etcd pod 的名称都是 etcd-xxx,并附加一个节点名称。这是因为在控制平面 V2 中,etcd pod 作为静态 pod 运行。

正在准备恢复

  1. 运行 scp 以将备份文件 snapshot.db 复制到所有用户控制平面节点:

    scp ~/snapshot.db -i NODE_NAME.key ubuntu@NODE_EXTERNAL_IP:/tmp/
    
  2. 将密钥复制到相应的用户控制平面节点:

    chmod a+rw pki/
    scp -r ~/pki -i NODE_NAME.key ubuntu@NODE_EXTERNAL_IP:/etc/kubernetes/
    
  3. 通过 shell 连接到用户控制平面节点:

    ssh -i NODE_NAME.key ubuntu@NODE_EXTERNAL_IP
    

执行恢复

  1. 回调 etcd pod 的名称和运行 pod 的节点的名称。

  2. 在 shell 中,停止所有用户控制平面节点上的 Kubernetes API 服务器和 etcd 服务器:

    sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/etcd.yaml ~
    
  3. 在 shell 中,使用 snapshot.db 恢复所有用户控制平面节点上的 etcd 数据:

    sudo docker run --rm -t \
    -v /opt/data/var/lib:/var/lib \
    -v /etc/kubernetes/pki/etcd:/etc/kubernetes/pki/etcd \
    -v /tmp:/tmp \
    --env ETCDCTL_API=3 \
    gcr.io/gke-on-prem-release/etcd-util:GKE_ON_PREM_VERSION etcdctl \
    --cacert=/etc/kubernetes/pki/etcd/ca.crt \
    --cert=/etc/kubernetes/pki/etcd/server.crt \
    --key=/etc/kubernetes/pki/etcd/server.key \
    --data-dir=/opt/data/var/lib/etcd \
    --name=NODE_NAME \
    --initial-advertise-peer-urls=https://NODE_IP_ADDRESS:2380 \
    --initial-cluster=NODE1=https://NODE1_IP:2380,NODE2=https://NODE2_IP:2380,NODE3=https://NODE3_IP:2380 \
    snapshot restore /tmp/snapshot.db
    

    其中:

    • GKE_ON_PREM_VERSION 是用作映像标记的 GKE Enterprise 版本
    • NODE_NAME 是要执行恢复的节点的名称
    • NODE_IP_ADDRESS 是上述节点的 IP
    • 针对 --initial-cluster 标志填充各自节点的 NODE1NODE2NODE3IP。您也可以从 etcd 清单中获取此值。
  4. 在 etcd 清单文件中的容器命令下添加标志 - --initial-cluster-state=existing

    示例:

    containers:
          - command:
            - etcd
            ...
            - --initial-cluster-state=existing
            ...

重启组件

  1. 在 shell 中,启动所有用户控制平面节点的 kube-apiserveretcd 服务器:

    sudo mv ~/etcd.yaml ~/kube-apiserver.yaml /etc/kubernetes/manifests/
    
  2. 在 shell 中,输入 exit 以退出 shell。

  3. 验证 kube-apiserveretcd 在所有用户控制平面节点上运行:

    kubectl get pod --kubeconfig USER_CLUSTER_KUBECONFIG \
    -n kube-system -l tier=control-plane
    

自动备份集群

您可以使用此处提供的示例脚本自动备份集群。请注意,以下脚本不受支持,仅供参考,您应在此基础上编写更好、更可靠且更完善的脚本。在运行脚本之前,请在脚本开头填写五个变量的值:

Kubeception

  • BACKUP_DIR 设置为您要存储管理员集群和用户集群备份的路径。此路径不应存在。
  • ADMIN_CLUSTER_KUBECONFIG 设置为管理员集群的 kubeconfig 文件的路径。
  • USER_CLUSTER_NAMESPACE 设置为您的用户集群的名称。用户集群的名称是管理员集群中的命名空间。
  • EXTERNAL_IP 设置为您为管理员控制层面服务预留的 VIP。
  • SSH_PRIVATE_KEY 设置为 SSH 密钥的路径。
  • 如果您使用的是专用网络,请将 JUMP_IP 设置为该网络的跳转服务器的 IP 地址。
#!/usr/bin/env bash

# Automates manual steps for taking backups of user and admin clusters.
# Fill in the variables below before running the script.

BACKUP_DIR=""                       # path to store user and admin cluster backups
ADMIN_CLUSTER_KUBECONFIG=""         # path to admin cluster kubeconfig
USER_CLUSTER_NAMESPACE=""           # user cluster namespace
EXTERNAL_IP=""                      # admin control plane node external ip - follow steps in documentation
SSH_PRIVATE_KEY=""                  # path to vsphere_tmp ssh private key - follow steps in documentation
JUMP_IP=""                          # network jump server IP - leave empty string if not using private network.

mkdir -p $BACKUP_DIR
mkdir $BACKUP_DIR/pki

# USER CLUSTER BACKUP

# Snapshot user cluster etcd
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} exec -it -n ${USER_CLUSTER_NAMESPACE} kube-etcd-0 -c kube-etcd -- /bin/sh -ec "export 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 snapshot save ${USER_CLUSTER_NAMESPACE}_snapshot.db"
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} cp ${USER_CLUSTER_NAMESPACE}/kube-etcd-0:${USER_CLUSTER_NAMESPACE}_snapshot.db $BACKUP_DIR/user-cluster_${USER_CLUSTER_NAMESPACE}_snapshot.db

# ADMIN CLUSTER BACKUP

# Set up ssh options
SSH_OPTS=(-oStrictHostKeyChecking=no -i ${SSH_PRIVATE_KEY})
if [ "${JUMP_IP}" != "" ]; then
  SSH_OPTS+=(-oProxyCommand="ssh -oStrictHostKeyChecking=no -i ${SSH_PRIVATE_KEY} -W %h:%p ubuntu@${JUMP_IP}")
fi

# Copy admin certs
ssh "${SSH_OPTS[@]}" ubuntu@${EXTERNAL_IP} 'sudo chmod -R +rw /etc/kubernetes/pki/*'
scp -r "${SSH_OPTS[@]}" ubuntu@${EXTERNAL_IP}:/etc/kubernetes/pki/* ${BACKUP_DIR}/pki/

# Snapshot admin cluster etcd
admin_etcd=$(kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} get pods -n kube-system -l component=etcd,tier=control-plane -ojsonpath='{$.items[*].metadata.name}{"\n"}')
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} exec -it -n kube-system ${admin_etcd} -- /bin/sh -ec "export ETCDCTL_API=3; etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key snapshot save admin_snapshot.db"
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} cp -n kube-system ${admin_etcd}:admin_snapshot.db $BACKUP_DIR/admin-cluster_snapshot.db

控制平面 V2

  • BACKUP_DIR 设置为您要存储管理员集群和用户集群备份的路径。此路径不应存在。
  • ADMIN_CLUSTER_KUBECONFIG 设置为管理员集群的 kubeconfig 文件的路径。
  • USER_CLUSTER_KUBECONFIG 设置为用户集群 kubeconfig 的路径。
  • EXTERNAL_IP 设置为您为管理员控制层面服务预留的 VIP。
  • SSH_PRIVATE_KEY 设置为 SSH 密钥的路径。
  • 如果您使用的是专用网络,请将 JUMP_IP 设置为该网络的跳转服务器的 IP 地址。
#!/usr/bin/env bash

# Automates manual steps for taking backups of user and admin clusters.
# Fill in the variables below before running the script.

BACKUP_DIR=""                       # path to store user and admin cluster backups
ADMIN_CLUSTER_KUBECONFIG=""         # path to admin cluster kubeconfig
USER_CLUSTER_KUBECONFIG=""          # path to user cluster kubeconfig
EXTERNAL_IP=""                      # admin control plane node external ip - follow steps in documentation
SSH_PRIVATE_KEY=""                  # path to ssh private key - follow steps in documentation
JUMP_IP=""                          # network jump server IP - leave empty string if not using private network

mkdir -p $BACKUP_DIR
mkdir $BACKUP_DIR/pki

# USER CLUSTER BACKUP
user_etcd=$(kubectl --kubeconfig=${USER_CLUSTER_KUBECONFIG} get pods -n kube-system -l component=etcd,tier=control-plane -ojsonpath='{$.items[0].metadata.name}{"\n"}')
kubectl --kubeconfig=${USER_CLUSTER_KUBECONFIG} exec -it -n kube-system ${user_etcd} -c etcd -- /bin/sh -ec "export ETCDCTL_API=3; etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key snapshot save /tmp/${user_etcd}_snapshot.db"
kubectl --kubeconfig=${USER_CLUSTER_KUBECONFIG} cp kube-system/${user_etcd}:/tmp/${user_etcd}_snapshot.db $BACKUP_DIR/${user_etcd}_snapshot.db

# ADMIN CLUSTER BACKUP

# Set up ssh options
SSH_OPTS=(-oStrictHostKeyChecking=no -i ${SSH_PRIVATE_KEY})
if [ "${JUMP_IP}" != "" ]; then
  SSH_OPTS+=(-oProxyCommand="ssh -oStrictHostKeyChecking=no -i ${SSH_PRIVATE_KEY} -W %h:%p ubuntu@${JUMP_IP}")
fi

# Copy admin certs
ssh "${SSH_OPTS[@]}" ubuntu@${EXTERNAL_IP} 'sudo chmod -R +rw /etc/kubernetes/pki/*'
scp -r "${SSH_OPTS[@]}" ubuntu@${EXTERNAL_IP}:/etc/kubernetes/pki/* ${BACKUP_DIR}/pki/

# Snapshot admin cluster etcd
admin_etcd=$(kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} get pods -n kube-system -l component=etcd,tier=control-plane -ojsonpath='{$.items[*].metadata.name}{"\n"}')
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} exec -it -n kube-system ${admin_etcd} -- /bin/sh -ec "export ETCDCTL_API=3; etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key snapshot save /tmp/${admin_etcd}_snapshot.db"
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} cp -n kube-system ${admin_etcd}:/tmp/${admin_etcd}_snapshot.db $BACKUP_DIR/${admin_etcd}_snapshot.db

验证恢复

如需验证您的集群是否已成功恢复,请运行 gkectl diagnose cluster

后续步骤