管理クラスタのバックアップと復元

このドキュメントでは、VMware 用 Google Distributed Cloud(ソフトウェアのみ)で作成された管理クラスタの etcd ストアをバックアップして復元する方法について説明します。このドキュメントでは、クラスタの etcd ストアを自動的にバックアップするために使用できるスクリプトも示します。gkectl コマンドライン ツールを使用して、管理クラスタのバックアップと復元を行うこともできます。

クラスタの etcd のデータに損害を与える可能性がある想定外の災害からの復旧用のバックアップを作成する必要があります。バックアップ ファイルは、クラスタの外部にあり、クラスタのオペレーションに依存しない場所に保存してください。

制限事項

このドキュメントで説明するバックアップと復元の手順には、次の制限があります。

  • この手順では、アプリケーション固有のデータはバックアップされません。

  • この手順では、PersistentVolume はバックアップされません。

  • バックアップの作成後にスケジュールされたワークロードは、そのバックアップでは復元されません。

  • アップグレードに失敗したクラスタは復元できません。

  • この手順は、削除されたクラスタを復元することを想定したものではありません。

制限事項の詳細については、インフラストラクチャの非互換性をご覧ください。

管理クラスタのバックアップ

管理クラスタのバックアップには次のものが含まれます。

  • 管理クラスタの etcd のスナップショット。
  • 管理コントロール プレーンの Secret。管理クラスタとユーザー クラスタに対する認証に必要です。

管理クラスタのバックアップを作成する前に、次の手順を完了します。

  1. 管理クラスタのコントロール プレーンに SSH 接続するために使用する管理クラスタの外部 IP アドレスを確認します。

    kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] get nodes -n kube-system -o wide | grep master

    ここで、[ADMIN_CLUSTER_KUBECONFIG] は、管理クラスタの kubeconfig ファイルです。

  2. 管理クラスタの秘密鍵から vsphere_tmp という SSH 認証鍵を作成します。

    秘密鍵は管理クラスタの Secret から取得できます。

    kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] get secrets sshkeys -n kube-system -o yaml

    コマンド出力では、vsphere_tmp フィールドに秘密鍵が表示されます。

    秘密鍵を vsphere_tmp にコピーします。

    echo "[PRIVATE_KEY]" | base64 -d > vsphere_tmp; chmod 600 vsphere_tmp
  3. 次の秘密鍵を使用して管理コントロール プレーンでシェルを実行できることを確認します。

    ssh -i vsphere_tmp ubuntu@[EXTERNAL_IP]
    
  4. コンテナを終了します。

    exit

管理クラスタの etcd ストアをバックアップする

管理クラスタの etcd ストアをバックアップするには、次の手順を行います。

  1. etcd Pod の名前を取得します。

    kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] get pods \
        -n kube-system -l component=etcd,tier=control-plane -ojsonpath='{$.items[*].metadata.name}{"\n"}'
  2. Pod の kube-etcd コンテナでシェルを起動します。

    kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG]  exec -it \
        -n kube-system [ADMIN_ETCD_POD] -- bin/sh

    ここで、[ADMIN_ETCD_POD] は etcd Pod の名前です。

  3. シェルから etcdctl を使用して、ローカル ディレクトリに 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/healthcheck-client.crt \
        --key=/etc/kubernetes/pki/etcd/healthcheck-client.key snapshot save /tmp/snapshot.db
    
  4. コンテナを終了します。

    exit
  5. kubectl cp を使用して kube-etcd コンテナからバックアップをコピーします。

    kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] cp \
    kube-system/[ADMIN_ETCD_POD]:tmp/snapshot.db [RELATIVE_DIRECTORY]
    

    ここで、[RELATIVE_DIRECTORY] はバックアップを保存するパスです。

管理クラスタの Secret をバックアップする

