Kubernetes では、Pod のスケジュールをより正確に制御し、クラスター内の特定のノードに割り当てる必要がある場合があります。 Kubernetes は、Pod に対して 4 種類のスケジューリング方法を提供します。 - 自動スケジューリング: プログラムが実行されるノードは、一連のアルゴリズムを通じてスケジューラによって完全に決定されます。
- 直接スケジューリング: NodeName、NodeSelector
- アフィニティ スケジューリング: NodeAffinity、PodAffinity、PodAntiAffinity
- 汚染(許容度)スケジュール: 汚染、許容度
このチュートリアルでは、直接スケジューリングとアフィニティ スケジューリングを使用して、ポッドが指定したノードでのみ実行されるようにする 2 つの方法を紹介します。 1. 方向スケジューリング1. NodeSelectorとは何かNodeSelector は、Kubernetes でポッドを特定のノードにスケジュールするためのメカニズムです。 Pod の構成で nodeSelector フィールドを定義することにより、Pod のキーと値のラベルのセットを指定できます。これらのラベルはクラスター内のノード ラベルと照合され、どのノードでポッドを実行するようにスケジュールするかが決定されます。 具体的には、nodeSelector を使用すると、ノードのラベルに基づいて、クラスターに Pod を選択的にスケジュールできます。このメカニズムは、特定のハードウェア要件を持つポッドや、正しいノードで実行されるように特定の環境を実行するポッドに最適です。 2. NodeSelectorの基本的な使い方この Pod 構成ファイルは、ディスクタイプ: ssd のノードセレクターを持つ Pod を記述します。これは、Pod が disktype=ssd ラベルを持つノードにスケジュールされることを示します。 apiVersion:v1 kind:Pod metadata: name:nginx labels: env:test spec: containers: -name:nginx image:nginx imagePullPolicy:IfNotPresent nodeSelector: disktype:ssd 次の例は、NodeSelector の基本的な使用方法を示しています。 (1)クラスター内のノードを、それらのノードのラベルも含めて一覧表示します。出力は次のようになります。 controlplane $ kubectl get node --show-labels NAME STATUS ROLES AGE VERSION LABELS controlplane Ready control-plane 12h v1.29.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=controlplane,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node.kubernetes.io/exclude-from-external-load-balancers= node01 Ready <none> 12h v1.29.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node01,kubernetes.io/os=linux (2)ノードの1つを選択し、ラベルを追加します。 kubectl label nodes node01 disktype=ssd (3)選択したノードにdisktype=ssdラベルがあることを確認します。 (4)選択したノードにスケジュールされるポッドを作成します。 kubectl create -f pod-nginx.yaml - pod-nginx.yaml ファイルの内容は上記の yaml に示されています。
- 作成が成功すると、ポッドはdisktype=ssdを含むラベルにスケジュールされます。
実行が成功したら、選択したノード上で Pod が実際に実行されていることを確認します。 controlplane $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 1/1 Running 0 11s 192.168.1.4 node01 <none> <none> spec.nodeName パラメータを設定することで、特定のノードに Pod をスケジュールすることもできます。デモ用の yaml は次のとおりです。 apiVersion:v1 kind:Pod metadata: name:nginx spec: nodeName:foo-node# 调度Pod 到特定的节点containers: -name:nginx image:nginx imagePullPolicy:IfNotPresent 2. アフィニティスケジューリングKubernetes はアフィニティ スケジューリング (Affinity) も提供します。これは NodeSelector の拡張です。設定により、スケジューリングの条件を満たすノードに優先順位を付けることができます。そうでない場合は、条件を満たさないノードにスケジュールすることもできるため、スケジュールの柔軟性が向上します。アフィニティは主に 3 つのカテゴリに分けられます。 - nodeAffinity: ノードをターゲットにし、ポッドをどのノードにスケジュールできるかという問題を解決します。
- podAffinity: ポッドをターゲットにし、ポッドと同じトポロジドメインにどの既存のポッドをデプロイできるかという問題を解決します。
- podAntiAffinity: ポッドをターゲットとし、既存のポッドと同じトポロジドメインにポッドをデプロイできない問題を解決します。
11.ノードアフィニティNodeAffinity はノード アフィニティ スケジューリング戦略を意味します。これは、NodeSelector を置き換えるために使用される新しいスケジューリング戦略です。現在、ノード アフィニティ式は 2 つあります。 - RequiredDuringSchedulingIgnoredDuringExecution: ポッドをノードにスケジュールする前に、指定されたルールを満たす必要があります。ハード制限に相当します。
- PreferredDuringSchedulingIgnoreDuringExecution: 確立されたルールを満たすことを優先することを強調します。スケジューラはポッドをノードにスケジュールしようとしますが、強制は行いません。これはソフト制限に相当します。複数の優先ルールでは、重み値を設定して、実行順序を定義することもできます。
まず、NodeAffinity の設定可能な項目を見てみましょう。 pod.spec.affinity.nodeAffinity requiredDuringSchedulingIgnoredDuringExecution #Node节点必须满足指定的所有规则才可以,相当于硬限制nodeSelectorTerms #节点选择列表matchFields #按节点字段列出的节点选择器要求列表matchExpressions #按节点标签列出的节点选择器要求列表(推荐) key #键values #值operat or #关系符支持Exists, DoesNotExist, In, NotIn, Gt, Lt preferredDuringSchedulingIgnoredDuringExecution #优先调度到满足指定的规则的Node,相当于软限制(倾向) preference #一个节点选择器项,与相应的权重相关联matchFields #按节点字段列出的节点选择器要求列表matchExpressions # 按节点标签列出的节点选择器要求列表(推荐) key #键values #值operator #关系符支持In, NotIn, Exists, DoesNotExist, Gt, Lt weight #倾向权重,在范围1-100。 たとえば、次の Pod は、disktype=ssd ラベルを持たないノードにデプロイする必要があります。 apiVersion:v1 kind:Pod metadata: name:nginx labels: env:test spec: containers: -name:nginx image:nginx imagePullPolicy:IfNotPresent affinity: nodeAffinity:#设置node亲和性requiredDuringSchedulingIgnoredDuringExecution:# 硬限制nodeSelectorTerms: -matchExpressions: -key:disktype operator:NotIn values:["ssd"] 作成コマンドが実行されると、ディスクタイプ値に ssd が含まれていないノードにポッドがスケジュールされます。 controlplane $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 1/1 Running 0 20s 192.168.0.4 controlplane <none> <none> controlplane $ kubectl get node --show-labels NAME STATUS ROLES AGE VERSION LABELS controlplane Ready control-plane 15h v1.29.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=controlplane,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node.kubernetes.io/exclude-from-external-load-balancers= node01 Ready <none> 14h v1.29.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=node01,kubernetes.io/os=linux 2.ポッドアフィニティPodAffinity は、Kubernetes のスケジューリング メカニズムであり、Pod 間のスケジューリング関係に影響する一連の条件を指定できます。具体的には、podAffinity を使用すると、同じノード上で類似のプロパティまたは関係を持つ Pod をスケジュールしたり、異なるノード上で関連するプロパティを持つ Pod をスケジュールしたりできます。 podAffinity は、requiredDuringSchedulingIgnoredDuringExecution および preferredDuringSchedulingIgnoredDuringExecution を通じても実装されます。次の例は、ポッド間のアフィニティと相互排他ポリシー設定を示しています。 (1)参照対象ポッド まず、 security=S1 および app=nginx というラベルを持つ pod-flag という名前の Pod を作成します。以降の例では、Pod アフィニティとミューテックスのターゲット Pod として pod-flag を使用します。 apiVersion:v1 kind:Pod metadata: name:pod-flag labels: security:"S1" app:nginx spec: containers: -name:nginx image:nginx (2)ポッドアフィニティスケジューリング 次に、Pod のアフィニティ スケジューリングを説明するために 2 番目の Pod を作成します。ここで定義されているアフィニティ ラベルは security=S1 です。上記の Pod pod-flag に対応して、topologyKey の値は kubemetes.io/hostname に設定されます。 apiVersion:v1 kind:Pod metadata: name:pod-affinity spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: -labelSelector: matchExpressions: -key:security operator:In values: -S1 topologyKey:kubernetes.io/hostname containers: -name:with-pod-affinity image:nginx 2 つの Pod が正常に作成されたら、 kubectl get pods -o wide コマンドを使用して、2 つの Pod が同じノード上で実行されていることを確認します。 controlplane $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-affinity 1/1 Running 0 8s 192.168.1.5 node01 <none> <none> pod-flag 1/1 Running 0 94s 192.168.1.4 node01 <none> <none> pod-affinity Pod を作成する前に、このノードの kubemetes.io/hostname ラベルを削除し、上記の作成手順を繰り返します。条件を満たすノードが見つからないため、ポッドは常に保留状態になります。 controlplane $ kubectl label node node01 kubernetes.io/hostname- node/node01 unlabeled controlplane $ kubectl get pod NAME READY STATUS RESTARTS AGE pod-affinity 1/1 Running 0 4m49s pod-flag 1/1 Running 0 6m15s controlplane $ kubectl delete pod pod-affinity pod "pod-affinity" deleted controlplane $ kubectl apply -f pod-affinity.yaml pod/pod-affinity created controlplane $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-affinity 0/1 Pending 0 16s <none> <none> <none> <none> pod-flag 1/1 Running 0 6m59s 192.168.1.4 node01 <none> <none> (3)ポッドの相互排他的スケジューリング 3 番目のポッドを作成します。参照ターゲット Pod と同じノード上で実行されないことを期待します。 apiVersion:v1 kind:Pod metadata: name:anti-affinity spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: -labelSelector: matchExpressions: -key:security operator:In values: -S1 topologyKey:beta.kubernetes.io/arch podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: -labelSelector: matchExpressions: -key:app operator:In values: -nginx topologyKey:kubernetes.io/hostname containers: -name:anti-affinity image:registry.aliyuncs.com/google_containers/pause:3.1 ここで、この新しい Pod と security=S1 の Pod は同じアーキテクチャ プラットフォーム上にある必要がありますが、 app=nginx の Pod と同じノード上にある必要はありません。 Pod を作成したら、 kubectl get pods -o wide を実行して新しい Pod を表示します。新しいポッドが他のアーキテクチャ プラットフォームの異なるノードにスケジュールされていることがわかります。 controlplane $ kubectl apply -f anti-affinity.yaml pod/anti-affinity created controlplane $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES anti-affinity 1/1 Running 0 6s 192.168.0.6 controlplane <none> <none> pod-affinity 1/1 Running 0 24m 192.168.1.6 node01 <none> <none> pod-flag 1/1 Running 0 31m 192.168.1.4 node01 <none> <none> 3. CKAの実際の質問1. 実際の質問のスクリーンショット2. 中国の分析k8s クラスター環境を切り替えます: kubectl config use-context k8sTask: nginx のイメージ アドレスを持つ nginx-kusc00401 という名前の Pod を作成し、disk=spinning ラベルを持つノードにスケジュールします。 3. 公式参考文書ノードにスケジュールするポッドを指定する 4. 質問を解いて答えるk8s クラスター環境を切り替えるには、次のスイッチを使用します。 kubectl config use-context k8s Pod リソース オブジェクトを作成します。 apiVersion:v1 kind:Pod metadata: name:nginx-kusc00401 spec: containers: -name:nginx image:nginx imagePullPolicy:IfNotPresent nodeSelector: disk:spinning ポッドを作成するには、次のコマンドを実行します。 kubectl apply -f nginx-kusc00401.yaml |