4.7. ノードセレクターの使用による特定ノードへの Pod の配置
ノードセレクター は、ノードのカスタムラベルと Pod で指定されるセレクターを使用して定義されるキー/値のペアのマップを指定します。
Pod がノードで実行する要件を満たすには、Pod にはノードのラベルと同じキー/値のペアがなければなりません。
4.7.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 topology.kubernetes.io/zone: us-east-1a node.openshift.io/os_version: '4.5' node-role.kubernetes.io/worker: '' topology.kubernetes.io/region: us-east-1 node.openshift.io/os_id: rhcos node.kubernetes.io/instance-type: m4.large kubernetes.io/hostname: ip-10-0-131-14 kubernetes.io/arch: amd64 region: east 1 type: user-node #...
- 1
- Pod ノードセレクターに一致するラベル。
Pod には
type: user-node,region: east
ノードセレクターがあります。ノードセレクターが含まれる
Pod
オブジェクトのサンプルapiVersion: v1 kind: Pod metadata: name: s1 #... 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 metadata: name: s1 #... 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 metadata: name: west-region #... spec: nodeSelector: region: west #...
4.7.2. ノードセレクターの使用による Pod 配置の制御
Pod でノードセレクターを使用し、ノードでラベルを使用して、Pod がスケジュールされる場所を制御できます。ノードセレクターにより、OpenShift Container Platform は一致するラベルが含まれるノード上に Pod をスケジュールします。
ラベルをノード、コンピュートマシンセット、またはマシン設定に追加します。コンピュートマシンセットにラベルを追加すると、ノードまたはマシンが停止した場合に、新規ノードにそのラベルが追加されます。ノードまたはマシン設定に追加されるラベルは、ノードまたはマシンが停止すると維持されません。
ノードセレクターを既存 Pod に追加するには、ノードセレクターを ReplicaSet
オブジェクト、DaemonSet
オブジェクト、StatefulSet
オブジェクト、Deployment
オブジェクト、または DeploymentConfig
オブジェクトなどの Pod の制御オブジェクトに追加します。制御オブジェクト下の既存 Pod は、一致するラベルを持つノードで再作成されます。新規 Pod を作成する場合、ノードセレクターを Pod 仕様に直接追加できます。Pod に制御オブジェクトがない場合は、Pod を削除し、Pod 仕様を編集して、Pod を再作成する必要があります。
ノードセレクターを既存のスケジュールされている Pod に直接追加することはできません。
前提条件
ノードセレクターを既存 Pod に追加するには、Pod の制御オブジェクトを判別します。たとえば、router-default-66d5cf9464-m2g75
Pod は router-default-66d5cf9464
レプリカセットによって制御されます。
$ oc describe pod router-default-66d5cf9464-7pwkc
出力例
kind: Pod apiVersion: v1 metadata: # ... Name: router-default-66d5cf9464-7pwkc Namespace: openshift-ingress # ... Controlled By: ReplicaSet/router-default-66d5cf9464 # ...
Web コンソールでは、Pod YAML の ownerReferences
に制御オブジェクトをリスト表示します。
apiVersion: v1 kind: Pod metadata: name: router-default-66d5cf9464-7pwkc # ... 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
ヒントあるいは、以下の YAML を適用してコンピュートマシンセットにラベルを追加することもできます。
apiVersion: machine.openshift.io/v1beta1 kind: MachineSet metadata: name: xf2bd-infra-us-east-2a namespace: openshift-machine-api spec: template: spec: metadata: labels: region: "east" type: "user-node" # ...
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
ヒントあるいは、以下の YAML を適用してノードにラベルを追加することもできます。
kind: Node apiVersion: v1 metadata: name: hello-node-6fbccf8d9 labels: 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.26.0
一致するノードセレクターを Pod に追加します。
ノードセレクターを既存 Pod および新規 Pod に追加するには、ノードセレクターを Pod の制御オブジェクトに追加します。
ラベルを含む
ReplicaSet
オブジェクトのサンプルkind: ReplicaSet apiVersion: apps/v1 metadata: name: hello-node-6fbccf8d9 # ... 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 metadata: name: hello-node-6fbccf8d9 # ... spec: nodeSelector: region: east type: user-node # ...
注記ノードセレクターを既存のスケジュールされている Pod に直接追加することはできません。
4.7.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
- 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
ヒントあるいは、以下の YAML を適用してコンピュートマシンセットにラベルを追加することもできます。
apiVersion: machine.openshift.io/v1beta1 kind: MachineSet metadata: name: <machineset> namespace: openshift-machine-api spec: template: spec: metadata: labels: region: "east" type: "user-node"
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 ...
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.26.0
ラベルをノードに直接追加します。
ノードの
Node
オブジェクトを編集します。$ oc label nodes <name> <key>=<value>
たとえば、ノードにラベルを付けるには、以下を実行します。
$ oc label nodes ci-ln-l8nry52-f76d1-hl7m7-worker-b-tgq49 type=user-node region=east
ヒントあるいは、以下の YAML を適用してノードにラベルを追加することもできます。
kind: Node apiVersion: v1 metadata: name: <node_name> labels: 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.26.0
4.7.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
ヒントあるいは、以下の YAML を適用してコンピュートマシンセットにラベルを追加することもできます。
apiVersion: machine.openshift.io/v1beta1 kind: MachineSet metadata: name: <machineset> namespace: openshift-machine-api spec: template: spec: metadata: labels: region: "east" type: "user-node"
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.26.0
ラベルをノードに直接追加します。
Node
オブジェクトを編集してラベルを追加します。$ oc label <resource> <name> <key>=<value>
たとえば、ノードにラベルを付けるには、以下を実行します。
$ oc label nodes ci-ln-l8nry52-f76d1-hl7m7-worker-c-tgq49 type=user-node region=east
ヒントあるいは、以下の YAML を適用してノードにラベルを追加することもできます。
kind: Node apiVersion: v1 metadata: name: <node_name> labels: 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.26.0