設定支援 NUMA 的 VM

本文說明如何設定叢集和 VM,以支援高效能和低延遲工作負載,並運用非一致性記憶體存取 (NUMA) 的運算效率。您可以按照操作說明,調整叢集節點的 Kubernetes 設定。本文也提供相關操作說明,協助您設定具備 NUMA 親和性的虛擬機器 (VM),以便在 NUMA 節點上排程及運用這些節點。

使用 NUMA 感知 VM 時,VM 內的所有通訊都會在本機 NUMA 節點進行。NUMA 感知 VM 可避免與遠端資源進行資料交易,以免 VM 效能降低。

將節點設為使用 NUMA

以下各節說明如何設定重要的 Kubernetes 元件,以調整節點並確保節點可以排程 NUMA 感知容器。這些 NUMA 節點經過調整,可最佳化 CPU 和記憶體效能。請按照要執行 NUMA 感知 VM 的每個節點的操作說明操作。

更新 kubelet 設定

如要支援 NUMA 節點相依性,您必須在 kubelet 設定中進行下列變更:

  • 使用 static 政策啟用 CPU 管理工具
  • 使用 Static 政策啟用記憶體管理工具
  • 使用 restricted 拓撲啟用拓撲管理工具

如要在工作站節點上設定 kubelet,請按照下列步驟操作:

  1. 在工作節點上找出 kubelet 檔案,然後開啟進行編輯:

    edit /etc/default/kubelet
    

    如果找不到 kubelet 檔案,請使用下列指令建立:

    echo "KUBELET_EXTRA_ARGS=\"\"" >> /etc/default/kubelet
    

    這個指令會建立 kubelet 檔案,其中包含空白的 KUBELET_EXTRA_ARGS="" 區段。

  2. 如要透過 static 政策啟用 CPU 管理器,請在檔案的 KUBELET_EXTRA_ARGS="" 區段中新增 --cpu-manager-policy=static 標記:

    KUBELET_EXTRA_ARGS="--cpu-manager-policy=static"
    
  3. 如要透過 Static 政策啟用記憶體管理工具,請在檔案的 KUBELET_EXTRA_ARGS="" 區段中加入 --memory-manager-policy=Static 旗標:

    KUBELET_EXTRA_ARGS="--cpu-manager-policy=static --memory-manager-policy=Static"
    
  4. 如要透過 restricted 政策啟用拓撲管理工具,請在檔案的 KUBELET_EXTRA_ARGS="" 區段中加入 --topology-manager-policy=restricted 旗標:

    KUBELET_EXTRA_ARGS="--cpu-manager-policy=static --memory-manager-policy=Static --topology-manager-policy=restricted"
    
  5. 查看 Google Distributed Cloud 目前保留的記憶體量:

    cat /var/lib/kubelet/kubeadm-flags.env
    

    輸出內容應如下所示:

    KUBELET_KUBEADM_ARGS="--anonymous-auth=false --authentication-token-webhook=true --authorization-mode=Webhook --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --feature-gates=SeccompDefault=true --kube-reserved=cpu=100m,memory=3470Mi --max-pods=110 --node-ip=192.168.1.190 --node-labels=baremetal.cluster.gke.io/k8s-ip=192.168.1.190,baremetal.cluster.gke.io/namespace=cluster-user001,baremetal.cluster.gke.io/node-pool=node-pool-1,cloud.google.com/gke-nodepool=node-pool-1 --pod-infra-container-image=gcr.io/anthos-baremetal-release/pause-amd64:3.1-gke.5 --provider-id=baremetal://192.168.1.190 --read-only-port=10255 --rotate-server-certificates=true --seccomp-default=true"

    --kube-reserved=cpu=100m,memory=3470Mi 設定表示 Google Distributed Cloud 已在節點上保留 3,470 MiB 的記憶體。

  6. kubelet 檔案的 KUBELET_EXTRA_ARGS 區段中,將 --reserved-memory 旗標設為比目前保留記憶體多 100 MiB,以考量逐出門檻。如果沒有保留記憶體,可以略過這個步驟。

    舉例來說,如果前一個步驟範例中的保留記憶體為 3470Mi,您可以在 kubelet 檔案中保留 3570Mi 的記憶體:

    KUBELET_EXTRA_ARGS="--cpu-manager-policy=static --memory-manager-policy=Static --topology-manager-policy=restricted --reserved-memory=0:memory=3570Mi"
    
  7. /var/lib 目錄移除 CPU 和記憶體狀態檔案:

    rm /var/lib/cpu_manager_state
    rm /var/lib/memory_manager_state
    
  8. 重新啟動 kubelet:

    systemctl start kubelet
    

