7.13. 高级虚拟机管理


7.13.1. 为虚拟机使用资源配额

为虚拟机创建和管理资源配额。

7.13.1.1. 为虚拟机设置资源配额限制

只有使用请求自动用于虚拟机 (VM) 的资源配额。如果您的资源配额使用限制,则必须为虚拟机手动设置资源限值。资源限值必须至少大于资源请求的 100 MiB。

流程

  1. 通过编辑 VirtualMachine 清单来为虚拟机设置限值。例如:

    apiVersion: kubevirt.io/v1
    kind: VirtualMachine
    metadata:
      name: with-limits
    spec:
      running: false
      template:
        spec:
          domain:
    # ...
            resources:
              requests:
                memory: 128Mi
              limits:
                memory: 256Mi  1
    1
    这个配置被支持,因为 limits.memory 值至少比 requests.memory 的值大 100Mi
  2. 保存 VirtualMachine 清单。

7.13.1.2. 其他资源

7.13.2. 为虚拟机指定节点

您可以使用节点放置规则将虚拟机放置到特定的节点上。

7.13.2.1. 关于虚拟机的节点放置

要确保虚拟机在适当的节点上运行,您可以配置节点放置规则。如果出现以下情况,您可能需要进行此操作:

  • 您有多台虚拟机。为确保容错,您希望它们在不同节点上运行。
  • 您有两个 chatty 虚拟机。为了避免冗余节点间路由,您希望虚拟机在同一节点上运行。
  • 您的虚拟机需要所有可用节点上不存在的特定硬件功能。
  • 您有一个 pod 可以向节点添加功能,并想将虚拟机放置到该节点上,以便它可以使用这些功能。
注意

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

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

nodeSelector
允许将虚拟机调度到使用此字段中指定的键值对标记的节点上。节点必须具有与所有列出的对完全匹配的标签。
关联性
这可让您使用更具表达力的语法来设置与虚拟机匹配的规则。例如,您可以指定规则是首选项,而非硬要求,因此在规则不满足时仍然可以调度虚拟机。虚拟机放置支持 Pod 关联性、pod 反关联性和节点关联性。Pod 关联性适用于虚拟机,因为 VirtualMachine 工作负载类型基于 Pod 对象。
容限(tolerations)

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

注意

关联性规则仅在调度期间应用。如果不再满足限制,OpenShift Container Platform 不会重新调度正在运行的工作负载。

7.13.2.2. 节点放置示例

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

7.13.2.2.1. 示例:使用 nodeSelector 放置虚拟机节点

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

警告

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

VM 清单示例

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
# ...

7.13.2.2.2. 示例:使用 pod 关联性和 pod 反关联性的虚拟机节点放置

在本例中,虚拟机必须调度到具有标签 example-key-1 = example-value-1 的正在运行的 pod 的节点上。如果没有在任何节点上运行这样的 pod,则不会调度虚拟机。

如果可能,虚拟机不会调度到具有标签 example-key-2 = example-value-2 的 pod 的节点上。但是,如果所有候选节点都有具有此标签的 pod,调度程序会忽略此约束。

VM 清单示例

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 规则类型,如果没有满足约束,则不会调度虚拟机。
2
如果您使用 preferredDuringSchedulingIgnoredDuringExecution 规则类型,只要满足所有必要的限制,仍会调度虚拟机(如果未满足约束)。
7.13.2.2.3. 示例:使用节点关联性进行虚拟机节点放置

在本例中,虚拟机必须调度到具有标签 example.io/example-key = example-value-1 或标签 example.io/example-key = example-value-2 的节点上。如果节点上只有一个标签,则会满足约束。如果没有标签,则不会调度虚拟机。

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

VM 清单示例

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 规则类型,如果没有满足约束,则不会调度虚拟机。
2
如果您使用 preferredDuringSchedulingIgnoredDuringExecution 规则类型,只要满足所有必要的限制,仍会调度虚拟机(如果未满足约束)。
7.13.2.2.4. 示例:带有容限的虚拟机节点放置

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

注意

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

VM 清单示例

metadata:
  name: example-vm-tolerations
apiVersion: kubevirt.io/v1
kind: VirtualMachine
spec:
  tolerations:
  - key: "key"
    operator: "Equal"
    value: "virtualization"
    effect: "NoSchedule"
# ...

7.13.2.3. 其他资源

7.13.3. 激活内核相同的页面合并 (KSM)

当节点过载时,OpenShift Virtualization 可以激活内核相同的页面合并 (KSM)。KSM 去除在虚拟机 (VM) 的内存页面中找到的相同数据。如果您有类似的虚拟机,则 KSM 可以在单个节点上调度更多虚拟机。

重要

您必须只使用带有可信工作负载的 KSM。

7.13.3.1. 先决条件

  • 确保管理员已在您希望 OpenShift Virtualization 激活 KSM 的任何节点上配置了 KSM 支持。

7.13.3.2. 关于使用 OpenShift Virtualization 激活 KSM

当节点遇到内存过载时,您可以将 OpenShift Virtualization 配置为激活内核相同的页面合并(KSM)。

7.13.3.2.1. 配置方法

您可以使用 OpenShift Container Platform Web 控制台或编辑 HyperConverged 自定义资源(CR)来启用或禁用所有节点的 KSM 激活功能。HyperConverged CR 支持更精细的配置。

CR 配置

您可以通过编辑 HyperConverged CR 的 spec.configuration.ksmConfiguration 小节来配置 KSM 激活功能。

  • 您可以通过编辑 ksmConfiguration 小节来启用功能和配置设置。
  • 您可以通过删除 ksmConfiguration 小节来禁用该功能。
  • 您可以通过在 ksmConfiguration.nodeLabelSelector 字段中添加节点选择语法来允许 OpenShift Virtualization 只在节点子集上启用 KSM。
注意

即使 OpenShift Virtualization 中禁用了 KSM 激活功能,管理员仍然可以在支持它的节点上启用 KSM。

7.13.3.2.2. KSM 节点标签

OpenShift Virtualization 识别配置为支持 KSM 并应用以下节点标签的节点:

kubevirt.io/ksm-handler-managed: "false"
当 OpenShift Virtualization 在遇到内存过载的节点上激活 KSM 时,该标签被设置为 "true"。如果管理员激活 KSM,则该标签没有设置为 "true"
kubevirt.io/ksm-enabled: "false"
当节点上激活 KSM 时,此标签被设置为 "true",即使 OpenShift Virtualization 没有激活 KSM。

这些标签不适用于不支持 KSM 的节点。

7.13.3.3. 使用 Web 控制台配置 KSM 激活

您可以使用 OpenShift Container Platform Web 控制台允许 OpenShift Virtualization 在集群中的所有节点上激活内核相同的页面合并 (KSM)。

流程

  1. 在侧边菜单中点 Virtualization Overview
  2. 选择 Settings 选项卡。
  3. 选择 Cluster 选项卡。
  4. 扩展 资源管理
  5. 为所有节点启用或禁用功能:

    • 内核同页合并(KSM) 设置为 on。
    • 内核同页合并(KSM) 设置为 off。

7.13.3.4. 使用 CLI 配置 KSM 激活

您可以通过编辑 HyperConverged 自定义资源(CR)来启用或禁用 OpenShift Virtualization 内核相同的页面合并(KSM)激活功能。如果您希望 OpenShift Virtualization 只在某个节点子集上激活 KSM,则使用此方法。

流程

  1. 运行以下命令,在默认编辑器中打开 HyperConverged CR:

    $ oc edit hyperconverged kubevirt-hyperconverged -n openshift-cnv
  2. 编辑 ksmConfiguration 小节:

    • 要为所有节点启用 KSM 激活功能,请将 nodeLabelSelector 值设置为 {}。例如:

      apiVersion: hco.kubevirt.io/v1beta1
      kind: HyperConverged
      metadata:
        name: kubevirt-hyperconverged
        namespace: openshift-cnv
      spec:
        configuration:
          ksmConfiguration:
            nodeLabelSelector: {}
      # ...
    • 要在节点的子集上启用 KSM 激活功能,请编辑 nodeLabelSelector 字段。添加与 OpenShift Virtualization 启用 KSM 的节点匹配的语法。例如,以下配置允许 OpenShift Virtualization 在 <first_example_key><second_example_key> 被设置为 "true" 的节点上启用 KSM。

      apiVersion: hco.kubevirt.io/v1beta1
      kind: HyperConverged
      metadata:
        name: kubevirt-hyperconverged
        namespace: openshift-cnv
      spec:
        configuration:
          ksmConfiguration:
            nodeLabelSelector:
              matchLabels:
                <first_example_key>: "true"
                <second_example_key>: "true"
      # ...
    • 要禁用 KSM 激活功能,请删除 ksmConfiguration 小节。例如:

      apiVersion: hco.kubevirt.io/v1beta1
      kind: HyperConverged
      metadata:
        name: kubevirt-hyperconverged
        namespace: openshift-cnv
      spec:
        configuration:
      # ...
  3. 保存该文件。

