×

您可以通过超额分配内存 (RAM) 来增加节点上虚拟机 (VM) 的数量。在以下情况下,提高虚拟机工作负载密度可能很有用:

  • 您有很多类似的工作负载。

  • 您的工作负载未充分利用。

内存超额分配可能会降低高利用率系统上的工作负载性能。

使用 wasp-agent 提高虚拟机工作负载密度

wasp-agent 组件通过为工作节点分配交换资源来促进内存超额分配。当节点由于高交换 I/O 流量或高利用率而面临风险时,它还会管理 Pod 驱逐。

交换资源只能分配给Burstable 服务质量 (QoS) 类别的虚拟机工作负载 (VM Pod)。Guaranteed QoS 类别的 VM Pod 和不属于虚拟机的任何 QoS 类别的 Pod 都不能交换资源。

有关 QoS 类别的说明,请参阅为 Pod 配置服务质量(Kubernetes 文档)。

先决条件
  • 您已安装 OpenShift CLI (oc)。

  • 您已使用 cluster-admin 角色登录集群。

  • 已定义内存超额分配比率。

  • 节点属于工作程序池。

wasp-agent 组件部署一个开放容器倡议 (OCI) 挂钩,以在节点级别为容器启用交换使用。低级别特性要求DaemonSet 对象具有特权。

步骤
  1. 配置kubelet 服务以允许交换使用

    1. 使用以下示例中显示的参数创建或编辑KubeletConfig 文件

      KubeletConfig 文件示例
      apiVersion: machineconfiguration.openshift.io/v1
      kind: KubeletConfig
      metadata:
        name: custom-config
      spec:
        machineConfigPoolSelector:
          matchLabels:
            pools.operator.machineconfiguration.openshift.io/worker: ''  # MCP
            #machine.openshift.io/cluster-api-machine-role: worker # machine
            #node-role.kubernetes.io/worker: '' # node
        kubeletConfig:
          failSwapOn: false
    2. 通过运行以下命令等待工作节点与新配置同步

      $ oc wait mcp worker --for condition=Updated=True --timeout=-1s
  2. 通过创建MachineConfig 对象来配置交换。例如

    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: worker
      name: 90-worker-swap
    spec:
      config:
        ignition:
          version: 3.4.0
        systemd:
          units:
            - contents: |
                [Unit]
                Description=Provision and enable swap
                ConditionFirstBoot=no
    
                [Service]
                Type=oneshot
                Environment=SWAP_SIZE_MB=5000
                ExecStart=/bin/sh -c "sudo dd if=/dev/zero of=/var/tmp/swapfile count=${SWAP_SIZE_MB} bs=1M && \
                sudo chmod 600 /var/tmp/swapfile && \
                sudo mkswap /var/tmp/swapfile && \
                sudo swapon /var/tmp/swapfile && \
                free -h && \
                sudo systemctl set-property --runtime system.slice MemorySwapMax=0 IODeviceLatencyTargetSec=\"/ 50ms\""
    
                [Install]
                RequiredBy=kubelet-dependencies.target
              enabled: true
              name: swap-provision.service

    为了获得足够应对最坏情况的交换空间,请确保预配的交换空间至少与超额分配的 RAM 相同。使用以下公式计算要在节点上预配的交换空间量

    NODE_SWAP_SPACE = NODE_RAM * (MEMORY_OVER_COMMIT_PERCENT / 100% - 1)
    示例
    NODE_SWAP_SPACE = 16 GB * (150% / 100% - 1)
                   = 16 GB * (1.5 - 1)
                   = 16 GB * (0.5)
                   =  8 GB
  3. 通过运行以下命令创建特权服务帐户

    $ oc adm new-project wasp
    $ oc create sa -n wasp wasp
    $ oc create clusterrolebinding wasp --clusterrole=cluster-admin --serviceaccount=wasp:wasp
    $ oc adm policy add-scc-to-user -n wasp privileged -z wasp
  4. 通过运行以下命令等待工作节点与新配置同步

    $ oc wait mcp worker --for condition=Updated=True --timeout=-1s
  5. 通过运行以下命令确定 wasp 代理镜像的拉取 URL

    $ oc get csv -n openshift-cnv -l=operators.coreos.com/kubevirt-hyperconverged.openshift-cnv -ojson | jq '.items[0].spec.relatedImages[] | select(.name|test(".*wasp-agent.*")) | .image'
  6. 通过创建如下例所示的DaemonSet 对象来部署wasp-agent

    kind: DaemonSet
    apiVersion: apps/v1
    metadata:
      name: wasp-agent
      namespace: wasp
      labels:
        app: wasp
        tier: node
    spec:
      selector:
        matchLabels:
          name: wasp
      template:
        metadata:
          annotations:
            description: >-
              Configures swap for workloads
          labels:
            name: wasp
        spec:
          containers:
            - env:
                - name: SWAP_UTILIZATION_THRESHOLD_FACTOR
                  value: "0.8"
                - name: MAX_AVERAGE_SWAP_IN_PAGES_PER_SECOND
                  value: "1000"
                - name: MAX_AVERAGE_SWAP_OUT_PAGES_PER_SECOND
                  value: "1000"
                - name: AVERAGE_WINDOW_SIZE_SECONDS
                  value: "30"
                - name: VERBOSITY
                  value: "1"
                - name: FSROOT
                  value: /host
                - name: NODE_NAME
                  valueFrom:
                    fieldRef:
                      fieldPath: spec.nodeName
              image: >-
                quay.io/openshift-virtualization/wasp-agent:v4.17 (1)
              imagePullPolicy: Always
              name: wasp-agent
              resources:
                requests:
                  cpu: 100m
                  memory: 50M
              securityContext:
                privileged: true
              volumeMounts:
                - mountPath: /host
                  name: host
                - mountPath: /rootfs
                  name: rootfs
          hostPID: true
          hostUsers: true
          priorityClassName: system-node-critical
          serviceAccountName: wasp
          terminationGracePeriodSeconds: 5
          volumes:
            - hostPath:
                path: /
              name: host
            - hostPath:
                path: /
              name: rootfs
      updateStrategy:
        type: RollingUpdate
        rollingUpdate:
          maxUnavailable: 10%
          maxSurge: 0
    1 image 值替换为上一步中的镜像 URL。
  7. 通过创建PrometheusRule 对象来部署警报规则。例如

    apiVersion: monitoring.coreos.com/v1
    kind: PrometheusRule
    metadata:
      labels:
        tier: node
        wasp.io: ""
      name: wasp-rules
      namespace: wasp
    spec:
      groups:
        - name: alerts.rules
          rules:
            - alert: NodeHighSwapActivity
              annotations:
                description: High swap activity detected at {{ $labels.instance }}. The rate
                  of swap out and swap in exceeds 200 in both operations in the last minute.
                  This could indicate memory pressure and may affect system performance.
                runbook_url: https://github.com/openshift-virtualization/wasp-agent/tree/main/docs/runbooks/NodeHighSwapActivity.md
                summary: High swap activity detected at {{ $labels.instance }}.
              expr: rate(node_vmstat_pswpout[1m]) > 200 and rate(node_vmstat_pswpin[1m]) >
                200
              for: 1m
              labels:
                kubernetes_operator_component: kubevirt
                kubernetes_operator_part_of: kubevirt
                operator_health_impact: warning
                severity: warning
  8. 通过运行以下命令将cluster-monitoring 标签添加到wasp 命名空间。

    $ oc label namespace wasp openshift.io/cluster-monitoring="true"
  9. 使用 Web 控制台或 CLI 在 OpenShift Virtualization 中启用内存超额分配。

    • Web 控制台

      1. 在 OpenShift Container Platform Web 控制台中,转到**虚拟化** → **概述** → **设置** → **常规设置** → **内存密度**。

      2. 将**启用内存密度**设置为开启。

    • CLI

      • 配置您的 OpenShift Virtualization 以启用更高的内存密度并设置超额分配率

        $ oc -n openshift-cnv patch HyperConverged/kubevirt-hyperconverged --type='json' -p='[ \
          { \
          "op": "replace", \
          "path": "/spec/higherWorkloadDensity/memoryOvercommitPercentage", \
          "value": 150 \
          } \
        ]'
        成功输出
        hyperconverged.hco.kubevirt.io/kubevirt-hyperconverged patched
