Práticas recomendadas para os recursos do agendador avançado no Serviço de Kubernetes do Azure (AKS)

À medida que você gerencia clusters no Serviço de Kubernetes do Azure (AKS), geralmente é necessário isolar equipes e cargas de trabalho. Os recursos avançados fornecidos pelo Agendador do Kubernetes permitem que você controle:

  • Quais pods podem ser agendados em determinados nós.
  • Como os aplicativos multipod podem ser distribuídos adequadamente pelo cluster.

Este artigo sobre práticas recomendadas se concentra em recursos de agendamento de Kubernetes avançados para os operadores do cluster. Neste artigo, você aprenderá como:

  • Use taints ou tolerations para limitar quais pods podem ser agendados nos nós.
  • Dê preferência ao pods para executar em determinados nós com seletores ou afinidade de nó.
  • Separe ou agrupe os pods com ou sem afinidade entre os pods.
  • Restrinja o agendamento de cargas de trabalho que exigem GPUs somente em nós com GPUs programáveis.

Fornecer nós dedicados usando taints e tolerations

Orientação de melhor prática:

Limite o acesso para aplicativos com uso intensivo de recursos, como controladores de entrada, a nós específicos. Manter os recursos de nó disponíveis para cargas de trabalho os exigem e não permitir o agendamento de outras cargas de trabalho em nós.

Quando você cria um cluster do AKS, você pode implantar nós com suporte de GPU ou um grande número de CPUs avançadas. Para obter mais informações, confira Usar GPUs no AKS. Você pode usar esses nós para cargas de trabalho de processamento de dados grandes, como ML (aprendizado de máquina) ou IA (inteligência artificial).

Como esse tipo de hardware geralmente é um recurso de nó caro de implantar, limite as cargas de trabalho que podem ser agendadas nesses nós. Como alternativa, convém dedicar alguns nós do cluster para executar serviços de entrada e impedir outras cargas de trabalho.

Esse suporte para nós diferentes é fornecido usando vários pools de nó. Um cluster do AKS dá suporte a um ou mais pools de nós.

O Agendador do Kubernetes usa taints e tolerations para restringir quais cargas de trabalho podem ser executadas nos nós.

  • Aplique um taint a um nó para indicar que apenas pods específicos podem ser programados nele.
  • Em seguida, aplique uma toleration a um pod, permitindo que ele tolere seu taint.

Quando você implanta um pod em um cluster do AKS, o Kubernetes apenas agenda pods em nós em que um taint está alinhado com a toleration. Taints e tolerâncias funcionam juntos para garantir que os pods não sejam agendados em nós inadequados. Um ou mais taints são aplicados a um nó, marcando o nó para que não aceite pods que não toleram taints.

Por exemplo, suponha que você tem um pool de nós no cluster do AKS para nós com suporte a GPU. Você define o nome, como gpu, em seguida, um valor para o agendamento. Definir esse valor como NoSchedule impede o Agendador do Kubernetes de agendar pods com toleration indefinida no nó.

az aks nodepool add \
    --resource-group myResourceGroup \
    --cluster-name myAKSCluster \
    --name taintnp \
    --node-taints sku=gpu:NoSchedule \
    --no-wait

Com um taint aplicado aos nós no pool de nós, você define uma tolerância na especificação do pod que permite o agendamento nos nós. O seguinte exemplo define o sku: gpu e effect: NoSchedule para tolerar o taint aplicado ao nó na etapa anterior:

kind: Pod
apiVersion: v1
metadata:
  name: tf-mnist
spec:
  containers:
  - name: tf-mnist
    image: mcr.microsoft.com/azuredocs/samples-tf-mnist-demo:gpu
    resources:
      requests:
        cpu: 0.5
        memory: 2Gi
      limits:
        cpu: 4.0
        memory: 16Gi
  tolerations:
  - key: "sku"
    operator: "Equal"
    value: "gpu"
    effect: "NoSchedule"

Quando esse pod é implantado usando kubectl apply -f gpu-toleration.yaml, o Kubernetes pode agendar com êxito o pod nos nós com o taint aplicado. Esse isolamento lógico permite que você controle o acesso a recursos dentro de um cluster.

Ao aplicar taints, trabalhe com seus desenvolvedores de aplicativos e proprietários para permitir que definam os tolerations necessários em suas implantações.

Para obter mais informações sobre como usar diversos pools de nós no AKS, confira Criar vários pools de nós para um cluster no AKS.

Comportamento de taints e tolerations no AKS

Quando você atualiza um pool de nós no AKS, os taints e tolerations seguem um padrão definido à medida que são aplicados a novos nós:

Clusters padrão que usam os Conjuntos de Dimensionamento de Máquinas Virtuais do Azure

Você pode aplicar um taint a um pool de nós por meio da API do AKS para que os nós escalados horizontalmente recebam os taints do nó especificado da API.

Imagine o seguinte cenário:

  1. Você começa com um cluster de dois nós: nó1 e nó2.
  2. Você atualiza o pool de nós.
  3. Dois outros nós são criados: nó3 e nó4.
  4. Os taints são transmitidos respectivamente.
  5. O node1 e o node2 originais são excluídos.

Clusters sem suporte aos Conjuntos de Dimensionamento de Máquinas Virtuais

Novamente, imagine o cenário:

  1. Você tem um cluster de dois nós: nó1 e nó2.
  2. Você atualiza o pool de nós.
  3. Um nó adicional é criado: nó3.
  4. Os taints do nó1 são aplicados ao nó3.
  5. O nó1 é excluído.
  6. Um novo nó1 é criado para substituir o nó1 original.
  7. Os taints do nó2 são aplicados ao novo nó1.
  8. O nó2 é excluído.

