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 添加节点选择器,请将节点选择器添加到该节点的控制对象,如 ReplicaSet、Daemonset 或 StatefulSet。任何属于该控制对象的现有 pod 都会在具有匹配标签的节点上重新创建。如果要创建新 pod,可以将节点选择器直接添加到 pod 规格中。
您可以向节点或 MachineConfig 添加标签,但标签不会在节点或机器停机后保留。将标签添加到 MachineSet 可确保新的节点或机器具有该标签。
您不能直接将节点选择器添加到现有调度的 pod 中。
前提条件
要将节点选择器添加到现有 pod 中,请确定该 pod 的控制对象。例如,router-default-66d5cf9464-m2g75
pod 由 router-default-66d5cf9464
ReplicaSet 控制:
$ 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 将标签添加到由 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)来配置集群范围节点选择器。您可以通过编辑节点对象、MachineSet 或 MachineConfig 向节点添加标签。将标签添加到 MachineSet 可确保节点或机器停机时,新节点具有标签。如果节点或机器停机,添加到节点或 MachineConfig 的标签不会保留。
例如,调度程序配置集群范围的 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 将标签添加到由 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
并扩展节点来重新部署与该 MachineSet 关联的节点:例如:
$ 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
参数,其中包含标签定义。您可以通过编辑节点对象、MachineSet 或 MachineConfig 向节点添加标签。将标签添加到 MachineSet 可确保节点或机器停机时,新节点具有标签。如果节点或机器停机,添加到节点或 MachineConfig 的标签不会保留。
您可以向 pod 添加额外的键/值对。但是,您无法为默认项目键添加其他值。
例如,以下项目具有 region=east
节点选择器:
Namespace 对象示例
apiVersion: v1 kind: Namespace metadata: annotations: openshift.io/node-selector: "region=east" ...
以下节点具有 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 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 将标签添加到由 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
重新部署与该 MachineSet 关联的节点:
例如:
$ 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 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
命令验证标签是否已添加到节点:$ 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