7.13.3.5. 其他资源

7.13.4. 配置证书轮转

配置证书轮转参数以替换现有证书。

7.13.4.1. 配置证书轮转

您可以在 web 控制台中的 OpenShift Virtualization 安装过程中,或者在安装 HyperConverged 自定义资源(CR)后完成此操作。

流程

  1. 运行以下命令打开 HyperConverged CR:

    $ oc edit hyperconverged kubevirt-hyperconverged -n openshift-cnv
  2. 按照以下示例所示,编辑 spec.certConfig 字段。要避免系统过载,请确保所有值都大于或等于 10 分钟。将所有值显示为符合 golang ParseDuration 格式的字符串

    apiVersion: hco.kubevirt.io/v1beta1
    kind: HyperConverged
    metadata:
      name: kubevirt-hyperconverged
      namespace: openshift-cnv
    spec:
      certConfig:
        ca:
          duration: 48h0m0s
          renewBefore: 24h0m0s 1
        server:
          duration: 24h0m0s  2
          renewBefore: 12h0m0s  3
    1
    ca.renewBefore 的值必须小于或等于 ca.duration 的值。
    2
    server.duration 的值必须小于或等于 ca.duration 的值。
    3
    server.renewBefore 的值必须小于或等于 server.duration 的值。
  3. 将 YAML 文件应用到集群。

7.13.4.2. 证书轮转参数故障排除

删除一个或多个 certConfig 值会导致它们恢复到默认值,除非默认值与以下条件之一冲突:

  • ca.renewBefore 的值必须小于或等于 ca.duration 的值。
  • server.duration 的值必须小于或等于 ca.duration 的值。
  • server.renewBefore 的值必须小于或等于 server.duration 的值。

如果默认值与这些条件冲突,您将收到错误。

如果您删除了以下示例中的 server.duration 值,则默认值 24h0m0s 大于 ca.duration 的值,并与指定条件冲突。

Example

certConfig:
   ca:
     duration: 4h0m0s
     renewBefore: 1h0m0s
   server:
     duration: 4h0m0s
     renewBefore: 4h0m0s

这会生成以下出错信息:

error: hyperconvergeds.hco.kubevirt.io "kubevirt-hyperconverged" could not be patched: admission webhook "validate-hco.kubevirt.io" denied the request: spec.certConfig: ca.duration is smaller than server.duration

错误消息仅提及第一个冲突。在继续操作前,查看所有 certConfig 值。

7.13.5. 配置默认 CPU 型号

使用 HyperConverged 自定义资源 (CR) 中的 defaultCPUModel 设置来定义集群范围的默认 CPU 模型。

虚拟机 (VM) CPU 模型取决于虚拟机和集群中的 CPU 模型的可用性。

  • 如果虚拟机没有定义的 CPU 模型:

    • defaultCPUModel 使用在集群范围级别上定义的 CPU 模型自动设置。
  • 如果虚拟机和集群都有定义的 CPU 模型:

    • 虚拟机的 CPU 模型具有优先权。
  • 如果虚拟机或集群都没有定义的 CPU 模型:

    • host-model 使用主机级别上定义的 CPU 模型自动设置。

7.13.5.1. 配置默认 CPU 型号

通过更新 HyperConverged 自定义资源(CR) 来配置 defaultCPUModel。您可以在 OpenShift Virtualization 运行时更改 defaultCPUModel

注意

defaultCPUModel 是区分大小写的。

先决条件

  • 安装 OpenShift CLI(oc)。

流程

  1. 运行以下命令打开 HyperConverged CR:

    $ oc edit hyperconverged kubevirt-hyperconverged -n openshift-cnv
  2. defaultCPUModel 字段添加到 CR,并将值设置为集群中存在的 CPU 模型的名称:

    apiVersion: hco.kubevirt.io/v1beta1
    kind: HyperConverged
    metadata:
     name: kubevirt-hyperconverged
     namespace: openshift-cnv
    spec:
      defaultCPUModel: "EPYC"
  3. 将 YAML 文件应用到集群。

7.13.6. 为虚拟机使用 UEFI 模式

您可以使用统一可扩展固件接口(UEFI)模式引导虚拟机(VM)。

7.13.6.1. 关于虚拟机的 UEFI 模式

像旧的 BIOS 一样,统一可扩展固件接口(UEFI)在计算机启动时初始化硬件组件和操作系统镜像文件。与 BIOS 相比,UEFI 支持更现代的功能和自定义选项,从而加快启动速度。

它将初始化和启动的所有信息保存在带有 .efi 扩展的文件中,该扩展被保存在名为 EFI 系统分区(ESP)的特殊分区中。ESP 还包含安装在计算机上的操作系统的引导装载程序程序。

7.13.6.2. 在 UEFI 模式中引导虚拟机

您可以通过编辑 VirtualMachine 清单,将虚拟机配置为在 UEFI 模式中引导。

先决条件

  • 安装 OpenShift CLI (oc) 。

流程

  1. 编辑或创建 VirtualMachine 清单文件。使用 spec.firmware.bootloader 小节来配置 UEFI 模式:

    使用安全引导活跃在 UEFI 模式中引导

    apiversion: kubevirt.io/v1
    kind: VirtualMachine
    metadata:
      labels:
        special: vm-secureboot
      name: vm-secureboot
    spec:
      template:
        metadata:
          labels:
            special: vm-secureboot
        spec:
          domain:
            devices:
              disks:
              - disk:
                  bus: virtio
                name: containerdisk
            features:
              acpi: {}
              smm:
                enabled: true 1
            firmware:
              bootloader:
                efi:
                  secureBoot: true 2
    # ...

    1
    OpenShift Virtualization 需要为 UEFI 模式的安全引导启用系统管理模式(SMM)。
    2
    使用 UEFI 模式时,OpenShift Virtualization 支持带有或不进行安全引导的虚拟机。如果启用了安全引导,则需要 UEFI 模式。但是,可以在不使用安全引导的情况下启用 UEFI 模式。
  2. 运行以下命令,将清单应用到集群:

    $ oc create -f <file_name>.yaml

7.13.7. 为虚拟机配置 PXE 启动

OpenShift Virtualization 中提供 PXE 启动或网络启动。网络启动支持计算机启动和加载操作系统或其他程序,无需本地连接的存储设备。例如,在部署新主机时,您可使用 PXE 启动从 PXE 服务器中选择所需操作系统镜像。

7.13.7.1. 先决条件

  • Linux 网桥必须已连接
  • PXE 服务器必须作为网桥连接至相同 VLAN。

7.13.7.2. 使用指定的 MAC 地址的 PXE 引导

作为管理员,您可首先为您的 PXE 网络创建 NetworkAttachmentDefinition 对象,以此通过网络引导客户端。然后在启动虚拟机实例前,在您的虚拟机实例配置文件中引用网络附加定义。如果 PXE 服务器需要,您还可在虚拟机实例配置文件中指定 MAC 地址。

先决条件

  • 必须已连接 Linux 网桥。
  • PXE 服务器必须作为网桥连接至相同 VLAN。

流程

  1. 在集群上配置 PXE 网络:

    1. 为 PXE 网络 pxe-net-conf 创建网络附加定义文件:

      apiVersion: "k8s.cni.cncf.io/v1"
      kind: NetworkAttachmentDefinition
      metadata:
        name: pxe-net-conf 1
      spec:
        config: |
          {
            "cniVersion": "0.3.1",
            "name": "pxe-net-conf", 2
            "type": "bridge", 3
            "bridge": "bridge-interface", 4
            "macspoofchk": false, 5
            "vlan": 100, 6
            "preserveDefaultVlan": false 7
          }
      1
      NetworkAttachmentDefinition 对象的名称。
      2
      配置的名称。建议您将配置名称与网络附加定义的 name 值匹配。
      3
      为这个网络附加定义的 Container Network Interface(CNI)插件的实际名称。这个示例使用 Linux bridge CNI 插件。您还可以使用 OVN-Kubernetes localnet 或 SR-IOV CNI 插件。
      4
      节点上配置的 Linux 网桥名称。
      5
      可选:启用 MAC 欺骗检查的标记。当设置为 true 时,您无法更改 pod 或客户机接口的 MAC 地址。此属性只允许单个 MAC 地址退出 pod,从而可防止 MAC 欺骗攻击。
      6
      可选: VLAN 标签。节点网络配置策略不需要额外的 VLAN 配置。
      7
      可选:指示虚拟机是否通过默认 VLAN 连接到网桥。默认值为 true
  2. 使用您在上一步中创建的文件创建网络附加定义:

    $ oc create -f pxe-net-conf.yaml
  3. 编辑虚拟机实例配置文件以包括接口和网络的详情。

    1. 如果 PXE 服务器需要,请指定网络和 MAC 地址。如果未指定 MAC 地址,则会自动分配一个值。

      请确保 bootOrder 设置为 1,以便该接口先启动。在本例中,该接口连接到了名为 <pxe-net> 的网络中:

      interfaces:
      - masquerade: {}
        name: default
      - bridge: {}
        name: pxe-net
        macAddress: de:00:00:00:00:de
        bootOrder: 1
      注意

      启动顺序对于接口和磁盘全局通用。

    2. 为磁盘分配一个启动设备号,以确保置备操作系统后能够正确启动。

      将磁盘 bootOrder 值设置为 2

      devices:
        disks:
        - disk:
            bus: virtio
          name: containerdisk
          bootOrder: 2
    3. 指定网络连接到之前创建的网络附加定义。在这种情况下,<pxe-net> 连接到名为 <pxe-net-conf> 的网络附加定义:

      networks:
      - name: default
        pod: {}
      - name: pxe-net
        multus:
          networkName: pxe-net-conf
  4. 创建虚拟机实例:

    $ oc create -f vmi-pxe-boot.yaml

    输出示例

      virtualmachineinstance.kubevirt.io "vmi-pxe-boot" created

  5. 等待虚拟机实例运行:

    $ oc get vmi vmi-pxe-boot -o yaml | grep -i phase
      phase: Running
  6. 使用 VNC 查看虚拟机实例:

    $ virtctl vnc vmi-pxe-boot
  7. 查看启动屏幕,验证 PXE 启动是否成功。
  8. 登录虚拟机实例:

    $ virtctl console vmi-pxe-boot

