Gerenciar pools de nós para um cluster do Serviço de Kubernetes do Azure (AKS)

No AKS (Serviço de Kubernetes do Azure), os nós da mesma configuração são agrupados em pools de nós. Esses pools de nós contêm as VMs subjacentes que executam seus aplicativos. Ao criar um cluster do AKS, você define o número inicial de nós e seu tamanho (SKU). Conforme as demandas dos aplicativos são alteradas, talvez seja necessário alterar as configurações dos pools de nós. Por exemplo, talvez seja necessário escalar o número de nós em um pool de nós ou atualizar a versão do Kubernetes de um pool de nós.

Este artigo mostra como gerenciar um ou mais pools de nós em um cluster do AKS.

Antes de começar

Limitações

As seguintes limitações se aplicam quando você cria e gerencia clusters do AKS com suporte a vários pools de nós:

  • Confira Cotas, restrições de tamanho de máquina virtual e disponibilidade de região no AKS (Serviço de Kubernetes do Azure).
  • Os pools do sistema devem conter pelo menos um nó, e os pools de nós de usuários podem conter zero ou mais nós.
  • Você não pode alterar o tamanho da VM de um pool de nós depois de criá-la.
  • Quando você cria vários pools de nós no momento da criação do cluster, todas as versões do Kubernetes utilizadas pelos pools de nós devem corresponder à versão definida para o plano de controle. Você pode fazer atualizações depois de provisionar o cluster utilizando as operações de pool por nó.
  • Não é possível executar simultaneamente operações de upgrade e dimensionamento em um cluster ou pool de nós. Se você tentar executá-las ao mesmo tempo, receberá um erro. Cada tipo de operação deve ser concluído no recurso de destino antes da próxima solicitação nesse mesmo recurso. Para obter mais informações, confira o guia de solução de problemas.

Fazer upgrade de um pool de nós únicos

Observação

A versão de imagem do sistema operacional do pool de nós está vinculada à versão do Kubernetes do cluster. Você só obterá atualizações de imagem do sistema operacional após uma atualização de cluster.

Neste exemplo, atualizamos o pool de nós mynodepool. Como existem dois pools de nós, devemos utilizar o comando az aks nodepool upgrade para fazer upgrade.

  1. Verifique se há atualizações disponíveis utilizando o comando az aks get-upgrades.

    az aks get-upgrades --resource-group myResourceGroup --name myAKSCluster
    
  2. Faça upgrade do pool de nós mynodepool utilizando o comando az aks nodepool upgrade.

    az aks nodepool upgrade \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --name mynodepool \
        --kubernetes-version KUBERNETES_VERSION \
        --no-wait
    
  3. Liste o status dos seus pools de nós utilizando o comando az aks nodepool list.

    az aks nodepool list -g myResourceGroup --cluster-name myAKSCluster
    

    A saída do exemplo a seguir mostra que mynodepool está no estado Atualizando:

    [
      {
        ...
        "count": 3,
        ...
        "name": "mynodepool",
        "orchestratorVersion": "KUBERNETES_VERSION",
        ...
        "provisioningState": "Upgrading",
        ...
        "vmSize": "Standard_DS2_v2",
        ...
      },
      {
        ...
        "count": 2,
        ...
        "name": "nodepool1",
        "orchestratorVersion": "1.15.7",
        ...
        "provisioningState": "Succeeded",
        ...
        "vmSize": "Standard_DS2_v2",
        ...
      }
    ]
    

    Leva alguns minutos para atualizar os nós para a versão especificada.

Como melhor prática, você deve atualizar todos os pools de nós em um cluster do AKS para a mesma versão do Kubernetes. O comportamento padrão do az aks upgrade é atualizar todos os pools de nós, juntamente com o plano de controle, para alcançar esse alinhamento. A capacidade de atualizar pools de nós individuais permite realizar uma atualização contínua e agendar pods entre pools de nós para manter o tempo de atividade do aplicativo dentro das restrições mencionadas acima.