Basicamente, o nó1 se torna o nó3e o nó2 se torna o novo nó1.

Quando você dimensiona um pool de nós no AKS, os taints e tolerâncias não são transportados por design.

Controle o agendando de pod usando os seletores de nó e afinidade

Orientação de melhor prática

Controle o agendamento de pods em nós usando seletores de nó, afinidade de nó ou afinidade entre pods. Essas configurações permitem que o agendador Kubernetes isole logicamente cargas de trabalho, como pelo hardware no nó.

Os taints e as tolerations isolam logicamente os recursos com uma separação rígida. Se o pod não tolerar o taint de um nó, ele não será agendado no nó.

Como alternativa, você pode usar seletores de nó. Por exemplo, você rotula os nós para indicar o armazenamento SSD localmente anexado ou uma grande quantidade de memória e, em seguida, define na especificação de pod um seletor de nó. O Kubernetes agenda os pods em um nó correspondente.

Ao contrário de tolerations, pods sem um seletor de nó correspondente ainda podem ser agendados em nós rotulados. Esse comportamento permite que recursos não utilizados nos nós sejam consumidos, mas prioriza os pods que definem o seletor de nó correspondente.

Vamos examinar um exemplo de nós com uma grande quantidade de memória. Esses nós priorizam pods que requerem uma grande quantidade de memória. Para garantir que os recursos não fiquem ociosos, eles também permitem que outros pods sejam executados. O comando de exemplo a seguir adiciona um pool de nós com o rótulo hardware=highmem ao myAKSCluster no myResourceGroup. Todos os nós nesse pool de nós têm esse rótulo.

az aks nodepool add \
    --resource-group myResourceGroup \
    --cluster-name myAKSCluster \
    --name labelnp \
    --node-count 1 \
    --labels hardware=highmem \
    --no-wait

Uma especificação de pod, em seguida, adiciona a nodeSelector propriedade para definir um seletor de nó que corresponde ao rótulo definido em um nó:

kind: Pod
apiVersion: v1
metadata:
  name: tf-mnist
spec:
  containers:
  - name: tf-mnist
    image: mcr.microsoft.com/azuredocs/samples-tf-mnist-demo:gpu
    resources:
      requests:
        cpu: 0.5
        memory: 2Gi
      limits:
        cpu: 4.0
        memory: 16Gi
  nodeSelector:
      hardware: highmem

Ao usar essas opções de agendador, trabalhe com seus desenvolvedores de aplicativos e proprietários para permitir que eles definam corretamente as especificações de pod.

Para obter mais informações sobre o uso de seletores de nó, consulte Atribuir Pods a Nós.

Afinidade de nó

Um seletor de nó é uma solução básica para atribuir pods a determinado nó. A afinidade de nó fornece mais flexibilidade, permitindo que você defina o que acontecerá se o pod não puder ser combinado com um nó. Você pode:

  • Exigir que o Agendador do Kubernetes combine um pod com um host rotulado. Ou,
  • Preferir uma combinação, mas permitir que o pod seja agendado em um host diferente, caso a combinação não esteja disponível.

O exemplo a seguir define a afinidade de nó para requiredDuringSchedulingIgnoredDuringExecution. Este afinidade exige o agendamento de Kubernetes para usar um nó com um rótulo correspondente. Se nenhum nó estiver disponível, o pod precisa esperar o agendamento para continuar. Para permitir que o pod seja agendado em um nó diferente, você pode definir o valor para preferred DuringSchedulingIgnoreDuringExecution:

kind: Pod
apiVersion: v1
metadata:
  name: tf-mnist
spec:
  containers:
  - name: tf-mnist
    image: mcr.microsoft.com/azuredocs/samples-tf-mnist-demo:gpu
    resources:
      requests:
        cpu: 0.5
        memory: 2Gi
      limits:
        cpu: 4.0
        memory: 16Gi
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: hardware
            operator: In
            values:
            - highmem

A parte IgnoredDuringExecution da configuração indica que o pod não deverá ser removido do nó se os rótulos do nó mudarem. O agendador Kubernetes usa apenas os rótulos de nó atualizado para novos pods serem agendados, não os pods já agendados em nós.

Para obter mais informações, consulte Afinidade e antiafinidade.

Afinidade entre pods e antiafinidade

Uma abordagem final para o agendador Kubernetes isolar logicamente as cargas de trabalho está usando a afinidade entre pods ou antiafinidade. Essas configurações definem que os pods não devem ou devem ser agendados em um nó que tem um pod correspondente existente. Por padrão, o agendador Kubernetes tenta agendar vários pods em uma réplica definida entre os nós. Você pode definir regras mais específicas alternativas para esse comportamento.

Um bom exemplo é um aplicativo Web que também usa um Cache do Azure para Redis.

  • Use regras antiafinidade de pod para solicitar que o Agendador do Kubernetes distribua réplicas entre os nós.
  • Use regras de afinidade para garantir que cada componente do aplicativo Web seja planejado no mesmo host que um cache correspondente.

A distribuição de pods entre nós é semelhante ao exemplo a seguir:

Nó 1 Nó 2 Nó 3
webapp-1 webapp-2 webapp-3
cache-1 cache-2 cache-3

A antiafinidade e a afinidade entre pods fornecem uma implantação mais complexa do que os seletores de nó ou a afinidade de nó. Com a implantação, você isola logicamente os recursos e controla como o Kubernetes agenda pods em nós.

Para um exemplo completo deste aplicativo web com o Cache do Azure para Redis, consulte Colocar pods no mesmo nó.

Próximas etapas

Este artigo se concentra nos recursos avançados de agendador Kubernetes. Para obter mais informações sobre operações de cluster no AKS, consulte as seguintes práticas recomendadas: