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

このページでは、GKE On-Prem の管理クラスタとユーザー クラスタのバックアップを手動で作成して復元する方法について説明します。このページには、クラスタを自動的にバックアップするためのスクリプトもあります。

etcd のデータや Secret に損害を与える可能性がある想定された災害からの復旧用のバックアップを作成する必要があります。クラスタの外部でクラスタのオペレーションに依存しない場所にバックアップを保存してください。安全のために必要であれば、バックアップのコピーも作成することを検討してください。

すべてのクラスタで実行される etcd イベント Pod は、ユーザー クラスタの復元には不可欠ではありませんが、同様のプロセスに従ってバックアップできます。

制限事項

  • アプリケーション固有のデータのバックアップはこの機能の対象外です。
  • Secret は手動でローテーションするまで有効です。
  • バックアップの作成後にスケジュールされたワークロードは、そのバックアップでは復元されません。
  • 現時点では、失敗したクラスタ アップグレードから復元することはできません。
  • この手順は、削除されたクラスタを復元することを想定したものではありません。

既知の問題

sudo コマンドの実行時に、次のエラーが発生する場合があります。

sudo: unable to resolve host gke-admin-master-[CLUSTER_ID]

その場合は、次の行を /etc/hosts ファイルに追加します。

127.0.0.1 gke-admin-master-[CLUSTER_ID]

ユーザー クラスタのバックアップ

ユーザー クラスタのバックアップには、ユーザー クラスタの etcd のスナップショットが含まれています。クラスタの etcd には、すべての Kubernetes オブジェクトと、クラスタの状態の管理に必要なカスタム オブジェクトが含まれています。このスナップショットには、クラスタのコンポーネントとワークロードを再作成するために必要なデータが含まれています。

ユーザー クラスタのバックアップ

管理クラスタの kubeconfig を使用してアクセスできるコントロール プレーンノードには、ユーザー クラスタの etcd が格納されます。

etcd のスナップショットを作成するには、次の手順を行います。

  1. kube-etcd コンテナに次のシェルを追加します。

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

    ここで

    • [ADMIN_CLUSTER_KUBECONFIG] は、管理クラスタの kubeconfig ファイルです。
    • [USER_CLUSTER_NAME] は、ユーザー クラスタの名前です。具体的には、ユーザー クラスタにちなんで名付けられた管理クラスタ内の Namespace で渡します。
  2. シェルで etcdctl を使用して、ローカル ディレクトリに 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. kubectl cp を使用して kube-etcd コンテナからバックアップをコピーします。

    kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] cp \
    [USER_CLUSTER_NAME]/kube-etcd-0:snapshot.db [DIRECTORY] -c kube-etcd

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

ユーザー クラスタ バックアップの復元

  • バックアップを復元する前にクラスタを診断し、既存の問題を解決してください。問題のあるクラスタにバックアップを復元すると、問題が再び発生する、または悪化することがあります。クラスタの復元について詳しくは、GKE On-Prem サポートチームにお問い合わせください。

  • HA ユーザー クラスタを作成した場合は、etcd クラスタ メンバーごとにこの手順を 1 回行ってください。各 etcd メンバーを復元する際、同じスナップショットを使用できます。すべての etcd Pod がクラッシュループしない限り、これらの手順を行わないでください。このクラッシュループはデータ破損が発生していることを意味します。

etcd Pod のクラッシュループ

