5.3. クラスターの直前の状態への復元
クラスターを直前の状態に復元するには、スナップショットを作成して、事前に etcd データのバックアップを行っている必要があります。このスナップショットを使用して、クラスターの状態を復元します。
5.3.1. クラスターの直前の状態への復元
保存された etcd バックアップを使用して、クラスターの以前の状態に戻すことができます。etcd バックアップを使用して単一のコントロールパネルホストを復元します。次に、etcd クラスター Operator は残りのマスターホストへのスケーリングを処理します。
クラスターを復元する際に、同じ z-stream リリースから取得した etcd バックアップを使用する必要があります。たとえば、OpenShift Container Platform 4.5.2 クラスターは、4.5.2 から取得した etcd バックアップを使用する必要があります。
前提条件
-
cluster-admin
ロールを持つユーザーとしてクラスターにアクセスできる。 - リカバリーホストとして使用する正常なマスターホスト。
- マスターホストへの SSH アクセス。
-
etcd スナップショットと静的 Pod のリソースの両方を含むバックアップディレクトリー (同じバックアップから取られるもの)。ディレクトリー内のファイル名は、
snapshot_<datetimestamp>.db
およびstatic_kuberesources_<datetimestamp>.tar.gz
の形式にする必要があります。
手順
- リカバリーホストとして使用するコントロールプレーンホストを選択します。これは、復元操作を実行するホストです。
リカバリーホストを含む、各コントロールプレーンノードへの SSH 接続を確立します。
Kubernetes API サーバーは復元プロセスの開始後にアクセスできなくなるため、コントロールプレーンノードにはアクセスできません。このため、別のターミナルで各コントロールプレーンホストに SSH 接続を確立することが推奨されます。
重要この手順を完了しないと、復元手順を完了するためにマスターホストにアクセスすることができなくなり、この状態からクラスターを回復できなくなります。
etcd バックアップディレクトリーをリカバリーコントロールプレーンホストにコピーします。
この手順では、etcd スナップショットおよび静的 Pod のリソースを含む
backup
ディレクトリーを、リカバリーコントロールプレーンホストの/home/core/
ディレクトリーにコピーしていることを前提としています。他のすべてのコントロールプレーンノードで静的 Pod を停止します。
注記リカバリーホストで Pod を手動で停止する必要はありません。リカバリースクリプトは、リカバリーホストの Pod を停止します。
- リカバリーホストではないコントロールプレーンホストにアクセスします。
既存の etcd Pod ファイルを kubelet マニフェストディレクトリーから移動します。
[core@ip-10-0-154-194 ~]$ sudo mv /etc/kubernetes/manifests/etcd-pod.yaml /tmp
etcd Pod が停止していることを確認します。
[core@ip-10-0-154-194 ~]$ sudo crictl ps | grep etcd | grep -v operator
コマンドの出力は空であるはずです。空でない場合は、数分待機してから再度確認します。
既存の Kubernetes API サーバー Pod ファイルを kubelet マニフェストディレクトリーから移動します。
[core@ip-10-0-154-194 ~]$ sudo mv /etc/kubernetes/manifests/kube-apiserver-pod.yaml /tmp
Kubernetes API サーバー Pod が停止していることを確認します。
[core@ip-10-0-154-194 ~]$ sudo crictl ps | grep kube-apiserver | grep -v operator
コマンドの出力は空であるはずです。空でない場合は、数分待機してから再度確認します。
etcd データディレクトリーを別の場所に移動します。
[core@ip-10-0-154-194 ~]$ sudo mv /var/lib/etcd/ /tmp
- リカバリーホストではない他のマスターホストでこの手順を繰り返します。
- リカバリーコントロールプレーンホストにアクセスします。
クラスター全体のプロキシーが有効になっている場合は、
NO_PROXY
、HTTP_PROXY
、およびHTTPS_PROXY
環境変数をエクスポートしていることを確認します。ヒントoc get proxy cluster -o yaml
の出力を確認して、プロキシーが有効にされているかどうかを確認できます。プロキシーは、httpProxy
、httpsProxy
、およびnoProxy
フィールドに値が設定されている場合に有効にされます。リカバリーコントロールプレーンホストで復元スクリプトを実行し、パスを etcd バックアップディレクトリーに渡します。
[core@ip-10-0-143-125 ~]$ sudo -E /usr/local/bin/cluster-restore.sh /home/core/backup
スクリプトの出力例
...stopping kube-scheduler-pod.yaml ...stopping kube-controller-manager-pod.yaml ...stopping etcd-pod.yaml ...stopping kube-apiserver-pod.yaml Waiting for container etcd to stop .complete Waiting for container etcdctl to stop .............................complete Waiting for container etcd-metrics to stop complete Waiting for container kube-controller-manager to stop complete Waiting for container kube-apiserver to stop ..........................................................................................complete Waiting for container kube-scheduler to stop complete Moving etcd data-dir /var/lib/etcd/member to /var/lib/etcd-backup starting restore-etcd static pod starting kube-apiserver-pod.yaml static-pod-resources/kube-apiserver-pod-7/kube-apiserver-pod.yaml starting kube-controller-manager-pod.yaml static-pod-resources/kube-controller-manager-pod-7/kube-controller-manager-pod.yaml starting kube-scheduler-pod.yaml static-pod-resources/kube-scheduler-pod-8/kube-scheduler-pod.yaml
すべてのマスターホストで kubelet サービスを再起動します。
リカバリーホストから以下のコマンドを実行します。
[core@ip-10-0-143-125 ~]$ sudo systemctl restart kubelet.service
- 他のすべてのマスターホストでこの手順を繰り返します。
単一メンバーのコントロールプレーンが正常に起動していることを確認します。
リカバリーホストから etcd コンテナーが実行中であることを確認します。
[core@ip-10-0-143-125 ~]$ sudo crictl ps | grep etcd | grep -v operator
出力例
3ad41b7908e32 36f86e2eeaaffe662df0d21041eb22b8198e0e58abeeae8c743c3e6e977e8009 About a minute ago Running etcd 0 7c05f8af362f0
リカバリーホストから、etcd Pod が実行されていることを確認します。
[core@ip-10-0-143-125 ~]$ oc get pods -n openshift-etcd | grep etcd
注記このコマンドを実行する前に
oc login
の実行を試行し、以下のエラーを受信すると、認証コントローラーが起動し、再試行するまでしばらく待機します。Unable to connect to the server: EOF
出力例
NAME READY STATUS RESTARTS AGE etcd-ip-10-0-143-125.ec2.internal 1/1 Running 1 2m47s
ステータスが
Pending
の場合や出力に複数の実行中の etcd Pod が一覧表示される場合、数分待機してから再度チェックを行います。
etcd の再デプロイメントを強制的に実行します。
クラスターにアクセスできるターミナルで、
cluster-admin
ユーザーとして以下のコマンドを実行します。$ oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge 1
- 1
forceRedeploymentReason
値は一意である必要があります。そのため、タイムスタンプが付加されます。
etcd クラスター Operator が再デプロイメントを実行すると、初期ブートストラップのスケールアップと同様に、既存のノードが新規 Pod と共に起動します。
すべてのノードが最新のリビジョンに更新されていることを確認します。
クラスターにアクセスできるターミナルで、
cluster-admin
ユーザーとして以下のコマンドを実行します。$ oc get etcd -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
etcd の
NodeInstallerProgressing
状況条件を確認し、すべてのノードが最新のリビジョンであることを確認します。更新が正常に実行されると、この出力にはAllNodesAtLatestRevision
が表示されます。AllNodesAtLatestRevision 3 nodes are at revision 7 1
- 1
- この例では、最新のリビジョン番号は
7
です。
出力に
2 nodes are at revision 6; 1 nodes are at revision 7
などの複数のリビジョン番号が含まれる場合、これは更新が依然として進行中であることを意味します。数分待機した後に再試行します。etcd の再デプロイ後に、コントロールプレーンの新規ロールアウトを強制的に実行します。kubelet が内部ロードバランサーを使用して API サーバーに接続されているため、Kubernetes API サーバーは他のノードに再インストールされます。
クラスターにアクセスできるターミナルで、
cluster-admin
ユーザーとして以下のコマンドを実行します。kubeapiserver
を更新します。$ oc patch kubeapiserver cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
すべてのノードが最新のリビジョンに更新されていることを確認します。
$ oc get kubeapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
NodeInstallerProgressing
状況条件を確認し、すべてのノードが最新のリビジョンであることを確認します。更新が正常に実行されると、この出力にはAllNodesAtLatestRevision
が表示されます。AllNodesAtLatestRevision 3 nodes are at revision 7 1
- 1
- この例では、最新のリビジョン番号は
7
です。
出力に
2 nodes are at revision 6; 1 nodes are at revision 7
などの複数のリビジョン番号が含まれる場合、これは更新が依然として進行中であることを意味します。数分待機した後に再試行します。kubecontrollermanager
を更新します。$ oc patch kubecontrollermanager cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
すべてのノードが最新のリビジョンに更新されていることを確認します。
$ oc get kubecontrollermanager -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
NodeInstallerProgressing
状況条件を確認し、すべてのノードが最新のリビジョンであることを確認します。更新が正常に実行されると、この出力にはAllNodesAtLatestRevision
が表示されます。AllNodesAtLatestRevision 3 nodes are at revision 7 1
- 1
- この例では、最新のリビジョン番号は
7
です。
出力に
2 nodes are at revision 6; 1 nodes are at revision 7
などの複数のリビジョン番号が含まれる場合、これは更新が依然として進行中であることを意味します。数分待機した後に再試行します。kubescheduler
を更新します。$ oc patch kubescheduler cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge
すべてのノードが最新のリビジョンに更新されていることを確認します。
$ oc get kubescheduler -o=jsonpath='{range .items[0].status.conditions[?(@.type=="NodeInstallerProgressing")]}{.reason}{"\n"}{.message}{"\n"}'
NodeInstallerProgressing
状況条件を確認し、すべてのノードが最新のリビジョンであることを確認します。更新が正常に実行されると、この出力にはAllNodesAtLatestRevision
が表示されます。AllNodesAtLatestRevision 3 nodes are at revision 7 1
- 1
- この例では、最新のリビジョン番号は
7
です。
出力に
2 nodes are at revision 6; 1 nodes are at revision 7
などの複数のリビジョン番号が含まれる場合、これは更新が依然として進行中であることを意味します。数分待機した後に再試行します。
すべてのマスターホストが起動しており、クラスターに参加していることを確認します。
クラスターにアクセスできるターミナルで、
cluster-admin
ユーザーとして以下のコマンドを実行します。$ oc get pods -n openshift-etcd | grep etcd
出力例
etcd-ip-10-0-143-125.ec2.internal 2/2 Running 0 9h etcd-ip-10-0-154-194.ec2.internal 2/2 Running 0 9h etcd-ip-10-0-173-171.ec2.internal 2/2 Running 0 9h
この手順の完了後、すべてのサービスを復元するまでに数分かかる場合があります。たとえば、oc login
を使用した認証は、OAuth サーバー Pod が再起動するまですぐに機能しない可能性があります。