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

CKA — Kubernetes管理者

スケジューリングを制御する

TT Labで続きを見る

目標

Podがどのノードで起動するかを決める7つの手段をすべて使ってみて、最後には、前のステップで作ったクラスターの状態(cordonされたノード、テイントされたノード)を考慮して、配置を設計します。

なぜ重要なのか

スケジューリングは、CKAでは配点が大きくありませんが、トラブルシューティングの問題の半分は、実はスケジューリングの問題です。PendingのPodを見て、filter段階のどの条件で引っかかったのかを、読み取れる必要があります。

特に、topologySpreadConstraintsは誤解が多いです。偏差を計算するときに使う候補ドメインは、PodのnodeAffinity/nodeSelectorを通過するノードたちです。テイントは、デフォルトでは無視して数えます。そのため、Podが使えないノードが、0個のドメインとして残って偏差を大きくし、DoNotScheduleなら残りのPodがすべてPendingになることがよくあります。候補を絞り込む鍵がノードアフィニティであると知ることが、このラボの核心です。

ステップ

  1. ネームスペースcka-schedを作成してください。lab-node-0にtopology.kubernetes.io/zone=zone-a、lab-node-1にzone-b、lab-node-2にzone-cのラベルを付け、lab-node-0には追加でdisktype=ssdを付けてください。そのあと、Podssd-pod(イメージnginx:1.27)を、nodeSelectordisktype=ssdで作成し、lab-node-0で起動するようにしてください。
  2. lab-node-2にdisktype=hddラベルを付け、Podaffinity-requiredを、requiredのノードアフィニティ(disktype In [hdd])だけで、lab-node-2に配置してください。nodeSelectorは使いません。
  3. Deploymentpref(レプリカ2、イメージnginx:1.27)を作成し、preferredのノードアフィニティを付けてください。weightは50、条件はdisktype In [ssd]です。
  4. Deploymentspread(レプリカ3、Podラベルapp=spread)を作成し、requiredのPodアンチアフィニティを付けてください。labelSelectorはapp=spread、topologyKeyはtopology.kubernetes.io/zoneです。
  5. Deploymentdrain-demo(レプリカ2、イメージnginx:1.27)を作成したあと、lab-node-1をcordonしてdrainし、完全に空にしてください。drain-demoは、別のノードで2/2に戻っている必要があります。
  6. lab-node-2に、テイントworkload=batch:NoScheduleを設定してください。Podbatch-podに、そのテイントに耐えるトレラレーションと、nodeSelectordisktype=hddを与えて、lab-node-2に配置してください。
  7. PriorityClasscka-highを作成してください。value 100000、globalDefault false、preemptionPolicyPreemptLowerPriorityです。Podimportantに、このクラスを指定してください。
  8. Deploymentevenly(レプリカ4、Podラベルapp=evenly)を作成してください。topologySpreadConstraintsは、maxSkew 1、topologyKeytopology.kubernetes.io/zone、whenUnsatisfiableDoNotSchedule、labelSelectorapp=evenlyです。ここにrequiredのノードアフィニティdisktype In [ssd, hdd]と、workload=batch:NoScheduleのトレラレーションを一緒に付けて、4つのPodが2つのゾーンに2:2で配置されるようにしてください。

参考

ノードのラベルとnodeSelector

ネームスペースcka-schedを作成してください。lab-node-0にtopology.kubernetes.io/zone=zone-a、lab-node-1にzone-b、lab-node-2にzone-cのラベルを付け、lab-node-0には追加でdisktype=ssdを付けてください。そのあと、Podssd-pod(イメージnginx:1.27)を、nodeSelectordisktype=ssdで作成し、lab-node-0で起動するようにしてください。

nodeSelectorは、Podのspecの最上位に来るマップです。ラベルが正確に一致する必要があり、式は使えません。

requiredのノードアフィニティ

lab-node-2にdisktype=hddラベルを付け、Podaffinity-requiredを、requiredのノードアフィニティ(disktype In [hdd])だけで、lab-node-2に配置してください。nodeSelectorは使いません。

affinity.nodeAffinityの下のrequiredDuringSchedulingIgnoredDuringExecutionの中には、nodeSelectorTermsの配列が入ります。matchExpressionsのoperatorはInです。nodeSelectorは使わないでください。

preferredのノードアフィニティ

Deploymentpref(レプリカ2、イメージnginx:1.27)を作成し、preferredのノードアフィニティを付けてください。weightは50、条件はdisktype In [ssd]です。

preferred側は配列で、各項目がweightとpreferenceを持ちます。合わせられなくても配置されるので、どこで起動したかは採点しません。

Podアンチアフィニティで散らばらせる

Deploymentspread(レプリカ3、Podラベルapp=spread)を作成し、requiredのPodアンチアフィニティを付けてください。labelSelectorはapp=spread、topologyKeyはtopology.kubernetes.io/zoneです。

podAntiAffinityの項目は、labelSelectorとtopologyKeyを持ちます。ノードごとにゾーンのラベルが違うので、ゾーン単位で散らばらせれば、結果としてノードが分かれます。

ノードを空にする

Deploymentdrain-demo(レプリカ2、イメージnginx:1.27)を作成したあと、lab-node-1をcordonしてdrainし、完全に空にしてください。drain-demoは、別のノードで2/2に戻っている必要があります。

cordonは新しいPodだけを防ぎ、すでに起動しているPodはそのままにします。実際に空にするにはdrainが必要で、DaemonSetとemptyDirに関するオプションを付けてはじめて進みます。

テイントとトレラレーション

lab-node-2に、テイントworkload=batch:NoScheduleを設定してください。Podbatch-podに、そのテイントに耐えるトレラレーションと、nodeSelectordisktype=hddを与えて、lab-node-2に配置してください。

テイントは、key=value:effectの形式です。トレラレーションは、operatorをEqualにして、valueまで合わせる必要があります。どのノードに行くかは、別途指定する必要があります。

PriorityClassを付ける

PriorityClasscka-highを作成してください。value 100000、globalDefault false、preemptionPolicyPreemptLowerPriorityです。Podimportantに、このクラスを指定してください。

PriorityClassはクラスタースコープです。globalDefaultをtrueにすると、クラスター全体のPodに影響するので注意してください。Podに名前だけを書けば、spec.priorityは自動で埋められます。

総合: 残りのノードに均等に散らばらせる

Deploymentevenly(レプリカ4、Podラベルapp=evenly)を作成してください。topologySpreadConstraintsは、maxSkew 1、topologyKeytopology.kubernetes.io/zone、whenUnsatisfiableDoNotSchedule、labelSelectorapp=evenlyです。ここにrequiredのノードアフィニティdisktype In [ssd, hdd]と、workload=batch:NoScheduleのトレラレーションを一緒に付けて、4つのPodが2つのゾーンに2:2で配置されるようにしてください。

今このクラスターで、Podを受け入れられるノードが何台あるか、まず数えてみてください。cordonされたノードは候補から外す必要があり、テイントされたノードは、トレラレーションがあってはじめて使えます。候補を減らす鍵は、ノードアフィニティです。