Configurar VMs compatibles con NUMA

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

En una máquina virtual compatible con NUMA, toda la comunicación dentro de la máquina virtual es local al nodo NUMA. La VM compatible con NUMA evita las transacciones de datos hacia y desde recursos remotos que pueden reducir el rendimiento de la VM.

Configurar los nodos para que usen NUMA

En las siguientes secciones se describe cómo configurar los componentes críticos de Kubernetes para ajustar el nodo y asegurarse de que puede programar contenedores compatibles con NUMA. Estos nodos NUMA se han ajustado para optimizar el rendimiento de la CPU y la memoria. Sigue las instrucciones de cada nodo en el que quieras ejecutar VMs compatibles con NUMA.

Actualizar la configuración de kubelet

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

  • Habilitar el gestor de CPU con una política static
  • Habilitar el gestor de memoria con una política Static
  • Habilita el gestor de topología con la topología restricted.

Para configurar kubelet en tu nodo de trabajador, sigue estos pasos:

  1. Busca el archivo kubelet en el nodo de trabajo 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
    

    Este comando crea el archivo kubelet con una sección KUBELET_EXTRA_ARGS="" vacía.

  2. Para habilitar CPU Manager con una política static, añade 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 gestor de memoria con una política Static, añade 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 Topology Manager con una política restricted, añade 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. Comprueba la cantidad de memoria reservada por Google Distributed Cloud:

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

    La salida debería tener este 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 ajuste --kube-reserved=cpu=100m,memory=3470Mi indica que Google Distributed Cloud ha reservado 3470 mebibytes de memoria en el nodo.

  6. Define la marca --reserved-memory en la sección KUBELET_EXTRA_ARGS del archivo kubelet con 100 mebibytes más que la memoria reservada actual para tener en cuenta el umbral de desalojo. Si no hay memoria reservada, puedes saltarte este paso.

    Por ejemplo, con la memoria reservada de 3470Mi del ejemplo del paso anterior, reserva 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. Elimina los archivos de estado de la CPU y la 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 estos ajustes de políticas, consulta la siguiente documentación de Kubernetes:

Configurar el nodo para que use páginas enormes

Una vez que hayas habilitado Memory Manager con la política Static, podrás añadir páginas enormes para mejorar aún más el rendimiento de la carga de trabajo de los contenedores en tus nodos NUMA. Las páginas enormes, como su nombre indica, te permiten especificar páginas de memoria que son más grandes que las páginas estándar de 4 kibibytes (KiB). El tiempo de ejecución de máquinas virtuales en GDC admite páginas enormes de 2 mebibytes (MiB) y 1 gibibyte (GiB). Puedes definir páginas enormes para un nodo en tiempo de ejecución o cuando se inicie la máquina del nodo. Te recomendamos que configures hugepages en cada nodo en el que quieras ejecutar máquinas virtuales compatibles con NUMA.

  1. Para configurar el número de páginas enormes de un tamaño específico en tu nodo NUMA en tiempo de ejecución, usa el siguiente comando:

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

    Haz los cambios siguientes:

    • HUGEPAGE_QTY: número de páginas enormes que se van a asignar del tamaño especificado.

    • NUMA_NODE: el nodo NUMA, como node0, al que vas a asignar páginas enormes.

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

Configurar una VM para que use el nodo NUMA

Una vez que los nodos del clúster estén optimizados para NUMA, podrás crear máquinas virtuales compatibles con NUMA. Las máquinas virtuales compatibles con NUMA se programan en nodos NUMA.

Para crear una VM compatible con NUMA, sigue estos pasos:

  1. Siga las instrucciones para crear una máquina virtual a partir de un manifiesto.

    Usa los siguientes ajustes de compute para configurar tu VM de forma que sea compatible con NUMA:

    • spec.compute.guaranteed: asigna el valor true a guaranteed. Con este ajuste, el pod virt-launcher se configura para que se coloque en la clase de calidad del servicio (QoS) garantizada de Kubernetes.

    • spec.compute.advancedCompute:

      • dedicatedCPUPlacement: asigna el valor true a dedicatedCPUPlacement. Esta opción fija las CPUs virtuales a las CPUs físicas del nodo.
      • hugePageSize: asigna a hugePageSize el valor 2Mi o 1Gi para especificar el tamaño de las páginas enormes que usará tu VM (2 mebibytes o 1 gibibyte).
      • numaGuestMappingPassthrough: incluye una estructura vacía ({}) para este ajuste. Este ajuste establece la afinidad NUMA para que tu VM solo se programe en nodos 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