TT Lab
はじめる
学ぶ 学習パス コース

KCNA — Kubernetes・クラウドネイティブ入門

ノードは3台あるのに、Pod の行き場がない

TT Labで続きを見る

目標

テイント/トレラレーション、nodeSelector、ノードアフィニティが、Podの配置をそれぞれどう変えるのかを実際に設定して確かめ、同じPendingでも原因(テイントに耐えられない / ラベルが合わない / 合うゾーンがない)が異なることを観察します。

なぜ重要なのか

Kubernetesで「Podがどのノードで動くのか」は偶然ではなく、スケジューラーの計算結果です。kube-schedulerは割り当てられていないPodを見張り、ノードごとにテイント・ラベル・リソース・アフィニティを調べて、通過するノードを選び、spec.nodeNameを埋めます。この判断がなぜそうなったのかを読めないと、Pending1つを前にして「リソースが足りないのか」「ノードが落ちたのか」と迷うことになります。

テイントは、ノードが「私は誰でも受け入れるわけではない」と宣言するもので、トレラレーションは、Podが「私はそれに耐えられる」と答えるものです。nodeSelectorとノードアフィニティは逆に、Podが「私はこういうノードが好ましい/必須だ」と要求するものです。両者は向きが逆なので、同時に設定されることが多く、そのため片方だけを見ても配置を説明できません。

ステップ

  1. ネームスペースkcna-schedを作成し、ノード名とゾーンラベルをファイルに取り出してください。
  2. 3つのノードすべてにtier=reserved:NoScheduleテイントを設定してください。
  3. トレラレーションのないPodplainがPendingで止まることを確認してください。
  4. テイントに耐えるトレラレーションを与えたPodtolerantが割り当てられることを確認してください。
  5. lab-node-0にdisktype=ssdラベルを付け、nodeSelectorでそのノードだけに配置されるPodを作成してください。
  6. ノードアフィニティでzone-1・zone-2のノードだけに配置されるPodを作成してください。
  7. 存在しないラベル(disktype=nvme)を要求してPendingで止まるPodを作成してください。
  8. 各Podの結果を/root/kcna-sched/report.txtに帳簿として残してください。

参考

作業用ネームスペースとノードマップを作成する

ネームスペースkcna-schedを作成し、ノード名と各ノードのtopology.kubernetes.io/zoneラベルを、1行に1つずつ이름=존の形式で(プレースホルダーは名前とゾーンです)/root/kcna-sched/nodes.txtに保存してください。

スケジューラーから見える世界はノードオブジェクトだけです。kubectl get nodes -L <라벨키>または-o jsonpathで、名前とゾーンラベルを一緒に取り出せます(プレースホルダーはラベルのキーです)。ネームスペースはcreateを--dry-run=clientで作ってapplyすれば、何度実行しても安全です。

3つのノードをすべて予約マークでロックする

3つのノードすべてにtier=reserved:NoScheduleテイントを付け、トレラレーションのないPodがどこにも入れないようにしてください。

NoScheduleテイントは、そのテイントに耐える(toleration)と宣言していないPodをノードから遠ざけます。kubectl taint node <이름> key=value:NoScheduleを3つのノードに設定します(プレースホルダーはノード名です)。すでに設定されていても再設定できるように、--overwriteを付けてください。

行き場のないPodがPendingで止まる

ネームスペースkcna-schedに、トレラレーションもセレクターもまったくないPodplain(イメージnginx:1.27-alpine)を作成してください。このPodはスケジュールされず、Pendingのままになるはずです。

3つのノードがすべてNoScheduleテイントでロックされているので、トレラレーションのない普通のPodは、どのノードにも割り当てられません。kubectl get pod plain -o wideとdescribeで、PodScheduled条件のreasonを確認してください。

予約マークに耐えるPodは入れる

ネームスペースkcna-schedにPodtolerant(イメージnginx:1.27-alpine)を作成してください。その際、tier=reservedのNoScheduleテイントに耐えるトレラレーションを宣言し、実際にノードへ割り当てられるようにしてください。

トレラレーションは、key・operator・value・effectでテイントと対応させます。operatorはEqualでvalueを明示するか、Existsでキーだけを合わせられます。割り当てられるとspec.nodeNameが埋まり、kwokがRunningにしてくれます。

SSDのノードにだけ配置する

ノードlab-node-0にラベルdisktype=ssdを付け、ネームスペースkcna-schedにPodpinned-ssd(イメージnginx:1.27-alpine)を作成してください。このPodは予約テイントに耐えつつ、nodeSelectorでdisktype=ssdのノードにだけ配置される必要があり、結果としてlab-node-0に割り当てられなければなりません。

nodeSelectorは、そのラベルを持つノードに候補を絞り込みます。テイントがまだ生きているので、トレラレーションも一緒に必要です。ラベルを1つのノードにだけ付ければ、nodeSelectorがそのノード1つに割り当てを寄せてくれます。

特定のゾーンにだけ送るノードアフィニティ

ネームスペースkcna-schedにPodzoned(イメージnginx:1.27-alpine)を作成してください。予約テイントに耐えつつ、requiredDuringSchedulingIgnoredDuringExecutionのノードアフィニティで、topology.kubernetes.io/zoneがzone-1またはzone-2のノードにだけ配置されるようにしてください。結果のノードはlab-node-1またはlab-node-2でなければなりません。

ノードアフィニティはnodeSelectorより表現力が高いです。In演算子に値のリストを渡すと、そのうちのどれか1つに合えばよくなります。ステップ1で取り出したゾーンラベルを見て、どのノードが候補になるか事前に確認してください。requiredルールは、合うノードがないとPodをPendingのままにします。

どのノードも満たせない要求

ネームスペースkcna-schedにPodnowhere(イメージnginx:1.27-alpine)を作成してください。予約テイントには耐えつつ、nodeSelectorでdisktype=nvmeを要求するようにしてください。そのようなノードはないので、このPodはPendingのままになるはずです。

トレラレーションがあっても、セレクターに合うノードを見つけられなければスケジュールされません。テイントに耐えられずブロックされるのと、ラベルが合わずブロックされるのは原因が違いますが、症状は同じくPendingです。describeのEventsで、何が足りないのかを読んでみてください。

何が配置を決めたのかを帳簿に残す

各Podがどうなったかを、/root/kcna-sched/report.txtに4行で書いてください。plain=pending、tolerant=scheduled、pinned-ssd=lab-node-0、nowhere=pendingです。値は実際のクラスターの状態と一致している必要があります(PendingのPodはpending、割り当てられたPodはそのノード名です)。

採点ツールは、このファイルの4行を実際のクラスターの状態と照合します。割り当てられたPodはspec.nodeNameを、PendingのPodはpendingを書いてください。推測で書かず、kubectl get pods -n kcna-sched -o wideで確認した値を写してください。