验证

  1. 验证虚拟机上的接口和 MAC 地址,并验证连接到网桥的接口是否具有指定的 MAC 地址。在本例中,我们使用了 eth1 进行 PXE 启动,无需 IP 地址。另一接口 eth0 从 OpenShift Container Platform 获取 IP 地址。

    $ ip addr

    输出示例

    ...
    3. eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
       link/ether de:00:00:00:00:de brd ff:ff:ff:ff:ff:ff

7.13.7.3. OpenShift Virtualization 术语表

以下是整个 OpenShift Virtualization 文档中使用的术语:

Container Network Interface (CNI)
一个 Cloud Native Computing Foundation 项目,侧重容器网络连接。OpenShift Virtualization 使用 CNI 插件基于基本 Kubernetes 网络功能进行构建。
Multus
一个“meta”CNI 插件,支持多个 CNI 共存,以便 pod 或虚拟机可使用其所需的接口。
自定义资源定义(CRD)
一个 Kubernetes API 资源,用于定义自定义资源,或使用 CRD API 资源定义的对象。
网络附加定义(NAD)
由 Multus 项目引入的 CRD,允许您将 Pod、虚拟机和虚拟机实例附加到一个或多个网络。
节点网络配置策略(NNCP)
nmstate 项目引入的 CRD,描述节点上请求的网络配置。您可以通过将 NodeNetworkConfigurationPolicy清单应用到集群来更新节点网络配置,包括添加和删除网络接口 。

7.13.8. 在虚拟机中使用巨页

您可以使用巨页作为集群中虚拟机的后备内存。

7.13.8.1. 先决条件

7.13.8.2. 巨页的作用

内存在块(称为页)中进行管理。在大多数系统中,页的大小为 4Ki。1Mi 内存相当于 256 个页,1Gi 内存相当于 256,000 个页。CPU 有内置的内存管理单元,可在硬件中管理这些页的列表。Translation Lookaside Buffer (TLB) 是虚拟页到物理页映射的小型硬件缓存。如果在硬件指令中包括的虚拟地址可以在 TLB 中找到,则其映射信息可以被快速获得。如果没有包括在 TLN 中,则称为 TLB miss。系统将会使用基于软件的,速度较慢的地址转换机制,从而出现性能降低的问题。因为 TLB 的大小是固定的,因此降低 TLB miss 的唯一方法是增加页的大小。

巨页指一个大于 4Ki 的内存页。在 x86_64 构架中,有两个常见的巨页大小: 2Mi 和 1Gi。在其它构架上的大小会有所不同。要使用巨页,必须写相应的代码以便应用程序了解它们。Transparent Huge Pages(THP)试图在应用程序不需要了解的情况下自动管理巨页,但这个技术有一定的限制。特别是,它的页大小会被限为 2Mi。当有较高的内存使用率时,THP 可能会导致节点性能下降,或出现大量内存碎片(因为 THP 的碎片处理)导致内存页被锁定。因此,有些应用程序可能更适用于(或推荐)使用预先分配的巨页,而不是 THP。

在 OpenShift Virtualization 中,可将虚拟机配置为消耗预先分配的巨页。

7.13.8.3. 为虚拟机配置巨页

您可以在虚拟机配置中包括 memory.hugepages.pageSizeresources.requests.memory 参数来配置虚拟机来使用预分配的巨页。

内存请求必须按页大小分离。例如,您不能对大小为 1Gi 的页请求 500Mi 内存。

注意

主机的内存布局和客户端操作系统不相关。虚拟机清单中请求的巨页适用于 QEMU。客户端中的巨页只能根据虚拟机实例的可用内存量来配置。

如果您编辑了正在运行的虚拟机,则必须重启虚拟机才能使更改生效。

先决条件

  • 节点必须配置预先分配的巨页。

流程

  1. 在虚拟机配置中,把 resources.requests.memorymemory.hugepages.pageSize 参数添加到 spec.domain。以下配置片段适用于请求总计 4Gi 内存的虚拟机,页面大小为 1Gi:

    kind: VirtualMachine
    # ...
    spec:
      domain:
        resources:
          requests:
            memory: "4Gi" 1
        memory:
          hugepages:
            pageSize: "1Gi" 2
    # ...
    1
    为虚拟机请求的总内存量。这个值必须可以被按页大小整除。
    2
    每个巨页的大小。x86_64 架构的有效值为 1Gi2Mi。页面大小必须小于请求的内存。
  2. 应用虚拟机配置:

    $ oc apply -f <virtual_machine>.yaml

7.13.9. 为虚拟机启用专用资源

要提高性能,您可以将节点的资源(如 CPU)专用于特定的一个虚拟机。

7.13.9.1. 关于专用资源

当为您的虚拟机启用专用资源时,您的工作负载将会在不会被其他进程使用的 CPU 上调度。通过使用专用资源,您可以提高虚拟机性能以及延迟预测的准确性。

7.13.9.2. 先决条件

  • 节点上必须配置 CPU Manager。在调度虚拟机工作负载前,请确认节点具有 cpumanager = true 标签。
  • 虚拟机必须关机。

7.13.9.3. 为虚拟机启用专用资源

您可以在 Details 选项卡中为虚拟机启用专用资源。从红帽模板创建的虚拟机可以使用专用资源进行配置。

流程

  1. 在 OpenShift Container Platform 控制台中,从侧边菜单中点 Virtualization VirtualMachines
  2. 选择虚拟机以打开 VirtualMachine 详情页面。
  3. Configuration Scheduling 选项卡中,点 Dedicated Resources 旁边的编辑图标。
  4. 选择 Schedule this workload with dedicated resources (guaranteed policy)
  5. Save

7.13.10. 调度虚拟机

在确保虚拟机的 CPU 模型和策略属性与节点支持的 CPU 模型和策略属性兼容的情况下,可在节点上调度虚拟机(VM)。

7.13.10.1. 策略属性

您可以指定策略属性和在虚拟机调度到节点上时匹配的 CPU 功能来调度虚拟机(VM)。为虚拟机指定的策略属性决定了如何在节点上调度该虚拟机。

策略属性描述

force

VM 被强制调度到某个节点上。即使主机 CPU 不支持虚拟机的 CPU,也是如此。

require

在虚拟机没有使用特定 CPU 模型和功能规格配置时,应用于虚拟机的默认策略。如果节点没有配置为支持使用此默认策略属性或其他策略属性的 CPU 节点发现,则虚拟机不会调度到该节点上。主机 CPU 必须支持虚拟机的 CPU,或者虚拟机监控程序必须可以模拟支持的 CPU 模型。

optional

如果主机物理机器 CPU 支持该虚拟机,则虚拟机会被添加到节点。

disable

无法通过 CPU 节点发现调度虚拟机。

forbid

即使主机 CPU 支持该功能,且启用了 CPU 节点发现,也不会调度虚拟机。

7.13.10.2. 设置策略属性和 CPU 功能

您可以为每个虚拟机(VM)设置策略属性和 CPU 功能,以确保根据策略和功能在节点上调度该功能。验证您设置的 CPU 功能以确保主机 CPU 支持或者虚拟机监控程序模拟该功能。

流程

  • 编辑虚拟机配置文件的 domain spec。以下示例设置虚拟机 (VM) 的 CPU 功能和 require 策略:

    apiVersion: kubevirt.io/v1
    kind: VirtualMachine
    metadata:
      name: myvm
    spec:
      template:
        spec:
          domain:
            cpu:
              features:
                - name: apic 1
                  policy: require 2
    1
    虚拟机的 CPU 功能名称。
    2
    虚拟机的策略属性.

