사용자 클러스터 백업 및 복원

이 문서에서는 VMware용 Google Distributed Cloud(소프트웨어 전용)로 만든 사용자 클러스터의 etcd 저장소를 백업 및 복원하는 방법을 설명합니다. 또한 클러스터의 etcd 저장소를 자동으로 백업하는 데 사용할 수 있는 스크립트도 제공합니다.

클러스터의 etcd 데이터를 손상시킬 수 있는 예측하지 못한 재해 발생 시 복구할 수 있는 백업 파일을 만들 수 있습니다. 클러스터 외부에 있고 클러스터 작업에 종속되지 않는 위치에 백업 파일을 저장합니다.

제한사항

  • 이 절차에서는 애플리케이션별 데이터를 백업하지 않습니다.

  • 또한 PersistentVolume을 백업하지 않습니다.

  • 백업을 만든 후에 예약된 워크로드는 백업으로 복원되지 않습니다.

  • 업그레이드에 실패한 후에는 클러스터를 복원할 수 없습니다.

  • 이 절차는 삭제된 클러스터를 복원하기 위한 것이 아닙니다.

제한사항에 관한 자세한 내용은 인프라 비호환성을 참조하세요.

사용자 클러스터 백업

사용자 클러스터 백업은 사용자 클러스터 etcd 저장소의 스냅샷입니다. etcd 저장소에는 클러스터 상태를 관리하는 데 필요한 모든 Kubernetes 객체와 커스텀 객체가 포함되어 있습니다. 스냅샷에는 클러스터의 구성요소와 워크로드를 다시 만드는 데 필요한 데이터가 포함되어 있습니다.

수행하는 백업 단계는 사용자 클러스터에 Controlplane V2가 사용 설정되었는지 여부에 따라 다릅니다. Controlplane V2가 사용 설정되면 사용자 클러스터의 제어 영역은 사용자 클러스터 자체에서 실행됩니다. Controlplane V2가 사용 설정되지 않았으면 사용자 클러스터의 제어 영역이 kubeception이라고 하는 관리자 클러스터의 하나 이상의 노드에서 실행됩니다.

다음 명령어를 실행하여 클러스터에 Controlplane V2가 사용 설정되었는지 확인합니다.

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

출력이 true이면 Controlplane V2 단계에 따라 클러스터를 백업합니다. 그렇지 않으면 Kubeception 단계를 수행합니다.

Kubeception

  1. 셸을 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. 셸의 /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. 셸에 exit를 입력하여 셸을 종료합니다.

  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 포드 이름을 가져옵니다.

    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 포드가 있을 수 있습니다(예: HA 클러스터의 경우 3개). 백업을 위해서는 etcd 포드가 작동해야 합니다.

  2. 셸을 etcd 컨테이너로 가져옵니다.

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

    각 항목의 의미는 다음과 같습니다.

    • POD_NAME은 이전 단계에서 가져온 etcd 포드의 이름입니다.
  3. 셸에서 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. 셸에 exit를 입력하여 셸을 종료합니다.

  5. snapshot.dbetcd 컨테이너에서 워크스테이션 홈 디렉터리로 복사합니다.

    kubectl --kubeconfig USER_CLUSTER_KUBECONFIG \
     cp POD_NAME:/tmp/snapshot.db ~/snapshot.db \
     -c etcd -n kube-system
    
  6. PKI 디렉터리에서 보안 비밀을 복사합니다.

    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는 보안 비밀을 복사하려는 사용자 제어 영역 노드의 IP 주소입니다.

백업에서 사용자 클러스터 복원(비HA)

백업 파일을 사용하여 사용자 클러스터 etcd 저장소를 복원하기 전에 클러스터를 진단하고 기존 문제를 해결합니다. 백업을 사용하여 문제가 있는 클러스터를 복원하면 문제가 다시 생기거나 악화될 수 있습니다. 클러스터 복원에 대한 추가 지원은 Google Cloud 지원팀에 문의하세요.

다음 안내에서는 클러스터의 etcd 데이터가 손상되고 사용자 클러스터의 etcd pod가 비정상 종료되는 경우에 백업 파일을 사용하여 사용자 클러스터를 복원하는 방법을 설명합니다.