验证
  1. 要验证wasp-agent 的部署,请运行以下命令

    $ oc rollout status ds wasp-agent -n wasp

    如果部署成功,则会显示以下消息

    示例输出
    daemon set "wasp-agent" successfully rolled out
  2. 要验证交换是否已正确预配,请完成以下步骤

    1. 通过运行以下命令查看工作节点列表

      $ oc get nodes -l node-role.kubernetes.io/worker
    2. 从列表中选择一个节点,并通过运行以下命令显示其内存使用情况

      $ oc debug node/<selected_node> -- free -m (1)
      1 <selected_node>替换为节点名称。

      如果已预配交换,则在Swap: 行中显示的值将大于零。

      表 1. 示例输出

      总计

      已用

      空闲

      共享

      缓冲/缓存

      可用

      内存

      31846

      23155

      1044

      6014

      14483

      8690

      交换

      8191

      2337

      5854

  3. 运行以下命令,验证 OpenShift Virtualization 内存超额配置:

    $ oc -n openshift-cnv get HyperConverged/kubevirt-hyperconverged -o jsonpath='{.spec.higherWorkloadDensity}{"\n"}'
    示例输出
    {"memoryOvercommitPercentage":150}

    返回的值必须与您之前配置的值匹配。

wasp-agent 使用的 Pod 驱逐条件

当系统负载过重且节点面临风险时,wasp-agent 会管理 Pod 驱逐。如果满足以下任一条件,则会触发驱逐:

高交换区 I/O 流量

当与交换区相关的 I/O 流量过高时,满足此条件。

条件
averageSwapInPerSecond > maxAverageSwapInPagesPerSecond
&&
averageSwapOutPerSecond > maxAverageSwapOutPagesPerSecond

默认情况下,maxAverageSwapInPagesPerSecondmaxAverageSwapOutPagesPerSecond 设置为 1000 页。计算平均值的默认时间间隔为 30 秒。

高交换区利用率

当交换区利用率过高,导致当前虚拟内存使用量超过设定阈值时,满足此条件。您在 MachineConfig 对象中的 NODE_SWAP_SPACE 设置会影响此条件。

条件
nodeWorkingSet + nodeSwapUsage < totalNodeMemory + totalSwapMemory × thresholdFactor

环境变量

您可以使用以下环境变量来调整用于计算驱逐条件的值:

环境变量

功能

MAX_AVERAGE_SWAP_IN_PAGES_PER_SECOND

设置 maxAverageSwapInPagesPerSecond 的值。

MAX_AVERAGE_SWAP_OUT_PAGES_PER_SECOND

设置 maxAverageSwapOutPagesPerSecond 的值。

SWAP_UTILIZATION_THRESHOLD_FACTOR

设置用于计算高交换区利用率的 thresholdFactor 值。

AVERAGE_WINDOW_SIZE_SECONDS

设置计算平均交换区使用率的时间间隔。