Incorporación de un grupo de nodos de Azure Spot a un clúster de Azure Kubernetes Service (AKS)

En este artículo se agrega un grupo de nodos de Spot secundarios a un clúster de Azure Kubernetes Service (AKS) existente.

Un grupo de nodos Spot es un grupo de nodos respaldado por un conjunto de escalado de máquinas virtuales Spot de Azure. Con las máquinas virtuales de Spot en su clúster de AKS, puede aprovechar la capacidad no utilizada de Azure con un importante ahorro de costes. La capacidad disponible no utilizada variará en función de muchos factores, como el tamaño del nodo, la región y la hora del día.

Cuando implementa un grupo de nodos Spot, Azure asigna los nodos Spot si hay capacidad disponible e implementa un conjunto de escalado de máquinas virtuales Spot que da soporte al grupo de nodos Spot en un único dominio predeterminado. No hay ningún Acuerdo de Nivel de Servicio para los nodos de acceso puntual. No hay garantías de alta disponibilidad. Si Azure necesita recuperar la capacidad, la infraestructura de Azure expulsará los nodos de acceso puntual.

Los nodos spot son ideales para cargas de trabajo que puedan tolerar interrupciones, finalizaciones anticipadas o desalojos. Por ejemplo, las cargas de trabajo como los trabajos de procesamiento por lotes, los entornos de desarrollo y pruebas, y las cargas de trabajo de computación intensiva podrían ser buenos candidatos para ejecutarse en un grupo de nodos Spot.

Antes de empezar

  • Se presupone que tiene un conocimiento básico de los conceptos de Kubernetes y Azure Load Balancer. Para más información, consulte Conceptos básicos de Kubernetes de Azure Kubernetes Service (AKS).
  • Si no tiene una suscripción a Azure, cree una cuenta gratuita antes de empezar.
  • Cuando cree un clúster para usar un grupo de nodos de Spot, el clúster debe usar Virtual Machine Scale Sets para los grupos de nodos y el equilibrador de carga SKU Standard. También debe agregar otro grupo de nodos después de crear el clúster, que se trata en este tutorial.
  • Para este artículo, es necesario usar la versión 2.14 de la CLI de Azure o posterior. Ejecute az --version para encontrar la versión. Si necesita instalarla o actualizarla, vea Instalación de la CLI de Azure.

Limitaciones

Al crear y administrar clústeres de AKS con un grupo de nodos de Spot se aplican las limitaciones siguientes:

  • Un grupo de nodos Spot no puede ser un grupo de nodos predeterminado; solo puede usarse como grupo de nodos secundario.
  • Los grupos de nodos y el plano de control no se pueden actualizar al mismo tiempo. Debe actualizarlos por separado o quitar el grupo de nodos de Spot para actualizar el plano de control y los grupos de nodos restantes al mismo tiempo.
  • Los grupos de nodos de Spot deben usar Virtual Machine Scale Sets.
  • No se puede cambiar ScaleSetPriority o SpotMaxPrice una vez creados.
  • Al establecer SpotMaxPrice, el valor debe ser -1 o un valor positivo con hasta cinco decimales.
  • Un grupo de nodos de acceso puntual tiene la etiqueta kubernetes.azure.com/scalesetpriority:spot, el valor taint kubernetes.azure.com/scalesetpriority=spot:NoSchedule, y los pods del sistema tienen antiafinidad.
  • Para programar cargas de trabajo en un grupo de nodos de Spot debe agregar una afinidad y una tolerancia correspondiente.

Incorporación de un grupo de nodos de Spot a un clúster de AKS

Al añadir un grupo de nodos Spot a un clúster existente, este debe tener activados varios grupos de nodos. Al crear un clúster de AKS con varios grupos de nodos habilitados, se crea un grupo de nodos con un priority de Regular forma predeterminada. Para agregar un grupo de nodos Spot, debe especificar Spot como valor para priority. Para más información sobre cómo crear un clúster de AKS con varios grupos de nodos, consulte Uso de varios grupos de nodos.

  • Cree un grupo de nodos en el que el valor de priority es Spot, y use para ello el comando az aks nodepool add.
export SPOT_NODEPOOL="spotnodepool"

