Partilhar via


Adicionar um pool de nós do Azure Spot a um cluster do Serviço Kubernetes do Azure (AKS)

Neste artigo, adiciona-se um pool secundário de nós Spot a um cluster existente do Serviço de Kubernetes (AKS) no Azure.

Um pool de nós Spot é um pool de nós suportado por um conjunto de escalas de Máquinas Virtuais Spot do Azure. Com VMs spot em seu cluster AKS, você pode aproveitar a capacidade não utilizada do Azure com economias de custos significativas. A quantidade de capacidade disponível não utilizada varia com base em muitos fatores, como tamanho do nó, região e hora do dia.

Quando você implanta um pool de nós Spot, o Azure aloca os nós Spot se houver capacidade disponível e implanta um conjunto de escala Spot que apoia o pool de nós Spot em um único domínio padrão. Não há SLA para os nós Spot. Não há garantias de alta disponibilidade. Se o Azure precisar novamente de capacidade, a infraestrutura do Azure suprimirá os nós Spot.

Os nós spot são ótimos para cargas de trabalho que podem lidar com interrupções, rescisões antecipadas ou expulsões. Por exemplo, cargas de trabalho como trabalhos de processamento em lote, ambientes de desenvolvimento e teste e grandes cargas de trabalho de computação podem ser bons candidatos para agendar em um pool de nós Spot.

Antes de começar

  • Este artigo pressupõe uma compreensão básica dos conceitos do Kubernetes e do Azure Load Balancer. Para obter mais informações, consulte Conceitos principais do Kubernetes para o Serviço Kubernetes do Azure (AKS).
  • Se não tiver uma subscrição do Azure, crie uma conta gratuita antes de começar.
  • Quando você cria um cluster para usar um pool de nós Spot, o cluster deve usar Conjuntos de Escala de Máquina Virtual para pools de nós e o balanceador de carga SKU Padrão . Você também deve adicionar outro pool de nós depois de criar seu cluster, que é abordado neste tutorial.
  • Este artigo requer que você esteja executando a CLI do Azure versão 2.14 ou posterior. Executar az --version para localizar a versão. Se precisar de instalar ou atualizar, consulte Install Azure CLI.

Limitações

As limitações a seguir se aplicam quando você cria e gerencia clusters AKS com um pool de nós Spot:

  • Um conjunto de nós Spot não pode ser um conjunto de nós padrão, podendo apenas ser utilizado como um conjunto secundário.
  • Não é possível atualizar o plano de controle e os pools de nós ao mesmo tempo. Você deve atualizá-los separadamente ou remover o pool de nós Spot para atualizar o plano de controle e os pools de nós restantes ao mesmo tempo.
  • Um pool de nós Spot deve usar Conjuntos de Escala de Máquina Virtual.
  • Não é possível alterar ScaleSetPriority ou SpotMaxPrice após a criação.
  • Ao definir SpotMaxPrice, o valor deve ser -1 ou um valor positivo com até cinco casas decimais.
  • Um pool de nós Spot tem o kubernetes.azure.com/scalesetpriority:spot rótulo, a kubernetes.azure.com/scalesetpriority=spot:NoSchedule mancha e os pods do sistema têm antiafinidade.
  • Você deve adicionar uma tolerância e afinidade correspondentes para agendar cargas de trabalho em um pool de nós Spot.

Adicionar um pool de nós Spot a um cluster AKS

Ao adicionar um pool de nós Spot a um cluster existente, é necessário que o cluster tenha vários pools de nós ativados. Ao criar um cluster AKS com vários pools de nós ativados, cria-se um pool de nós com um priority de Regular por padrão. Para adicionar um pool de nós Spot, você deve especificar Spot como o valor de priority. Para obter mais detalhes sobre como criar um cluster AKS com vários pools de nós, consulte Usar vários pools de nós.

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

No comando anterior, o priority de Spot transforma o pool de nós num pool Spot. O eviction-policy parâmetro é definido como Delete, que é o valor padrão. Quando você define a política de remoção como Delete, os nós no conjunto de escala subjacente do pool de nós são excluídos quando são removidos.

