ユーザー クラスタをバックアップおよび復元する

このドキュメントでは、ユーザー クラスタの 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 ストアを復元する前に、クラスタを診断して既存の問題を解決します。バックアップを使用して問題のあるクラスタを復元すると、問題が再び発生したり、悪化したりすることがあります。クラスタの復元について詳しくは、Anthos clusters on VMware サポートチームにお問い合わせください。

次の手順では、クラスタの etcd データが破損し、ユーザー クラスタの etcd Pod がクラッシュ ループした場合に、バックアップ ファイルを使用してユーザー クラスタを復元する方法について説明します。

破損したデータをバックアップで上書きするユーティリティ 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. 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 ユーザー クラスタの場合、ユーザー クラスタのコントロール プレーンとして機能する 3 つのノードが管理クラスタにあります。これらの各ノードでは、ストレージ ボリュームで etcd データを維持する etcd Pod が実行されます。

etcd Pod のうち 2 つが正常で、関連するストレージ ボリュームのデータに問題がない場合、バックアップ ファイルを使用する必要はありません。これは、まだ etcd クォーラムがあるためです。

まれに、2 つの 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 メンテナンス 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 について説明しています。

  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
    

    上記のコマンドにより、etcd データを /kube-etcd-MEMBER_NUMBER.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 メンテナンス 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
    

クラスタの自動バックアップ

クラスタを自動的にバックアップする方法の例として、以下に示すスクリプトを使用できます。以下のスクリプトはサポートされていないため、より適切で堅牢であり、完全なスクリプトを記述するための参照としてのみ使用してください。スクリプトを実行する前に、スクリプトの先頭にある 5 つの変数の値を入力します。

  • BACKUP_DIR を、管理クラスタとユーザー クラスタのバックアップを保存するパスに設定します。このパスは存在しません。
  • ADMIN_CLUSTER_KUBECONFIG を管理クラスタの kubeconfig ファイルのパスに設定します。
  • USER_CLUSTER_NAMESPACE をユーザー クラスタの名前に設定します。ユーザー クラスタの名前は管理クラスタ内の名前空間です。
  • EXTERNAL_IP を管理コントロール プレーン サービス用に予約した VIP に設定します。
  • SSH_PRIVATE_KEYSSH 認証鍵のパスに設定します。
  • プライベート ネットワークを使用している場合は、ネットワークの踏み台サーバーの IP アドレスに JUMP_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

次のステップ