7.13.10.3. 使用支持的 CPU 型号调度虚拟机

您可以为虚拟机 (VM) 配置 CPU 模型,将其调度到支持其 CPU 模型的节点。

流程

  • 编辑虚拟机配置文件的 domain spec。以下示例显示了为虚拟机定义的特定 CPU 模型:

    apiVersion: kubevirt.io/v1
    kind: VirtualMachine
    metadata:
      name: myvm
    spec:
      template:
        spec:
          domain:
            cpu:
              model: Conroe 1
    1
    虚拟机的 CPU 模型.

7.13.10.4. 使用主机模型调度虚拟机

当将虚拟机(VM)的 CPU 模型设置为 host-model 时,虚拟机会继承调度节点的 CPU 模型。

流程

  • 编辑虚拟机配置文件的 domain spec。以下示例演示了为虚拟机指定 host-model

    apiVersion: kubevirt/v1alpha3
    kind: VirtualMachine
    metadata:
      name: myvm
    spec:
      template:
        spec:
          domain:
            cpu:
              model: host-model 1
    1
    继承调度节点的 CPU 模型的虚拟机。

7.13.10.5. 使用自定义调度程序调度虚拟机

您可以使用自定义调度程序在节点上调度虚拟机 (VM)。

先决条件

  • 为集群配置二级调度程序。

流程

  • 通过编辑 VirtualMachine 清单,将自定义调度程序添加到虚拟机配置中。例如:

    apiVersion: kubevirt.io/v1
    kind: VirtualMachine
    metadata:
      name: vm-fedora
    spec:
      running: true
      template:
        spec:
          schedulerName: my-scheduler 1
          domain:
            devices:
              disks:
                - name: containerdisk
                  disk:
                    bus: virtio
    # ...
    1
    自定义调度程序的名称。如果 schedulerName 值与现有调度程序不匹配,virt-launcher pod 会一直处于 Pending 状态,直到找到指定的调度程序为止。

验证

  • 通过检查 virt-launcher pod 事件来验证虚拟机是否使用 VirtualMachine 清单中指定的自定义调度程序:

    1. 输入以下命令来查看集群中的 pod 列表:

      $ oc get pods

      输出示例

      NAME                             READY   STATUS    RESTARTS   AGE
      virt-launcher-vm-fedora-dpc87    2/2     Running   0          24m

    2. 运行以下命令以显示 pod 事件:

      $ oc describe pod virt-launcher-vm-fedora-dpc87

      输出中的 From 字段的值验证调度程序名称与 VirtualMachine 清单中指定的自定义调度程序匹配:

      输出示例

      [...]
      Events:
        Type    Reason     Age   From              Message
        ----    ------     ----  ----              -------
        Normal  Scheduled  21m   my-scheduler  Successfully assigned default/virt-launcher-vm-fedora-dpc87 to node01
      [...]

7.13.11. 配置 PCI 透传

通过 Peripheral Component Interconnect (PCI) 透传功能,您可以从虚拟机 (VM) 访问和管理硬件设备。配置 PCI 透传后,PCI 设备的功能就如同它们实际上附加到客户机操作系统上一样。

集群管理员可以使用 oc CLI 来公开和管理集群中允许在集群中使用的主机设备。

7.13.11.1. 为 GPU 透传准备节点

您可以防止 GPU 操作对象部署到您为 GPU 透传指定的 worker 节点上。

7.13.11.1.1. 防止在节点上部署 NVIDIA GPU 操作对象

如果在集群中使用 NVIDIA GPU Operator,您可以将 nvidia.com/gpu.deploy.operands=false 标签应用到您不想为 GPU 或 vGPU 操作对象配置的节点。该标签可防止创建配置 GPU 或 vGPU 操作对象的 pod,并在 pod 已存在时终止 pod。

先决条件

  • 已安装 OpenShift CLI (oc)。

流程

  • 运行以下命令标记节点:

    $ oc label node <node_name> nvidia.com/gpu.deploy.operands=false 1
    1
    <node_name> 替换为您要安装 NVIDIA GPU 操作对象的节点名称。

验证

  1. 运行以下命令,验证标签是否已添加到节点:

    $ oc describe node <node_name>
  2. 可选: 如果之前在节点上部署了 GPU 操作对象,请验证其删除。

    1. 运行以下命令,检查 nvidia-gpu-operator 命名空间中的 pod 状态:

      $ oc get pods -n nvidia-gpu-operator

      输出示例

      NAME                             READY   STATUS        RESTARTS   AGE
      gpu-operator-59469b8c5c-hw9wj    1/1     Running       0          8d
      nvidia-sandbox-validator-7hx98   1/1     Running       0          8d
      nvidia-sandbox-validator-hdb7p   1/1     Running       0          8d
      nvidia-sandbox-validator-kxwj7   1/1     Terminating   0          9d
      nvidia-vfio-manager-7w9fs        1/1     Running       0          8d
      nvidia-vfio-manager-866pz        1/1     Running       0          8d
      nvidia-vfio-manager-zqtck        1/1     Terminating   0          9d

    2. 监控 pod 状态,直到具有 Terminating 状态的 pod 被删除:

      $ oc get pods -n nvidia-gpu-operator

      输出示例

      NAME                             READY   STATUS    RESTARTS   AGE
      gpu-operator-59469b8c5c-hw9wj    1/1     Running   0          8d
      nvidia-sandbox-validator-7hx98   1/1     Running   0          8d
      nvidia-sandbox-validator-hdb7p   1/1     Running   0          8d
      nvidia-vfio-manager-7w9fs        1/1     Running   0          8d
      nvidia-vfio-manager-866pz        1/1     Running   0          8d

7.13.11.2. 为 PCI 透传准备主机设备

7.13.11.2.1. 关于为 PCI 透传准备主机设备

要使用 CLI 为 PCI 透传准备主机设备,请创建一个 MachineConfig 对象并添加内核参数,以启用输入输出内存管理单元(IOMMU)。将 PCI 设备绑定到虚拟功能 I/O(VFIO)驱动程序,然后通过编辑 HyperConverged 自定义资源(CR)的 allowedHostDevices 字段在集群中公开它。首次安装 OpenShift Virtualization Operator 时,allowedHostDevices 列表为空。

要使用 CLI 从集群中删除 PCI 主机设备,可从 HyperConverged CR 中删除 PCI 设备信息。

7.13.11.2.2. 添加内核参数以启用 IOMMU 驱动程序

要在内核中启用 IOMMU 驱动程序,请创建 MachineConfig 对象并添加内核参数。

先决条件

  • 有集群管理员权限。
  • 您的 CPU 硬件是 Intel 或 AMD。
  • 您在 BIOS 中为直接 I/O 扩展或 AMD IOMMU 启用 Intel 虚拟化技术。

流程

  1. 创建用于标识内核参数的 MachineConfig 对象。以下示例显示了 Intel CPU 的内核参数。

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: worker 1
      name: 100-worker-iommu 2
    spec:
      config:
        ignition:
          version: 3.2.0
      kernelArguments:
          - intel_iommu=on 3
    # ...
    1
    仅将新内核参数应用到 worker 节点。
    2
    name 表示此内核参数(100)在机器配置及其目的中的排名。如果您有 AMD CPU,请将内核参数指定为 amd_iommu=on
    3
    将内核参数标识为 Intel CPU 的 intel_iommu
  2. 创建新的 MachineConfig 对象:

    $ oc create -f 100-worker-kernel-arg-iommu.yaml

验证

  • 验证是否添加了新的 MachineConfig 对象。

    $ oc get MachineConfig
7.13.11.2.3. 将 PCI 设备绑定到 VFIO 驱动程序

要将 PCI 设备绑定到 VFIO(虚拟功能 I/O)驱动程序,请从每个设备获取 vendor-IDdevice-ID 的值,并创建值的列表。将这个列表添加到 MachineConfig 对象。MachineConfig Operator 在带有 PCI 设备的节点上生成 /etc/modprobe.d/vfio.conf,并将 PCI 设备绑定到 VFIO 驱动程序。

先决条件

  • 您添加了内核参数来为 CPU 启用 IOMMU。

