13.4. 配置虚拟机内存

要提高虚拟机 (VM) 的性能,您可以将额外的主机 RAM 分配给虚拟机。类似地,您可以减少分配给虚拟机的内存量,从而使主机内存可以分配给其他虚拟机或任务。

要执行这些操作,您可以使用 Web 控制台命令行界面

13.4.1. 使用 web 控制台添加和删除虚拟机内存

要提高虚拟机 (VM) 的性能或释放它使用的主机资源,您可以使用 Web 控制台来调整分配给虚拟机的内存量。

先决条件

  • 客户端操作系统正在运行内存 balloon 驱动程序。请执行以下命令校验:

    1. 确保虚拟机的配置包含 memballoon 设备:

      # virsh dumpxml testguest | grep memballoon
      <memballoon model='virtio'>
          </memballoon>

      如果此命令显示任何输出,并且型号未设置为 none,则存在 memballoon 设备。

    2. 确保 balloon 驱动程序在客户机操作系统中运行。

      • 在 Windows 客户机中,驱动程序作为 virtio-win 驱动程序软件包的一部分安装。具体步骤请参阅为 Windows 虚拟机安装半虚拟化 KVM 驱动程序
      • 在 Linux 客户机中,通常默认包含驱动程序,并在存在 memballoon 设备时激活。
  • Web 控制台 VM 插件 已安装在您的系统上

流程

  1. 可选:包含有关虚拟机最大内存和当前使用的内存的信息。这将作为您更改的基准,并进行验证。

    # virsh dominfo testguest
    Max memory:     2097152 KiB
    Used memory:    2097152 KiB
  2. Virtual Machines 界面中,点您要查看其信息的虚拟机。

    此时将打开一个新页面,其中包含关于所选虚拟机基本信息的概述部分,以及用于访问虚拟机的图形界面的控制台部分。

  3. 点概述窗格中 Memory 行旁边的 edit

    此时将显示 Memory Adjustment 对话框。

    显示虚拟机内存调整对话框的图片。
  4. 为所选虚拟机配置虚拟 CPU。

    • 最大分配 - 设置虚拟机可用于其进程的最大主机内存量。您可以在创建虚拟机时指定最大内存,或可以在以后增大。您可以将内存指定为 MiB 或 GiB 的倍数。

      只有在关闭虚拟机上才能调整最大内存分配。

    • 当前分配 - 设置分配给虚拟机的实际内存量。这个值可以小于最大分配量,但不能超过它。您可以调整值,来控制虚拟机的进程可使用的内存。您可以将内存指定为 MiB 或 GiB 的倍数。

      如果没有指定这个值,则默认分配是 Maximum allocation 值。

  5. Save

    调整了虚拟机的内存分配。

13.4.2. 使用命令行界面添加和删除虚拟机内存

若要提高虚拟机 (VM) 的性能或释放其使用的主机资源,您可以使用 CLI 来调整分配给虚拟机的内存量。

先决条件

  • 客户端操作系统正在运行内存 balloon 驱动程序。请执行以下命令校验:

    1. 确保虚拟机的配置包含 memballoon 设备:

      # virsh dumpxml testguest | grep memballoon
      <memballoon model='virtio'>
          </memballoon>

      如果此命令显示任何输出,并且型号未设置为 none,则存在 memballoon 设备。

    2. 确定 ballon 驱动程序正在客户端操作系统中运行。

      • 在 Windows 客户机中,驱动程序作为 virtio-win 驱动程序软件包的一部分安装。具体步骤请参阅为 Windows 虚拟机安装半虚拟化 KVM 驱动程序
      • 在 Linux 客户机中,通常默认包含驱动程序,并在存在 memballoon 设备时激活。