管理コントロール プレーンの Secret をバックアップするには、次の手順を行います。

  1. SSH を使用して管理コントロール プレーンノードに接続します。

    ssh -i vsphere_tmp ubuntu@EXTERNAL_IP
    

    EXTERNAL_IP は、以前に記録した管理コントロール プレーンの外部 IP アドレスに置き換えます。

  2. 省略可、強く推奨: ローカル バックアップ ディレクトリを作成します。

    バックアップ Secret の権限を変更してノードからコピーする必要があります。

    mkdir backup
  3. Secret をローカル バックアップ ディレクトリにローカルにコピーします。

    sudo cp -r /etc/kubernetes/pki/* backup/
  4. バックアップ Secret の権限を変更します。

    sudo chmod -R a+rX backup/
  5. 管理コントロール プレーンノードを終了します。

    exit
  6. scp を実行して、管理コントロール プレーン ノードからバックアップ フォルダをコピーします。

    sudo scp -r -i vsphere_tmp  ubuntu@EXTERNAL_IP:backup/ RELATIVE_DIRECTORY
    

    RELATIVE_DIRECTORY をバックアップを保存する場所のパスに置き換えます。

管理クラスタの復元

次の手順では、etcd スナップショット作成時に、バックアップされた管理クラスタと管理対象のすべてのユーザー コントロール プレーンを再作成します。

  1. scp を実行して、snapshot.db を管理コントロール プレーンにコピーします。

    sudo scp -i vsphere_tmp snapshot.db ubuntu@[EXTERNAL_IP]:

    ここで、[EXTERNAL_IP] は事前に収集した管理コントロール プレーンの外部 IP アドレスです。

  2. 管理コントロール プレーンでシェルを起動します。

    sudo ssh -i vsphere_tmp ubuntu@[EXTERNAL_IP]
    
  3. snapshot.db//mnt にコピーします。

    sudo cp snapshot.db /mnt/
  4. backup のような一時ディレクトリを作成します。

    mkdir backup
  5. 管理コントロール プレーンを終了します。

    exit
  6. 証明書を backup/ にコピーします。

    sudo scp -r -i vsphere_tmp [BACKUP_CERT_FILE] ubuntu@[EXTERNAL_IP]:backup/
  7. 管理コントロール プレーン ノードでシェルを起動します。

    ssh -i vsphere_tmp ubuntu@[EXTERNAL_IP]
    

    ここで、[EXTERNAL_IP] は事前に収集した管理コントロール プレーンの外部 IP アドレスです。

  8. kube-etcdkube-apiserver を停止します。

    sudo mv /etc/kubernetes/manifests/etcd.yaml /tmp/etcd.yaml
    sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/kube-apiserver.yaml
  9. バックアップの Secret を /etc/kubernetes/pki/ にコピーします。

    sudo cp -r backup/* /etc/kubernetes/pki/
  10. Docker で etcdctl restore を実行します。

    sudo docker run --rm \
    -v '/mnt:/backup' \
    -v '/var/lib/etcd:/var/lib/etcd' --env ETCDCTL_API=3 'gcr.io/gke-on-prem-release/etcd-util:GKE_ON_PREM_VERSION' /bin/sh -c "etcdctl snapshot restore '/backup/snapshot.db'; rm -r /var/lib/etcd/*; mv /default.etcd/member/ /var/lib/etcd/"
  11. kube-etcdkube-apiserver を再起動します。

    sudo mv /tmp/etcd.yaml /etc/kubernetes/manifests/etcd.yaml
    sudo mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml
  12. kube-etcdkube-apiserver が起動したことを確認します。

    sudo crictl ps -a
  13. 管理ワークステーションからアクセスできるように、/etc/kubernetes/admin.conf.kube フォルダにコピーします。

    mkdir -p [HOME]/.kube
    sudo cp -i /etc/kubernetes/admin.conf [HOME]/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
  14. 管理コントロール プレーンを終了します。

    exit
  15. 新しく生成された kubeconfig ファイルを管理ノードからコピーします。

    sudo scp -i vsphere_tmp ubuntu@[EXTERNAL_IP]:[HOME]/.kube/config kubeconfig
    sudo chown $(id -u):$(id -g) kubeconfig

    ここで

    • [EXTERNAL_IP] は、管理コントロール プレーンの外部 IP アドレスです。
    • [HOME] は、管理ノードのホーム ディレクトリです。

    この新しい kubeconfig ファイルを使用して、復元されたクラスタにアクセスできるようになりました。

管理クラスタ復元のトラブルシューティング

管理クラスタのリストア中に問題が発生した場合は、Google サポートに連絡して管理クラスタの問題を解決する必要があります。

それまで、以下を確認してさらにトラブルシューティングを行うことができます。

  1. etcd コンテナ ID を見つける

    sudo crictl ps -a | grep [ADMIN_ETCD_POD]

    ここで、[ADMIN_ETCD_POD] は etcd Pod の名前です。

  2. etcd コンテナのログを調べる

    sudo crictl logs [ETCD_CONTAINER_ID]

    ここで、[ETCD_CONTAINER_ID] は etcd コンテナの ID です。

  3. 次のような権限拒否のログメッセージを探します。

    etcdserver: create snapshot directory error:mkdir /var/lib/etcd/member/snap: permission denied

  4. 権限が拒否されたというメッセージが見つかった場合は、/opt/data/var/lib/etcd/ の所有権を更新します。

    sudo chown -R 2001:2001 /opt/data/var/lib/etcd/

  5. kube-etcdkube-apiserver が起動したことを確認します。

    sudo crictl ps

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

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

  • BACKUP_DIR を、管理クラスタとユーザー クラスタのバックアップを保存するパスに設定します。このパスは存在しません。
  • ADMIN_CLUSTER_KUBECONFIG を管理クラスタの kubeconfig ファイルのパスに設定します。
  • USER_CLUSTER_NAMESPACE をユーザー クラスタの名前に設定します。ユーザー クラスタの名前は管理クラスタ内の 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 /tmp/${USER_CLUSTER_NAMESPACE}_snapshot.db"
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} cp ${USER_CLUSTER_NAMESPACE}/kube-etcd-0:tmp/${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 a+rX /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_snapshot.db"
kubectl --kubeconfig=${ADMIN_CLUSTER_KUBECONFIG} cp -n kube-system ${admin_etcd}:tmp/admin_snapshot.db $BACKUP_DIR/admin-cluster_snapshot.db

次のステップ