次の手順では、ユーザー クラスタの etcd データが破損し、etcd Pod がクラッシュループした場合にバックアップを復元する方法について説明します。ユーザー クラスタの API サーバーが実行中で、新しい Pod をスケジュールできる場合は、etcd Pod を既存の Pod の Volume にデプロイし、バックアップで破損したデータを上書きすることによって、復元することが可能です。

  1. 次のプレースホルダ値を入力した後、以下の etcd Pod 仕様を restore-etcd.yaml ファイルにコピーします。

    • [MEMBER_NUMBER] は、復元する番号付きの Pod です。
    • [NODE_NAME] は、[MEMBER_NUMBER[ Pod が実行されているノードです。
    • [ADMIN_CLUSTER_KUBECONFIG] は、管理クラスタの kubeconfig ファイルです。
    • [USER_CLUSTER_NAME] は、ユーザー クラスタの名前です。
    • [DEFAULT_TOKEN] は認証に使用されます。次のコマンドを実行すればこの値を確認できます。

      kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] \
      -n [USER_CLUSTER_NAME] get pods kube-etcd-0 \
      -o yaml | grep default-token

    restore-etcd.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        Component: restore-etcd-[MEMBER_NUMBER]
      name: restore-etcd-0
      namespace: restore-etcd-[MEMBER_NUMBER]
    spec:
      restartPolicy: Never
      containers:
      - command: ["/bin/sh"]
        args: ["-ec", "while :; do echo '.'; sleep 5 ; done"]
        image: gcr.io/gke-on-prem-release/etcd:v3.2.24-1-gke.0
        imagePullPolicy: IfNotPresent
        name: restore-etcd
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /var/lib/etcd
          name: data
        - mountPath: /etcd.local.config/certificates
          name: etcd-certs
        - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
          name: [DEFAULT_TOKEN]
          readOnly: true
      dnsPolicy: ClusterFirst
      hostname: restore-etcd-0
      imagePullSecrets:
      - name: private-registry-creds
      nodeSelector:
        kubernetes.googleapis.com/cluster-name: [USER_CLUSTER_NAME]
        kubernetes.io.hostname: [NODE_NAME]
      priority: 0
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      serviceAccount: default
      serviceAccountName: default
      subdomain: restore-etcd
      terminationGracePeriodSeconds: 30
      tolerations:
      - effect: NoExecute
        key: node.kubernetes.io/not-ready
        operator: Exists
        tolerationSeconds: 300
      - effect: NoExecute
        key: node.kubernetes.io/unreachable
        operator: Exists
        tolerationSeconds: 300
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: data-kube-etcd-[MEMBER_NUMBER]
      - name: etcd-certs
        secret:
          defaultMode: 420
          secretName: kube-etcd-certs
      - name: [DEFAULT_TOKEN]
        secret:
          defaultMode: 420
          secretName: [DEFAULT_TOKEN]
          
  2. Pod をデプロイします。

    kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] \
    -n [USER_CLUSTER_NAME] create -f restore-etcd.yaml
  3. etcd のバックアップ ファイル snapshot.db を新しい Pod にコピーします。snapshot.db は、バックアップを作成した相対ディレクトリにあります。

    kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] \
    cp [RELATIVE_DIRECTORY]/snapshot.db \
    [USER_CLUSTER_NAME]/restore-etcd-0:snapshot.db
  4. restore-etcd Pod にシェルを追加します。

    kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] \
    -it -n [USER_CLUSTER_NAME] exec restore-etcd-0 -- bin/sh
  5. 次のコマンドを実行して、バックアップを含む新しい default.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 \
    snapshot restore snapshot.db
  6. 破損した etcd データをバックアップで上書きします。

    rm -r var/lib/etcd/*; cp -r default.etcd/* var/lib/etcd/
  7. コンテナを終了します。

    exit
  8. クラッシュした etcd Pod を削除します。

    kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] \
    -n [USER_CLUSTER_NAME] delete pod kube-etcd-0
  9. etcd Pod がクラッシュしていないことを確認します。

  10. restore-etcd.yaml を削除し、restore-etcd Pod を削除します。

    rm restore-etcd.yaml;
    kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] \
    -n [USER_CLUSTER_NAME] delete pod restore-etcd-0

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

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

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

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

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

    kubectl --kubeconfig [ADMIN_KUBECONFIG] get nodes -n kube-system -o wide | grep gke-admin-master

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

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

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

    kubectl --kubeconfig [ADMIN_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 とそのコントロール プレーンの Secret をバックアップできます。

etcd

管理クラスタの etcd をバックアップするには:

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

    kubectl --kubeconfig [ADMIN_KUBECONFIG] get pods \
    -n kube-system | grep etcd-gke-admin-master
  2. Pod の kube-etcd コンテナでシェルを起動します。

    kubectl --kubeconfig [ADMIN_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 snapshot.db
  4. コンテナを終了します。

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

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

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

Secret

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

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

    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 +rw 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. kubeadm reset を実行します。これにより、管理クラスタで実行中のすべての処理が停止し、すべての etcd データと /etc/kubernetes/pki/ の Secret が削除されます。

    sudo kubeadm reset --ignore-preflight-errors=all
  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 'k8s.gcr.io/etcd-amd64:3.1.12' /bin/sh -c "etcdctl snapshot restore '/backup/snapshot.db'; mv /default.etcd/member/ /var/lib/etcd/"
  11. kubeadm init を実行します。これにより、バックアップされたすべての Secret が再利用され、復元されたスナップショットを使用して etcd が再起動されます。

    sudo kubeadm init --config /etc/kubernetes/kubeadm_config.yaml --ignore-preflight-errors=DirAvailable--var-lib-etcd
  12. 管理コントロール プレーンを終了します。

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

    sudo scp -i vsphere_tmp ubuntu@[EXTERNAL_IP]:[HOME]/.kube/config kubeconfig

    ここで

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

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

バックアップ スクリプト

ここで説明されるスクリプトを使用して、クラスタを自動的にバックアップできます。スクリプトを実行する前に、スクリプトの先頭にある 5 つの変数の値を入力します。

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

# 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 "${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 -o=name | grep etcd | cut -c 5-)
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"

トラブルシューティング

詳しくは、トラブルシューティングをご覧ください。

gkectl を使用してクラスタの問題を診断する

クラスタの問題を特定し、クラスタの情報を Google と共有するために、gkectl diagnose コマンドを使用します。クラスタの問題を診断するをご覧ください。

デフォルトのロギング動作

gkectlgkeadm では、デフォルトのロギング設定を使用するだけで十分です。

  • デフォルトでは、ログエントリは次のように保存されます。

    • gkectl の場合、デフォルトのログファイルは /home/ubuntu/.config/gke-on-prem/logs/gkectl-$(date).log で、このファイルは gkectl を実行するローカル ディレクトリの logs/gkectl-$(date).log ファイルにシンボリック リンクされます。
    • gkeadm の場合、デフォルトのログファイルは、gkeadm を実行するローカル ディレクトリの logs/gkeadm-$(date).log です。
  • すべてのログエントリは、ターミナルに出力されていない場合(--alsologtostderrfalse の場合)でもログファイルに保存されます。
  • -v5 詳細レベル(デフォルト)は、サポートチームが必要とするログエントリすべてを対象としています。
  • ログファイルには、実行されたコマンドと失敗メッセージも含まれます。

サポートが必要な場合は、サポートチームにログファイルを送信することをおすすめします。

ログファイルにデフォルト以外の場所を指定する

gkectl ログファイルにデフォルト以外の場所を指定するには、--log_file フラグを使用します。指定したログファイルは、ローカル ディレクトリにシンボリック リンクされません。

gkeadm ログファイルにデフォルト以外の場所を指定するには、--log_file フラグを使用します。

管理クラスタで Cluster API ログを見つける

管理コントロール プレーンの起動後に VM が起動しない場合は、管理クラスタの Cluster API コントローラのログを調べてデバッグを試すことができます。

  1. kube-system Namespace で Cluster API コントローラ Pod の名前を確認します。ここで、[ADMIN_CLUSTER_KUBECONFIG] は管理クラスタの kubeconfig ファイルのパスです。

    kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] -n kube-system get pods | grep clusterapi-controllers
  2. Pod のログを開きます。ここで、[POD_NAME] は Pod の名前です。必要に応じて、grep または同様のツールを使用してエラーを検索します。

    kubectl --kubeconfig [ADMIN_CLUSTER_KUBECONFIG] -n kube-system logs [POD_NAME] vsphere-controller-manager

次のステップ