流程

  1. 可选:包含有关虚拟机最大内存和当前使用的内存的信息。这将作为您更改的基准,并进行验证。

    # virsh dominfo testguest
    Max memory:     2097152 KiB
    Used memory:    2097152 KiB
  2. 调整分配给虚拟机的最大内存。增加这个值可以提高虚拟机的性能风险,降低这个值会降低虚拟机在主机上的性能占用空间。请注意,此更改只能在关闭的虚拟机上执行,因此调整正在运行的虚拟机需要重新启动才能生效。

    例如,将 testguest 虚拟机可以使用的最大内存更改为 4096 MiB:

    # virt-xml testguest --edit --memory memory=4096,currentMemory=4096
    Domain 'testguest' defined successfully.
    Changes will take effect after the domain is fully powered off.

    要增加正在运行的虚拟机的最大内存,您可以将内存设备附加到虚拟机。这也被称为内存热插拔。详情请参阅将设备附加到虚拟机

    警告

    不支持从正在运行的虚拟机中删除内存设备(也称为内存热插拔),因此红帽强烈不鼓励这样做。

  3. 可选: 您还可以调整虚拟机当前使用的内存,最多不超过最大分配数。这调整了虚拟机在主机上的内存负载,直到下一次重启为止,而不需要更改最大的虚拟机分配。

    # virsh setmem testguest --current 2048

验证

  1. 确认虚拟机使用的内存已更新:

    # virsh dominfo testguest
    Max memory:     4194304 KiB
    Used memory:    2097152 KiB
  2. 可选:如果您调整了当前虚拟机内存,您可以获取虚拟机的内存 balloon 统计,以评估它如何有效地控制其内存使用量。

     # virsh domstats --balloon testguest
    Domain: 'testguest'
      balloon.current=365624
      balloon.maximum=4194304
      balloon.swap_in=0
      balloon.swap_out=0
      balloon.major_fault=306
      balloon.minor_fault=156117
      balloon.unused=3834448
      balloon.available=4035008
      balloon.usable=3746340
      balloon.last-update=1587971682
      balloon.disk_caches=75444
      balloon.hugetlb_pgalloc=0
      balloon.hugetlb_pgfail=0
      balloon.rss=1005456

13.4.3. 使用 virtio-mem 添加和删除虚拟机内存

作为技术预览,RHEL 9 提供 virtio-mem 半虚拟化内存设备。virtio-mem 可用于在虚拟机(VM)中动态添加或删除主机内存。例如,您可以使用这个设备在运行的虚拟机之间移动内存资源,或者根据您当前的要求在云设置中调整虚拟机内存大小。

重要

virtio-mem 作为技术预览包含在 RHEL 9 中,这意味着它不被支持。

13.4.3.1. 先决条件

  • 主机具有 Intel 64 或 AMD64 CPU 架构。
  • 主机和虚拟机使用 RHEL 9 作为操作系统。

13.4.3.2. virtio-mem 概述

virtio-mem 是一个半虚拟化内存设备,可用于在虚拟机中动态添加或删除主机内存。例如,您可以使用这个设备在运行的虚拟机之间移动内存资源,或者根据您当前的要求在云设置中调整虚拟机内存大小。

使用 virtio-mem,您可以将虚拟机的内存增加到超出其初始大小,并将其缩小回其原始大小,单位可以是 2 到几百兆字节(MiB)。但请注意,virtio-mem 也依赖于特定的客户机操作系统配置,特别是为了可靠地拔出内存。

重要

virtio-mem 作为技术预览包含在 RHEL 9 中,这意味着它不被支持。

virtio-mem 技术预览限制

virtio-mem 目前与以下功能不兼容:

  • 在主机上使用内存预分配
  • 在主机上使用巨页
  • 对主机上的实时应用程序使用内存锁定
  • 在主机上使用加密的虚拟化
  • 主机中的动态内存元数据分配
  • 在主机上将 virtio-memmemballoon 膨胀和收缩合并
  • 从虚拟机中拔出 virtio-mem 设备
  • 在虚拟机中卸载或重新载入 virtio_mem 驱动程序
  • 休眠或挂起载入了 virtio_mem 驱动程序的虚拟机

虚拟机中的内存在线

将内存附加到正在运行的 RHEL 虚拟机(也称为内存热插拔)时,您必须在虚拟机操作系统中将热插拔内存设置为在线状态。否则,系统将无法使用内存。

下表总结了在可用内存在线配置间选择时的主要注意事项。

表 13.1. 内存在线配置的比较