流程

  1. 运行 lspci 命令,以获取 PCI 设备的 vendor-IDdevice-ID

    $ lspci -nnv | grep -i nvidia

    输出示例

    02:01.0 3D controller [0302]: NVIDIA Corporation GV100GL [Tesla V100 PCIe 32GB] [10de:1eb8] (rev a1)

  2. 创建 Butane 配置文件 100-worker-vfiopci.bu,将 PCI 设备绑定到 VFIO 驱动程序。

    注意

    有关 Butane 的信息,请参阅"使用 Butane 创建机器配置"。

    Example

    variant: openshift
    version: 4.15.0
    metadata:
      name: 100-worker-vfiopci
      labels:
        machineconfiguration.openshift.io/role: worker 1
    storage:
      files:
      - path: /etc/modprobe.d/vfio.conf
        mode: 0644
        overwrite: true
        contents:
          inline: |
            options vfio-pci ids=10de:1eb8 2
      - path: /etc/modules-load.d/vfio-pci.conf 3
        mode: 0644
        overwrite: true
        contents:
          inline: vfio-pci

    1
    仅将新内核参数应用到 worker 节点。
    2
    指定之前确定的 vendor-ID 值(10de)和 device-ID 值(1eb8)来将单个设备绑定到 VFIO 驱动程序。您可以使用其供应商和设备信息添加多个设备列表。
    3
    在 worker 节点上载入 vfio-pci 内核模块的文件。
  3. 使用 Butane 生成 MachineConfig 对象文件 100-worker-vfiopci.yaml,包含要发送到 worker 节点的配置:

    $ butane 100-worker-vfiopci.bu -o 100-worker-vfiopci.yaml
  4. MachineConfig 对象应用到 worker 节点:

    $ oc apply -f 100-worker-vfiopci.yaml
  5. 验证 MachineConfig 对象是否已添加。

    $ oc get MachineConfig

    输出示例

    NAME                             GENERATEDBYCONTROLLER                      IGNITIONVERSION  AGE
    00-master                        d3da910bfa9f4b599af4ed7f5ac270d55950a3a1   3.2.0            25h
    00-worker                        d3da910bfa9f4b599af4ed7f5ac270d55950a3a1   3.2.0            25h
    01-master-container-runtime      d3da910bfa9f4b599af4ed7f5ac270d55950a3a1   3.2.0            25h
    01-master-kubelet                d3da910bfa9f4b599af4ed7f5ac270d55950a3a1   3.2.0            25h
    01-worker-container-runtime      d3da910bfa9f4b599af4ed7f5ac270d55950a3a1   3.2.0            25h
    01-worker-kubelet                d3da910bfa9f4b599af4ed7f5ac270d55950a3a1   3.2.0            25h
    100-worker-iommu                                                            3.2.0            30s
    100-worker-vfiopci-configuration                                            3.2.0            30s

验证

  • 验证是否已加载 VFIO 驱动程序。

    $ lspci -nnk -d 10de:

    输出确认使用了 VFIO 驱动程序。

    输出示例

    04:00.0 3D controller [0302]: NVIDIA Corporation GP102GL [Tesla P40] [10de:1eb8] (rev a1)
            Subsystem: NVIDIA Corporation Device [10de:1eb8]
            Kernel driver in use: vfio-pci
            Kernel modules: nouveau

7.13.11.2.4. 使用 CLI 在集群中公开 PCI 主机设备

要在集群中公开 PCI 主机设备,将 PCI 设备的详细信息添加到 HyperConverged 自定义资源(CR)的 spec.permittedHostDevices.pciHostDevices 数组中。

流程

  1. 运行以下命令,在默认编辑器中编辑 HyperConverged CR:

    $ oc edit hyperconverged kubevirt-hyperconverged -n openshift-cnv
  2. 将 PCI 设备信息添加到 spec.percommitHostDevices.pciHostDevices 数组。例如:

    配置文件示例

    apiVersion: hco.kubevirt.io/v1
    kind: HyperConverged
    metadata:
      name: kubevirt-hyperconverged
      namespace: openshift-cnv
    spec:
      permittedHostDevices: 1
        pciHostDevices: 2
        - pciDeviceSelector: "10DE:1DB6" 3
          resourceName: "nvidia.com/GV100GL_Tesla_V100" 4
        - pciDeviceSelector: "10DE:1EB8"
          resourceName: "nvidia.com/TU104GL_Tesla_T4"
        - pciDeviceSelector: "8086:6F54"
          resourceName: "intel.com/qat"
          externalResourceProvider: true 5
    # ...

    1
    允许在集群中使用的主机设备。
    2
    节点上可用的 PCI 设备列表。
    3
    标识 PCI 设备所需的 vendor-IDdevice-ID
    4
    PCI 主机设备的名称。
    5
    可选:将此字段设置为 true 表示资源由外部设备插件提供。OpenShift Virtualization 允许在集群中使用这个设备,但会把分配和监控留给外部设备插件。
    注意

    上例代码片段显示有两个 PCI 主机设备,名为 nvidia.com/GV100GL_Tesla_V100nvidia.com/TU104GL_Tesla_Tesla_T4。它们被添加到 HyperConverged CR 中的允许主机设备列表中。这些设备已经过测试和验证以用于 OpenShift Virtualization。

  3. 保存更改并退出编辑器。

验证

  • 运行以下命令,验证 PCI 主机设备是否已添加到节点。示例输出显示,每个设备都与 nvidia.com/GV100GL_Tesla_V100nvidia.com/TU104GL_Tesla_T4intel.com/qat 资源名称关联。

    $ oc describe node <node_name>

    输出示例

    Capacity:
      cpu:                            64
      devices.kubevirt.io/kvm:        110
      devices.kubevirt.io/tun:        110
      devices.kubevirt.io/vhost-net:  110
      ephemeral-storage:              915128Mi
      hugepages-1Gi:                  0
      hugepages-2Mi:                  0
      memory:                         131395264Ki
      nvidia.com/GV100GL_Tesla_V100   1
      nvidia.com/TU104GL_Tesla_T4     1
      intel.com/qat:                  1
      pods:                           250
    Allocatable:
      cpu:                            63500m
      devices.kubevirt.io/kvm:        110
      devices.kubevirt.io/tun:        110
      devices.kubevirt.io/vhost-net:  110
      ephemeral-storage:              863623130526
      hugepages-1Gi:                  0
      hugepages-2Mi:                  0
      memory:                         130244288Ki
      nvidia.com/GV100GL_Tesla_V100   1
      nvidia.com/TU104GL_Tesla_T4     1
      intel.com/qat:                  1
      pods:                           250

7.13.11.2.5. 使用 CLI 从集群中删除 PCI 主机设备

要从集群中删除 PCI 主机设备,请从 HyperConverged 自定义资源(CR)中删除该设备的信息。

流程

  1. 运行以下命令,在默认编辑器中编辑 HyperConverged CR:

    $ oc edit hyperconverged kubevirt-hyperconverged -n openshift-cnv
  2. 通过删除相应设备的 pciDeviceSelectorresourceNameexternalResourceProvider(如果适用)字段来从 spec.permittedHostDevices.pciHostDevices 阵列中删除 PCI 设备信息。在本例中,intel.com/qat 资源已被删除。

    配置文件示例

    apiVersion: hco.kubevirt.io/v1
    kind: HyperConverged
    metadata:
      name: kubevirt-hyperconverged
      namespace: openshift-cnv
    spec:
      permittedHostDevices:
        pciHostDevices:
        - pciDeviceSelector: "10DE:1DB6"
          resourceName: "nvidia.com/GV100GL_Tesla_V100"
        - pciDeviceSelector: "10DE:1EB8"
          resourceName: "nvidia.com/TU104GL_Tesla_T4"
    # ...

  3. 保存更改并退出编辑器。

验证

  • 运行以下命令,验证 PCI 主机设备已从节点移除。示例输出显示,与 intel.com/qat 资源名称关联的设备为零。

    $ oc describe node <node_name>

    输出示例

    Capacity:
      cpu:                            64
      devices.kubevirt.io/kvm:        110
      devices.kubevirt.io/tun:        110
      devices.kubevirt.io/vhost-net:  110
      ephemeral-storage:              915128Mi
      hugepages-1Gi:                  0
      hugepages-2Mi:                  0
      memory:                         131395264Ki
      nvidia.com/GV100GL_Tesla_V100   1
      nvidia.com/TU104GL_Tesla_T4     1
      intel.com/qat:                  0
      pods:                           250
    Allocatable:
      cpu:                            63500m
      devices.kubevirt.io/kvm:        110
      devices.kubevirt.io/tun:        110
      devices.kubevirt.io/vhost-net:  110
      ephemeral-storage:              863623130526
      hugepages-1Gi:                  0
      hugepages-2Mi:                  0
      memory:                         130244288Ki
      nvidia.com/GV100GL_Tesla_V100   1
      nvidia.com/TU104GL_Tesla_T4     1
      intel.com/qat:                  0
      pods:                           250

7.13.11.3. 为 PCI 透传配置虚拟机

将 PCI 设备添加到集群中后,您可以将它们分配到虚拟机。PCI 设备现在可用。就像它们被物理地连接到虚拟机一样。

7.13.11.3.1. 为虚拟机分配 PCI 设备

当集群中有 PCI 设备时,您可以将其分配到虚拟机并启用 PCI 透传。