Atualizar um plano de controle de cluster com vários pools de nós

Observação

O Kubernetes usa o esquema de controle de versão semântico padrão. O número de versão é expresso como x.y.z, em que x é a versão principal, y é a versão secundária e z é a versão do patch. Por exemplo, na versão 1.12.6, 1 é a versão principal, 12 é a versão secundária e 6 é a versão do patch. A versão do Kubernetes do plano de controle e o pool de nós inicial são definidos durante a criação do cluster. A versão do Kubernetes de todos os pools de nós adicionais é definida quando eles são adicionados ao cluster. As versões do Kubernetes podem diferir entre os pools de nós e entre um pool de nós e o plano de controle.

Um cluster do AKS tem dois objetos de recursos de cluster com versões do Kubernetes associadas a eles:

  1. A versão do Kubernetes do plano de controle do cluster e
  2. Um pool de nós com uma versão do Kubernetes.

O plano de controle é mapeado para um ou vários pools de nós. O comportamento de uma operação de atualização depende do comando da CLI do Azure que você utilizar.

  • az aks upgrade atualiza o plano de controle e todos os pools de nós no cluster para a mesma versão do Kubernetes.
  • az aks upgrade com o sinalizador --control-plane-only atualiza apenas o plano de controle do cluster e deixa todos os pools de nós inalterados.
  • az aks nodepool upgrade atualiza apenas o pool de nós de destino com a versão especificada do Kubernetes.

Regras de validação para atualizações

As atualizações do Kubernetes para um plano de controle de cluster e pools de nós são validadas utilizando os seguintes conjuntos de regras:

  • Regras para versões válidas para atualizar pools de nós:

    • A versão do pool de nós deve ter a mesma versão principal que o plano de controle.
    • A versão secundária do pool de nós deve estar dentro de duas versões secundárias da versão do plano de controle.
    • A versão do pool de nós não pode ser posterior à versão major.minor.patch de controle.
  • Regras para o envio de uma operação de upgrade:

    • Não é possível fazer downgrade do plano de controle ou de uma versão do Kubernetes do pool de nós.
    • Se uma versão do Kubernetes do pool de nós não for especificada, o comportamento dependerá do cliente. Nos modelos do Resource Manager, a declaração volta para a versão existente definida para o pool de nós. Se nada for definido, ele utilizará a versão do plano de controle para fazer o fallback.
    • Não é possível enviar simultaneamente várias operações em um único plano de controle ou recurso de pool de nós. É possível atualizar ou dimensionar um plano de controle ou um pool de nós em um determinado tempo.

Dimensionar um pool de nós manualmente

À medida que as demandas de carga de trabalho do aplicativo mudam, talvez seja necessário dimensionar o número de nós em um pool de nós. O número de nós pode ser aumentado ou reduzido.

  1. Escale o número de nós em um pool de nós utilizando o comando az aks node pool scale.

    az aks nodepool scale \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --name mynodepool \
        --node-count 5 \
        --no-wait
    
  2. Liste o status dos seus pools de nós utilizando o comando az aks node pool list.

    az aks nodepool list -g myResourceGroup --cluster-name myAKSCluster
    

    O exemplo de saída a seguir mostra que mynodepool está no estado Colocação em escala com uma nova contagem de cinco nós:

    [
      {
        ...
        "count": 5,
        ...
        "name": "mynodepool",
        "orchestratorVersion": "1.15.7",
        ...
        "provisioningState": "Scaling",
        ...
        "vmSize": "Standard_DS2_v2",
        ...
      },
      {
        ...
        "count": 2,
        ...
        "name": "nodepool1",
        "orchestratorVersion": "1.15.7",
        ...
        "provisioningState": "Succeeded",
        ...
        "vmSize": "Standard_DS2_v2",
        ...
      }
    ]
    

    Leva alguns minutos para que a operação de dimensionamento seja concluída.

