3.8. ノードセレクターの使用による特定ノードへの Pod の配置
ノードセレクター は、ノードのカスタムラベルと Pod で指定されるセレクターを使用して定義されるキー/値のペアのマップを指定します。
Pod がノードで実行する要件を満たすには、Pod にはノードのラベルと同じキー/値のペアがなければなりません。
3.8.1. ノードセレクターについて
Pod でノードセレクターを使用し、ノードでラベルを使用して、Pod がスケジュールされる場所を制御できます。ノードセレクターにより、OpenShift Container Platform は一致するラベルが含まれるノード上に Pod をスケジュールします。
ノードセレクターを使用して特定の Pod を特定のノードに配置し、クラスタースコープのノードセレクターを使用して特定ノードの新規 Pod をクラスター内の任意の場所に配置し、プロジェクトノードを使用して新規 Pod を特定ノードのプロジェクトに配置できます。
たとえば、クラスター管理者は、作成するすべての Pod にノードセレクターを追加して、アプリケーション開発者が地理的に最も近い場所にあるノードにのみ Pod をデプロイできるインフラストラクチャーを作成できます。この例では、クラスターは 2 つのリージョンに分散する 5 つのデータセンターで設定されます。米国では、ノードに us-east
、us-central
、または us-west
のラベルを付けます。アジア太平洋リージョン (APAC) では、ノードに apac-east
または apac-west
のラベルを付けます。開発者は、Pod がこれらのノードにスケジュールされるように、作成する Pod にノードセレクターを追加できます。
Pod
オブジェクトにノードセレクターが含まれる場合でも、一致するラベルを持つノードがない場合、Pod はスケジュールされません。
同じ Pod 設定でノードセレクターとノードのアフィニティーを使用している場合は、以下のルールが Pod のノードへの配置を制御します。
-
nodeSelector
とnodeAffinity
の両方を設定する場合、Pod が候補ノードでスケジュールされるにはどちらの条件も満たしている必要があります。 -
nodeAffinity
タイプに関連付けられた複数のnodeSelectorTerms
を指定する場合、nodeSelectorTerms
のいずれかが満たされている場合に Pod をノードにスケジュールすることができます。 -
nodeSelectorTerms
に関連付けられた複数のmatchExpressions
を指定する場合、すべてのmatchExpressions
が満たされている場合にのみ Pod をノードにスケジュールすることができます。
- 特定の Pod およびノードのノードセレクター
ノードセレクターおよびラベルを使用して、特定の Pod がスケジュールされるノードを制御できます。
ノードセレクターおよびラベルを使用するには、まずノードにラベルを付けて Pod がスケジュール解除されないようにしてから、ノードセレクターを Pod に追加します。
注記ノードセレクターを既存のスケジュールされている Pod に直接追加することはできません。デプロイメント設定などの Pod を制御するオブジェクトにラベルを付ける必要があります。
たとえば、以下の
Node
オブジェクトにはregion: east
ラベルがあります。ラベルを含む
Node
オブジェクトのサンプルkind: Node apiVersion: v1 metadata: name: ip-10-0-131-14.ec2.internal selfLink: /api/v1/nodes/ip-10-0-131-14.ec2.internal uid: 7bc2580a-8b8e-11e9-8e01-021ab4174c74 resourceVersion: '478704' creationTimestamp: '2019-06-10T14:46:08Z' labels: kubernetes.io/os: linux failure-domain.beta.kubernetes.io/zone: us-east-1a node.openshift.io/os_version: '4.5' node-role.kubernetes.io/worker: '' failure-domain.beta.kubernetes.io/region: us-east-1 node.openshift.io/os_id: rhcos beta.kubernetes.io/instance-type: m4.large kubernetes.io/hostname: ip-10-0-131-14 beta.kubernetes.io/arch: amd64 region: east 1
- 1
- Pod ノードセレクターに一致するラベル。
Pod には
type: user-node,region: east
ノードセレクターがあります。ノードセレクターが含まれる
Pod
オブジェクトのサンプルapiVersion: v1 kind: Pod .... spec: nodeSelector: 1 region: east type: user-node
- 1
- ノードトラベルに一致するノードセレクター。
サンプル Pod 仕様を使用して Pod を作成する場合、これはサンプルノードでスケジュールできます。
- クラスタースコープのデフォルトノードセレクター
デフォルトのクラスタースコープのノードセレクターを使用する場合、クラスターで Pod を作成すると、OpenShift Container Platform はデフォルトのノードセレクターを Pod に追加し、一致するラベルのあるノードで Pod をスケジュールします。
たとえば、以下の
Scheduler
オブジェクトにはデフォルトのクラスタースコープのregion=east
およびtype=user-node
ノードセレクターがあります。スケジューラー Operator カスタムリソースの例
apiVersion: config.openshift.io/v1 kind: Scheduler metadata: name: cluster ... spec: defaultNodeSelector: type=user-node,region=east ...
クラスター内のノードには
type=user-node,region=east
ラベルがあります。Node
オブジェクトの例apiVersion: v1 kind: Node metadata: name: ci-ln-qg1il3k-f76d1-hlmhl-worker-b-df2s4 ... labels: region: east type: user-node ...
ノードセレクターを持つ
Pod
オブジェクトの例apiVersion: v1 kind: Pod ... spec: nodeSelector: region: east ...
サンプルクラスターでサンプル Pod 仕様を使用して Pod を作成する場合、Pod はクラスタースコープのノードセレクターで作成され、ラベルが付けられたノードにスケジュールされます。
ラベルが付けられたノード上の Pod を含む Pod 一覧の例
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-s1 1/1 Running 0 20s 10.131.2.6 ci-ln-qg1il3k-f76d1-hlmhl-worker-b-df2s4 <none> <none>
注記Pod を作成するプロジェクトにプロジェクトノードセレクターがある場合、そのセレクターはクラスタースコープのセレクターよりも優先されます。Pod にプロジェクトノードセレクターがない場合、Pod は作成されたり、スケジュールされたりしません。
- プロジェクトノードセレクター
プロジェクトノードセレクターを使用する場合、このプロジェクトで Pod を作成すると、OpenShift Container Platform はノードセレクターを Pod に追加し、Pod を一致するラベルを持つノードでスケジュールします。クラスタースコープのデフォルトノードセレクターがない場合、プロジェクトノードセレクターが優先されます。
たとえば、以下のプロジェクトには
region=east
ノードセレクターがあります。Namespace
オブジェクトの例apiVersion: v1 kind: Namespace metadata: name: east-region annotations: openshift.io/node-selector: "region=east" ...
以下のノードには
type=user-node,region=east
ラベルがあります。Node
オブジェクトの例apiVersion: v1 kind: Node metadata: name: ci-ln-qg1il3k-f76d1-hlmhl-worker-b-df2s4 ... labels: region: east type: user-node ...
Pod をこのサンプルプロジェクトでサンプル Pod 仕様を使用して作成する場合、Pod はプロジェクトノードセレクターで作成され、ラベルが付けられたノードにスケジュールされます。
Pod
オブジェクトの例apiVersion: v1 kind: Pod metadata: namespace: east-region ... spec: nodeSelector: region: east type: user-node ...
ラベルが付けられたノード上の Pod を含む Pod 一覧の例
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-s1 1/1 Running 0 20s 10.131.2.6 ci-ln-qg1il3k-f76d1-hlmhl-worker-b-df2s4 <none> <none>
Pod に異なるノードセレクターが含まれる場合、プロジェクトの Pod は作成またはスケジュールされません。たとえば、以下の Pod をサンプルプロジェクトにデプロイする場合、これは作成されません。
無効なノードセレクターを持つ
Pod
オブジェクトの例apiVersion: v1 kind: Pod ... spec: nodeSelector: region: west ....
3.8.2. ノードセレクターの使用による Pod 配置の制御
Pod でノードセレクターを使用し、ノードでラベルを使用して、Pod がスケジュールされる場所を制御できます。ノードセレクターにより、OpenShift Container Platform は一致するラベルが含まれるノード上に Pod をスケジュールします。
ラベルをノード、マシンセット、またはマシン設定に追加します。マシンセットにラベルを追加すると、ノードまたはマシンが停止した場合に、新規ノードにそのラベルが追加されます。ノードまたはマシン設定に追加されるラベルは、ノードまたはマシンが停止すると維持されません。
ノードセレクターを既存 Pod に追加するには、ノードセレクターを ReplicaSet
オブジェクト、DaemonSet
オブジェクト、StatefulSet
オブジェクト、Deployment
オブジェクト、または DeploymentConfig
オブジェクトなどの Pod の制御オブジェクトに追加します。制御オブジェクト下の既存 Pod は、一致するラベルを持つノードで再作成されます。新規 Pod を作成する場合、ノードセレクターを Pod
仕様に直接追加できます。
ノードセレクターを既存のスケジュールされている Pod に直接追加することはできません。
前提条件
ノードセレクターを既存 Pod に追加するには、Pod の制御オブジェクトを判別します。たとえば、router-default-66d5cf9464-m2g75
Pod は router-default-66d5cf9464
レプリカセットによって制御されます。
$ oc describe pod router-default-66d5cf9464-7pwkc Name: router-default-66d5cf9464-7pwkc Namespace: openshift-ingress .... Controlled By: ReplicaSet/router-default-66d5cf9464
Web コンソールでは、Pod YAML の ownerReferences
に制御オブジェクトを一覧表示します。
ownerReferences: - apiVersion: apps/v1 kind: ReplicaSet name: router-default-66d5cf9464 uid: d81dd094-da26-11e9-a48a-128e7edf0312 controller: true blockOwnerDeletion: true
手順
マシンセットを使用するか、またはノードを直接編集してラベルをノードに追加します。
MachineSet
オブジェクトを使用して、ノードの作成時にマシンセットによって管理されるノードにラベルを追加します。以下のコマンドを実行してラベルを
MachineSet
オブジェクトに追加します。$ oc patch MachineSet <name> --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"<key>"="<value>","<key>"="<value>"}}]' -n openshift-machine-api
以下に例を示します。
$ oc patch MachineSet abc612-msrtw-worker-us-east-1c --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"type":"user-node","region":"east"}}]' -n openshift-machine-api
oc edit
コマンドを使用して、ラベルがMachineSet
オブジェクトに追加されていることを確認します。以下に例を示します。
$ oc edit MachineSet abc612-msrtw-worker-us-east-1c -n openshift-machine-api
MachineSet
オブジェクトの例apiVersion: machine.openshift.io/v1beta1 kind: MachineSet .... spec: ... template: metadata: ... spec: metadata: labels: region: east type: user-node ....
ラベルをノードに直接追加します。
ノードの
Node
オブジェクトを編集します。$ oc label nodes <name> <key>=<value>
たとえば、ノードにラベルを付けるには、以下を実行します。
$ oc label nodes ip-10-0-142-25.ec2.internal type=user-node region=east
ラベルがノードに追加されていることを確認します。
$ oc get nodes -l type=user-node,region=east
出力例
NAME STATUS ROLES AGE VERSION ip-10-0-142-25.ec2.internal Ready worker 17m v1.18.3+002a51f
一致するノードセレクターを Pod に追加します。
ノードセレクターを既存 Pod および新規 Pod に追加するには、ノードセレクターを Pod の制御オブジェクトに追加します。
ラベルを含む
ReplicaSet
オブジェクトのサンプルkind: ReplicaSet .... spec: .... template: metadata: creationTimestamp: null labels: ingresscontroller.operator.openshift.io/deployment-ingresscontroller: default pod-template-hash: 66d5cf9464 spec: nodeSelector: kubernetes.io/os: linux node-role.kubernetes.io/worker: '' type: user-node 1
- 1
- ノードセレクターを追加します。
ノードセレクターを特定の新規 Pod に追加するには、セレクターを
Pod
オブジェクトに直接追加します。ノードセレクターを持つ
Pod
オブジェクトの例apiVersion: v1 kind: Pod .... spec: nodeSelector: region: east type: user-node
注記ノードセレクターを既存のスケジュールされている Pod に直接追加することはできません。
3.8.3. クラスタースコープのデフォルトノードセレクターの作成
クラスター内の作成されたすべての Pod を特定のノードに制限するために、デフォルトのクラスタースコープのノードセレクターをノード上のラベルと共に Pod で使用することができます。
クラスタースコープのノードセレクターを使用する場合、クラスターで Pod を作成すると、OpenShift Container Platform はデフォルトのノードセレクターを Pod に追加し、一致するラベルのあるノードで Pod をスケジュールします。
スケジューラー Operator カスタムリソース (CR) を編集して、クラスタースコープのノードセレクターを設定します。ラベルをノード、マシンセット、またはマシン設定に追加します。マシンセットにラベルを追加すると、ノードまたはマシンが停止した場合に、新規ノードにそのラベルが追加されます。ノードまたはマシン設定に追加されるラベルは、ノードまたはマシンが停止すると維持されません。
Pod にキーと値のペアを追加できます。ただし、デフォルトキーの異なる値を追加することはできません。
手順
デフォルトのクラスタースコープのセレクターを追加するには、以下を実行します。
スケジューラー Operator CR を編集して、デフォルトのクラスタースコープのノードクラスターを追加します。
$ oc edit scheduler cluster
ノードセレクターを含むスケジューラー Operator CR のサンプル
apiVersion: config.openshift.io/v1 kind: Scheduler metadata: name: cluster ... spec: defaultNodeSelector: type=user-node,region=east 1 mastersSchedulable: false policy: name: ""
- 1
- 適切な
<key>:<value>
ペアが設定されたノードセレクターを追加します。
この変更を加えた後に、
openshift-kube-apiserver
プロジェクトの Pod の再デプロイを待機します。これには数分の時間がかかる場合があります。デフォルトのクラスター全体のノードセレクターは、Pod の再起動まで有効になりません。マシンセットを使用するか、またはノードを直接編集してラベルをノードに追加します。
マシンセットを使用して、ノードの作成時にマシンセットによって管理されるノードにラベルを追加します。
以下のコマンドを実行してラベルを
MachineSet
オブジェクトに追加します。$ oc patch MachineSet <name> --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"<key>"="<value>","<key>"="<value>"}}]' -n openshift-machine-api 1
- 1
- それぞれのラベルに
<key> /<value>
ペアを追加します。
以下に例を示します。
$ oc patch MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"type":"user-node","region":"east"}}]' -n openshift-machine-api
oc edit
コマンドを使用して、ラベルがMachineSet
オブジェクトに追加されていることを確認します。以下に例を示します。
$ oc edit MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api
出力例
apiVersion: machine.openshift.io/v1beta1 kind: MachineSet metadata: ... spec: ... template: metadata: ... spec: metadata: labels: region: east type: user-node
0
にスケールダウンし、ノードをスケールアップして、そのマシンセットに関連付けられたノードを再デプロイします。以下に例を示します。
$ oc scale --replicas=0 MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api
$ oc scale --replicas=1 MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api
ノードの準備ができ、利用可能な状態になったら、
oc get
コマンドを使用してラベルがノードに追加されていることを確認します。$ oc get nodes -l <key>=<value>
以下に例を示します。
$ oc get nodes -l type=user-node
出力例
NAME STATUS ROLES AGE VERSION ci-ln-l8nry52-f76d1-hl7m7-worker-c-vmqzp Ready worker 61s v1.18.3+002a51f
ラベルをノードに直接追加します。
ノードの
Node
オブジェクトを編集します。$ oc label nodes <name> <key>=<value>
たとえば、ノードにラベルを付けるには、以下を実行します。
$ oc label nodes ci-ln-l8nry52-f76d1-hl7m7-worker-b-tgq49 type=user-node region=east
oc get
コマンドを使用して、ラベルがノードに追加されていることを確認します。$ oc get nodes -l <key>=<value>,<key>=<value>
以下に例を示します。
$ oc get nodes -l type=user-node,region=east
出力例
NAME STATUS ROLES AGE VERSION ci-ln-l8nry52-f76d1-hl7m7-worker-b-tgq49 Ready worker 17m v1.18.3+002a51f
3.8.4. プロジェクトスコープのノードセレクターの作成
プロジェクトで作成されたすべての Pod をラベルが付けられたノードに制限するために、プロジェクトのノードセレクターをノード上のラベルと共に使用できます。
このプロジェクトで Pod を作成する場合、OpenShift Container Platform はノードセレクターをプロジェクトの Pod に追加し、プロジェクトの一致するラベルを持つノードで Pod をスケジュールします。クラスタースコープのデフォルトノードセレクターがない場合、プロジェクトノードセレクターが優先されます。
You add node selectors to a project by editing the Namespace
object to add the openshift.io/node-selector
parameter.ラベルをノード、マシンセット、またはマシン設定に追加します。マシンセットにラベルを追加すると、ノードまたはマシンが停止した場合に、新規ノードにそのラベルが追加されます。ノードまたはマシン設定に追加されるラベルは、ノードまたはマシンが停止すると維持されません。
Pod
オブジェクトにノードセレクターが含まれる場合でも、一致するノードセレクターを持つプロジェクトがない場合、Pod はスケジュールされません。その仕様から Pod を作成すると、以下のメッセージと同様のエラーが表示されます。
エラーメッセージの例
Error from server (Forbidden): error when creating "pod.yaml": pods "pod-4" is forbidden: pod node label selector conflicts with its project node label selector
Pod にキーと値のペアを追加できます。ただし、プロジェクトキーに異なる値を追加することはできません。
手順
デフォルトのプロジェクトノードセレクターを追加するには、以下を実行します。
namespace を作成するか、既存の namespace を編集して
openshift.io/node-selector
パラメーターを追加します。$ oc edit namespace <name>
出力例
apiVersion: v1 kind: Namespace metadata: annotations: openshift.io/node-selector: "type=user-node,region=east" 1 openshift.io/description: "" openshift.io/display-name: "" openshift.io/requester: kube:admin openshift.io/sa.scc.mcs: s0:c30,c5 openshift.io/sa.scc.supplemental-groups: 1000880000/10000 openshift.io/sa.scc.uid-range: 1000880000/10000 creationTimestamp: "2021-05-10T12:35:04Z" labels: kubernetes.io/metadata.name: demo name: demo resourceVersion: "145537" uid: 3f8786e3-1fcb-42e3-a0e3-e2ac54d15001 spec: finalizers: - kubernetes
- 1
- 適切な
<key>:<value>
ペアを持つopenshift.io/node-selector
を追加します。
マシンセットを使用するか、またはノードを直接編集してラベルをノードに追加します。
MachineSet
オブジェクトを使用して、ノードの作成時にマシンセットによって管理されるノードにラベルを追加します。以下のコマンドを実行してラベルを
MachineSet
オブジェクトに追加します。$ oc patch MachineSet <name> --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"<key>"="<value>","<key>"="<value>"}}]' -n openshift-machine-api
以下に例を示します。
$ oc patch MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c --type='json' -p='[{"op":"add","path":"/spec/template/spec/metadata/labels", "value":{"type":"user-node","region":"east"}}]' -n openshift-machine-api
oc edit
コマンドを使用して、ラベルがMachineSet
オブジェクトに追加されていることを確認します。以下に例を示します。
$ oc edit MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api
出力例
apiVersion: machine.openshift.io/v1beta1 kind: MachineSet metadata: ... spec: ... template: metadata: ... spec: metadata: labels: region: east type: user-node
そのマシンセットに関連付けられたノードを再デプロイします。
以下に例を示します。
$ oc scale --replicas=0 MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api
$ oc scale --replicas=1 MachineSet ci-ln-l8nry52-f76d1-hl7m7-worker-c -n openshift-machine-api
ノードの準備ができ、利用可能な状態になったら、
oc get
コマンドを使用してラベルがノードに追加されていることを確認します。$ oc get nodes -l <key>=<value>
以下に例を示します。
$ oc get nodes -l type=user-node,region=east
出力例
NAME STATUS ROLES AGE VERSION ci-ln-l8nry52-f76d1-hl7m7-worker-c-vmqzp Ready worker 61s v1.18.3+002a51f
ラベルをノードに直接追加します。
Node
オブジェクトを編集してラベルを追加します。$ oc label <resource> <name> <key>=<value>
たとえば、ノードにラベルを付けるには、以下を実行します。
$ oc label nodes ci-ln-l8nry52-f76d1-hl7m7-worker-c-tgq49 type=user-node region=east
oc get
コマンドを使用して、ラベルがNode
オブジェクトに追加されていることを確認します。$ oc get nodes -l <key>=<value>
以下に例を示します。
$ oc get nodes -l type=user-node,region=east
出力例
NAME STATUS ROLES AGE VERSION ci-ln-l8nry52-f76d1-hl7m7-worker-b-tgq49 Ready worker 17m v1.18.3+002a51f