4.3. 使用节点关联性规则控制节点上的 pod 放置
关联性是 pod 的一个属性,用于控制它们希望调度到的节点。
在 OpenShift Dedicated 中,节点关联性是由调度程序用来确定 pod 的可放置位置的一组规则。规则是使用节点中的自定义标签和 pod 中指定的选择器进行定义的。
4.3.1. 了解节点关联性
节点关联性允许 pod 指定与可以放置该 pod 的一组节点的关联性。节点对放置没有控制权。
例如,您可以将 pod 配置为仅在具有特定 CPU 或位于特定可用区的节点上运行。
节点关联性规则有两种,即必要规则和偏好规则。
必须满足必要规则,pod 才能调度到节点上。偏好规则指定在满足规则时调度程序会尝试强制执行规则,但不保证一定能强制执行成功。
如果节点标签在运行时改变,使得不再满足 pod 上的节点关联性规则,该 pod 将继续在这个节点上运行。
您可以通过 Pod
规格文件配置节点关联性。您可以指定必要规则或偏好规则,或同时指定这两种规则。如果您同时指定,节点必须首先满足必要规则,然后尝试满足偏好规则。
下例中的 Pod
spec 包含一条规则,要求 pod 放置到具有键为 e2e-az-NorthSouth
且值为 e2e-az-North
或 e2e-az-South
的标签的节点上:
具有节点关联性必要规则的 pod 配置文件示例
apiVersion: v1 kind: Pod metadata: name: with-node-affinity spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault affinity: nodeAffinity: 1 requiredDuringSchedulingIgnoredDuringExecution: 2 nodeSelectorTerms: - matchExpressions: - key: e2e-az-NorthSouth 3 operator: In 4 values: - e2e-az-North 5 - e2e-az-South 6 containers: - name: with-node-affinity image: docker.io/ocpqe/hello-pod securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] # ...
下例中的节点规格包含一条偏好规则,其规定优先为 pod 选择具有键为 e2e-az-EastWest
且值为 e2e-az-East
或 e2e-az-West
的节点:
具有节点关联性偏好规则的 pod 配置文件示例
apiVersion: v1 kind: Pod metadata: name: with-node-affinity spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault affinity: nodeAffinity: 1 preferredDuringSchedulingIgnoredDuringExecution: 2 - weight: 1 3 preference: matchExpressions: - key: e2e-az-EastWest 4 operator: In 5 values: - e2e-az-East 6 - e2e-az-West 7 containers: - name: with-node-affinity image: docker.io/ocpqe/hello-pod securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] # ...
没有明确的节点反关联性概念,但使用 NotIn
或 DoesNotExist
运算符就能实现这种行为。
如果您在同一 pod 配置中同时使用节点关联性和节点选择器,请注意以下几点:
-
如果同时配置了
nodeSelector
和nodeAffinity
,则必须满足这两个条件时 pod 才能调度到候选节点。 -
如果您指定了多个与
nodeAffinity
类型关联的nodeSelectorTerms
,那么其中一个nodeSelectorTerms
满足时 pod 就能调度到节点上。 -
如果您指定了多个与
nodeSelectorTerms
关联的matchExpressions
,那么只有所有matchExpressions
都满足时 pod 才能调度到节点上。
4.3.2. 配置节点关联性必要规则
必须满足必要规则,pod 才能调度到节点上。
流程
以下步骤演示了一个简单的配置,此配置会创建一个节点,以及调度程序要放置到该节点上的 pod。
创建 pod 规格中具有特定标签的 pod:
使用以下内容创建 YAML 文件:
注意您不能直接将关联性添加到调度的 pod 中。
输出示例
apiVersion: v1 kind: Pod metadata: name: s1 spec: affinity: 1 nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: 2 nodeSelectorTerms: - matchExpressions: - key: e2e-az-name 3 values: - e2e-az1 - e2e-az2 operator: In 4 #...
创建 pod:
$ oc create -f <file-name>.yaml
4.3.3. 配置首选的节点关联性规则
偏好规则指定在满足规则时调度程序会尝试强制执行规则,但不保证一定能强制执行成功。
流程
以下步骤演示了一个简单的配置,此配置会创建一个节点,以及调度程序尝试放置到该节点上的 pod。
创建具有特定标签的 pod:
使用以下内容创建 YAML 文件:
注意您不能直接将关联性添加到调度的 pod 中。
apiVersion: v1 kind: Pod metadata: name: s1 spec: affinity: 1 nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: 2 - weight: 3 preference: matchExpressions: - key: e2e-az-name 4 values: - e2e-az3 operator: In 5 #...
创建 pod。
$ oc create -f <file-name>.yaml
4.3.4. 节点关联性规则示例
以下示例演示了节点关联性。
4.3.4.1. 具有匹配标签的节点关联性
以下示例演示了具有匹配标签的节点与 pod 的节点关联性:
Node1 节点具有标签
zone:us
:$ oc label node node1 zone=us
提示您还可以应用以下 YAML 来添加标签:
kind: Node apiVersion: v1 metadata: name: <node_name> labels: zone: us #...
pod-s1 pod 在节点关联性必要规则下具有
zone
和us
键/值对:$ cat pod-s1.yaml
输出示例
apiVersion: v1 kind: Pod metadata: name: pod-s1 spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault containers: - image: "docker.io/ocpqe/hello-pod" name: hello-pod securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: "zone" operator: In values: - us #...
pod-s1 pod 可以调度到 Node1 上:
$ oc get pod -o wide
输出示例
NAME READY STATUS RESTARTS AGE IP NODE pod-s1 1/1 Running 0 4m IP1 node1
4.3.4.2. 没有匹配标签的节点关联性
以下示例演示了无匹配标签的节点与 pod 的节点关联性:
Node1 节点具有标签
zone:emea
:$ oc label node node1 zone=emea
提示您还可以应用以下 YAML 来添加标签:
kind: Node apiVersion: v1 metadata: name: <node_name> labels: zone: emea #...
pod-s1 pod 在节点关联性必要规则下具有
zone
和us
键/值对:$ cat pod-s1.yaml
输出示例
apiVersion: v1 kind: Pod metadata: name: pod-s1 spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault containers: - image: "docker.io/ocpqe/hello-pod" name: hello-pod securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: "zone" operator: In values: - us #...
pod-s1 pod 无法调度到 Node1 上:
$ oc describe pod pod-s1
输出示例
... Events: FirstSeen LastSeen Count From SubObjectPath Type Reason --------- -------- ----- ---- ------------- -------- ------ 1m 33s 8 default-scheduler Warning FailedScheduling No nodes are available that match all of the following predicates:: MatchNodeSelector (1).