Escalar um pool de nós específico automaticamente utilizando o dimensionador automático do cluster

O AKS oferece um recurso separado para dimensionar automaticamente os pools de nós com um recurso chamado de dimensionador automático de cluster. Você pode habilitar esse recurso com contagens de escalas mínimas e máximas exclusivas por pool de nós.

Para obter mais informações, confira utilizar o dimensionador automático do cluster.

Associar grupos de reserva de capacidade a pools de nós

À medida que as demandas de carga de trabalho são alteradas, é possível associar grupos de reserva de capacidade existentes a pools de nós para garantir a capacidade alocada para os pools de nós.

Pré-requisitos para uso de grupos de reserva de capacidade com o AKS

  • Use a CLI versão 2.56 ou superior e a API versão 2023-10-01 ou superior.

  • O grupo de reserva de capacidade já deve existir e conter, no mínimo, uma reserva de capacidade, caso contrário o pool de nós será adicionado ao cluster com um aviso e nenhum grupo de reserva de capacidade será associado. Para obter mais informações, confira grupos de reserva de capacidade.

  • Você precisa criar uma identidade gerenciada atribuída pelo usuário para o grupo de recursos que contém o CRG (grupo de reserva de capacidade). As identidades gerenciadas atribuídas pelo sistema não funcionarão para esse recurso. No exemplo a seguir, substitua as variáveis de ambiente por valores próprios.

    IDENTITY_NAME=myID
    RG_NAME=myResourceGroup
    CLUSTER_NAME=myAKSCluster
    VM_SKU=Standard_D4s_v3
    NODE_COUNT=2
    LOCATION=westus2
    az identity create --name $IDENTITY_NAME --resource-group $RG_NAME  
    IDENTITY_ID=$(az identity show --name $IDENTITY_NAME --resource-group $RG_NAME --query identity.id -o tsv)
    
  • Você precisa atribuir a função Contributor à identidade atribuída pelo usuário criada acima. Para obter mais detalhes, confira Etapas para atribuir uma função do Azure.

  • Crie um cluster e atribua a identidade recém-criada.

      az aks create --resource-group $RG_NAME --name $CLUSTER_NAME --location $LOCATION \
          --node-vm-size $VM_SKU --node-count $NODE_COUNT \
          --assign-identity $IDENTITY_ID --enable-managed-identity         
    
  • Você também pode atribuir a identidade gerenciada pelo usuário em um cluster gerenciado existente com o comando update.

      az aks update --resource-group $RG_NAME --name $CLUSTER_NAME --location $LOCATION \
              --node-vm-size $VM_SKU --node-count $NODE_COUNT \
              --assign-identity $IDENTITY_ID --enable-managed-identity         
    

Associar um grupo de reserva de capacidade existente a um pool de nós

Associe um grupo de reserva de capacidade existente a um pool de nós usando o comando az aks nodepool add e especifique um grupo de reserva de capacidade com o sinalizador --crg-id. O exemplo a seguir pressupõe que você tenha um CRG chamado “myCRG”.

RG_NAME=myResourceGroup
CLUSTER_NAME=myAKSCluster
NODEPOOL_NAME=myNodepool
CRG_NAME=myCRG
CRG_ID=$(az capacity reservation group show --capacity-reservation-group $CRG_NAME --resource-group $RG_NAME --query id -o tsv)
az aks nodepool add --resource-group $RG_NAME --cluster-name $CLUSTER_NAME --name $NODEPOOL_NAME --crg-id $CRG_ID

Associar um grupo de reserva de capacidade existente a um pool de nós do sistema

Para associar um grupo de reserva de capacidade existente a um pool de nós do sistema, associe o cluster à identidade atribuída pelo usuário à função Colaborador no CRG e ao próprio CRG durante a criação do cluster. Use o comando az aks create com os sinalizadores --assign-identity e --crg-id.

