Estos contenidos se han traducido de forma automática para su comodidad, pero Huawei Cloud no garantiza la exactitud de estos. Para consultar los contenidos originales, acceda a la versión en inglés.
Actualización más reciente 2024-09-10 GMT+08:00

Programación de afinidad de NUMA

Antecedente

Cuando el nodo ejecuta muchos pods unidos a CPU, la carga de trabajo puede moverse a diferentes núcleos de CPU dependiendo de si el pod está limitado y qué núcleos de CPU están disponibles en el tiempo de programación. Muchas cargas de trabajo no son sensibles a esta migración y, por lo tanto, funcionan bien sin ninguna intervención. Sin embargo, en cargas de trabajo en las que la afinidad de la memoria caché de la CPU y la latencia de programación afectan significativamente el rendimiento de la carga de trabajo, el kubelet permite políticas alternativas de gestión de la CPU para determinar algunas preferencias de ubicación en el nodo.

Tanto el CPU Manager como el Topology Manager son componentes kubelet, pero tienen las siguientes limitaciones:

  • El planificador no es consciente de la topología. Por lo tanto, la carga de trabajo puede planificarse en un nodo y, a continuación, fallar en el nodo debido al Topology Manager. Esto es inaceptable para los puestos de trabajo TensorFlow. Si algún trabajador o ps falla en el nodo, el trabajo fallará.
  • Los administradores son a nivel de nodo que resulta en una incapacidad para hacer coincidir el mejor nodo para la topología de NUMA en todo el clúster.

Para obtener más información, consulte https://github.com/volcano-sh/volcano/blob/master/docs/design/numa-aware.md.

Volcano tiene como objetivo resolver la limitación de hacer que la topología de NUMA del planificador sea consciente para lograr lo siguiente:

  • No programe pods para los nodos que no coincidan con la topología de NUMA.
  • Programe los pods en el mejor nodo para la topología de NUMA.

Ámbito de aplicación

  • Compatible con la programación de topología de recursos de CPU
  • Compatible con las políticas de topología a nivel de pod

Predicción de programación

Para los pods con la política de topología, predique la lista de nodos coincidentes.

política

acción

Ninguna

1. Sin acción de filtro

best-effort

1. Filtre el nodo con el best-effort de política de topología.

restricted

1. Filtre el nodo con el restricted de política de topología.

2. Filtrar el nodo que la topología de la CPU cumple con los requisitos de la CPU para restricted.

single-numa-node

1. Filtre el nodo con el single-numa-node de política de topología.

2. Filtrar el nodo que la topología de la CPU cumple con los requisitos de la CPU para single-numa-node.

Figura 1 Comparación de políticas de programación de NUMA

Planificación de prioridades

La política de topología tiene como objetivo programar pods para el nodo óptimo. En este ejemplo, cada nodo se puntúa para ordenar el nodo óptimo.

Principio: Programe pods para los nodos de trabajo que requieren el número mínimo de nodos de NUMA.

La fórmula de puntuación es la siguiente:

score = weight * (100 - 100 * numaNodeNum / maxNumaNodeNum)

Descripción de parámetros:

  • weight: indica la ponderación del NUMA Aware Plugin.
  • numaNodeNum: indica el número de nodos de NUMA necesarios para ejecutar el pod en el nodo de trabajo.
  • maxNumaNodeNum: indica el número máximo de nodos de NUMA en un pod de todos los nodos de trabajo.

