電通総研 テックブログ

電通総研が運営する技術ブログ

Amazon EKS マネージド型ノードグループの更新動作におけるEviction APIの実行状況を確認する方法

こんにちは。X(クロス)イノベーション本部クラウドイノベーションセンターの柴田です。

この記事ではAmazon EKS マネージド型ノードグループの更新動作におけるEviction APIの実行状況を確認する方法をご紹介します。

背景・課題

Amazon EKS マネージド型ノードグループでは、ノードグループのバージョンや設定を更新すると、 マネージド型ノードの更新動作 に記載された手順に従い、自動的に各ノードをローリングアップデートで再作成してくれます。

マネージド型ノードグループの更新動作は以下の4つのフェーズから構成されます。

  1. セットアップフェーズ
  2. スケールアップフェーズ
  3. アップグレードフェーズ
  4. スケールダウンフェーズ

このうちアップグレードフェーズの具体的な手順は以下のとおりです。1

アップグレードフェーズには、次の手順があります。

  1. ノードグループのために設定されている使用不可の最大数を上限として、アップグレードが必要なノードをランダムに選択します。
  2. ノードから Pods をドレインします。 Pods が 15 分以内にノードを離れず、強制フラグがない場合、 PodEvictionFailure というエラーが表示され、アップグレードフェーズは失敗します。このシナリオでは、 update-nodegroup-version リクエストで強制フラグを適用して、Pods を削除できます。
  3. すべての Pod が削除された後にノードを遮断し、60 秒間待ちます。これは、サービスコントローラーがこのノードに新しくリクエストを送信しないようにするためと、アクティブなノードのリストからこのノードを削除するために行われます。
  4. 遮断されたノードの Auto Scaling グループに終了リクエストを送信します。
  5. 以前のバージョンの起動テンプレートでデプロイされたノードグループ内にノードが存在しなくなるまで、以前のアップグレード手順を繰り返します。

手順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

このAPIのレスポンスは以下のとおりです。2

  • 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.code4xx または 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で執筆されました


  1. マネージド型ノードの更新動作 - Amazon EKS より引用。
  2. APIを起点とした退避 | Kubernetes より引用。
  3. これはAWSの公式ドキュメントに記載されている情報ではありません。実際にマネージド型ノードグループの更新動作を試した際のkube-apiserverの監査ログの内容からこのように推測しています。
  4. 詳細は Amazon EKS コントロールプレーンのログ記録 - Amazon EKS をご参照ください。
  5. kube-apiserverの監査ログのデータ量は多いです。そのためCloudWathc Logs Insightsでkube-apiserverの監査ログを検索する際、検索対象の期間をあまり長くすると、CloudWatch Logs Insightsの利用料が高額になる恐れがあります。ご注意ください。
  6. このクエリは Amazon EKS ノードグループの更新の失敗に関する問題をトラブルシューティングする | AWS re:Post に記載されたクエリを参考にしています。
  7. マネージド型ノードの更新動作 - Amazon EKSAmazon EKS ノードグループの更新の失敗に関する問題をトラブルシューティングする | AWS re:Post でPodの退避に失敗する既知の原因について紹介されています。