IDENTITY_NAME=myID
RG_NAME=myResourceGroup
CLUSTER_NAME=myAKSCluster
NODEPOOL_NAME=myNodepool
CRG_NAME=myCRG
CRG_ID=$(az capacity reservation group show --capacity-reservation-group $CRG_NAME --resource-group $RG_NAME --query id -o tsv)
IDENTITY_ID=$(az identity show --name $IDENTITY_NAME --resource-group $RG_NAME --query identity.id -o tsv)
az aks create --resource-group $RG_NAME --cluster-name $CLUSTER_NAME --crg-id $CRG_ID --assign-identity $IDENTITY_ID --enable-managed-identity

Observação

Excluir um pool de nós dissocia implicitamente esse pool de nós de qualquer grupo de reserva de capacidade associado antes que o pool de nós seja excluído. Excluir um cluster dissocia implicitamente todos os pools de nós desse cluster de seus grupos de reserva de capacidade associados.

Observação

Não é possível atualizar um pool de nós existente com um grupo de reserva de capacidade. A abordagem recomendada é associar um grupo de reserva de capacidade durante a criação do pool de nós.

Especificar um tamanho de VM para um pool de nós

Talvez seja necessário criar pools de nós com diferentes tamanhos e recursos de VM. Por exemplo, você pode criar um pool de nós que contenha nós com grandes quantidades de CPU ou memória ou um pool de nós que dê suporte a GPU. Na próxima seção, utilize taints e tolerâncias para informar ao agendador do Kubernetes como limitar o acesso aos pods que podem ser executados nesses nós.

No exemplo a seguir, criamos um pool de nós baseado em GPU que usa o tamanho da VM Standard_NC6s_v3. Essas VMs são alimentadas pelo cartão NVIDIA Tesla K80. Para obter informações, confira Tamanhos disponíveis para as máquinas virtuais do Linux no Azure.

  1. Crie um pool de nós utilizando o comando az aks node pool add. Especifique o nome gpunodepool e utilize o parâmetro --node-vm-size para especificar o tamanho Standard_NC6.

    az aks nodepool add \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --name gpunodepool \
        --node-count 1 \
        --node-vm-size Standard_NC6s_v3 \
        --no-wait
    
  2. Verifique o status do pool de nós utilizando o comando az aks nodepool list.

    az aks nodepool list -g myResourceGroup --cluster-name myAKSCluster
    

    A saída do exemplo a seguir mostra que o pool de nós gpunodepool está Criando nós com o VmSize especificado:

    [
      {
        ...
        "count": 1,
        ...
        "name": "gpunodepool",
        "orchestratorVersion": "1.15.7",
        ...
        "provisioningState": "Creating",
        ...
        "vmSize": "Standard_NC6s_v3",
        ...
      },
      {
        ...
        "count": 2,
        ...
        "name": "nodepool1",
        "orchestratorVersion": "1.15.7",
        ...
        "provisioningState": "Succeeded",
        ...
        "vmSize": "Standard_DS2_v2",
        ...
      }
    ]
    

    Leva alguns minutos para que o gpunodepool seja criado com sucesso.

Especificar um taint, um rótulo ou uma marca para um pool de nós

Ao criar um pool de nós, você pode adicionar taints, rótulos ou marcas a ele. Quando você adiciona um taint, um rótulo ou uma marca, todos os nós nesse pool de nós também recebem esse taint, esse rótulo ou essa marca.

Importante

A adição de taints, rótulos ou marcas a nós deve ser feita para o pool de nós inteiro usando az aks nodepool. Não recomendamos utilizar kubectl para aplicar taints, rótulos ou marcas a nós individuais em um pool de nós.

