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

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

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

제한사항

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

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

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

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

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

사용자 클러스터 백업

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

etcd 저장소의 스냅샷을 만들려면 다음 단계를 수행합니다.

  1. 셸을 kube-etcd 컨테이너로 가져옵니다.

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG exec -it \
       kube-etcd-0 --container kube-etcd --namespace USER_CLUSTER_NAME \
       -- bin/sh
    

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

    • ADMIN_CLUSTER_KUBECONFIG는 관리자 클러스터의 kubeconfig 파일입니다.
    • USER_CLUSTER_NAME은 사용자 클러스터 이름입니다.
  2. 셸의 루트 디렉터리에 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 snapshot.db
    
  3. 셸에 exit를 입력하여 셸을 종료합니다.

  4. snapshot.dbkube-etcd 컨테이너에서 현재 디렉터리로 복사합니다.

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

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

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

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

손상된 데이터를 백업으로 덮어쓰는 유틸리티 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
    

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

이 섹션에서는 고가용성(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       ...   node-xxx
    kube-etcd-1       ...   node-yyy
    kube-etcd-2       ...   node-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의 컨테이너 이미지 이름을 재호출합니다.

유틸리티 포드 배포

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

  3. 관리자 클러스터에서 유틸리티 pod를 만듭니다.

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG apply -f etcd-utility-MEMBER_NUMBER.yaml
    
  4. 백업 파일 snapshot.db를 유틸리티 pod의 루트 디렉터리에 복사합니다.

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG cp snapshot.db \
       USER_CLUSTER_NAME/etcd-utility-MEMBER_NUMBER:snapshot.db
    
  5. 유틸리티 pod의 etcd-utility 컨테이너로 셸을 가져옵니다.

    kubectl --kubeconfig ADMIN_CLUSTER_KUBECONIFG exec -it --namespace USER_CLUSTER_NAME \
       etcd-utility-MEMBER_NUMBER --container etcd-utility -- bin/sh
    
  6. 셸의 루트 디렉터리에서 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 데이터를 저장했습니다.

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

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

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

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

  11. 유틸리티 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
    

자동 클러스터 백업

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

  • 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

다음 단계