node(s) didn’t match Pod’s nodeでEKSのPodが起動しない時
背景
D2Cのデータサイエンティスト(MLエンジニア)の須田です。
D2Cでは社内用の機械学習を伴う分析・開発のプラットフォームを一部Amazon EKS上で運用しています。
先日、そのプラットフォームのメンテナンス作業を行った際に一部サービス(Redash/JupyterHub)のPodが立たなくなってしまうトラブルがありました。今回はその時のトラブルシュートについて共有したいと思います。
前提の話ですが、
メンテナンス作業の内容は「Amazon EKSのバージョンアップにおけるコンテナランタイムの変更」です。
EKSクラスター1.23までのPodのコンテナランタイムのデフォルトはdockerですが、1.24からデフォルトのコンテナランタイムがcontainerdに変わるため次のversion upに向けて変更しておくというモチベーションでメンテナンスを行いました。
▼当時の状態
- Redashのredis/JupyterHubのserverのPodが立ち上がっていない
- Redash/JupyterHubどちらもkubectl describe Podで以下のログが出ていた
NotTriggerScaleUp 85s (x232 over 51m)
cluster-autoscaler pod didn't trigger scale-up: 15 node(s) didn't match Pod's node affinity/selector, 1 node(s) had volume node affinity conflict
▼やったこと
- 古いVolume attacherが残っているようだったので削除→何回やっても削除されず
EBSCSIドライバーが作成したストレージのpvcと既存のEFSのためのpvcでconflictが起きている可能性も考えましたが、Volume周りのイリバーシブルな問題に関わる部分は誰かとダブルチェックしながら触った方が良いと思い、作業を一旦ストップ。
原因は「アベイラビリティゾーンの不一致」
色々調べて試行錯誤しましたが、原因はとても単純でした、、、
今回のコンテナランタイムの変更でNodegroup(EC2)を新しく立ち上げたため、Podも新しく立ち上がりそのアベイラビリティゾーンとEBSのアベイラビリティゾーンが別だったことが原因でした。
もう少し詳しく説明すると新しく立てられたNodeGroup(EC2インスタンス)のアベイラビリティゾーンがus-east-1aとus-east-1bだった場合、Podはそのどちらかにスケジューリングされます。ただ、EBSに関しては初めてappをdeployした時のアベイラビリティゾーンに依存する特徴があるため、特定のアベイラビリティゾーン(イラストで言うとus-east-1c)に作成される構成になっていました。
このことから、EBSは希望するアベイラビリティゾーンに存在している想定のPodにマウントすることができなかったのです。
解決方法
1. 対象のNodeGroupの容量を一時的に増やし、全てのアベイラビリティゾーンでインスタンスを立ち上げる
対象のNodegroupの希望するインスタンス数を6つに増やし、Podが希望するアベイラビリティゾーンに割り当てられるようにしました(以下のイラストではシンプルにするためにインスタンス数を6つではなく3つにしています)
2.Redashはpodを、JupyterHubはアプリケーションを再起動
この結果、Podが立てられるようになりサービスを復旧することができました。
対策
EKSで使用しているすべてのアベイラビリティゾーンにNodeGroup(EC2インスタンス)が立つようにしておく(定常的に)
今回の原因はメンテナンス作業というよりも現行の構成から起こったトラブルでした。
元々このプラットフォームでは3つのアベイラビリティゾーンを使用しているのにも関わらず、Nodegroupにおいて希望するインスタンスの数は2つに設定されていたからです。(これでは2つのアベイラビリティゾーンにしかPodを割り当てられません)
そのため、 元々のNodegroupの希望するインスタンスの数を3つにしておけば今回のようなトラブルは防げるのではないかと思います。
今回のトラブルシュートで課題がまた1つ見つかりました!
ここまでお読みいただきありがとうございます。
株式会社D2C d2c.co.jp のテックブログです。 D2Cは、NTTドコモと電通などの共同出資により設立されたデジタルマーケティング企業です。 ドコモの膨大なデータを活用した最適化を行える広告配信システムの開発をしています。
Discussion