Habilitar volcano para apoyar la programación de afinidad de NUMA

  1. Habilite la política de gestión de CPU. Para obtener más información, véase Habilitación de la política de gestión de CPU.
  2. Configure una política de topología de CPU.

    1. Inicie sesión en la consola de CCE y acceda a la consola del clúster. Elija Nodes en el panel de navegación. En el panel derecho, haga clic en la ficha Node Pools. Elija More > Manage en la columna Operation del grupo de nodos de destino.
    2. Cambie el valor de topology-manager-policy en kubelet a la política de topología de CPU requerida. Como se muestra en la siguiente figura, la política de topología de la CPU es best-effort.

      Las políticas de topología válidas son none, best-effort, restricted y single-numa-node. Para obtener más información sobre estas políticas, consulte Predicción de programación.

  3. El parámetro resource_exporter_enable está habilitado para que el complemento de volcano recopile información de NUMA del nodo.

    {
       "plugins": {
          "eas_service": {
             "availability_zone_id": "",
             "driver_id": "",
             "enable": "false",
             "endpoint": "",
             "flavor_id": "",
             "network_type": "",
             "network_virtual_subnet_id": "",
             "pool_id": "",
             "project_id": "",
             "secret_name": "eas-service-secret"
          }
       },
       "resource_exporter_enable": "true"
    }
    Una vez activada esta función, puede ver la información de topología de NUMA del nodo actual.
    kubectl get numatopo 
    NAME              AGE
    node-1            4h8m
    node-2            4h8m
    node-3            4h8m

  4. Habilite el complemento del algoritmo de reconocimiento de numa del volcano.

    kubectl edit cm -n kube-system volcano-scheduler-configmap
    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: volcano-scheduler-configmap
      namespace: kube-system
    data:
      default-scheduler.conf: |-
        actions: "allocate, backfill"
        tiers:
        - plugins:
          - name: priority
          - name: gang
          - name: conformance
        - plugins:
          - name: overcommit
          - name: drf
          - name: predicates
          - name: nodeorder
        - plugins:
          - name: cce-gpu-topology-predicate
          - name: cce-gpu-topology-priority
          - name: cce-gpu
        - plugins:
          - name: nodelocalvolume
          - name: nodeemptydirvolume
          - name: nodeCSIscheduling
          - name: networkresource
            arguments:
              NetworkType: vpc-router
          - name: numa-aware # add it to enable numa-aware plugin
            arguments:
              weight: 10 # the weight of the NUMA Aware Plugin

Usar volcano para apoyar la programación de afinidad de NUMA

  1. Configurar la afinidad de NUMA para las Deployments. A continuación se presenta un ejemplo:

    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: numa-tset
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: numa-tset
      template:
        metadata:
          labels:
            app: numa-tset
          annotations:
            volcano.sh/numa-topology-policy: single-numa-node    # set the topology policy
        spec:
          containers:
            - name: container-1
              image: nginx:alpine
              resources:
                requests:
                  cpu: 2           # The value must be an integer and must be the same as that in limits.
                  memory: 2048Mi
                limits:
                  cpu: 2           # The value must be an integer and must be the same as that in requests.
                  memory: 2048Mi
          imagePullSecrets:
          - name: default-secret

  2. Cree un trabajo de volcano y use la afinidad de NUMA.

    apiVersion: batch.volcano.sh/v1alpha1
    kind: Job
    metadata:
      name: vj-test
    spec:
      schedulerName: volcano
      minAvailable: 1
      tasks:
        - replicas: 1
          name: "test"
          topologyPolicy: best-effort   # set the topology policy for task 
          template:
            spec:
              containers:
                - image: alpine
                  command: ["/bin/sh", "-c", "sleep 1000"]
                  imagePullPolicy: IfNotPresent
                  name: running
                  resources:
                    limits:
                      cpu: 20
                      memory: "100Mi"
              restartPolicy: OnFailure

  3. Compruebe el uso de NUMA.

    # Check the CPU usage of the current node.
    lscpu
    ...
    CPU(s):              32
    NUMA node(s):        2
    NUMA node0 CPU(s):   0-15
    NUMA node1 CPU(s):   16-31
    
    # Check the CPU allocation of the current node.
    cat /var/lib/kubelet/cpu_manager_state
    {"policyName":"static","defaultCpuSet":"0,10-15,25-31","entries":{"777870b5-c64f-42f5-9296-688b9dc212ba":{"container-1":"16-24"},"fb15e10a-b6a5-4aaa-8fcd-76c1aa64e6fd":{"container-1":"1-9"}},"checksum":318470969}