流程

  • 将 PCI 设备分配到虚拟机作为主机设备。

    Example

    apiVersion: kubevirt.io/v1
    kind: VirtualMachine
    spec:
      domain:
        devices:
          hostDevices:
          - deviceName: nvidia.com/TU104GL_Tesla_T4 1
            name: hostdevices1

    1
    集群中作为主机设备允许的 PCI 设备的名称。虚拟机可以访问此主机设备。

验证

  • 使用以下命令,验证主机设备可从虚拟机使用。

    $ lspci -nnk | grep NVIDIA

    输出示例

    $ 02:01.0 3D controller [0302]: NVIDIA Corporation GV100GL [Tesla V100 PCIe 32GB] [10de:1eb8] (rev a1)

7.13.11.4. 其他资源

7.13.12. 配置虚拟 GPU

如果您有图形处理单元(GPU)卡,OpenShift Virtualization 可以自动创建您可以分配给虚拟机(VM)的虚拟 GPU (vGPU)。

7.13.12.1. 关于在 OpenShift Virtualization 中使用虚拟 GPU

有些图形处理单元(GPU)卡支持创建虚拟 GPU(vGPU)。如果管理员在 HyperConverged 自定义资源(CR)中提供配置详情,则 OpenShift Virtualization 可以自动创建 vGPU 和其他介质设备。这个自动化对大型集群特别有用。

注意

有关功能和支持详情,请参考您的硬件供应商文档。

介质设备
划分为一个或多个虚拟设备的物理设备。vGPU 是一个介质设备(mdev)类型,物理 GPU 的性能会被划分到各个虚拟设备中。您可以将介质设备分配给一个或多个虚拟机(VM),但客户机数量必须与您的 GPU 兼容。有些 GPU 不支持多个虚拟机。

7.13.12.2. 为介质设备准备主机

在配置介质设备前,您必须启用输入输出内存管理单元 (IOMMU) 驱动程序。

7.13.12.2.1. 添加内核参数以启用 IOMMU 驱动程序

要在内核中启用 IOMMU 驱动程序,请创建 MachineConfig 对象并添加内核参数。

先决条件

  • 有集群管理员权限。
  • 您的 CPU 硬件是 Intel 或 AMD。
  • 您在 BIOS 中为直接 I/O 扩展或 AMD IOMMU 启用 Intel 虚拟化技术。

流程

  1. 创建用于标识内核参数的 MachineConfig 对象。以下示例显示了 Intel CPU 的内核参数。

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: worker 1
      name: 100-worker-iommu 2
    spec:
      config:
        ignition:
          version: 3.2.0
      kernelArguments:
          - intel_iommu=on 3
    # ...
    1
    仅将新内核参数应用到 worker 节点。
    2
    name 表示此内核参数(100)在机器配置及其目的中的排名。如果您有 AMD CPU,请将内核参数指定为 amd_iommu=on
    3
    将内核参数标识为 Intel CPU 的 intel_iommu
  2. 创建新的 MachineConfig 对象:

    $ oc create -f 100-worker-kernel-arg-iommu.yaml

验证

  • 验证是否添加了新的 MachineConfig 对象。

    $ oc get MachineConfig

7.13.12.3. 配置 NVIDIA GPU Operator

您可以使用 NVIDIA GPU Operator 置备 worker 节点,以便在 OpenShift Virtualization 中运行 GPU 加速虚拟机(VM)。

注意

NVIDIA GPU Operator 仅支持 NVIDIA。如需更多信息,请参阅红帽知识库中的从 NVIDIA 获得支持

7.13.12.3.1. 关于使用 NVIDIA GPU Operator

您可以将 NVIDIA GPU Operator 与 OpenShift Virtualization 搭配使用来快速置备 worker 节点来运行启用了 GPU 的虚拟机 (VM)。NVIDIA GPU Operator 在 OpenShift Container Platform 集群中管理 NVIDIA GPU 资源,并自动执行为 GPU 工作负载准备节点时所需的任务。

在将应用程序工作负载部署到 GPU 资源前,您必须安装如 NVIDIA 驱动程序,如启用计算统一设备架构 (CUDA)、Kubernetes 设备插件、容器运行时和其他功能,如自动节点标签和监控。通过自动化这些任务,您可以快速扩展基础架构的 GPU 容量。NVIDIA GPU Operator 有助于置备复杂智能和机器学习(AI/ML) 工作负载。

7.13.12.3.2. 配置介质设备的选项

使用 NVIDIA GPU Operator 时有两种可用的配置介质设备的方法。红帽测试的方法使用 OpenShift Virtualization 功能来调度介质设备,而 NVIDIA 方法只使用 GPU Operator。

使用 NVIDIA GPU Operator 配置介质设备
这个方法只使用 NVIDIA GPU Operator 来配置介质设备。要使用这个方法,请参阅 NVIDIA 文档中的带有 OpenShift Virtualization 的 NVIDIA GPU Operator
使用 OpenShift Virtualization 配置介质设备

这个方法由红帽测试,使用 OpenShift Virtualization 的功能来配置介质设备。在这种情况下,NVIDIA GPU Operator 仅用于使用 NVIDIA vGPU Manager 安装驱动程序。GPU Operator 不配置介质设备。

使用 OpenShift Virtualization 方法时,您仍遵循 NVIDIA 文档 配置 GPU Operator。但是,此方法与 NVIDIA 文档的以下方法不同:

  • 您不能覆盖 HyperConverged 自定义资源(CR) 中的默认 disableMDEVConfiguration: false 设置。

    重要

    按照 NVIDIA 文档所述 设置此功能门可防止 OpenShift Virtualization 配置介质设备。

  • 您必须配置 ClusterPolicy 清单,使其与以下示例匹配:

    清单示例

    kind: ClusterPolicy
    apiVersion: nvidia.com/v1
    metadata:
      name: gpu-cluster-policy
    spec:
      operator:
        defaultRuntime: crio
        use_ocp_driver_toolkit: true
        initContainer: {}
      sandboxWorkloads:
        enabled: true
        defaultWorkload: vm-vgpu
      driver:
        enabled: false 1
      dcgmExporter: {}
      dcgm:
        enabled: true
      daemonsets: {}
      devicePlugin: {}
      gfd: {}
      migManager:
        enabled: true
      nodeStatusExporter:
        enabled: true
      mig:
        strategy: single
      toolkit:
        enabled: true
      validator:
        plugin:
          env:
            - name: WITH_WORKLOAD
              value: "true"
      vgpuManager:
        enabled: true 2
        repository: <vgpu_container_registry> 3
        image: <vgpu_image_name>
        version: nvidia-vgpu-manager
      vgpuDeviceManager:
        enabled: false 4
        config:
          name: vgpu-devices-config
          default: default
      sandboxDevicePlugin:
        enabled: false 5
      vfioManager:
        enabled: false 6

    1
    将此值设置为 false。虚拟机不需要。
    2
    将此值设置为 true。将 vGPU 与虚拟机搭配使用是必需的。
    3
    <vgpu_container_registry> 替换为您的 registry 值。
    4
    将此值设置为 false,以允许 OpenShift Virtualization 配置介质设备而不是 NVIDIA GPU Operator。
    5
    将此值设置为 false 以防止发现 vGPU 设备并将 vGPU 设备公告到 kubelet。
    6
    将此值设置为 false 以防止加载 vfio-pci 驱动程序。相反,请按照 OpenShift Virtualization 文档来配置 PCI 透传。

其他资源

7.13.12.4. vGPU 如何分配给节点

对于每个物理设备,OpenShift Virtualization 配置以下值:

  • 单个 mdev 类型。
  • 所选 mdev 类型的最大实例数量。

集群架构会影响创建设备并分配到节点的方式。

每个节点具有多个卡的大型集群

在支持多个 vGPU 类型的节点上,以轮循方式创建相关设备类型。例如:

# ...
mediatedDevicesConfiguration:
  mediatedDeviceTypes:
  - nvidia-222
  - nvidia-228
  - nvidia-105
  - nvidia-108
# ...

在这种情况下,每个节点有两个卡,它们支持以下 vGPU 类型:

nvidia-105
# ...
nvidia-108
nvidia-217
nvidia-299
# ...

在每个节点上,OpenShift Virtualization 会创建以下 vGPU:

  • 在第一个卡上,16 个类型为 nvidia-105 的 vGPU。
  • 第二卡上的 2 个类型为 nvidia-108 的 vGPU。
一个节点有一个卡,它支持多个请求的 vGPU 类型

OpenShift Virtualization 使用最先在 mediatedDeviceTypes 列表中提供的支持的类型。

例如,节点卡中的卡支持 nvidia-223nvidia-224。配置了以下 mediatedDeviceTypes 列表:

# ...
mediatedDevicesConfiguration:
  mediatedDeviceTypes:
  - nvidia-22
  - nvidia-223
  - nvidia-224
# ...

在本例中,OpenShift Virtualization 使用 nvidia-223 类型。

7.13.12.5. 管理介质设备

在向虚拟机分配介质设备前,您必须创建设备并将其公开给集群。您还可以重新配置和删除介质设备。

