こんにちは。X(クロス)イノベーション本部クラウドイノベーションセンターの柴田です。
この記事ではAmazon EKS マネージド型ノードグループの更新動作におけるEviction APIの実行状況を確認する方法をご紹介します。
背景・課題
Amazon EKS マネージド型ノードグループでは、ノードグループのバージョンや設定を更新すると、 マネージド型ノードの更新動作 に記載された手順に従い、自動的に各ノードをローリングアップデートで再作成してくれます。
マネージド型ノードグループの更新動作は以下の4つのフェーズから構成されます。
- セットアップフェーズ
- スケールアップフェーズ
- アップグレードフェーズ
- スケールダウンフェーズ
このうちアップグレードフェーズの具体的な手順は以下のとおりです。1
アップグレードフェーズには、次の手順があります。
- ノードグループのために設定されている使用不可の最大数を上限として、アップグレードが必要なノードをランダムに選択します。
- ノードから Pods をドレインします。 Pods が 15 分以内にノードを離れず、強制フラグがない場合、
PodEvictionFailure
というエラーが表示され、アップグレードフェーズは失敗します。このシナリオでは、update-nodegroup-version
リクエストで強制フラグを適用して、Pods を削除できます。- すべての Pod が削除された後にノードを遮断し、60 秒間待ちます。これは、サービスコントローラーがこのノードに新しくリクエストを送信しないようにするためと、アクティブなノードのリストからこのノードを削除するために行われます。
- 遮断されたノードの Auto Scaling グループに終了リクエストを送信します。
- 以前のバージョンの起動テンプレートでデプロイされたノードグループ内にノードが存在しなくなるまで、以前のアップグレード手順を繰り返します。
手順2に注目してください。各ノードについて Eviction API を使用したPodの退避が15分以内に完了しない場合、ノードグループの更新動作が失敗してしまいます。
ノードグループの更新動作の失敗を避けるには以下の2つの方法があります。
- 方法1. 強制フラグを有効にします。強制フラグを有効にすると、ノード上にまだ退避が完了していないPodが存在していても、手順3へ進み、そのノードを終了します。
- 方法2. 退避が完了していないPodを把握して手動で対応します。
方法1だと重要なワークロードのPodが強制的に停止してしまう恐れがあります。そのため今回は方法2を採用して、Podを強制的に停止するか、それともノードグループの更新動作を失敗させるかを自分たちで判断したいと思います。
しかし残念ながら現時点ではAWSのマネジメントコンソールやawscliでは退避が完了していないPodの一覧を確認することができません。
Eviction APIの実行状況を確認する方法
ではどうしたらよいでしょうか。
Podの退避はkube-apiserverの Create Eviction を呼び出して Eviction API を実行することで行われます。
POST /api/v1/namespaces/{namespace}/pods/{name}/eviction
200 OK
:この場合、退去が許可されるとEviction
サブリソースが作成され、PodのURLにDELETE
リクエストを送るのと同じように、Podが削除されます。429 Too Many Requests
:PodDisruptionBudgetの設定により、現在退去が許可されていないことを示します。しばらく時間を空けてみてください。また、APIのレート制限のため、このようなレスポンスが表示されることもあります。500 Internal Server Error
:複数のPodDisruptionBudgetが同じPodを参照している場合など、設定に誤りがあり退去が許可されないことを示します。
よってkube-apiserverの監査ログに以下の条件を満たすログが記録されていた場合、そのときそのPodの退避に失敗したことがわかります。
requestURI
が/api/v1/namespaces/{namespace}/pods/{name}/eviction
responseObject.code
が4xx
または5xx
マネージド型ノードグループのアップグレードフェーズでは、あるPodの退避に失敗した場合、約1分後に再びそのPodの退避を試みます。3 例えば、同じPodに対して上述の監査ログが15件以上記録されている場合、それはそのPodの退避が15分以内に完了しなかったことを意味します。
Amazon EKSではコントロールプレーンのログをCloudWatch Logsへ出力できます。4 この中にはkube-apiserverの監査ログも含まれています。よって、CloudWatch Logsに格納されたkube-apiserverの監査ログに対して、Eviction APIの失敗に関するログを検索することで、退避が完了していないPodを把握できます。
デモ
試しにCloudWatch Logs Insightsを使ってマネージド型ノードグループの更新動作中のkube-apiserverの監査ログを見てみましょう。5使用するクエリは以下のとおりです。6
fields @timestamp, @message | filter @logStream like "kube-apiserver-audit" | filter requestURI like /\/api\/v1\/namespaces\/.*\/pods\/.*\/eviction.*/ | filter (responseStatus.code like /4\d\d/ or responseStatus.code like /5\d\d/) | display @logStream, requestURI, responseObject.message | stats count(*) as retry by requestURI, responseObject.message
結果は以下のとおりです。
Pod productpage-v1-6dd7865bcd-vbz5r
についてEviction APIの失敗に関するログが 9
件記録されています。このことから、このPodは何らかの理由7で退避に連続して失敗しており、原因に応じた何らかの対応が必要かもしれないことがわかります。
おわりに
この記事ではAmazon EKS マネージド型ノードグループの更新動作におけるEviction APIの実行状況を確認する方法をご紹介しました。最後までお読みいただき、ありがとうございました。
私たちは一緒に働いてくれる仲間を募集しています!
クラウドアーキテクト執筆:@shibata.takao、レビュー:@kobayashi.hinami
(Shodoで執筆されました)
- マネージド型ノードの更新動作 - Amazon EKS より引用。↩
- APIを起点とした退避 | Kubernetes より引用。↩
- これはAWSの公式ドキュメントに記載されている情報ではありません。実際にマネージド型ノードグループの更新動作を試した際のkube-apiserverの監査ログの内容からこのように推測しています。↩
- 詳細は Amazon EKS コントロールプレーンのログ記録 - Amazon EKS をご参照ください。↩
- kube-apiserverの監査ログのデータ量は多いです。そのためCloudWathc Logs Insightsでkube-apiserverの監査ログを検索する際、検索対象の期間をあまり長くすると、CloudWatch Logs Insightsの利用料が高額になる恐れがあります。ご注意ください。↩
- このクエリは Amazon EKS ノードグループの更新の失敗に関する問題をトラブルシューティングする | AWS re:Post に記載されたクエリを参考にしています。↩
- マネージド型ノードの更新動作 - Amazon EKS や Amazon EKS ノードグループの更新の失敗に関する問題をトラブルシューティングする | AWS re:Post でPodの退避に失敗する既知の原因について紹介されています。↩