Configura la programación de VM compatibles con NUMA

En este documento, se describe cómo configurar clústeres y VM para admitir cargas de trabajo de alto rendimiento y baja latencia con la eficiencia de procesamiento del acceso a la memoria no uniforme (NUMA). Hay instrucciones para ajustar la configuración de Kubernetes para los nodos del clúster. En este documento, también se incluyen instrucciones para configurar máquinas virtuales (VM) con afinidad de NUMA a fin de que se programen y aprovechen los nodos de NUMA.

Con una VM compatible con NUMA, toda la comunicación dentro de la VM es local para el nodo de NUMA. La VM compatible con NUMA evita transacciones de datos hacia y desde recursos remotos que pueden degradar el rendimiento de la VM.

Configura nodos para usar NUMA

En las siguientes secciones, se describe cómo configurar los componentes fundamentales de Kubernetes para ajustar el nodo y asegurarse de que pueda programar contenedores compatibles con NUMA. Estos nodos de NUMA se ajustan para optimizar el rendimiento de la CPU y la memoria. Sigue las instrucciones para cada nodo en el que desees ejecutar VMs compatibles con NUMA.

Actualiza la configuración de kubelet

Como parte de la configuración de nodos para admitir la afinidad de nodos de NUMA, debes realizar los siguientes cambios en la configuración de kubelet:

  • Habilita el administrador de CPU con una política static
  • Habilita el administrador de memoria con una política Static
  • Habilita el administrador de topologías con la topología restricted

Para configurar kubelet en tu nodo trabajador, haz lo siguiente:

  1. Busca el archivo kubelet en tu nodo trabajador y ábrelo para editarlo:

    edit /etc/default/kubelet
    

    Si no ves el archivo kubelet, créalo con el siguiente comando:

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

    Con este comando, se crea el archivo kubelet con una sección KUBELET_EXTRA_ARGS="" vacía.

  2. Para habilitar el administrador de CPU con una política static, agrega la marca --cpu-manager-policy=static a la sección KUBELET_EXTRA_ARGS="" del archivo:

    KUBELET_EXTRA_ARGS="--cpu-manager-policy=static"
    
  3. Para habilitar el administrador de memoria con una política Static, agrega la marca --memory-manager-policy=Static a la sección KUBELET_EXTRA_ARGS="" del archivo:

    KUBELET_EXTRA_ARGS="--cpu-manager-policy=static --memory-manager-policy=Static"
    
  4. Para habilitar el Administrador de topologías con una política restricted, agrega la marca --topology-manager-policy=restricted a la sección KUBELET_EXTRA_ARGS="" del archivo:

    KUBELET_EXTRA_ARGS="--cpu-manager-policy=static --memory-manager-policy=Static --topology-manager-policy=restricted"
    
  5. Verifica la cantidad actual de memoria reservada por GKE en Bare Metal:

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

    El resultado debe tener el siguiente aspecto:

    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"

    El parámetro de configuración --kube-reserved=cpu=100m,memory=3470Mi indica que GKE en Bare Metal reservó 3,470 mebibytes de memoria en el nodo.

  6. Establece la marca --reserved-memory en la sección KUBELET_EXTRA_ARGS del archivo kubelet en 100 mebibytes más que la memoria reservada actual para dar cuenta del umbral de expulsión. Si no hay memoria reservada, puedes omitir este paso.

    Por ejemplo, con la memoria reservada de 3470Mi del ejemplo del paso anterior, reservas 3570Mi de memoria en el archivo kubelet:

    KUBELET_EXTRA_ARGS="--cpu-manager-policy=static --memory-manager-policy=Static --topology-manager-policy=restricted --reserved-memory=0:memory=3570Mi"
    
  7. Quita los archivos de estado de CPU y memoria del directorio /var/lib:

    rm /var/lib/cpu_manager_state
    rm /var/lib/memory_manager_state
    
  8. Reinicia kubelet:

    systemctl start kubelet
    

Para obtener más información sobre esta configuración de políticas, consulta la siguiente documentación de Kubernetes:

Configura el nodo para usar largepages

Una vez que hayas habilitado el administrador de memoria con la política Static, puedes agregar páginas grandes para mejorar aún más el rendimiento de la carga de trabajo del contenedor en tus nodos de NUMA. Largepages, como su nombre lo indica, te permite especificar páginas de memoria que son más grandes que los 4 kibibyte (KiB) estándar. El entorno de ejecución de VM en Google Distributed Cloud admite páginas enormes de 2 mebibyte (MiB) y 1 gibibyte (GiB). Puedes configurar bigpages para un nodo en el entorno de ejecución o para cuando se inicia la máquina de nodos. Te recomendamos que configures páginas enormes en cada nodo en el que desees ejecutar VMs compatibles con NUMA.

  1. Para configurar la cantidad de bigpages de un tamaño específico en tu nodo NUMA en el entorno de ejecución, usa el siguiente comando:

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

    Reemplaza lo siguiente:

    • HUGEPAGE_QTY: Es la cantidad de páginas grandes que se asignarán del tamaño especificado.

    • NUMA_NODE: Es el nodo de NUMA, como node0, al que le asignas grandespáginas.

    • HUGEPAGE_SIZE: Es el tamaño de las grandes páginas en kibibytes, 2048 (2 MiB) o 1048576 (1 GiB).

Configura una VM para usar el nodo de NUMA

Una vez que los nodos del clúster estén ajustados para NUMA, puedes crear VMs compatibles con NUMA. Las VMs compatibles con NUMA están programadas en NUMA nodos.

Sigue estos pasos para crear una VM compatible con NUMA:

  1. Sigue las instrucciones para crear una VM a partir de un manifiesto.

    Usa la siguiente configuración de compute a fin de configurar tu VM para que reconozca NUMA:

    • spec.compute.guaranteed: Establece guaranteed en true. Con esta configuración, el Pod virt-launcher se configura para que se ubique en la clase de Calidad de servicio (QoS) garantizada de Kubernetes.

    • spec.compute.advancedCompute:

      • dedicatedCPUPlacement: Establece dedicatedCPUPlacement en true. Con esta configuración, se fijan las CPU virtuales a las CPU físicas del nodo.
      • hugePageSize: Configura hugePageSize como 2Mi o 1Gi para especificar el tamaño de bigpages que usará tu VM, 2 mebibyte o 1 gibibyte.
      • numaGuestMappingPassthrough: Incluye una estructura vacía ({}) para esta configuración. Esta configuración establece la afinidad de NUMA para que la VM se programe solo en los nodos de NUMA.

    En el siguiente ejemplo de manifiesto de VirtualMachine, se muestra cómo podría ser una configuración de VM compatible con NUMA:

    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