配置名称从虚拟机中拔出内存创建内存区不平衡的风险一个潜在的用例预期工作负载的内存要求

online_movable

热插内存可以可靠地拔出。

热插拔相对较少的内存

主要是用户空间内存

auto-movable

热插内存的可移动部分可以可靠地拔出。

最小

热插拔大量内存

主要是用户空间内存

online_kernel

热插拔内存无法可靠地拔出。

不可靠内存拔出是可以接受的。

用户空间或内核空间内存

区域不平衡 是某个 Linux 内存区域中缺少可用内存页。区域不平衡 会对系统性能造成负面影响。例如,如果内核用完了不可移动分配的可用内存,则内核可能会崩溃。通常,可移动分配主要包含用户空间内存页,不可移动分配主要包含内核空间内存页。

有关内存在线注意事项的详细说明,请参阅: 在线和离线内存块区域不平衡

13.4.3.3. 在虚拟机中配置内存在线

在使用 virtio-mem 将内存附加到正在运行的虚拟机(也称为内存热插拔)之前,您必须配置虚拟机(VM)操作系统,以便可将热插拔内存自动设置为在线状态。否则,客户端操作系统无法使用额外的内存。您可以从以下内存在线的配置中选择:

  • online_movable
  • online_kernel
  • auto-movable

要了解这些配置之间的区别,请参阅:虚拟机中的内存在线

RHEL 中默认内存在线是使用 udev 规则配置的。但是,在使用 virtio-mem 时,建议直接在内核中配置内存在线。

重要

virtio-mem 作为技术预览包含在 RHEL 9 中,这意味着它不被支持。

先决条件

  • 主机具有 Intel 64 或 AMD64 CPU 架构。
  • 主机和虚拟机使用 RHEL 9 作为操作系统。

步骤

  • 要在虚拟机中设置内存在线,以使用 online_movable 配置:

    1. memhp_default_state 内核命令行参数设置为 online_movable

      # grubby --update-kernel=ALL --remove-args=memhp_default_state --args=memhp_default_state=online_movable
    2. 重启虚拟机。
  • 要在虚拟机中设置内存在线,以使用 online_kernel 配置:

    1. memhp_default_state 内核命令行参数设置为 online_kernel

      # grubby --update-kernel=ALL --remove-args=memhp_default_state --args=memhp_default_state=online_kernel
    2. 重启虚拟机。
  • 要在虚拟机中使用 auto-movable 内存在线策略:

    1. memhp_default_state 内核命令行参数设置为 online

      # grubby --update-kernel=ALL --remove-args=memhp_default_state --args=memhp_default_state=online
    2. memory_hotplug.online_policy 内核命令行参数设置为 auto-movable

      # grubby --update-kernel=ALL --remove-args="memory_hotplug.online_policy" --args=memory_hotplug.online_policy=auto-movable
    3. 可选: 要进一步调整 auto-movable 在线策略,请更改 memory_hotplug.auto_movable_ratiomemory_hotplug.auto_movable_numa_aware 参数:

      # grubby --update-kernel=ALL --remove-args="memory_hotplug.auto_movable_ratio" --args=memory_hotplug.auto_movable_ratio=<percentage>
      
      # grubby --update-kernel=ALL --remove-args="memory_hotplug.memory_auto_movable_numa_aware" --args=memory_hotplug.auto_movable_numa_aware=<y/n>
      • 与可用于任何分配的内存相比,memory_hotplug.auto_movable_ratio 参数 设置仅可用于可移动分配的最大内存比率。比率以百分比表示,默认值为 301 (%),它是 3:1 的比率。
      • memory_hotplug.auto_movable_numa_aware 参数控制 memory_hotplug.auto_movable_ratio 参数是否应用到跨所有可用 NUMA 节点的内存,或仅应用到单个 NUMA 节点上的内存。默认值为:y (yes)

        例如,如果最大比率设置为 301%,并且 memory_hotplug.auto_movable_numa_aware 设置为 y (yes),即使在附加了 virtio-mem 设备的 NUMA 节点内也应用 3:1 比率。如果参数设置为 n (no),则最大 3:1 比率仅应用于整个 NUMA 节点。

        另外,如果没有超过比率,则新热插拔内存将只可用于可移动分配。否则,新热拔插内存将同时可用于可移动和不可移动分配。

    4. 重启虚拟机。