az aks nodepool add \
    --resource-group $RESOURCE_GROUP \
    --cluster-name $AKS_CLUSTER \
    --name $SPOT_NODEPOOL \
    --priority Spot \
    --eviction-policy Delete \
    --spot-max-price -1 \
    --enable-cluster-autoscaler \
    --min-count 1 \
    --max-count 3 \
    --no-wait

En el comando anterior, el priority de Spot hace que el grupo de nodos sea un grupo de nodos Spot. El parámetro eviction-policy se establece en Delete, que es el valor predeterminado. Al establecer eviction-policy en Delete, los nodos del grupo de escalado subyacente del grupo de nodos se eliminan al ser expulsados.

También se puede establecer eviction-policy en Deallocate, que significa que los nodos del conjunto de escalado subyacente se establecen en estado stopped-deallocated durante la expulsión. Los nodos en estado stopped-deallocated se consideran también a efectos de la cuota de proceso, lo cual puede generar problemas de escalado o actualización del clúster. Los valores de priority y eviction-policy solo se pueden establecer durante la creación del grupo de nodos. Estos valores no se pueden actualizar más adelante.

El comando anterior también habilita el escalador automático de clúster, que recomendamos usar con grupos de nodos Spot. En función de las cargas de trabajo que se ejecuten en el clúster, el escalador automático de clúster escala y reduce verticalmente el número de nodos del grupo. Para los grupos de nodos Spot, el autoscaler del clúster aumentará el número de nodos tras una expulsión si aún se necesitan más nodos. Si cambia el número máximo de nodos que puede tener un grupo de nodos, también debe ajustar el valor de maxCount asociado con el escalador automático del clúster. Si no usa un escalador automático del clúster, tras el desalojo, el grupo de Spot acabará reduciéndose a 0 y requerirá una intervención manual para recibir nodos Spot adicionales.

Importante

Programe solo las cargas de trabajo en grupos de nodos de Spot que puedan controlar las interrupciones, como los trabajos de procesamiento por lotes y los entornos de prueba. Recomendamos que configure los valores de taint y tolerancia en el grupo de nodos de acceso puntual para asegurarse de que en un grupo de nodos de acceso puntual solo estén programadas las cargas de trabajo que pueden controlar las expulsiones de nodos. Por ejemplo, el comando anterior agrega el valor taint kubernetes.azure.com/scalesetpriority=spot:NoSchedule para que, en este nodo, solo se programen los pods con el valor de tolerancia correspondiente.

Verifique el grupo de nodos Spot

  • Utilice el comando az aks nodepool show para comprobar que el grupo de nodos se ha agregado y confirme que el valor de scaleSetPriority es Spot.
az aks nodepool show --resource-group $RESOURCE_GROUP --cluster-name $AKS_CLUSTER --name $SPOT_NODEPOOL

Resultados:

{
  "artifactStreamingProfile": null,
  "availabilityZones": null,
  "capacityReservationGroupId": null,
  "count": 3,
  "creationData": null,
  "currentOrchestratorVersion": "1.30.10",
  "eTag": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "enableAutoScaling": true,
  "enableCustomCaTrust": false,
  "enableEncryptionAtHost": false,
  "enableFips": false,
  "enableNodePublicIp": false,
  "enableUltraSsd": false,
  "gatewayProfile": null,
  "gpuInstanceProfile": null,
  "gpuProfile": null,
  "hostGroupId": null,
  "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourcegroups/xxxxxxxxxxxxxxxx/providers/Microsoft.ContainerService/managedClusters/xxxxxxxxxxxxxxxx/agentPools/xxxxxxxxxxxx",
  "kubeletConfig": null,
  "kubeletDiskType": "OS",
  "linuxOsConfig": null,
  "maxCount": 3,
  "maxPods": 30,
  "messageOfTheDay": null,
  "minCount": 1,
  "mode": "User",
  "name": "xxxxxxxxxxxx",
  "networkProfile": {
    "allowedHostPorts": null,
    "applicationSecurityGroups": null,
    "nodePublicIpTags": null
  },
  "nodeImageVersion": "AKSUbuntu-2204gen2containerd-xxxxxxxx.xx.x",
  "nodeInitializationTaints": null,
  "nodeLabels": {
    "kubernetes.azure.com/scalesetpriority": "spot"
  },
  "nodePublicIpPrefixId": null,
  "nodeTaints": [
    "kubernetes.azure.com/scalesetpriority=spot:NoSchedule"
  ],
  "orchestratorVersion": "x.xx.xx",
  "osDiskSizeGb": 128,
  "osDiskType": "Managed",
  "osSku": "Ubuntu",
  "osType": "Linux",
  "podIpAllocationMode": null,
  "podSubnetId": null,
  "powerState": {
    "code": "Running"
  },
  "provisioningState": "Creating",
  "proximityPlacementGroupId": null,
  "resourceGroup": "xxxxxxxxxxxxxxxx",
  "scaleDownMode": "Delete",
  "scaleSetEvictionPolicy": "Delete",
  "scaleSetPriority": "Spot",
  "securityProfile": {
    "enableSecureBoot": false,
    "enableVtpm": false,
    "sshAccess": "LocalUser"
  },
  "spotMaxPrice": -1.0,
  "status": null,
  "tags": null,
  "type": "Microsoft.ContainerService/managedClusters/agentPools",
  "typePropertiesType": "VirtualMachineScaleSets",
  "upgradeSettings": {
    "drainTimeoutInMinutes": null,
    "maxSurge": null,
    "maxUnavailable": null,
    "nodeSoakDurationInMinutes": null,
    "undrainableNodeBehavior": null
  },
  "virtualMachineNodesStatus": null,
  "virtualMachinesProfile": null,
  "vmSize": "Standard_DS2_v2",
  "vnetSubnetId": null,
  "windowsProfile": null,
  "workloadRuntime": "OCIContainer"
}

