2.7. 使用节点选择器将 pod 放置到特定节点
节点选择器指定一个键值对映射。使用节点中的自定义标签和 pod 中指定的选择器来定义规则。您可以使用特定节点选择器将特定的 pod 放置到特定的节点上,项目节点选择器将新 pod 放置到该项目的特定节点上,或默认的集群范围节点选择器,以将新 pod 放置到集群中的任何特定节点上。
要使 pod 有资格在节点上运行,pod 必须具有与节点上标签相同的键值节点选择器。
如果您在同一 pod 配置中使用节点选择器和节点关联性,则以下规则控制 pod 放置到节点上:
-
如果同时配置了
nodeSelector
和nodeAffinity
,则必须满足这两个条件时 pod 才能调度到候选节点。 -
如果您指定了多个与
nodeAffinity
类型关联的nodeSelectorTerms
,那么其中一个nodeSelectorTerms
满足时 pod 就能调度到节点上。 -
如果您指定了多个与
nodeSelectorTerms
关联的matchExpressions
,那么只有所有matchExpressions
都满足时 pod 才能调度到节点上。
2.7.1. 使用节点选择器控制 pod 放置
您可以使用 pod 上的节点选择器标签来控制 pod 的调度位置。
使用节点选择器时,OpenShift Container Platform 会将 pod 调度到包含匹配标签的节点。
要将节点选择器添加到现有 pod 中,将节点选择器添加到该 pod 的控制对象中,如 ReplicaSet
对象、DaemonSet
对象、StatefulSet
对象、Deployment
对象或 DeploymentConfig
对象。任何属于该控制对象的现有 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 的控制对象添加节点选择器:
ReplicaSet
对象示例kind: ReplicaSet .... spec: .... template: metadata: creationTimestamp: null labels: ingresscontroller.operator.openshift.io/deployment-ingresscontroller: default pod-template-hash: 66d5cf9464 spec: nodeSelector: beta.kubernetes.io/os: linux node-role.kubernetes.io/worker: '' type: user-node 1
- 1
- 添加节点选择器。
要将节点选择器添加到特定的 pod,直接将选择器添加到
Pod
对象中:Pod
对象示例apiVersion: v1 kind: Pod ... spec: nodeSelector: <key>: <value> ...
例如:
使用节点选择器的
Pod
对象示例apiVersion: v1 kind: Pod .... spec: nodeSelector: region: east type: user-node
2.7.2. 创建默认的集群范围节点选择器
您可以组合使用 pod 上的默认集群范围节点选择器和节点上的标签,将集群中创建的所有 pod 限制到特定节点。
使用集群范围节点选择器时,如果您在集群中创建 pod,OpenShift Container Platform 会将默认节点选择器添加到 pod,并将该 pod 调度到具有匹配标签的节点。
您可以通过创建调度程序 Operator 自定义资源(CR)来配置集群范围节点选择器。您可以通过编辑 Node
对象、MachineSet
对象或 MachineConfig
对象向节点添加标签。将标签添加到机器集可确保节点或机器停机时,新节点具有标签。如果节点或机器停机,添加到节点或机器配置的标签不会保留。
例如,Scheduler 配置集群范围的 region=east
节点选择器:
Scheduler Operator 自定义资源示例
apiVersion: config.openshift.io/v1
kind: Scheduler
metadata:
name: cluster
...
spec:
defaultNodeSelector: type=user-node,region=east 1
...
集群中的节点具有 type=user-node,region=east
标签:
节点对象示例
apiVersion: v1 kind: Node metadata: name: ci-ln-qg1il3k-f76d1-hlmhl-worker-b-df2s4 ... labels: region: east type: user-node ...
如果您在该集群中创建 pod,则该 pod 使用集群范围节点选择器创建,并调度到标记的节点:
Pod 对象示例
apiVersion: v1 kind: Pod ... spec: nodeSelector: region: east ...
在标记的节点上带有 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
spec 中的节点选择器不使用项目节点选择器,则 Pod 不会被创建或调度。
如果 Pod
对象包含不是集群范围节点选择器或项目节点选择器,则 pod 不会被创建或调度。例如,如果您将以下 Pod 部署到示例项目中,则不会创建它:
带有无效节点选择器的 Pod 输出示例
apiVersion: v1 kind: Pod .... spec: nodeSelector: region: west
从该 spec 创建 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 添加额外的键/值对。但是,您无法为默认项目键添加其他值。
流程
添加默认的集群范围节点选择器:
编辑调度程序 Operator 自定义资源以添加集群节点选择器:
$ oc edit scheduler cluster
apiVersion: config.openshift.io/v1 kind: Scheduler metadata: name: cluster ... spec: defaultNodeSelector: type=user-node,region=east 1 mastersSchedulable: false policy: name: ""
完成此更改后,请等待重新部署
openshift-kube-apiserver
项目中的 pod。这可能需要几分钟。只有 pod 重新部署后,默认集群节点选择器才会生效。通过使用机器集或直接编辑节点,为节点添加标签:
在创建节点时,使用
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 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
2.7.3. 创建项目范围节点选择器
您可以组合使用项目中的节点选择器和节点上的标签,将该项目中创建的所有 pod 限制到标记的节点。
当您在这个项目中创建 pod 时,OpenShift Container Platform 会将节点选择器添加到项目中 pod,并将 pod 调度到项目中具有匹配标签的节点。如果存在集群范围默认节点选择器,则以项目节点选择器为准。
您可以通过编辑 Namespace
对象来向项目添加标签,以添加 openshift.io/node-selector
参数,其中包含标签定义。您可以通过编辑 Node
对象、MachineSet
对象或 MachineConfig
对象向节点添加标签。将标签添加到机器集可确保节点或机器停机时,新节点具有标签。如果节点或机器停机,添加到节点或机器配置的标签不会保留。
您可以向 pod 添加额外的键/值对。但是,您无法为默认项目键添加其他值。
例如,以下项目具有 region=east
节点选择器:
Namespace
对象示例
apiVersion: v1 kind: Namespace metadata: 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
对象示例
apiVersion: v1 kind: Pod metadata: ... 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 ....
在创建 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
流程
添加默认项目节点选择器:
创建项目或编辑现有项目以添加
openshift.io/node-selector
参数:$ oc edit project <name>
apiVersion: v1 kind: Project metadata: annotations: openshift.io/node-selector: "type=user-node,region=east" 1 openshift.io/sa.scc.mcs: s0:c17,c14 openshift.io/sa.scc.supplemental-groups: 1000300000/10000 openshift.io/sa.scc.uid-range: 1000300000/10000 creationTimestamp: 2019-06-10T14:39:45Z labels: openshift.io/run-level: "0" name: demo resourceVersion: "401885" selfLink: /api/v1/namespaces/openshift-kube-apiserver uid: 96ecc54b-8b8d-11e9-9f54-0a9ae641edd0 spec: finalizers: - kubernetes status: phase: Active
- 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
命令验证该标签已添加到Node
对象:$ oc label MachineSet abc612-msrtw-worker-us-east-1c type=user-node region=east
例如:
$ 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 <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