验证

  • 要查看 online_movable 配置是否已正确设置,请检查 memhp_default_state 内核参数的当前值:

    # cat /sys/devices/system/memory/auto_online_blocks
    
    online_movable
  • 要查看 online_kernel 配置是否已正确设置,请检查 memhp_default_state 内核参数的当前值:

    # cat /sys/devices/system/memory/auto_online_blocks
    
    online_kernel
  • 要查看 auto-movable 配置是否已正确设置,请检查以下内核参数:

    • memhp_default_state

      # cat /sys/devices/system/memory/auto_online_blocks
      
      online
    • memory_hotplug.online_policy:

      # cat /sys/module/memory_hotplug/parameters/online_policy
      
      auto-movable
    • memory_hotplug.auto_movable_ratio:

      # cat /sys/module/memory_hotplug/parameters/auto_movable_ratio
      
      301
    • memory_hotplug.auto_movable_numa_aware:

      # cat /sys/module/memory_hotplug/parameters/auto_movable_numa_aware
      
      y

13.4.3.4. 将 virtio-mem 设备附加到虚拟机

要将额外内存附加到正在运行的虚拟机(也称为内存热插拔),之后能够调整热插拔内存的大小,您可以使用 virtio-mem 设备。特别是,您可以使用 libvirt XML 配置文件和 virsh 命令来定义并将 virtio-mem 设备附加到虚拟机(VM)。

重要

virtio-mem 作为技术预览包含在 RHEL 9 中,这意味着它不被支持。

先决条件

  • 主机具有 Intel 64 或 AMD64 CPU 架构。
  • 主机和虚拟机使用 RHEL 9 作为操作系统。
  • 虚拟机配置了内存在线。具体说明,请参阅:在虚拟机中配置内存在线