Você também pode definir a política de despejo como Deallocate, o que significa que os nós no conjunto de escala subjacente são definidos para o estado parado-desalocado após o despejo. Os nós no estado de desalocação interrompida contam em relação à sua cota de computação e podem causar problemas com o dimensionamento ou atualização do cluster. Os valores priority e eviction-policy só podem ser definidos durante a criação do pool de nós. Esses valores não podem ser atualizados posteriormente.

O comando anterior também habilita o autoscaler de cluster, que recomendamos usar com pools de nós spot. Com base nas cargas de trabalho em execução no cluster, o autoscaler do cluster dimensiona o número de nós para cima e para baixo. Para pools de nós spot, o escalador automático do cluster aumentará o número de nós após um despejo, caso ainda sejam necessários mais nós. Se você alterar o número máximo de nós que um pool de nós pode ter, também precisará ajustar o maxCount valor associado ao autoscaler de cluster. Se não utilizar um dimensionador automático de cluster, após o despejo, o pool de spot acabará por diminuir para 0 e exigirá intervenção manual para receber quaisquer nós de spot adicionais.

Importante

Agende apenas cargas de trabalho em pools de nós Spot que possam lidar com interrupções, como trabalhos de processamento em lote e ambientes de teste. Recomendamos que configure restrições e tolerâncias no seu pool de nós Spot para garantir que apenas cargas de trabalho capazes de lidar com remoções de instância sejam agendadas num pool de nós Spot. Por exemplo, o comando acima adiciona uma mancha de kubernetes.azure.com/scalesetpriority=spot:NoSchedule, portanto, apenas pods com uma tolerância correspondente são agendados neste nó.

Verificar o pool de nós Spot

  • Verifique se o pool de nós foi adicionado usando o comando az aks nodepool show e confirme que scaleSetPriority seja 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 um pod para executar no nó Spot

Para programar um pod para ser executado em um nó Spot, você pode adicionar uma tolerância e afinidade de nó que corresponda à marcação aplicada ao seu nó Spot.

O exemplo a seguir mostra uma parte de um arquivo YAML que define uma tolerância correspondente à kubernetes.azure.com/scalesetpriority=spot:NoSchedule mancha e uma afinidade de nó correspondente ao kubernetes.azure.com/scalesetpriority=spot rótulo usado na etapa anterior com requiredDuringSchedulingIgnoredDuringExecution e preferredDuringSchedulingIgnoredDuringExecution regras de afinidade de nó:

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

Quando você implanta um pod com essa tolerância e afinidade de nós, o Kubernetes agenda com êxito o pod nos nós com a mancha e o rótulo aplicados. Neste exemplo, aplicam-se as seguintes regras:

  • O nó deve ter uma etiqueta com a chave kubernetes.azure.com/scalesetpriority, e o valor dessa etiqueta deve ser spot.
  • O nó de preferência tem um rótulo com a chave another-node-label-key, e o valor desse rótulo deve ser another-node-label-value.

Para obter mais informações, consulte Atribuindo pods a nós.

Atualizar um pool de nós Spot

Quando você atualiza um pool de nós Spot, o AKS emite internamente um cordão e um aviso de despejo, mas nenhum dreno é aplicado. Não há nós de expansão disponíveis para atualizações do pool de nós Spot. À exceção dessas alterações, o comportamento ao atualizar pools de nós Spot é consistente com o de outros tipos de pool de nós.

Para obter mais informações sobre atualização, consulte Atualizar um cluster AKS.

Preço máximo para uma piscina Spot

O preço das instâncias spot é variável, com base na região e na SKU. Para obter mais informações, consulte informações de preços para Linux e Windows.

Com preços variáveis, você tem a opção de definir um preço máximo, em dólares americanos (USD), usando até cinco casas decimais. Por exemplo, o valor 0,98765 seria um preço máximo de $0,98765 USD por hora. Se você definir o preço máximo como -1, a instância não será removida com base no preço. Enquanto houver capacidade e cota disponíveis, o preço da instância será o mais baixo entre o preço atual de uma instância Spot e o de uma instância padrão.

Próximos passos

Neste artigo, você aprendeu como adicionar um pool de nós Spot a um cluster AKS. Para obter mais informações sobre como controlar pods em pools de nós, consulte Práticas recomendadas para funcionalidades avançadas do agendador no AKS.