如要進一步瞭解這些政策設定,請參閱下列 Kubernetes 說明文件:

設定節點以使用巨頁

使用 Static 政策啟用記憶體管理工具後,您可以新增 hugepage,進一步提升 NUMA 節點上的容器工作負載效能。顧名思義,Hugepages 可讓您指定大於標準 4 KiB 的記憶體頁面。GDC 的 VM 執行階段支援 2 MiB 和 1 GiB 的巨頁。您可以為節點設定執行階段的巨頁,也可以為節點機器啟動時設定巨頁。建議您在要執行 NUMA 感知 VM 的每個節點上設定 hugepages。

  1. 如要在 NUMA 節點上設定特定大小的巨頁數量,請在執行階段使用下列指令:

    echo HUGEPAGE_QTY > \
        /sys/devices/system/node/NUMA_NODE/hugepages/hugepages-HUGEPAGE_SIZEkB/nr_hugepages
    

    更改下列內容:

    • HUGEPAGE_QTY:要分配指定大小的巨頁數量。

    • NUMA_NODE:NUMA 節點,例如 node0,您要將 hugepage 分配給該節點。

    • HUGEPAGE_SIZE:以 KiB 為單位的巨頁大小,2048 (2 MiB) 或 1048576 (1 GiB)。

設定 VM 使用 NUMA 節點

叢集節點完成 NUMA 調整後,即可建立 NUMA 感知 VM。系統會將 NUMA 感知 VM 排程至 NUMA 節點。

如要建立支援 NUMA 的 VM,請按照下列步驟操作:

  1. 請按照操作說明從資訊清單建立 VM

    請使用下列 compute 設定,將 VM 設定為 NUMA 感知型:

    • spec.compute.guaranteed:將 guaranteed 設為 true。使用這項設定時,系統會將 virt-launcher Pod 設為 Kubernetes Guaranteed 服務品質 (QoS) 類別

    • spec.compute.advancedCompute

      • dedicatedCPUPlacement:將 dedicatedCPUPlacement 設為 true。這項設定會將虛擬 CPU 固定在節點的實體 CPU 上。
      • hugePageSize:將 hugePageSize 設為 2Mi1Gi,指定 VM 要使用的巨頁大小,即 2 MiB 或 1 GiB。
      • numaGuestMappingPassthrough:請為這項設定加入空白結構 ({})。這項設定會建立 NUMA 相依性,讓 VM 只排定在 NUMA 節點上。

    以下 VirtualMachine 資訊清單範例顯示 NUMA 感知 VM 設定的可能樣貌:

    apiVersion: vm.cluster.gke.io/v1
    kind: VirtualMachine
    metadata:
      name: vm1
    spec:
      compute:
        cpu:
          vcpus: 2
        guaranteed: true
        advancedCompute:
          dedicatedCPUPlacement: true
          hugePageSize: 2Mi
          numaGuestMappingPassthrough: {}
        memory:
          capacity: 256Mi
      interfaces:
      - name: eth0
        networkName: pod-network
        default: true
      disks:
      - virtualMachineDiskName: disk-from-gcs
        boot: true
        readOnly: true