4.10. etcd タスク
etcd のバックアップ、etcd 暗号化の有効化または無効化、または etcd データのデフラグを行います。
4.10.1. etcd 暗号化について リンクのコピーリンクがクリップボードにコピーされました!
デフォルトで、etcd データは OpenShift Container Platform で暗号化されません。クラスターの etcd 暗号化を有効にして、データセキュリティーのレイヤーを追加で提供することができます。たとえば、etcd バックアップが正しくない公開先に公開される場合に機密データが失われないように保護することができます。
etcd の暗号化を有効にすると、以下の OpenShift API サーバーおよび Kubernetes API サーバーリソースが暗号化されます。
- シークレット
- 設定マップ
- ルート
- OAuth アクセストークン
- OAuth 認証トークン
etcd 暗号を有効にすると、暗号化キーが作成されます。これらのキーは週ごとにローテーションされます。etcd バックアップから復元するには、これらのキーが必要です。
etcd 暗号化は、キーではなく、値のみを暗号化します。リソースの種類、namespace、およびオブジェクト名は暗号化されません。
バックアップ中に etcd 暗号化が有効になっている場合は、static_kuberesources_<datetimestamp>.tar.gz ファイルに etcd スナップショットの暗号化キーが含まれています。セキュリティー上の理由から、このファイルは etcd スナップショットとは別に保存してください。ただし、このファイルは、それぞれの etcd スナップショットから etcd の以前の状態を復元するために必要です。
4.10.2. etcd 暗号化の有効化 リンクのコピーリンクがクリップボードにコピーされました!
etcd 暗号化を有効にして、クラスターで機密性の高いリソースを暗号化できます。
初期暗号化プロセスが完了するまで、etcd リソースをバックアップしないでください。暗号化プロセスが完了しない場合、バックアップは一部のみ暗号化される可能性があります。
etcd 暗号化を有効にすると、いくつかの変更が発生する可能性があります。
- etcd 暗号化は、いくつかのリソースのメモリー消費に影響を与える可能性があります。
- リーダーがバックアップを提供する必要があるため、バックアップのパフォーマンスに一時的な影響が生じる場合があります。
- ディスク I/O は、バックアップ状態を受け取るノードに影響を与える可能性があります。
前提条件
-
cluster-adminロールを持つユーザーとしてクラスターにアクセスできる。
手順
APIServerオブジェクトを変更します。$ oc edit apiserverencryptionフィールドタイプをaescbcに設定します。spec: encryption: type: aescbc1 - 1
aescbcタイプは、暗号化を実行するために PKCS#7 パディングを実装している AES-CBC と 32 バイトのキーが使用されることを意味します。
変更を適用するためにファイルを保存します。
暗号化プロセスが開始されます。クラスターのサイズによっては、このプロセスが完了するまで 20 分以上かかる場合があります。
etcd 暗号化が正常に行われたことを確認します。
OpenShift API サーバーの
Encryptedステータスを確認し、そのリソースが正常に暗号化されたことを確認します。$ oc get openshiftapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'この出力には、暗号化が正常に実行されると
EncryptionCompletedが表示されます。EncryptionCompleted All resources encrypted: routes.route.openshift.io出力に
EncryptionInProgressが表示される場合、これは暗号化が進行中であることを意味します。数分待機した後に再試行します。Kubernetes API サーバーの
Encryptedステータス状態を確認し、そのリソースが正常に暗号化されたことを確認します。$ oc get kubeapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'この出力には、暗号化が正常に実行されると
EncryptionCompletedが表示されます。EncryptionCompleted All resources encrypted: secrets, configmaps出力に
EncryptionInProgressが表示される場合、これは暗号化が進行中であることを意味します。数分待機した後に再試行します。OpenShift OAuth API サーバーの
Encryptedステータスを確認し、そのリソースが正常に暗号化されたことを確認します。$ oc get authentication.operator.openshift.io -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'この出力には、暗号化が正常に実行されると
EncryptionCompletedが表示されます。EncryptionCompleted All resources encrypted: oauthaccesstokens.oauth.openshift.io, oauthauthorizetokens.oauth.openshift.io出力に
EncryptionInProgressが表示される場合、これは暗号化が進行中であることを意味します。数分待機した後に再試行します。
4.10.3. etcd 暗号化の無効化 リンクのコピーリンクがクリップボードにコピーされました!
クラスターで etcd データの暗号化を無効にできます。
前提条件
-
cluster-adminロールを持つユーザーとしてクラスターにアクセスできる。
手順
APIServerオブジェクトを変更します。$ oc edit apiserverencryptionフィールドタイプをidentityに設定します。spec: encryption: type: identity1 - 1
identityタイプはデフォルト値であり、暗号化は実行されないことを意味します。
変更を適用するためにファイルを保存します。
復号化プロセスが開始されます。クラスターのサイズによっては、このプロセスが完了するまで 20 分以上かかる場合があります。
etcd の復号化が正常に行われたことを確認します。
OpenShift API サーバーの
Encryptedステータス条件を確認し、そのリソースが正常に暗号化されたことを確認します。$ oc get openshiftapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'この出力には、復号化が正常に実行されると
DecryptionCompletedが表示されます。DecryptionCompleted Encryption mode set to identity and everything is decrypted出力に
DecryptionInProgressが表示される場合、これは復号化が進行中であることを意味します。数分待機した後に再試行します。Kubernetes API サーバーの
Encryptedステータス状態を確認し、そのリソースが正常に復号化されたことを確認します。$ oc get kubeapiserver -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'この出力には、復号化が正常に実行されると
DecryptionCompletedが表示されます。DecryptionCompleted Encryption mode set to identity and everything is decrypted出力に
DecryptionInProgressが表示される場合、これは復号化が進行中であることを意味します。数分待機した後に再試行します。OpenShift API サーバーの
Encryptedステータス条件を確認し、そのリソースが正常に復号化されたことを確認します。$ oc get authentication.operator.openshift.io -o=jsonpath='{range .items[0].status.conditions[?(@.type=="Encrypted")]}{.reason}{"\n"}{.message}{"\n"}'この出力には、復号化が正常に実行されると
DecryptionCompletedが表示されます。DecryptionCompleted Encryption mode set to identity and everything is decrypted出力に
DecryptionInProgressが表示される場合、これは復号化が進行中であることを意味します。数分待機した後に再試行します。
4.10.4. etcd データのバックアップ リンクのコピーリンクがクリップボードにコピーされました!
以下の手順に従って、etcd スナップショットを作成し、静的 Pod のリソースをバックアップして etcd データをバックアップします。このバックアップは保存でき、etcd を復元する必要がある場合に後で使用することができます。
単一コントロールプレーンホスト (別名マスターホスト) からのバックアップのみを保存します。クラスター内の各コントロールプレーンホストからのバックアップは取得しないでください。
前提条件
-
cluster-adminロールを持つユーザーとしてクラスターにアクセスできる。 クラスター全体のプロキシーが有効になっているかどうかを確認している。
ヒントoc get proxy cluster -o yamlの出力を確認して、プロキシーが有効にされているかどうかを確認できます。プロキシーは、httpProxy、httpsProxy、およびnoProxyフィールドに値が設定されている場合に有効にされます。
手順
コントロールプレーンノードのデバッグセッションを開始します。
$ oc debug node/<node_name>ルートディレクトリーを
/hostに変更します。sh-4.2# chroot /host-
クラスター全体のプロキシーが有効になっている場合は、
NO_PROXY、HTTP_PROXY、およびHTTPS_PROXY環境変数をエクスポートしていることを確認します。 etcd-snapshot-backup.shスクリプトを実行し、バックアップの保存先となる場所を渡します。ヒントcluster-backup.shスクリプトは etcd Cluster Operator のコンポーネントとして維持され、etcdctl snapshot saveコマンドに関連するラッパーです。sh-4.4# /usr/local/bin/cluster-backup.sh /home/core/assets/backupスクリプトの出力例
found latest kube-apiserver: /etc/kubernetes/static-pod-resources/kube-apiserver-pod-6 found latest kube-controller-manager: /etc/kubernetes/static-pod-resources/kube-controller-manager-pod-7 found latest kube-scheduler: /etc/kubernetes/static-pod-resources/kube-scheduler-pod-6 found latest etcd: /etc/kubernetes/static-pod-resources/etcd-pod-3 ede95fe6b88b87ba86a03c15e669fb4aa5bf0991c180d3c6895ce72eaade54a1 etcdctl version: 3.4.14 API version: 3.4 {"level":"info","ts":1624647639.0188997,"caller":"snapshot/v3_snapshot.go:119","msg":"created temporary db file","path":"/home/core/assets/backup/snapshot_2021-06-25_190035.db.part"} {"level":"info","ts":"2021-06-25T19:00:39.030Z","caller":"clientv3/maintenance.go:200","msg":"opened snapshot stream; downloading"} {"level":"info","ts":1624647639.0301006,"caller":"snapshot/v3_snapshot.go:127","msg":"fetching snapshot","endpoint":"https://10.0.0.5:2379"} {"level":"info","ts":"2021-06-25T19:00:40.215Z","caller":"clientv3/maintenance.go:208","msg":"completed snapshot read; closing"} {"level":"info","ts":1624647640.6032252,"caller":"snapshot/v3_snapshot.go:142","msg":"fetched snapshot","endpoint":"https://10.0.0.5:2379","size":"114 MB","took":1.584090459} {"level":"info","ts":1624647640.6047094,"caller":"snapshot/v3_snapshot.go:152","msg":"saved","path":"/home/core/assets/backup/snapshot_2021-06-25_190035.db"} Snapshot saved at /home/core/assets/backup/snapshot_2021-06-25_190035.db {"hash":3866667823,"revision":31407,"totalKey":12828,"totalSize":114446336} snapshot db and kube resources are successfully saved to /home/core/assets/backupこの例では、コントロールプレーンホストの
/home/core/assets/backup/ディレクトリーにファイルが 2 つ作成されます。-
snapshot_<datetimestamp>.db: このファイルは etcd スナップショットです。cluster-backup.shスクリプトで、その有効性を確認します。 static_kuberesources_<datetimestamp>.tar.gz: このファイルには、静的 Pod のリソースが含まれます。etcd 暗号化が有効にされている場合、etcd スナップショットの暗号化キーも含まれます。注記etcd 暗号化が有効にされている場合、セキュリティー上の理由から、この 2 つ目のファイルを etcd スナップショットとは別に保存することが推奨されます。ただし、このファイルは etcd スナップショットから復元するために必要になります。
etcd 暗号化はキーではなく値のみを暗号化することに注意してください。つまり、リソースタイプ、namespace、およびオブジェクト名は暗号化されません。
-
4.10.5. etcd データのデフラグ リンクのコピーリンクがクリップボードにコピーされました!
大規模で密度の高いクラスターの場合に、キースペースが過剰に拡大し、スペースのクォータを超過すると、etcd は低下するパフォーマンスの影響を受ける可能性があります。etcd を定期的に維持および最適化して、データストアのスペースを解放します。Prometheus で etcd メトリックをモニターし、必要に応じてデフラグします。そうしないと、etcd はクラスター全体のアラームを発生させ、クラスターをメンテナンスモードにして、キーの読み取りと削除のみを受け入れる可能性があります。
これらの主要な指標をモニターします。
-
etcd_server_quota_backend_bytes、これは現在のクォータ制限です -
etcd_mvcc_db_total_size_in_use_in_bytes、これはヒストリーコンパクション後の実際のデータベース使用状況を示します。 -
etcd_debugging_mvcc_db_total_size_in_bytes、これはデフラグを待機している空き領域を含む、データベースのサイズを示します。
etcd データをデフラグし、etcd 履歴の圧縮などのディスクの断片化を引き起こすイベント後にディスク領域を回収します。
履歴の圧縮は 5 分ごとに自動的に行われ、これによりバックエンドデータベースにギャップが生じます。この断片化された領域は etcd が使用できますが、ホストファイルシステムでは利用できません。ホストファイルシステムでこの領域を使用できるようにするには、etcd をデフラグする必要があります。
etcd はデータをディスクに書き込むため、そのパフォーマンスはディスクのパフォーマンスに大きく依存します。etcd のデフラグは、毎月、月に 2 回、またはクラスターでの必要に応じて行うことを検討してください。etcd_db_total_size_in_bytes メトリクスをモニターして、デフラグが必要であるかどうかを判別することもできます。
また、PromQL 式を使用した最適化によって解放される etcd データベースのサイズ (MB 単位) を確認することで、最適化が必要かどうかを判断することもできます ((etcd_mvcc_db_total_size_in_bytes - etcd_mvcc_db_total_size_in_use_in_bytes)/1024/1024)。
etcd のデフラグはプロセスを阻止するアクションです。etcd メンバーはデフラグが完了するまで応答しません。このため、各 Pod のデフラグアクションごとに少なくとも 1 分間待機し、クラスターが回復できるようにします。
以下の手順に従って、各 etcd メンバーで etcd データをデフラグします。
前提条件
-
cluster-adminロールを持つユーザーとしてクラスターにアクセスできる。
手順
リーダーを最後にデフラグする必要があるため、どの etcd メンバーがリーダーであるかを判別します。
etcd Pod の一覧を取得します。
$ oc get pods -n openshift-etcd -o wide | grep -v quorum-guard | grep etcd出力例
etcd-ip-10-0-159-225.example.redhat.com 3/3 Running 0 175m 10.0.159.225 ip-10-0-159-225.example.redhat.com <none> <none> etcd-ip-10-0-191-37.example.redhat.com 3/3 Running 0 173m 10.0.191.37 ip-10-0-191-37.example.redhat.com <none> <none> etcd-ip-10-0-199-170.example.redhat.com 3/3 Running 0 176m 10.0.199.170 ip-10-0-199-170.example.redhat.com <none> <none>Pod を選択し、以下のコマンドを実行して、どの etcd メンバーがリーダーであるかを判別します。
$ oc rsh -n openshift-etcd etcd-ip-10-0-159-225.example.redhat.com etcdctl endpoint status --cluster -w table出力例
Defaulting container name to etcdctl. Use 'oc describe pod/etcd-ip-10-0-159-225.example.redhat.com -n openshift-etcd' to see all of the containers in this pod. +---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS | +---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ | https://10.0.191.37:2379 | 251cd44483d811c3 | 3.4.9 | 104 MB | false | false | 7 | 91624 | 91624 | | | https://10.0.159.225:2379 | 264c7c58ecbdabee | 3.4.9 | 104 MB | false | false | 7 | 91624 | 91624 | | | https://10.0.199.170:2379 | 9ac311f93915cc79 | 3.4.9 | 104 MB | true | false | 7 | 91624 | 91624 | | +---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+この出力の
IS LEADER列に基づいて、https://10.0.199.170:2379エンドポイントがリーダーになります。このエンドポイントを直前の手順の出力に一致させると、リーダーの Pod 名はetcd-ip-10-0-199-170.example.redhat.comになります。
etcd メンバーのデフラグ。
実行中の etcd コンテナーに接続し、リーダーでは ない Pod の名前を渡します。
$ oc rsh -n openshift-etcd etcd-ip-10-0-159-225.example.redhat.comETCDCTL_ENDPOINTS環境変数の設定を解除します。sh-4.4# unset ETCDCTL_ENDPOINTSetcd メンバーのデフラグを実行します。
sh-4.4# etcdctl --command-timeout=30s --endpoints=https://localhost:2379 defrag出力例
Finished defragmenting etcd member[https://localhost:2379]タイムアウトエラーが発生した場合は、コマンドが正常に実行されるまで
--command-timeoutの値を増やします。データベースサイズが縮小されていることを確認します。
sh-4.4# etcdctl endpoint status -w table --cluster出力例
+---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS | +---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+ | https://10.0.191.37:2379 | 251cd44483d811c3 | 3.4.9 | 104 MB | false | false | 7 | 91624 | 91624 | | | https://10.0.159.225:2379 | 264c7c58ecbdabee | 3.4.9 | 41 MB | false | false | 7 | 91624 | 91624 | |1 | https://10.0.199.170:2379 | 9ac311f93915cc79 | 3.4.9 | 104 MB | true | false | 7 | 91624 | 91624 | | +---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+この例では、この etcd メンバーのデータベースサイズは、開始時のサイズの 104 MB ではなく 41 MB です。
これらの手順を繰り返して他の etcd メンバーのそれぞれに接続し、デフラグします。常に最後にリーダーをデフラグします。
etcd Pod が回復するように、デフラグアクションごとに 1 分以上待機します。etcd Pod が回復するまで、etcd メンバーは応答しません。
領域のクォータの超過により
NOSPACEアラームがトリガーされる場合、それらをクリアします。NOSPACEアラームがあるかどうかを確認します。sh-4.4# etcdctl alarm list出力例
memberID:12345678912345678912 alarm:NOSPACEアラームをクリアします。
sh-4.4# etcdctl alarm disarm
4.10.6. クラスターの直前の状態への復元 リンクのコピーリンクがクリップボードにコピーされました!
保存された etcd のバックアップを使用して、クラスターの以前の状態を復元したり、大多数のコントロールプレーンホスト (別名マスターホスト) が失われたクラスターを復元したりできます。
クラスターを復元する際に、同じ z-stream リリースから取得した etcd バックアップを使用する必要があります。たとえば、OpenShift Container Platform 4.7.2 クラスターは、4.7.2 から取得した etcd バックアップを使用する必要があります。
前提条件
-
cluster-adminロールを持つユーザーとしてクラスターにアクセスできる。 - リカバリーホストとして使用する正常なコントロールプレーンホストがあること。
- コントロールプレーンホストへの SSH アクセス。
-
etcd スナップショットと静的 Pod のリソースの両方を含むバックアップディレクトリー (同じバックアップから取られるもの)。ディレクトリー内のファイル名は、
snapshot_<datetimestamp>.dbおよびstatic_kuberesources_<datetimestamp>.tar.gzの形式にする必要があります。
非復元コントロールプレーンノードの場合は、SSH 接続を確立したり、静的 Pod を停止したりする必要はありません。他のリカバリー以外のコントロールプレーンマシンを 1 つずつ削除し、再作成します。
手順
- リカバリーホストとして使用するコントロールプレーンホストを選択します。これは、復元操作を実行するホストです。
リカバリーホストを含む、各コントロールプレーンノードへの SSH 接続を確立します。
Kubernetes API サーバーは復元プロセスの開始後にアクセスできなくなるため、コントロールプレーンノードにはアクセスできません。このため、別のターミナルで各コントロールプレーンホストに SSH 接続を確立することが推奨されます。
重要この手順を完了しないと、復元手順を完了するためにコントロールプレーンホストにアクセスすることができなくなり、この状態からクラスターを回復できなくなります。
etcd バックアップディレクトリーをリカバリーコントロールプレーンホストにコピーします。
この手順では、etcd スナップショットおよび静的 Pod のリソースを含む
backupディレクトリーを、リカバリーコントロールプレーンホストの/home/core/ディレクトリーにコピーしていることを前提としています。他のすべてのコントロールプレーンノードで静的 Pod を停止します。
注記リカバリーホストで Pod を手動で停止する必要はありません。リカバリースクリプトは、リカバリーホストの Pod を停止します。
- リカバリーホストではないコントロールプレーンホストにアクセスします。
既存の etcd Pod ファイルを kubelet マニフェストディレクトリーから移動します。
$ sudo mv /etc/kubernetes/manifests/etcd-pod.yaml /tmpetcd Pod が停止していることを確認します。
$ sudo crictl ps | grep etcd | grep -v operatorコマンドの出力は空であるはずです。空でない場合は、数分待機してから再度確認します。
既存の Kubernetes API サーバー Pod ファイルを kubelet マニフェストディレクトリーから移動します。
$ sudo mv /etc/kubernetes/manifests/kube-apiserver-pod.yaml /tmpKubernetes API サーバー Pod が停止していることを確認します。
$ sudo crictl ps | grep kube-apiserver | grep -v operatorコマンドの出力は空であるはずです。空でない場合は、数分待機してから再度確認します。
etcd データディレクトリーを別の場所に移動します。
$ sudo mv /var/lib/etcd/ /tmp- リカバリーホストではない他のコントロールプレーンホストでこの手順を繰り返します。
- リカバリーコントロールプレーンホストにアクセスします。
クラスター全体のプロキシーが有効になっている場合は、
NO_PROXY、HTTP_PROXY、およびHTTPS_PROXY環境変数をエクスポートしていることを確認します。ヒントoc get proxy cluster -o yamlの出力を確認して、プロキシーが有効にされているかどうかを確認できます。プロキシーは、httpProxy、httpsProxy、およびnoProxyフィールドに値が設定されている場合に有効にされます。リカバリーコントロールプレーンホストで復元スクリプトを実行し、パスを etcd バックアップディレクトリーに渡します。
$ 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注記最後の etcd バックアップの後にノード証明書が更新された場合、復元プロセスによってノードが
NotReady状態になる可能性があります。ノードをチェックして、
Ready状態であることを確認します。以下のコマンドを実行します。
$ oc get nodes -w出力例
NAME STATUS ROLES AGE VERSION host-172-25-75-28 Ready master 3d20h v1.23.3+e419edf host-172-25-75-38 Ready infra,worker 3d20h v1.23.3+e419edf host-172-25-75-40 Ready master 3d20h v1.23.3+e419edf host-172-25-75-65 Ready master 3d20h v1.23.3+e419edf host-172-25-75-74 Ready infra,worker 3d20h v1.23.3+e419edf host-172-25-75-79 Ready worker 3d20h v1.23.3+e419edf host-172-25-75-86 Ready worker 3d20h v1.23.3+e419edf host-172-25-75-98 Ready infra,worker 3d20h v1.23.3+e419edfすべてのノードが状態を報告するのに数分かかる場合があります。
NotReady状態のノードがある場合は、ノードにログインし、各ノードの/var/lib/kubelet/pkiディレクトリーからすべての PEM ファイルを削除します。ノードに SSH 接続するか、Web コンソールのターミナルウィンドウを使用できます。$ ssh -i <ssh-key-path> core@<master-hostname>サンプル
pkiディレクトリーsh-4.4# pwd /var/lib/kubelet/pki sh-4.4# ls kubelet-client-2022-04-28-11-24-09.pem kubelet-server-2022-04-28-11-24-15.pem kubelet-client-current.pem kubelet-server-current.pem
すべてのコントロールプレーンホストで kubelet サービスを再起動します。
リカバリーホストから以下のコマンドを実行します。
$ sudo systemctl restart kubelet.service- 他のすべてのコントロールプレーンホストでこの手順を繰り返します。
保留中の CSR を承認します。
現在の CSR の一覧を取得します。
$ oc get csr出力例
NAME AGE SIGNERNAME REQUESTOR CONDITION csr-2s94x 8m3s kubernetes.io/kubelet-serving system:node:<node_name> Pending1 csr-4bd6t 8m3s kubernetes.io/kubelet-serving system:node:<node_name> Pending2 csr-4hl85 13m kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Pending3 csr-zhhhp 3m8s kubernetes.io/kube-apiserver-client-kubelet system:serviceaccount:openshift-machine-config-operator:node-bootstrapper Pending4 ...CSR の詳細をレビューし、これが有効であることを確認します。
$ oc describe csr <csr_name>1 - 1
<csr_name>は、現行の CSR の一覧からの CSR の名前です。
それぞれの有効な
node-bootstrapperCSR を承認します。$ oc adm certificate approve <csr_name>ユーザーによってプロビジョニングされるインストールの場合は、それぞれの有効な kubelet 提供の CSR を承認します。
$ oc adm certificate approve <csr_name>
単一メンバーのコントロールプレーンが正常に起動していることを確認します。
リカバリーホストから etcd コンテナーが実行中であることを確認します。
$ sudo crictl ps | grep etcd | grep -v operator出力例
3ad41b7908e32 36f86e2eeaaffe662df0d21041eb22b8198e0e58abeeae8c743c3e6e977e8009 About a minute ago Running etcd 0 7c05f8af362f0リカバリーホストから、etcd Pod が実行されていることを確認します。
$ oc get pods -n openshift-etcd | grep -v etcd-quorum-guard | 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 が一覧表示される場合、数分待機してから再度チェックを行います。- リカバリーホストではない喪失したコントロールプレーンホストで、このステップを繰り返します。
他のリカバリー以外のコントロールプレーンマシンを 1 つずつ削除し、再作成します。これらのマシンが再作成されると、新規リビジョンが強制的に実行され、etcd は自動的にスケールアップします。
インストーラーでプロビジョニングされるインフラストラクチャーを実行している場合、またはマシン API を使用してマシンを作成している場合は、以下の手順を実行します。それ以外の場合は、最初に作成したときと同じ方法で、新しいコントロールプレーンノードを作成する必要があります。
警告リカバリーホストのマシンを削除し、再作成しないでください。
失われたコントロールプレーンホストのいずれかのマシンを取得します。
クラスターにアクセスできるターミナルで、cluster-admin ユーザーとして以下のコマンドを実行します。
$ oc get machines -n openshift-machine-api -o wide出力例:
NAME PHASE TYPE REGION ZONE AGE NODE PROVIDERID STATE clustername-8qw5l-master-0 Running m4.xlarge us-east-1 us-east-1a 3h37m ip-10-0-131-183.ec2.internal aws:///us-east-1a/i-0ec2782f8287dfb7e stopped1 clustername-8qw5l-master-1 Running m4.xlarge us-east-1 us-east-1b 3h37m ip-10-0-143-125.ec2.internal aws:///us-east-1b/i-096c349b700a19631 running clustername-8qw5l-master-2 Running m4.xlarge us-east-1 us-east-1c 3h37m ip-10-0-154-194.ec2.internal aws:///us-east-1c/i-02626f1dba9ed5bba running clustername-8qw5l-worker-us-east-1a-wbtgd Running m4.large us-east-1 us-east-1a 3h28m ip-10-0-129-226.ec2.internal aws:///us-east-1a/i-010ef6279b4662ced running clustername-8qw5l-worker-us-east-1b-lrdxb Running m4.large us-east-1 us-east-1b 3h28m ip-10-0-144-248.ec2.internal aws:///us-east-1b/i-0cb45ac45a166173b running clustername-8qw5l-worker-us-east-1c-pkg26 Running m4.large us-east-1 us-east-1c 3h28m ip-10-0-170-181.ec2.internal aws:///us-east-1c/i-06861c00007751b0a running- 1
- これは、失われたコントロールプレーンホストのコントロールプレーンマシンです (
ip-10-0-131-183.ec2.internal)。
マシン設定をファイルシステムのファイルに保存します。
$ oc get machine clustername-8qw5l-master-0 \1 -n openshift-machine-api \ -o yaml \ > new-master-machine.yaml- 1
- 失われたコントロールプレーンホストのコントロールプレーンマシンの名前を指定します。
直前の手順で作成された
new-master-machine.yamlファイルを編集し、新しい名前を割り当て、不要なフィールドを削除します。statusセクション全体を削除します。status: addresses: - address: 10.0.131.183 type: InternalIP - address: ip-10-0-131-183.ec2.internal type: InternalDNS - address: ip-10-0-131-183.ec2.internal type: Hostname lastUpdated: "2020-04-20T17:44:29Z" nodeRef: kind: Node name: ip-10-0-131-183.ec2.internal uid: acca4411-af0d-4387-b73e-52b2484295ad phase: Running providerStatus: apiVersion: awsproviderconfig.openshift.io/v1beta1 conditions: - lastProbeTime: "2020-04-20T16:53:50Z" lastTransitionTime: "2020-04-20T16:53:50Z" message: machine successfully created reason: MachineCreationSucceeded status: "True" type: MachineCreation instanceId: i-0fdb85790d76d0c3f instanceState: stopped kind: AWSMachineProviderStatusmetadata.nameフィールドを新規の名前に変更します。古いマシンと同じベース名を維持し、最後の番号を次に利用可能な番号に変更することが推奨されます。この例では、
clustername-8qw5l-master-0はclustername-8qw5l-master-3に変更されています。apiVersion: machine.openshift.io/v1beta1 kind: Machine metadata: ... name: clustername-8qw5l-master-3 ...spec.providerIDフィールドを削除します。providerID: aws:///us-east-1a/i-0fdb85790d76d0c3fmetadata.annotationsおよびmetadata.generationフィールドを削除します。annotations: machine.openshift.io/instance-state: running ... generation: 2metadata.resourceVersionおよびmetadata.uidフィールドを削除します。resourceVersion: "13291" uid: a282eb70-40a2-4e89-8009-d05dd420d31a
失われたコントロールプレーンホストのマシンを削除します。
$ oc delete machine -n openshift-machine-api clustername-8qw5l-master-01 - 1
- 失われたコントロールプレーンホストのコントロールプレーンマシンの名前を指定します。
マシンが削除されたことを確認します。
$ oc get machines -n openshift-machine-api -o wide出力例:
NAME PHASE TYPE REGION ZONE AGE NODE PROVIDERID STATE clustername-8qw5l-master-1 Running m4.xlarge us-east-1 us-east-1b 3h37m ip-10-0-143-125.ec2.internal aws:///us-east-1b/i-096c349b700a19631 running clustername-8qw5l-master-2 Running m4.xlarge us-east-1 us-east-1c 3h37m ip-10-0-154-194.ec2.internal aws:///us-east-1c/i-02626f1dba9ed5bba running clustername-8qw5l-worker-us-east-1a-wbtgd Running m4.large us-east-1 us-east-1a 3h28m ip-10-0-129-226.ec2.internal aws:///us-east-1a/i-010ef6279b4662ced running clustername-8qw5l-worker-us-east-1b-lrdxb Running m4.large us-east-1 us-east-1b 3h28m ip-10-0-144-248.ec2.internal aws:///us-east-1b/i-0cb45ac45a166173b running clustername-8qw5l-worker-us-east-1c-pkg26 Running m4.large us-east-1 us-east-1c 3h28m ip-10-0-170-181.ec2.internal aws:///us-east-1c/i-06861c00007751b0a runningnew-master-machine.yamlファイルを使用して新規マシンを作成します。$ oc apply -f new-master-machine.yaml新規マシンが作成されたことを確認します。
$ oc get machines -n openshift-machine-api -o wide出力例:
NAME PHASE TYPE REGION ZONE AGE NODE PROVIDERID STATE clustername-8qw5l-master-1 Running m4.xlarge us-east-1 us-east-1b 3h37m ip-10-0-143-125.ec2.internal aws:///us-east-1b/i-096c349b700a19631 running clustername-8qw5l-master-2 Running m4.xlarge us-east-1 us-east-1c 3h37m ip-10-0-154-194.ec2.internal aws:///us-east-1c/i-02626f1dba9ed5bba running clustername-8qw5l-master-3 Provisioning m4.xlarge us-east-1 us-east-1a 85s ip-10-0-173-171.ec2.internal aws:///us-east-1a/i-015b0888fe17bc2c8 running1 clustername-8qw5l-worker-us-east-1a-wbtgd Running m4.large us-east-1 us-east-1a 3h28m ip-10-0-129-226.ec2.internal aws:///us-east-1a/i-010ef6279b4662ced running clustername-8qw5l-worker-us-east-1b-lrdxb Running m4.large us-east-1 us-east-1b 3h28m ip-10-0-144-248.ec2.internal aws:///us-east-1b/i-0cb45ac45a166173b running clustername-8qw5l-worker-us-east-1c-pkg26 Running m4.large us-east-1 us-east-1c 3h28m ip-10-0-170-181.ec2.internal aws:///us-east-1c/i-06861c00007751b0a running- 1
- 新規マシン
clustername-8qw5l-master-3が作成され、ProvisioningからRunningにフェーズが変更されると準備状態になります。
新規マシンが作成されるまでに数分の時間がかかる場合があります。etcd クラスター Operator はマシンまたはノードが正常な状態に戻ると自動的に同期します。
- リカバリーホストではない喪失したコントロールプレーンホストで、これらのステップを繰り返します。
別のターミナルウィンドウで、以下のコマンドを使用して
cluster-adminロールが割り当てられたユーザーとしてクラスターにログインします。$ oc login -u <cluster_admin>1 - 1
<cluster_admin>については、cluster-adminロールでユーザー名を指定します。
etcd の再デプロイメントを強制的に実行します。
クラスターにアクセスできるターミナルで、
cluster-adminユーザーとして以下のコマンドを実行します。$ oc patch etcd cluster -p='{"spec": {"forceRedeploymentReason": "recovery-'"$( date --rfc-3339=ns )"'"}}' --type=merge1 - 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 71 - 1
- この例では、最新のリビジョン番号は
7です。
出力に
2 nodes are at revision 6; 1 nodes are at revision 7などの複数のリビジョン番号が含まれる場合、これは更新が依然として進行中であることを意味します。数分待機した後に再試行します。etcd の再デプロイ後に、コントロールプレーンの新規ロールアウトを強制的に実行します。kubelet が内部ロードバランサーを使用して API サーバーに接続されているため、Kubernetes API サーバーは他のノードに再インストールされます。
クラスターにアクセスできるターミナルで、
cluster-adminユーザーとして以下のコマンドを実行します。Kubernetes API サーバーの新規ロールアウトを強制的に実行します。
$ 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 71 - 1
- この例では、最新のリビジョン番号は
7です。
出力に
2 nodes are at revision 6; 1 nodes are at revision 7などの複数のリビジョン番号が含まれる場合、これは更新が依然として進行中であることを意味します。数分待機した後に再試行します。Kubernetes コントローラーマネージャーの新規ロールアウトを強制的に実行します。
$ 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 71 - 1
- この例では、最新のリビジョン番号は
7です。
出力に
2 nodes are at revision 6; 1 nodes are at revision 7などの複数のリビジョン番号が含まれる場合、これは更新が依然として進行中であることを意味します。数分待機した後に再試行します。Kubernetes スケジューラーの新規ロールアウトを強制的に実行します。
$ 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 71 - 1
- この例では、最新のリビジョン番号は
7です。
出力に
2 nodes are at revision 6; 1 nodes are at revision 7などの複数のリビジョン番号が含まれる場合、これは更新が依然として進行中であることを意味します。数分待機した後に再試行します。
すべてのコントロールプレーンホストが起動しており、クラスターに参加していることを確認します。
クラスターにアクセスできるターミナルで、
cluster-adminユーザーとして以下のコマンドを実行します。$ oc get pods -n openshift-etcd | grep -v etcd-quorum-guard | 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
復元手順の後にすべてのワークロードが通常の動作に戻るようにするには、Kubernetes API 情報を保存している各 Pod を再起動します。これには、ルーター、Operator、サードパーティーコンポーネントなどの OpenShift Container Platform コンポーネントが含まれます。
この手順の完了後、すべてのサービスを復元するまでに数分かかる場合があります。たとえば、oc login を使用した認証は、OAuth サーバー Pod が再起動するまですぐに機能しない可能性があります。
4.10.7. 永続ストレージの状態復元に関する問題および回避策 リンクのコピーリンクがクリップボードにコピーされました!
OpenShift Container Platform クラスターがいずれかの形式の永続ストレージを使用する場合に、クラスターの状態は通常 etcd 外に保存されます。たとえば、Pod で実行されている Elasticsearch クラスター、または StatefulSet オブジェクトで実行されているデータベースなどである可能性があります。etcd バックアップから復元する場合には、OpenShift Container Platform のワークロードのステータスも復元されます。ただし、etcd スナップショットが古い場合には、ステータスは無効または期限切れの可能性があります。
永続ボリューム (PV) の内容は etcd スナップショットには含まれません。etcd スナップショットから OpenShift Container Platform クラスターを復元する時に、重要ではないワークロードから重要なデータにアクセスしたり、その逆ができたりする場合があります。
以下は、古いステータスを生成するシナリオ例です。
- MySQL データベースが PV オブジェクトでバックアップされる Pod で実行されている。etcd スナップショットから OpenShift Container Platform を復元すると、Pod の起動を繰り返し試行しても、ボリュームをストレージプロバイダーに戻したり、実行中の MySQL Pod が生成したりされるわけではありません。この Pod は、ストレージプロバイダーでボリュームを復元し、次に PV を編集して新規ボリュームを参照するように手動で復元する必要があります。
- Pod P1 は、ノード X に割り当てられているボリューム A を使用している。別の Pod がノード Y にある同じボリュームを使用している場合に etcd スナップショットが作成された場合に、etcd の復元が実行されると、ボリュームがノード Y に割り当てられていることが原因で Pod P1 が正常に起動できなくなる可能性があります。OpenShift Container Platform はこの割り当てを認識せず、ボリュームが自動的に切り離されるわけではありません。これが生じる場合には、ボリュームをノード Y から手動で切り離し、ノード X に割り当ててることで Pod P1 を起動できるようにします。
- クラウドプロバイダーまたはストレージプロバイダーの認証情報が etcd スナップショットの作成後に更新された。これが原因で、プロバイダーの認証情報に依存する CSI ドライバーまたは Operator が機能しなくなります。これらのドライバーまたは Operator で必要な認証情報を手動で更新する必要がある場合があります。
デバイスが etcd スナップショットの作成後に OpenShift Container Platform ノードから削除されたか、または名前が変更された。ローカルストレージ Operator で、
/dev/disk/by-idまたは/devディレクトリーから管理する各 PV のシンボリックリンクが作成されます。この状況では、ローカル PV が存在しないデバイスを参照してしまう可能性があります。この問題を修正するには、管理者は以下を行う必要があります。
- デバイスが無効な PV を手動で削除します。
- 各ノードからシンボリックリンクを削除します。
-
LocalVolumeまたはLocalVolumeSetオブジェクトを削除します (ストレージ永続ストレージの設定 ローカルボリュームを使用した永続ストレージ ローカルストレージ Operator のリソースの削除 を参照)。