【Kubernetes】nodeSelectorでPodがassignされるNodeを指定する

会社のアプリケーションをローカルの開発環境で走らせようとして、manifestファイルを開発環境のClusterにapplyしたのだが、いつまで待ってもPendingのまま。 kubectl describe で調べてみると、Event欄に以下の表示が出ていた。

0/9 nodes are available: 3 Insufficient memory, 9 node(s) didn't match node selector.

メモリの方は単にmanifestファイルの resource 欄を修正すれば良かったが、node selectorの方は触ったことがなかったので調べてみた。

Nodeとは

NodeはPodを動作させるCluster内のワーカーマシンを指し、VMであったり物理的なマシンだったりする。Namespaceとは異なり、NodeはCluster内のPodの場所を物理的に区分けしている。NodeはNamespaceよりもさらに低レベルに位置するResourceなので、特定のNamespaceには属していない。

NodeSelectorとは

Kubernetesでは、Podをassignする先のNodeを意識しなければいけないことはあまりない。なぜならKubernetesにはSchedulerがあり、NodeにassignされていないPodがあれば、各Nodeに残された利用可能なResourceを考慮して最適なNodeに割り振ってくれるからだ。
しかし、例えばフロントエンドとバックエンドのアプリケーションがそれぞれあり、バックエンドの方は大量のデータ処理を伴うため性能の良いEC2インスタンスで動かしたいというような場合、Nodeによってマシンスペックが異なることもありうる。そのような場合、PodがassignされるNodeを指定したいということもあるだろう。NodeSelectorを使えば、個々のNode名を入力することなく、条件に合致するNodeを簡単に絞れる。各Nodeには、他のResourceと同様にk-v形式のLabelを付与することができる。NodeSelector内でそのk-vを指定すれば、assignされるNodeを指定できる。

今回の場合、まずStatefulSetのmanifestファイルを確認すると、 nodeSelector として nodegroup: backend と指定されていた。次にnamespaceを検索してみる。

$ kubectl get namespace -L nodegroup
NAME    STATUS   ...  NODEGROUP
docker-desktop   Ready      ... backend-dev
docker-desktop   Ready      ... backend-dev
...

-L オプションで、表示させるlabelのキーを指定することができる。用意してあった開発環境には nodegroup=backend のLabelが付与されたnodeがなかったため、Podのassignができなかったようだ。
manifestファイル内でnodegroupを backend-dev に修正して再度applyすることで、無事podが起動した。

kubernetes.io