NUMA 対応の VM を構成する

このドキュメントでは、不均一メモリアクセス(NUMA)のコンピューティング効率で高パフォーマンスと低レイテンシのワークロードに対応できるように、クラスタと VM を構成する方法について説明します。クラスタノードの 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_EXTRA_ARGS="" セクションのある kubelet ファイルを作成します。

  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 設定は、ノード上で 3,470 メビバイト(MiB)のメモリが Google Distributed Cloud に予約されていることを示します。

  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 ドキュメントをご覧ください。

hugepages を使用するようにノードを構成する

Static ポリシーでメモリ マネージャーを有効にしたら、hugepages を追加することで NUMA ノードでのコンテナ ワークロードのパフォーマンスをさらに向上できます。hugepages はその名前のとおり、標準の 4 キビバイト(KiB)よりも大きいメモリページを指定できるようにします。GDC 上の VM ランタイムは、2 メビバイト(MiB)と 1 ギビバイト(GiB)の hugepages をサポートします。実行時のノード用、またはノードマシンの起動時用に、hugepages を設定できます。NUMA 対応の VM を実行させる予定の各ノードで、hugepages を構成することをおすすめします。

  1. 実行時の NUMA ノードで使用される特定サイズの hugepages の数を構成するには、次のコマンドを使用します。

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

    次のように置き換えます。

    • HUGEPAGE_QTY: 指定サイズの hugepages の割り当て数。

    • NUMA_NODE: node0 など hugepages を割り当てる NUMA ノード。

    • HUGEPAGE_SIZE: hugepages のサイズ。KiB 単位で 2048(2 MiB)または 1048576(1 GiB)。

NUMA ノードを使用するように VM を構成する

NUMA 用にクラスタノードを調整したら、NUMA 対応の VM を作成できます。NUMA 対応の VM は、NUMA ノードでスケジューリングされます。

NUMA 対応の VM を作成するには:

  1. 手順に沿って、マニフェストから VM を作成します。

    次の compute 設定を使用して、VM を NUMA 対応に構成します。

    • spec.compute.guaranteed: guaranteedtrue に設定します。この設定では、virt-launcher Pod は Kubernetes の Guaranteed Quality of Service(QoS)クラスに配置されるように構成されます。

    • spec.compute.advancedCompute:

      • dedicatedCPUPlacement: dedicatedCPUPlacementtrue に設定します。この設定により、仮想 CPU がノードの物理 CPU に固定されます。
      • hugePageSize: hugePageSize2Mi1Gi のいずれかに設定して、VM で使用する hugepages のサイズを 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