流程

  1. 确保目标虚拟机的 XML 配置包含 maxMemory 参数:

    # virsh edit testguest1
    
    <domain type='kvm'>
      <name>testguest1</name>
      ...
      <maxMemory slots='2' unit='GiB'>128</maxMemory>
      ...
    </domain>

    在本例中,testguest1 虚拟机的 XML 配置定义了一个有 2 个插槽和 128 gibibyte (GiB)大小的 maxMemory 参数。maxMemory 大小指定虚拟机可以使用的最大内存,其包括初始内存和热插拔内存。目前,您必须为每个附加的 virtio-mem 设备保留一个插槽。

  2. 确保目标虚拟机的 XML 配置至少定义了一个 NUMA 节点,例如:

    # virsh edit testguest1
    
    <domain type='kvm'>
      <name>testguest1</name>
      ...
      <vcpu placement='static'>8</vcpu>
      ...
      <cpu ...>
        <numa>
          <cell id='0' cpus='0-7' memory='16' unit='GiB'/>
        </numa>
      ...
    </domain>

    在本例中,定义了一个具有 16 GiB 初始内存的 NUMA 节点,并在 testguest1 虚拟机上分配了 8 个 CPU。要在虚拟机中使用内存设备,您必须至少定义一个 NUMA 节点。

  3. 创建并打开 XML 文件,来在主机上定义 virtio-mem 设备,例如:

    # vim virtio-mem-device.xml
  4. 在文件中添加 virtio-mem 设备的 XML 定义并保存:

    <memory model='virtio-mem'>
            <target>
                    <size unit='GiB'>48</size>
                    <node>0</node>
                    <block unit='MiB'>2</block>
                    <requested unit='GiB'>16</requested>
                    <current unit='GiB'>16</current>
            </target>
            <alias name='ua-virtiomem0'/>
            <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </memory>
    <memory model='virtio-mem'>
            <target>
                    <size unit='GiB'>48</size>
                    <node>1</node>
                    <block unit='MiB'>2</block>
                    <requested unit='GiB'>0</requested>
                    <current unit='GiB'>0</current>
            </target>
            <alias name='ua-virtiomem1'/>
            <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </memory>

    在本例中,使用以下参数定义了两个 virtio-mem 设备:

    • size :这是设备的最大大小。在示例中,它是 48 GiB。size 必须是 block 大小的倍数。
    • node :这是为 virtio-mem 设备分配的 vNUMA 节点。
    • block :这是设备的块大小。它必须至少是 Transparent Huge Page (THP)的大小,在 Intel 64 或 AMD64 CPU 架构上它是 2 MiB。Intel 64 或 AMD64 架构上的 2 MiB 块大小通常是好的默认选择。当使用带有 虚拟功能 I/O(VFIO)中介设备(mdev)virtio-mem 时,跨所有 virtio-mem 设备的总块数不能大于 32768,否则 RAM 的插入可能会失败。
    • requested :这是您附加到具有 virtio-mem 设备的虚拟机的内存量。但是,它只对虚拟机的请求,可能无法成功解决,例如如果虚拟机没有正确配置。requested 大小必须是 block 大小的倍数,且不能超过定义的 size最大值。
    • current:这代表提供给虚拟机的当前 virtio-mem 设备的大小。current 大小可能与 requested 不同,例如当请求无法完成或重启虚拟机时。
    • alias :这是一个可选d 用户定义的别名,您可用来指定预期的 virtio-mem 设备,例如使用 libvirt 命令编辑设备时。libvirt 中所有用户定义的别名必须以 "ua-" 前缀开头。

      除了这些特定的参数外,libvirt 像处理任何其他 PCI 设备一样处理 virtio-mem 设备。

  5. 使用 XML 文件将定义的 virtio-mem 设备附加到虚拟机。例如,要将 virtio-mem-device.xml 中定义的两个设备永久附加到正在运行的 testguest1 虚拟机:

    # virsh attach-device testguest1 virtio-mem-device.xml --live --config

    --live 选项仅将设备附加到正在运行的虚拟机,在引导间不持久。--config 选项使配置更改持久。您还可以将设备附加到没有 --live 选项的关闭的虚拟机。

  6. 可选: 要动态更改附加到正在运行的虚拟机的 virtio-mem 设备的 requested 大小,请使用 virsh update-memory-device 命令:

    # virsh update-memory-device testguest1 --alias ua-virtiomem0 --requested-size 4GiB

    在本例中:

    • testguest1 是您要更新的虚拟机。
    • --alias ua-virtiomem0 是之前由定义的别名指定的 virtio-mem 设备。
    • --requested-size 4GiBvirtio-mem 设备的 requested 大小更改为 4 GiB。

验证

  • 在虚拟机中,检查可用的 RAM ,并查看总内存现在是否包含热插拔内存:

    # free -h
    
            total    used    free   shared  buff/cache   available
    Mem:    31Gi     5.5Gi   14Gi   1.3Gi   11Gi         23Gi
    Swap:   8.0Gi    0B      8.0Gi
    # numactl -H
    
    available: 1 nodes (0)
    node 0 cpus: 0 1 2 3 4 5 6 7
    node 0 size: 29564 MB
    node 0 free: 13351 MB
    node distances:
    node   0
      0:  10
  • 也可以通过显示正在运行的虚拟机的 XML 配置来查看主机上当前的插入的 RAM 量:

    # virsh dumpxml testguest1
    
    <domain type='kvm'>
      <name>testguest1</name>
      ...
      <currentMemory unit='GiB'>31</currentMemory>
      ...
      <memory model='virtio-mem'>
          <target>
            <size unit='GiB'>48</size>
            <node>0</node>
            <block unit='MiB'>2</block>
            <requested unit='GiB'>16</requested>
            <current unit='GiB'>16</current>
          </target>
          <alias name='ua-virtiomem0'/>
          <address type='pci' domain='0x0000' bus='0x08' slot='0x00' function='0x0'/>
      ...
    </domain>

    在本例中:

    • <currentMemory unit='GiB'>31</currentMemory> 代表虚拟机中所有源的可用 RAM 总量。
    • <current unit='GiB'>16</current> 代表 virtio-mem 设备提供的插入的 RAM 的当前大小。

13.4.4. 其他资源