NUMA 対応の VM を構成する

不均一メモリアクセス(NUMA)を使用すると、クラスタと仮想マシン(VM)で高パフォーマンス、低レイテンシのワークロードをサポートできます。クラスタノードで Kubernetes の設定をチューニングし、NUMA アフィニティで VM を構成すると、ワークロードが NUMA ノードで直接スケジューリングされるようになります。

NUMA 対応の VM では、すべての通信が NUMA ノードに対してローカルのままになります。このアーキテクチャにより、パフォーマンスを低下させる可能性があるリモート データ転送が防止されます。

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 ポリシーで Topology Manager を有効にするには、ファイルの 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 メビバイト大きく設定します。予約済みのメモリがない場合は、この手順をスキップできます。

    たとえば、前の手順の例での 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: guaranteed を true に設定します。この設定では、virt-launcher Pod は Kubernetes の Guaranteed Quality of Service(QoS)クラスに配置されるように構成されます。

    • spec.compute.advancedCompute:

      • dedicatedCPUPlacement: dedicatedCPUPlacement を true に設定します。この設定により、仮想 CPU がノードの物理 CPU に固定されます。
      • hugePageSize: hugePageSize を 2Mi と 1Gi のいずれかに設定して、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