Definir os taints do pool de nós

  1. Criar um pool de nós com uma mancha utilizando o comando az aks nodepool add. Especifique o nome taintnp e use o parâmetro --node-taints para especificar sku=gpu:NoSchedule para o taint.

    az aks nodepool add \
        --resource-group myResourceGroup \
        --cluster-name myAKSCluster \
        --name taintnp \
        --node-count 1 \
        --node-taints sku=gpu:NoSchedule \
        --no-wait
    
  2. Verifique o status do pool de nós utilizando o comando az aks nodepool list.

    az aks nodepool list -g myResourceGroup --cluster-name myAKSCluster
    

    A saída do exemplo a seguir mostra que o pool de nós taintnp está Criando nós com os nodeTaints especificados:

    [
      {
        ...
        "count": 1,
        ...
        "name": "taintnp",
        "orchestratorVersion": "1.15.7",
        ...
        "provisioningState": "Creating",
        ...
        "nodeTaints":  [
          "sku=gpu:NoSchedule"
        ],
        ...
      },
     ...
    ]
    

As informações do taint ficam visíveis no Kubernetes para identificar as regras de agendamento para nós. O Agendador Kubernetes pode usar taints e tolerations para restringir quais cargas de trabalho podem ser executados em nós.

  • Um taint é aplicado a um nó que indica que apenas os pods específicos podem ser agendados neles.
  • Um toleration, em seguida, é aplicado a um pod que lhes permite tolerar um taint de nó.

Para obter mais informações sobre como usar os recursos avançados agendados do Kubernetes, confira Melhores práticas para recursos avançados do agendador no AKS

Definir as tolerâncias do pool de nós

Na etapa anterior, você aplicou o taint sku=gpu:NoSchedule ao criar o pool de nós. O exemplo de manifesto YAML a seguir utiliza uma tolerância para permitir que o agendador do Kubernetes execute um pod NGINX em um nó nesse pool de nós.

  1. Crie um arquivo chamado nginx-toleration.yaml e copie-o no YAML de exemplo a seguir.

    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      containers:
     - image: mcr.microsoft.com/oss/nginx/nginx:1.15.9-alpine
        name: mypod
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 1
            memory: 2G
      tolerations:
     - key: "sku"
        operator: "Equal"
        value: "gpu"
        effect: "NoSchedule"
    
  2. Agende o pod utilizando o comando kubectl apply.

    kubectl apply -f nginx-toleration.yaml
    

    Leva alguns segundos para agendar o pod e efetuar pull da imagem NGINX.

  3. Verifique o status utilizando o comando kubectl describe pod.

    kubectl describe pod mypod
    

    A saída de exemplo condensada a seguir mostra que o toleration sku=gpu:NoSchedule foi aplicado. Na seção de eventos, o agendador atribuiu o pod ao nó aks-taintnp-28993262-vmss000000:

    [...]
    Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                     node.kubernetes.io/unreachable:NoExecute for 300s
                     sku=gpu:NoSchedule
    Events:
      Type    Reason     Age    From                Message
      ----    ------     ----   ----                -------
      Normal  Scheduled  4m48s  default-scheduler   Successfully assigned default/mypod to aks-taintnp-28993262-vmss000000
      Normal  Pulling    4m47s  kubelet             pulling image "mcr.microsoft.com/oss/nginx/nginx:1.15.9-alpine"
      Normal  Pulled     4m43s  kubelet             Successfully pulled image "mcr.microsoft.com/oss/nginx/nginx:1.15.9-alpine"
      Normal  Created    4m40s  kubelet             Created container
      Normal  Started    4m40s  kubelet             Started container
    

    Somente os pods que têm esse toleration aplicado podem ser agendados nos nós em taintnp. Quaisquer outros pods são agendados no pool de nós nodepool1. Se você criar pools de nós adicionais, pode usar outros taints e tolerâncias para limitar quais pods podem ser agendados nesses recursos de nó.

Configurar rótulos do pool de nós

Para obter mais informações, confira Utilizar rótulos em um cluster do Serviço de Kubernetes do Azure (AKS).

