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 Manager を有効にする
  • Static ポリシーで Memory Manager を有効にする
  • restricted トポロジで Topology Manager を有効にする

ワーカーノードで kubelet を構成するには:

  1. ワーカーノードで kubelet ファイルを見つけて、編集のために開きます。

    edit /etc/default/kubelet
    

    kubelet ファイルが表示されない場合は、次のコマンドを使用して作成します。

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

    このコマンドは、空の KUBELET_EXTRA_ARGS="" セクションを含む kubelet ファイルを作成します。

  2. static ポリシーで CPU Manager を有効にするには、ファイルの KUBELET_EXTRA_ARGS="" セクションに --cpu-manager-policy=static フラグを追加します。

    KUBELET_EXTRA_ARGS="--cpu-manager-policy=static"
    
  3. Static ポリシーで Memory Manager を有効にするには、ファイルの 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. GKE on Bare Metal が予約している現在のメモリ量を確認します。

    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 設定は、GKE on Bare Metal がノード上で 3,470 メビバイトのメモリを予約したことを示します。

  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. CPU とメモリの状態ファイルを /var/lib ディレクトリから削除します。

    rm /var/lib/cpu_manager_state
    rm /var/lib/memory_manager_state
    
  8. kubelet を再起動します。

    systemctl start kubelet
    

これらのポリシー設定の詳細については、次の Kubernetes ドキュメントをご覧ください。

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

Static ポリシーで Memory Manager を有効にしたら、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: hugepage を割り当てる node0 などの NUMA ノード。

    • HUGEPAGE_SIZE: hugepages のサイズ(キビバイト単位)、2048(2 MiB)または 1048576(1 GiB)。

VM を構成して NUMA ノードを使用する

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

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

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

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

    • spec.compute.guaranteed: guaranteedtrue に設定します。この設定では、virt-launcher Pod は Kubernetes 保証付きの Quality of Service(QoS)クラスに配置されます。

    • spec.compute.advancedCompute:

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