×

关于虚拟机的节点放置

为了确保虚拟机 (VM) 在合适的节点上运行,您可以配置节点放置规则。如果您遇到以下情况,可能需要这样做:

  • 您有多个虚拟机。为了确保容错性,您希望它们运行在不同的节点上。

  • 您有两个通信量大的虚拟机。为了避免冗余的节点间路由,您希望这两个虚拟机运行在同一个节点上。

  • 您的虚拟机需要特定硬件功能,而并非所有可用节点都具备这些功能。

  • 您有一个 Pod 向节点添加了功能,并且您希望将虚拟机放置在该节点上,以便它可以使用这些功能。

虚拟机放置依赖于工作负载的任何现有节点放置规则。如果工作负载在组件级别被排除在特定节点之外,则虚拟机无法放置在这些节点上。

您可以在VirtualMachine清单的spec字段中使用以下规则类型:

nodeSelector

允许将虚拟机调度到用您在此字段中指定的键值对标记的节点上。节点必须具有与所有列出的键值对完全匹配的标签。

亲和性 (affinity)

使您可以使用更具表达性的语法来设置与虚拟机匹配节点的规则。例如,您可以指定规则是一个偏好,而不是硬性要求,以便即使不满足规则,虚拟机仍然可以被调度。Pod 亲和性、Pod 反亲和性和节点亲和性都支持虚拟机放置。由于VirtualMachine工作负载类型基于Pod对象,因此 Pod 亲和性适用于虚拟机。

容忍度 (tolerations)

允许将虚拟机调度到具有匹配污点的节点上。如果将污点应用于节点,则该节点仅接受容忍该污点的虚拟机。

亲和性规则仅适用于调度期间。如果约束不再满足,Red Hat OpenShift Service on AWS 不会重新调度正在运行的工作负载。

节点放置示例

以下示例 YAML 文件片段使用nodePlacementaffinitytolerations字段来自定义虚拟机的节点放置。

示例:使用 nodeSelector 进行虚拟机节点放置

在此示例中,虚拟机需要一个具有包含example-key-1 = example-value-1example-key-2 = example-value-2标签的元数据的节点。

如果没有符合此描述的节点,则不会调度虚拟机。

示例虚拟机清单
metadata:
  name: example-vm-node-selector
apiVersion: kubevirt.io/v1
kind: VirtualMachine
spec:
  template:
    spec:
      nodeSelector:
        example-key-1: example-value-1
        example-key-2: example-value-2
# ...

示例:使用 Pod 亲和性和 Pod 反亲和性进行虚拟机节点放置

在此示例中,VM 必须调度到具有运行的 Pod(其标签为example-key-1 = example-value-1)的节点上。如果任何节点上都没有这样的 Pod 正在运行,则不会调度 VM。

如果可能,VM 不会调度到具有任何标签为example-key-2 = example-value-2的 Pod 的节点上。但是,如果所有候选节点都具有此标签的 Pod,则调度程序会忽略此约束。

示例虚拟机清单
metadata:
  name: example-vm-pod-affinity
apiVersion: kubevirt.io/v1
kind: VirtualMachine
spec:
  template:
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution: (1)
          - labelSelector:
              matchExpressions:
              - key: example-key-1
                operator: In
                values:
                - example-value-1
            topologyKey: kubernetes.io/hostname
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution: (2)
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: example-key-2
                  operator: In
                  values:
                  - example-value-2
              topologyKey: kubernetes.io/hostname
# ...
1 如果您使用requiredDuringSchedulingIgnoredDuringExecution规则类型,则如果不满足约束,则不会调度 VM。
2 如果您使用preferredDuringSchedulingIgnoredDuringExecution规则类型,则只要满足所有必需的约束,即使不满足约束,VM 仍然会被调度。

示例:使用节点亲和性进行虚拟机节点放置

在此示例中,VM 必须调度到具有标签example.io/example-key = example-value-1或标签example.io/example-key = example-value-2的节点上。如果节点上只有其中一个标签存在,则满足约束条件。如果两个标签都不存在,则不会调度 VM。

如果可能,调度程序会避免具有标签example-node-label-key = example-node-label-value的节点。但是,如果所有候选节点都具有此标签,则调度程序会忽略此约束。

示例虚拟机清单
metadata:
  name: example-vm-node-affinity
apiVersion: kubevirt.io/v1
kind: VirtualMachine
spec:
  template:
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution: (1)
            nodeSelectorTerms:
            - matchExpressions:
              - key: example.io/example-key
                operator: In
                values:
                - example-value-1
                - example-value-2
          preferredDuringSchedulingIgnoredDuringExecution: (2)
          - weight: 1
            preference:
              matchExpressions:
              - key: example-node-label-key
                operator: In
                values:
                - example-node-label-value
# ...
1 如果您使用requiredDuringSchedulingIgnoredDuringExecution规则类型,则如果不满足约束,则不会调度 VM。
2 如果您使用preferredDuringSchedulingIgnoredDuringExecution规则类型,则只要满足所有必需的约束,即使不满足约束,VM 仍然会被调度。

示例:使用容忍度进行虚拟机节点放置

在此示例中,为虚拟机保留的节点已使用key=virtualization:NoSchedule污点标记。由于此虚拟机具有匹配的tolerations,因此它可以调度到被污点的节点上。

容忍污点的虚拟机不需要调度到具有该污点的节点上。

示例虚拟机清单
metadata:
  name: example-vm-tolerations
apiVersion: kubevirt.io/v1
kind: VirtualMachine
spec:
  tolerations:
  - key: "key"
    operator: "Equal"
    value: "virtualization"
    effect: "NoSchedule"
# ...