7.13.12.5.1. 创建并公开介质设备

作为管理员,您可以通过编辑 HyperConverged 自定义资源(CR)来创建介质设备并将其公开给集群。

先决条件

  • 启用了输入输出内存管理单元(IOMMU)驱动程序。
  • 如果您的硬件厂商提供驱动程序,您可以在要创建介质设备的节点上安装它们。

流程

  1. 运行以下命令,在默认编辑器中打开 HyperConverged CR:

    $ oc edit hyperconverged kubevirt-hyperconverged -n openshift-cnv

    例 7.1. 配置了介质设备的配置文件示例

    apiVersion: hco.kubevirt.io/v1
    kind: HyperConverged
    metadata:
      name: kubevirt-hyperconverged
      namespace: openshift-cnv
    spec:
      mediatedDevicesConfiguration:
        mediatedDeviceTypes:
        - nvidia-231
        nodeMediatedDeviceTypes:
        - mediatedDeviceTypes:
          - nvidia-233
          nodeSelector:
            kubernetes.io/hostname: node-11.redhat.com
      permittedHostDevices:
        mediatedDevices:
        - mdevNameSelector: GRID T4-2Q
          resourceName: nvidia.com/GRID_T4-2Q
        - mdevNameSelector: GRID T4-8Q
          resourceName: nvidia.com/GRID_T4-8Q
    # ...
  2. 通过在 spec.mediatedDevicesConfiguration 小节中添加来创建介质设备:

    YAML 片断示例

    # ...
    spec:
      mediatedDevicesConfiguration:
        mediatedDeviceTypes: 1
        - <device_type>
        nodeMediatedDeviceTypes: 2
        - mediatedDeviceTypes: 3
          - <device_type>
          nodeSelector: 4
            <node_selector_key>: <node_selector_value>
    # ...

    1
    必需:为集群配置全局设置。
    2
    可选:覆盖特定节点或一组节点的全局配置。必须与全局 mediatedDeviceTypes 配置一起使用。
    3
    使用 nodeMediatedDeviceTypes 时需要此项。覆盖指定节点的全局 mediatedDeviceTypes 配置。
    4
    使用 nodeMediatedDeviceTypes 时需要此项。必须包含一个 key:value 对。
    重要

    在 OpenShift Virtualization 4.14 之前,mediatedDeviceTypes 字段被命名为 mediatedDevicesTypes。确定在配置介质设备时使用正确的字段名称。

  3. 识别您要公开给集群的设备的 name selector 和 resource name 值。您将在下一步中将这些值添加到 HyperConverged CR 中。

    1. 运行以下命令来查找 resourceName 值:

      $ oc get $NODE -o json \
        | jq '.status.allocatable \
          | with_entries(select(.key | startswith("nvidia.com/"))) \
          | with_entries(select(.value != "0"))'
    2. 通过查看 /sys/bus/pci/devices/<slot>:<bus>:<domain>.<function>/mdev_supported_types/<type>/name 的内容来查找 mdevNameSelector 值,替换您的系统的正确值。

      例如,nvidia-231 类型的名称文件包含选择器字符串 GRID T4-2Q。使用 GRID T4-2Q 作为 mdevNameSelector 值,允许节点使用 nvidia-231 类型。

  4. 通过将 mdevNameSelectorresourceName 值添加到 HyperConverged CR 的 spec.permittedHostDevices.mediatedDevices 小节来向集群公开介质设备:

    YAML 片断示例

    # ...
      permittedHostDevices:
        mediatedDevices:
        - mdevNameSelector: GRID T4-2Q 1
          resourceName: nvidia.com/GRID_T4-2Q 2
    # ...

    1
    公开映射到主机上这个值的介质设备。
    2
    匹配节点上分配的资源名称。
  5. 保存更改并退出编辑器。

验证

  • 可选:通过运行以下命令确认将设备添加到特定节点:

    $ oc describe node <node_name>
7.13.12.5.2. 关于更改和删除介质设备

您可以通过几种方式重新配置或删除介质设备:

  • 编辑 HyperConverged CR 并更改 mediatedDeviceTypes 小节的内容。
  • 更改与 nodeMediatedDeviceTypes 节点选择器匹配的节点标签。
  • HyperConverged CR 的 spec.mediatedDevicesConfigurationspec.permittedHostDevices 小节中删除设备信息。

    注意

    如果您在 spec.permittedHostDevices 小节中删除设备信息,且没有将其从 spec.mediatedDevicesConfiguration 小节中移除,则无法在同一节点上创建新的介质设备类型。要正确删除介质设备,请从两个段中删除设备信息。

7.13.12.5.3. 从集群中删除介质设备

要从集群中删除介质设备,请从 HyperConverged 自定义资源(CR)中删除该设备的信息。

流程

  1. 运行以下命令,在默认编辑器中编辑 HyperConverged CR:

    $ oc edit hyperconverged kubevirt-hyperconverged -n openshift-cnv
  2. HyperConverged CR 的 spec.mediatedDevicesConfigurationspec.permittedHostDevices 小节中删除设备信息。删除这两个条目可确保您稍后在同一节点上创建新的介质设备类型。例如:

    配置文件示例

    apiVersion: hco.kubevirt.io/v1
    kind: HyperConverged
    metadata:
      name: kubevirt-hyperconverged
      namespace: openshift-cnv
    spec:
      mediatedDevicesConfiguration:
        mediatedDeviceTypes: 1
          - nvidia-231
      permittedHostDevices:
        mediatedDevices: 2
        - mdevNameSelector: GRID T4-2Q
          resourceName: nvidia.com/GRID_T4-2Q

    1
    要删除 nvidia-231 设备类型,请从 mediatedDeviceTypes 阵列中删除它。
    2
    要删除 GRID T4-2Q 设备,请删除 mdevNameSelector 字段及其对应的 resourceName 字段。
  3. 保存更改并退出编辑器。

7.13.12.6. 使用介质设备

您可以将介质设备分配给一个或多个虚拟机。

7.13.12.6.1. 使用 CLI 将 vGPU 分配给虚拟机

为虚拟机(VM)分配介质设备,如虚拟 GPU (vGPU)。

先决条件

  • 介质设备在 HyperConverged 自定义资源中配置。
  • 虚拟机已停止。

流程

  • 通过编辑 VirtualMachine 清单的 spec.domain.devices.gpus 小节,将介质设备分配给虚拟机(VM):

    虚拟机清单示例

    apiVersion: kubevirt.io/v1
    kind: VirtualMachine
    spec:
      domain:
        devices:
          gpus:
          - deviceName: nvidia.com/TU104GL_Tesla_T4 1
            name: gpu1 2
          - deviceName: nvidia.com/GRID_T4-2Q
            name: gpu2

    1
    与介质设备关联的资源名称。
    2
    用于标识虚拟机上设备的名称。

验证

  • 要验证该设备在虚拟机中可用,运行以下命令,将 <device_name> 替换为 VirtualMachine 清单中的 deviceName 值:

    $ lspci -nnk | grep <device_name>
7.13.12.6.2. 使用 Web 控制台为虚拟机分配 vGPU

您可以使用 OpenShift Container Platform web 控制台为虚拟机分配虚拟 GPU。

注意

您可以将硬件设备添加到从自定义模板或 YAML 文件创建的虚拟机中。您不能将设备添加到特定操作系统的预先提供的引导源模板中。

先决条件

  • vGPU 配置为集群中的介质设备。

    • 要查看连接到集群的设备,请从侧边菜单中点 Compute Hardware Devices
  • 虚拟机已停止。

流程

  1. 在 OpenShift Container Platform web 控制台中,从侧边菜单中点 Virtualization VirtualMachines
  2. 选择您要为其分配该设备的虚拟机。
  3. Details 标签页中,点 GPU 设备
  4. Add GPU 设备
  5. Name 字段中输入识别值。
  6. Device name 列表中选择您要添加到虚拟机的设备。
  7. 点击 Save

验证

  • 要确认设备已添加到虚拟机,请点 YAML 选项卡并查看 VirtualMachine 配置。介质设备添加到 spec.domain.devices 小节中。

7.13.12.7. 其他资源

7.13.13. 在虚拟机上启用 descheduler 驱除

您可以使用 descheduler 来驱除 pod,以便可将 pod 重新调度到更合适的节点上。如果 pod 是虚拟机,pod 驱除会导致虚拟机实时迁移到另一节点。

重要

虚拟机的 descheduler 驱除功能只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

7.13.13.1. Descheduler 配置集

使用技术预览 DevPreviewLifecycle 配置集为虚拟机启用 descheduler。这是当前可用于 OpenShift Virtualization 的 descheduler 配置集。为确保正确调度,请创建带有 CPU 和内存请求的虚拟机用于预期的负载。

DevPreviewLongLifecycle

