跳转至

1 ksm

KSM(Kernel Samepage Merging)

KSM 是Linux内核的一项内存管理功能,其主要用途是在多个运行着相同或相似内容的虚拟机之间共享物理内存页。在虚拟化环境中,当多台虚拟机运行相同的程序或拥有重复的数据时, 它们各自的内存中可能会有大量相同的页面。KSM可以检测并合并这些相同的内存页,从而减少物理内存使用量,提高服务器上虚拟机的密度。

  • 使用KSM可以节省内存资源。通过合并重复的内存页,能够有效减少服务器所需的物理内存总量,尤其是在大规模部署同质化的虚拟机场景下,比如云服务提供商托管大量的相同镜像实例,可以允许在同一台物理服务器上运行更多的虚拟机,提高了服务器硬件的虚拟化密度和总体计算能力。
  • 但是,KSM会带来额外开销。KSM 运行过程中会持续扫描内存页进行比较,这一过程会占用CPU和I/O资源,可能会影响系统性能,延迟增加。特别是在内存变化频繁的情况下,因为KSM需要动态地合并和拆分内存页以适应不同虚拟机的 需求,这可能导致一定的延迟,并且在极端情况下,如果系统资源紧张,KSM 可能无法及时响应,影响到虚拟机的稳定性和性能。

因此,在实际应用中,是否启用KSM以及如何配置KSM参数,往往需要根据具体工作负载的特点和资源需求进行权衡。对于那些内存内容高度一致、并且对性能敏感度较低的应用场景,KSM可以显著提高资源利用率; 而在要求高性能、低延迟或者内存访问模式不规律的应用中,则可能需要谨慎考虑启用KSM。

在kubevirt中启用KSM

通过修改kubevirt CR spec.configuration.ksmConfiguration 指示将在哪些节点上启用KSM - 在主机名为node01node03的节点上启用 KSM:

spec:
  configuration:
    ksmConfiguration:
      nodeLabelSelector:
        matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
              - node01
              - node03
- 在有标签kubevirt.io/first-label: true, kubevirt.io/second-label: true的主机上启用KSM
spec:
  configuration:
    ksmConfiguration:
      nodeLabelSelector:
        matchLabels:
          kubevirt.io/first-label: "true"
          kubevirt.io/second-label: "true"
- 在每个节点上启用KSM
spec:
  configuration:
    ksmConfiguration:
      nodeLabelSelector: {}
注意
如果 nodeLabelSelector的值为nil或者零值(即kubevirt CR ksmConfiguration配置项中不包含nodeLabelSelector这个key),则不会在任何节点上启用 KSM,也就是说默认不会在任何节点上启用KSM。 如果 nodeLabelSelector的值为{},则将在所有节点上启用KSM。

  • 不启用KSM
    spec:
      configuration:
        ksmConfiguration:
    

当节点上启用了KSM功能时,会在启用KSM的节点上添加一个注解kubevirt.io/ksm-handler-managed,这个注解是内部记录, 用于跟踪当前由 virt-handler 管理并启用了 KSM 的节点列表,以便在未来 KSM 配置发生变化时能够识别出哪些节点需要恢复到之前的状态。 场景示例: 1. 集群中有 3 个节点,其中一个节点 node01 的 KSM 是外部手动启用的。 2. 管理员更新 KubeVirt CR,添加了一个 ksmConfiguration,该配置使得 node02 和 node03 节点启用 KSM。 3. 过了一段时间后,管理员再次更新 KubeVirt CR,并删除了先前设置的 ksmConfiguration。 由于有了这个注解机制,virt-handler 可以仅在那些由其自身启用 KSM 的节点(即 node02 和 node03)上禁用 KSM,而不会影响其他未通过 virt-handler 管理且已启用 KSM 的节点(如本例中的 node01), 这就确保了对 KubeVirt 配置变更时,KSM 状态可以准确地恢复到之前的设定。

  • 节点标签

    KubeVirt 能够检测到哪些节点启用了KSM 功能,并给这些节点打上一个特殊的标签 (kubevirt.io/ksm-enabled),其值为 true。 这样,就可以利用这个标签来调度虚拟机(VMs, Virtual Machines),使得它们能够在已启用 KSM 的节点上运行或者避免在未启用 KSM 的节点上运行。

也就是说在启用节点支持 KSM 时,KubeVirt 会执行两个操作: 1、添加注解 (Annotation):在由 virt-handler 管理并启用 KSM 的节点上添加一个内部注解 kubevirt.io/ksm-handler-managed。这个注解用于记录哪些节点是由 virt-handler 控制和管理 KSM 状态的,以便在后续配置变更时能够恢复到正确的状态。 2、添加标签 (Label):对于启用了 KSM 功能的节点,KubeVirt 会给它们打上一个特殊的标签 kubevirt.io/ksm-enabled: true。这样做的目的是方便用户通过 Kubernetes 调度系统来调度虚拟机,使得虚拟机可以根据节点是否启用了 KSM 进行有选择地运行在合适的节点上。

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: testvm
spec:
  running: true
  template:
    metadata:
      labels:
        kubevirt.io/vm: testvm
    spec:
      nodeSelector:
        kubevirt.io/ksm-enabled: "true"
      [...]