Configurar marcas do Azure do pool de nós

Para obter mais informações, confira Utilizar marcas do Azure no Serviço de Kubernetes do Azure (AKS).

Gerenciar pools de nós usando um modelo do ARM

Ao utilizar um modelo do Azure Resource Manager para criar e gerenciar recursos, você pode alterar as configurações no modelo e reimplantá-lo para atualizar os recursos. Com os pools de nós do AKS, não é possível atualizar o perfil inicial do pool de nós depois que o cluster do AKS tiver sido criado. Esse comportamento significa que você não pode atualizar um modelo existente do Resource Manager, fazer alterações nos pools de nós e, em seguida, reimplantar o modelo. Em vez disso, você deve criar um modelo separado do Resource Manager que atualize os pools de nós para o cluster do AKS existente.

  1. Crie um modelo, como aks-agentpools.json, e cole o seguinte exemplo de manifesto. Verifique se os valores foram editados conforme necessário. Este modelo de exemplo define as seguintes configurações:

    • Atualiza o pool de nós do Linux denominado myagentpool para executar três nós.
    • Define os nós no pool de nós para executar o Kubernetes versão 1.15.7.
    • Define o tamanho do nó como Standard_DS2_v2.
    {
        "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
        "contentVersion": "1.0.0.0",
        "parameters": {
            "clusterName": {
                "type": "string",
                "metadata": {
                    "description": "The name of your existing AKS cluster."
                }
            },
            "location": {
                "type": "string",
                "metadata": {
                    "description": "The location of your existing AKS cluster."
                }
            },
            "agentPoolName": {
                "type": "string",
                "defaultValue": "myagentpool",
                "metadata": {
                    "description": "The name of the agent pool to create or update."
                }
            },
            "vnetSubnetId": {
                "type": "string",
                "defaultValue": "",
                "metadata": {
                    "description": "The Vnet subnet resource ID for your existing AKS cluster."
                }
            }
        },
        "variables": {
            "apiVersion": {
                "aks": "2020-01-01"
            },
            "agentPoolProfiles": {
                "maxPods": 30,
                "osDiskSizeGB": 0,
                "agentCount": 3,
                "agentVmSize": "Standard_DS2_v2",
                "osType": "Linux",
                "vnetSubnetId": "[parameters('vnetSubnetId')]"
            }
        },
        "resources": [
            {
                "apiVersion": "2020-01-01",
                "type": "Microsoft.ContainerService/managedClusters/agentPools",
                "name": "[concat(parameters('clusterName'),'/', parameters('agentPoolName'))]",
                "location": "[parameters('location')]",
                "properties": {
                    "maxPods": "[variables('agentPoolProfiles').maxPods]",
                    "osDiskSizeGB": "[variables('agentPoolProfiles').osDiskSizeGB]",
                    "count": "[variables('agentPoolProfiles').agentCount]",
                    "vmSize": "[variables('agentPoolProfiles').agentVmSize]",
                    "osType": "[variables('agentPoolProfiles').osType]",
                    "type": "VirtualMachineScaleSets",
                    "vnetSubnetID": "[variables('agentPoolProfiles').vnetSubnetId]",
                    "orchestratorVersion": "1.15.7"
                }
            }
        ]
    }
    
  2. Implante o modelo utilizando o comando az deployment group create.

    az deployment group create \
        --resource-group myResourceGroup \
        --template-file aks-agentpools.json
    

    Dica

    Você pode adicionar uma marca ao pool de nós adicionando a propriedade marca no modelo, conforme mostrado no exemplo a seguir:

    ...
    "resources": [
    {
      ...
      "properties": {
        ...
        "tags": {
          "name1": "val1"
        },
        ...
      }
    }
    ...
    

    Pode levar alguns minutos para atualizar o cluster do AKS, dependendo das configurações do pool de nós e das operações definidas no modelo do ARM.

Próximas etapas