此配置集在节点间平衡资源使用量并启用以下策略:

  • RemovePodsHavingTooManyRestarts :删除其容器重启次数太多的 pod,以及其中所有容器(包括 Init 容器)重启的总数超过 100 的 pod。重启虚拟机客户端操作系统不会增加这个计数。
  • LowNodeUtilization :在存在没有被充分利用的节点时,将 pod 从过度使用的节点上驱除。被驱除的 pod 的目标节点将由调度程序决定。

    • 如果节点的用量低于 20%(CPU、内存和 pod 的数量),则该节点将被视为使用率不足。
    • 如果节点的用量超过 50%(CPU、内存和 pod 的数量),则该节点将被视为过量使用。

7.13.13.2. 安装 descheduler

在默认情况下,不提供 descheduler。要启用 descheduler,您必须从 OperatorHub 安装 Kube Descheduler Operator,并启用一个或多个 descheduler 配置集。

默认情况下,descheduler 以预测模式运行,这意味着它只模拟 pod 驱除。您必须将 descheduler 的模式更改为自动进行 pod 驱除。

重要

如果您在集群中启用了托管的 control plane,设置自定义优先级阈值,以降低托管 control plane 命名空间中的 pod 被驱除。将优先级阈值类名称设置为 hypershift-control-plane,因为它有托管的 control plane 优先级类的最低优先级值(100000000)。

先决条件

  • 以具有 cluster-admin 角色的用户身份登录到 OpenShift Container Platform。
  • 访问 OpenShift Container Platform Web 控制台。

流程

  1. 登陆到 OpenShift Container Platform Web 控制台。
  2. 为 Kube Descheduler Operator 创建所需的命名空间。

    1. 进行 Administration Namespaces,点 Create Namespace
    2. Name 字段中输入 openshift-kube-descheduler-operator,在 Labels 字段中输入 openshift.io/cluster-monitoring=true 来启用 descheduler 指标,然后点击 Create
  3. 安装 Kube Descheduler Operator。

    1. 进入 Operators OperatorHub
    2. 在过滤框中输入 Kube Descheduler Operator
    3. 选择 Kube Descheduler Operator 并点 Install
    4. Install Operator 页面中,选择 A specific namespace on the cluster。从下拉菜单中选择 openshift-kube-descheduler-operator
    5. Update ChannelApproval Strategy 的值调整为所需的值。
    6. 点击 Install
  4. 创建 descheduler 实例。

    1. Operators Installed Operators 页面中,点 Kube Descheduler Operator
    2. 选择 Kube Descheduler 标签页并点 Create KubeDescheduler
    3. 根据需要编辑设置。

      1. 要驱除 pod 而不是模拟驱除,请将 Mode 字段更改为 Automatic
      2. 展开 Profiles 部分,再选择 DevPreviewLongLifecycleAffinityAndTaints 配置集默认为启用。

        重要

        当前仅适用于 OpenShift Virtualization 的配置集是 DevPreviewLongLifecycle

您还可以稍后使用 OpenShift CLI(oc)为 descheduler 配置配置集和设置。

7.13.13.3. 在虚拟机(VM)上启用 descheduler 驱除

安装 descheduler 后,您可以通过在 VirtualMachine 自定义资源(CR)中添加注解来在虚拟机上启用 descheduler 驱除。

先决条件

  • 在 OpenShift Container Platform Web 控制台或 OpenShift CLI(oc)中安装 descheduler。
  • 确保虚拟机没有运行。

流程

  1. 在启动虚拟机前,将 descheduler.alpha.kubernetes.io/evict 注解添加到 VirtualMachine CR:

    apiVersion: kubevirt.io/v1
    kind: VirtualMachine
    spec:
      template:
        metadata:
          annotations:
            descheduler.alpha.kubernetes.io/evict: "true"
  2. 如果您还没有在安装过程中在 web 控制台中设置 DevPreviewLongLifecycle 配置集,请在 KubeDescheduler 对象的 spec.profile 部分指定 DevPreviewLongLifecycle

    apiVersion: operator.openshift.io/v1
    kind: KubeDescheduler
    metadata:
      name: cluster
      namespace: openshift-kube-descheduler-operator
    spec:
      deschedulingIntervalSeconds: 3600
      profiles:
      - DevPreviewLongLifecycle
      mode: Predictive 1
    1
    默认情况下,descheduler 不会驱除 pod。要驱除 pod,请将 mode 设置为 Automatic

现在在虚拟机上启用了 descheduler。

7.13.13.4. 其他资源

7.13.14. 关于虚拟机的高可用性

您可以通过手动删除故障节点来触发虚拟机故障切换或配置补救节点,为虚拟机 (VM) 启用高可用性。

手动删除出现故障的节点

如果节点失败,且集群中没有部署机器健康检查,则带有 runStrategy: Always 配置的虚拟机不会自动重新定位到健康的节点。要触发虚拟机故障切换,您必须手动删除 Node 对象。

请参阅删除失败的节点来触发虚拟机故障切换

配置补救节点

您可以通过从 OperatorHub 安装 Self Node Remediation Operator 或 Fence Agents Remediation Operator 来配置补救节点,并启用机器健康检查或节点补救检查。

如需有关补救、隔离和维护节点的更多信息,请参阅 Red Hat OpenShift 文档中的工作负载可用性

7.13.15. 虚拟机 control plane 调整

OpenShift Virtualization 在 control-plane 级别提供以下调整选项:

  • highBurst 配置集(使用固定 QPSburst 率)在一个批处理中创建数百个虚拟机 (VM)
  • 基于工作负载类型的迁移设置调整

7.13.15.1. 配置 highBurst 配置集

使用 highBurst 配置集在一个集群中创建和维护大量虚拟机(VM)。

流程

  • 应用以下补丁以启用 highBurst 调优配置文件:

    $ oc patch hyperconverged kubevirt-hyperconverged -n openshift-cnv \
      --type=json -p='[{"op": "add", "path": "/spec/tuningPolicy", \
      "value": "highBurst"}]'

验证

  • 运行以下命令,以验证启用了 highBurst 调优配置文件:

    $ oc get kubevirt.kubevirt.io/kubevirt-kubevirt-hyperconverged \
      -n openshift-cnv -o go-template --template='{{range $config, \
      $value := .spec.configuration}} {{if eq $config "apiConfiguration" \
      "webhookConfiguration" "controllerConfiguration" "handlerConfiguration"}} \
      {{"\n"}} {{$config}} = {{$value}} {{end}} {{end}} {{"\n"}}

7.13.16. 分配计算资源

在 OpenShift Virtualization 中,分配给虚拟机的计算资源由保证 CPU 或时间分片 CPU 共享提供支持。

保证的 CPU (也称为 CPU 保留)将 CPU 内核或线程专用于特定工作负载,从而使它们对任何其他工作负载都不可用。为虚拟机分配有保证的 CPU 可确保虚拟机只能访问保留的物理 CPU。为虚拟机启用专用资源以使用保证 CPU。

时间分片 CPU 将一个时间分片用于每个工作负载共享物理 CPU。您可以指定虚拟机创建过程中或虚拟机离线期间的分片大小。默认情况下,每个 vCPU 收到 100 毫秒,或一个物理 CPU 时间的 1/10 秒。

CPU 保留类型取决于实例类型或虚拟机配置。

7.13.16.1. 过度分配 CPU 资源

时间分片允许多个虚拟 CPU (vCPU) 共享单个物理 CPU。这称为 CPU 过量分配(CPU overcommitment)。保证虚拟机不会被过度分配。

配置 CPU 过量分配,以便在为虚拟机分配 CPU 时优先选择虚拟机密度。对于 vCPU 的 CPU 过量分配,更多虚拟机适合给定节点。

7.13.16.2. 设置 CPU 分配比率

CPU 分配率通过将 vCPU 映射到物理 CPU 时间分片来指定过量分配程度。

例如,一个映射或 10:1 的比例通过使用时间片段将 10 个虚拟 CPU 映射到 1 个物理 CPU。

要更改映射到每个物理 CPU 的默认 vCPU 数量,请在 HyperConverged CR 中设置 vmiCPUAllocationRatio 值。pod CPU 请求是通过 CPU 分配比率重新处理的 vCPU 数量来计算的。例如,如果 vmiCPUAllocationRatio 设置为 10,OpenShift Virtualization 会在该虚拟机的 pod 上请求 10 倍的 CPU。

流程

HyperConverged CR 中设置 vmiCPUAllocationRatio 值来定义节点 CPU 分配比率。

  1. 运行以下命令,在默认编辑器中打开 HyperConverged CR:

    $ oc edit hyperconverged kubevirt-hyperconverged -n openshift-cnv
  2. 设置 vmiCPUAllocationRatio

    ...
    spec:
      resourceRequirements:
        vmiCPUAllocationRatio: 1 1
    # ...
    1
    vmiCPUAllocationRatio 设置为 1 时,容器集请求的最大 vCPU 数量。

7.13.16.3. 其他资源

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.