Kubeception

손상된 데이터를 백업으로 덮어쓰는 유틸리티 pod를 배포하면 etcd 데이터를 복원할 수 있습니다. 관리자 클러스터의 API 서버가 실행 중이어야 하며 관리자 클러스터의 스케줄러가 새 pod를 예약할 수 있어야 합니다.

  1. 사용자 클러스터에서 etcd에 의해 사용되는 보안 비밀의 이름을 찾습니다.

    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: kube-etcd-certs로 시작하는 사용자 클러스터에서 etcd에 의해 사용되는 보안 비밀의 이름입니다.

    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. 셸을 etcd-utility 컨테이너로 가져옵니다.

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG exec it \
      etcd-utility-0 --container etcd-utility --namespace USER_CLUSTER_NAME \
      -- bin/sh
    
  6. 셸의 루트 디렉터리에서 다음 명령어를 실행하여 백업이 포함된 새 폴더를 만듭니다.

    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. 셸에서 이전 etcd 데이터를 삭제합니다.

    rm -r var/lib/etcd/*
    
  8. 셸에서 복원된 etcd 데이터를 영구 위치로 복사합니다.

    cp -r default.etcd/* var/lib/etcd/
    
  9. 셸에 exit를 입력하여 셸을 종료합니다.

  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. 사용자 제어 영역 노드로 셸을 가져옵니다.

    ssh -i NODE_NAME.key ubuntu@NODE_EXTERNAL_IP
    
  2. 셸에서 Kubernetes API 서버 및 etcd 서버를 중지합니다.

    sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/etcd.yaml ~
    
  3. 셸에 exit를 입력하여 셸을 종료합니다.

  4. scp를 실행하여 백업 파일 snapshot.db와 보안 비밀을 사용자 제어 영역 노드에 복사합니다.

    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. 셸에서 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. 셸에서 kube-apiserver 및 etcd 서버를 시작합니다.

    sudo mv ~/etcd.yaml ~/kube-apiserver.yaml /etc/kubernetes/manifests/
    
  8. 셸에 exit를 입력하여 셸을 종료합니다.

백업에서 사용자 클러스터 복원(HA)

Kubeception

이 섹션에서는 고가용성(HA) 사용자 클러스터의 etcd 데이터를 복원하는 방법을 설명합니다.

HA 사용자 클러스터의 경우 사용자 클러스터의 제어 영역 역할을 하는 노드 세 개가 관리자 클러스터에 있습니다. 이러한 각 노드는 etcd pod를 실행하고 etcd 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 유지보수 배포를 중지합니다. 이렇게 하면 복원 중에 구성요소가 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 이름과 포드가 실행되는 노드의 이름을 재호출합니다.

  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 데이터를 복원하는 유틸리티 포드를 설명합니다.

  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. 유틸리티 pod의 etcd-utility 컨테이너로 셸을 가져옵니다.

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG exec -it --namespace USER_CLUSTER_NAME \
    etcd-utility-MEMBER_NUMBER --container etcd-utility -- bin/sh
    
  4. 셸의 루트 디렉터리에서 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
    

    앞의 명령어는 /kube-etcd-MEMBER_NUMBER.etcd 디렉터리에 etcd 데이터를 저장했습니다.

  5. 셸에서 이전 etcd 데이터를 삭제합니다.

    rm -r var/lib/etcd/*
    
  6. 셸에서 복원된 etcd 데이터를 영구 위치로 복사합니다.

    cp -r kube-etcd-MEMBER_NUMBER.etcd/* var/lib/etcd/
    
  7. 셸에서 임시 etcd 디렉터리와 백업 파일을 삭제합니다.

    rm -R kube-etcd-MEMBER_NUMBER.etcd/
    rm snapshot.db
    
  8. 셸에 exit를 입력하여 셸을 종료합니다.

  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 유지보수 배포를 시작합니다.

    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 데이터를 복원하는 방법을 설명합니다.

HA 사용자 클러스터의 경우 사용자 클러스터의 제어 영역 역할을 하는 노드 세 개가 사용자 클러스터에 있습니다. 이러한 각 노드는 etcd pod를 실행하고 etcd pod는 스토리지 볼륨에 etcd 데이터를 유지합니다.

etcd pod 두 개가 정상이고 연결된 스토리지 볼륨의 데이터가 손상되지 않았으면 백업 파일을 사용할 필요가 없습니다. 여전히 etcd 쿼럼이 있기 때문입니다.

드물지만 etcd 스토리지 볼륨 두 개의 데이터가 손상되었으면 백업 파일을 사용하여 etcd 데이터를 복원해야 합니다.

이 섹션의 단계를 수행하려면 사용자 클러스터 백업의 설명대로 이미 snapshot.db 파일을 만든 상태여야 합니다.

etcd Pod 및 노드 나열

  1. etcd 포드 및 해당 노드를 나열합니다.

    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 포드 이름은 etcd-xxx에 노드 이름이 추가된 이름입니다. Controlplane V2에서는 etcd 포드가 정적 포드로 실행되기 때문입니다.

복원 준비

  1. scp를 실행하여 백업 파일 snapshot.db를 모든 사용자 제어 영역 노드에 복사합니다.

    scp -i NODE_NAME.key ~/snapshot.db ubuntu@NODE_EXTERNAL_IP:/tmp/
    
  2. 보안 비밀을 각 사용자 제어 영역 노드에 복사합니다.

    chmod a+rw ~/pki_*
    scp -ri NODE_NAME.key ~/pki_NODE_NAME/* ubuntu@NODE_EXTERNAL_IP:/opt/data/etc/kubernetes/pki/
    
  3. 사용자 제어 영역 노드로 셸을 가져옵니다.

    ssh -i NODE_NAME.key ubuntu@NODE_EXTERNAL_IP
    

복원 수행

  1. etcd pod 이름과 포드가 실행되는 노드의 이름을 재호출합니다.

  2. 셸의 모든 사용자 제어 영역 노드에서 Kubernetes API 서버 및 etcd 서버를 중지합니다.

    sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/etcd.yaml ~
    
  3. 셸에서 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 플래그에 NODE1, NODE2, NODE3 및 각 노드의 IP를 입력합니다. etcd 매니페스트에서도 가져올 수 있습니다.
  4. 컨테이너 명령어 아래의 etcd 매니페스트 파일에 - --initial-cluster-state=existing 플래그를 추가합니다.

    예:

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

구성요소 다시 시작

  1. 셸의 모든 사용자 제어 영역 노드에서 kube-apiserveretcd 서버를 시작합니다.

    sudo mv ~/etcd.yaml ~/kube-apiserver.yaml /etc/kubernetes/manifests/
    
  2. 셸에 exit를 입력하여 셸을 종료합니다.

  3. kube-apiserveretcd가 모든 사용자 제어 영역 노드에서 실행되는지 확인합니다.

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

자동 클러스터 백업

여기에서 제공된 스크립트를 클러스터를 자동으로 백업하는 방법에 대한 예시로 사용할 수 있습니다. 다음 스크립트는 지원되지 않으며 더 강력하고 완전한 스크립트를 작성하기 위한 참조로만 사용되어야 합니다. 스크립트를 실행하기 전에 스크립트 시작 부분에 있는 변수 5개의 값을 입력합니다.

Kubeception

  • BACKUP_DIR를 관리자 클러스터와 사용자 클러스터 백업을 저장할 경로로 설정합니다. 이 경로는 존재하지 않아야 합니다.
  • ADMIN_CLUSTER_KUBECONFIG를 관리자 클러스터의 kubeconfig 파일 경로로 설정합니다.
  • USER_CLUSTER_NAMESPACE를 사용자 클러스터 이름으로 설정합니다. 사용자 클러스터 이름은 관리자 클러스터의 네임스페이스입니다.
  • EXTERNAL_IP를 관리자 컨트롤 플레인 서비스에 사용하도록 예약한 VIP로 설정합니다.
  • SSH_PRIVATE_KEYSSH 키 경로로 설정합니다.
  • 비공개 네트워크를 사용하는 경우 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_KEYSSH 키 경로로 설정합니다.
  • 비공개 네트워크를 사용하는 경우 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 진단 클러스터를 실행합니다.

다음 단계