Programar un pod para que se ejecute en un nodo Spot

Para programar un pod para que se ejecute en un nodo de acceso puntual, puede agregar una tolerancia y una afinidad de nodos que se corresponda con la intolerancia aplicada al nodo de acceso puntual.

En el ejemplo siguiente se muestra una parte de un archivo YAML que define una tolerancia que corresponde al valor kubernetes.azure.com/scalesetpriority=spot:NoSchedule y una afinidad de nodos que corresponde a la etiqueta kubernetes.azure.com/scalesetpriority=spot usada en el paso anterior con las reglas de afinidad de los nodos requiredDuringSchedulingIgnoredDuringExecution y preferredDuringSchedulingIgnoredDuringExecution:

spec:
  containers:
  - name: spot-example
  tolerations:
  - key: "kubernetes.azure.com/scalesetpriority"
    operator: "Equal"
    value: "spot"
    effect: "NoSchedule"
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: "kubernetes.azure.com/scalesetpriority"
            operator: In
            values:
            - "spot"
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value

Cuando implementa un pod con esta tolerancia y afinidad de nodos, Kubernetes lo programa correctamente en los nodos con el valor y la etiqueta aplicadas. En este ejemplo, se aplican las siguientes reglas:

  • El nodo debe tener una etiqueta con la clave kubernetes.azure.com/scalesetpriorityy el valor de esa etiqueta debe ser spot.
  • El nodo tiene preferiblemente una etiqueta con la clave another-node-label-keyy el valor de esa etiqueta debe ser another-node-label-value.

Para más información, consulte Asignación de pods a nodos.

Actualización de un grupo de nodos de Spot

Cuando actualiza un grupo de nodos de acceso puntual, AKS emite internamente un cordón y un aviso de expulsión, pero no se aplica ninguna purga. No hay nodos de sobrecarga disponibles para las actualizaciones del grupo de nodos de Spot. Aparte de estos cambios, el comportamiento al actualizar los grupos de nodos Spot es coherente con el de otros tipos de grupos de nodos.

Para más información sobre la actualización, consulte Actualización de un clúster de Azure Kubernetes Service (AKS).

Precio máximo para un pool de Spot

Los precios de las instancias de Spot varían en función de la región y la SKU. Para más información, consulte la información de precios para Linux y Windows.

La variabilidad en los precios permite establecer un precio máximo, en dólares estadounidenses (USD), con un máximo de 5 decimales. Por ejemplo, el valor 0.98765 correspondería a un precio máximo de 0,98765 USD por hora. Si establece el precio máximo en -1, la instancia no se expulsará según el precio. Siempre que haya capacidad y cuota disponibles, el precio de la instancia será el menor entre el precio actual de una instancia Spot y el de una instancia estándar.

Pasos siguientes

En este artículo ha aprendido a agregar un grupo de nodos de Spot a un clúster de AKS. Para más información sobre cómo controlar pods en grupos de nodos, consulte Procedimientos recomendados para las características avanzadas del programador en AKS.