Proteção de nó (versão prévia) em AKS (Serviço de Kubernetes do Azure)

O Node Hardening é um recurso opcional para pools de nós do Linux que protege a estabilidade do nó quando as cargas de trabalho colocam nós sob pressão de CPU, memória ou disco. Quando você habilita o Reforço de Segurança do Nó em um cluster, o AKS altera a forma como cada nó reserva e impõe recursos para componentes do Kubernetes e serviços de host e como o kubelet remove pods quando os recursos ficam escassos.

Este artigo explica quais são as alterações do Node Hardening, compara os padrões reforçados com os padrões padrão do AKS e mostra como habilitar, verificar, personalizar e desabilitar o recurso.

Importante

As funcionalidades em versão preliminar do AKS estão disponíveis de forma optativa e por autoatendimento. As versões prévias são fornecidas “no estado em que se encontram” e “conforme disponíveis” e são excluídas dos contratos de nível de serviço e da garantia limitada. As versões prévias do AKS são parcialmente cobertas pelo suporte ao cliente em uma base de melhor esforço. Dessa forma, esses recursos não são destinados ao uso em produção. Para obter mais informações, consulte os seguintes artigos:

Benefícios do Reforço de Segurança do Nó

Em nós ocupados ou com picos de carga, as cargas de trabalho podem consumir recursos de que o kubelet, o runtime do contêiner e os serviços de host precisam. Quando isso acontece, os nós podem ficar sem resposta, relatar um NotReady status ou encerrar pods abruptamente. Hardening de nó reduz esses riscos das seguintes maneiras:

  • Reservas aplicadas: Por padrão, o AKS usa valores de kube-reserved apenas para calcular quanta capacidade o agendador pode alocar para pods. Usando o Node Hardening, o kubelet também impõe as capacidades kube-reserved e system-reserved por meio de grupos de controle do Linux (cgroups). O kubelet e o containerd são executados em um cgroup dedicado kubereserved.slice, portanto, eles mantêm o compartilhamento de CPU reservado e a memória mesmo quando os pods saturam o nó.
  • Capacidade dedicada para serviços de host: o Reforço de Segurança do Nó adiciona uma alocação reservada ao sistema para serviços do sistema operacional do host, que são executados em system.slice.
  • Mais margem de memória: O limite rígido de remoção para memória disponível é dimensionado de acordo com a memória do nó, de modo que o kubelet remove pods antes que o nó atinja um nível crítico de falta de memória.
  • Remoção com carência: os limites de remoção temporária permitem que o kubelet remova pods normalmente, com um período de carência de término, quando o espaço em disco ou a memória estiverem baixos. A remoção permanente, que encerra os pods imediatamente, atua como último recurso.
  • Reservas que se dimensionam com a densidade de pods: o cálculo da memória reservada do kube aumenta com o número máximo de pods por nó, o que leva em conta a sobrecarga do kubelet e do containerd ao executar mais pods.

O que muda quando você habilita o Node Hardening

As tabelas a seguir comparam os padrões padrão para nós do Linux que executam o Kubernetes 1.29 ou posterior com os padrões que o AKS aplica quando o Node Hardening está habilitado.

Reservas de recursos

Setting Sem Reforço de Segurança do Nó Com Node Hardening
CPU reservada para Kube Com base no número de núcleos de CPU. Para obter mais informações, consulte as reservas de CPU. Inalterado
Memória reservada do Kube min(20 × maxPods + 50, 25% of node memory) MiB min(35 × maxPods + max(250, 2% of node memory), 25% of node memory) MiB
IDs de processos reservados pelo Kube 1000 Não reservado
CPU reservada ao sistema None 100m
Memória reservada do sistema None 200 MiB, mais 100 MiB para cada 32 GiB completos de memória de nó, além de 100 MiB para clusters que usam Azure CNI
Armazenamento efêmero reservado ao sistema None 1Gi

Limites de remoção

Setting Sem Reforço de Segurança do Nó Com Reforço de Segurança do Nó
Despejo forçado: memory.available 100Mi 250Mi para nós com 8 GiB de memória ou menos, 375Mi para nós com mais de 8 GiB e menos de 32 GiB, e 512Mi para nós com 32 GiB ou mais
Remoção permanente: nodefs.available e nodefs.inodesFree 10% e 5% Inalterado
Despejo forçado: pid.available 2000 Não definido
Remoção temporária: memory.available None 500Mi, 750Mi ou 1Gi, usando as mesmas camadas de memória de nó que a remoção permanente, com um período de carência de 30 segundos
Remoção temporária nodefs.available e nodefs.inodesFree None 12% e 7%, cada um com um período de carência de 2 minutos
Período máximo de carência de término do pod durante a remoção temporária Não definido 60 segundos

Imposição de cgroup

Setting Sem Reforço de Segurança do Nó Com Node Hardening
Nó imposto alocável pods pods, kube-reserved e system-reserved
Kubelet e cgroup do containerd system.slice, sem limites kubereserved.slice, com memória limitada à memória kube-reserved e um compartilhamento de CPU proporcional à CPU kube-reserved
cgroup de serviços do host system.slice, sem limites system.slice, com memória limitada à memória reservada do sistema e um compartilhamento de CPU proporcional à CPU reservada ao sistema

Como o Node Hardening reserva mais capacidade, os nós relatam menos capacidade alocável para pods. Por exemplo, em um nó com 4 vCPUs e 16 GiB de memória que usa Azure CNI, habilitar o Node Hardening reduz a capacidade alocável da seguinte maneira:

  • Com o máximo padrão de 250 pods por nó, isso representa cerca de 570 MiB de memória, 100 milicores de CPU e 1 GiB de armazenamento efêmero.
  • Com um máximo de 30 pods por nó, cerca de 1,3 GiB de memória, 100 milicores de CPU e 1 GiB de armazenamento efêmero.

Os limites de remoção temporária não reduzem a capacidade alocável. Eles só mudam quando o kubelet começa a remover pods.

Considerations

Tenha as seguintes considerações em mente antes de habilitar o Node Hardening:

  • Você habilita o Reforço de Segurança do Nó no nível do cluster, e ele se aplica a todos os pools de nós do Linux no cluster. Você não pode habilitá-lo para pools de nós individuais e isso não afeta Windows pools de nós.
  • Os nós relatam menos capacidade alocável, portanto, os pods que se encaixam em um nó antes de habilitar o Node Hardening podem não caber posteriormente. Examine as solicitações de recurso de pod e os tamanhos do pool de nós.
  • Os serviços de host system.slice compartilham um limite de memória rígido igual à memória reservada pelo sistema. Se você executar seus próprios agentes em nós como serviços do systemd, como agentes de segurança, monitoramento ou encaminhamento de logs, esses agentes serão contabilizados nesse limite. Valide o uso de memória e a estabilidade deles antes de usar o Reforço de Segurança do Nó na produção.
  • Os valores definidos na configuração personalizada do kubelet de um pool de nós substituem os padrões do Reforço de Segurança do Nó correspondentes. Para obter mais informações, consulte Personalizar as configurações de proteção de nó.
  • Se você desabilitar o Node Hardening mais tarde, os pools de nós existentes manterão as configurações reforçadas de expulsão suave, mesmo depois que seus nós forem reimageados. Para remover essas configurações, você precisa criar novos pools de nós. Para obter mais informações, consulte Desabilitar o hardening do nó.
  • Os valores padrão podem ser alterados enquanto o recurso está em versão prévia. Comece com um cluster de não produção e valide suas cargas de trabalho em condições representativas de pressão de nó.

Prerequisites

  • Uma assinatura do Azure. Se você não tiver uma, crie uma conta gratuita.
  • Um cluster do AKS com pools de nós do Linux ou permissões para criar um.
  • A aks-preview extensão CLI do Azure e o CustomNodeConfigPreview sinalizador de recurso, conforme descrito nas seções a seguir.

Instalar a extensão aks-preview CLI do Azure

  1. Instale a aks-preview extensão usando o az extension add comando.

    az extension add --name aks-preview
    
  2. Atualize para a versão mais recente da extensão usando o az extension update comando.

    az extension update --name aks-preview
    

Registrar o sinalizador de recurso CustomNodeConfigPreview

  1. Registre o sinalizador de recurso CustomNodeConfigPreview usando o comando az feature register.

    az feature register --namespace "Microsoft.ContainerService" --name "CustomNodeConfigPreview"
    

    Demora alguns minutos para o status mostrar Registrado.

  2. Verifique o status do registro usando o az feature show comando.

    az feature show --namespace "Microsoft.ContainerService" --name "CustomNodeConfigPreview"
    
  3. Quando o status mostrar Registrado, atualize o registro do provedor de recursos Microsoft.ContainerService usando o comando az provider register.

    az provider register --namespace "Microsoft.ContainerService"
    

Habilitar o Reforço de Segurança do Nó

Durante a visualização, o Node Hardening não está habilitado por padrão.

Habilitar a proteção de nó em um novo cluster

Crie um cluster com o Node Hardening habilitado usando o az aks create comando com o --enable-node-hardening parâmetro.

Esse comando requer a extensão aks-preview e o sinalizador de recurso CustomNodeConfigPreview. Para obter mais informações, veja Pré-requisitos.

az aks create \
    --resource-group <resource-group-name> \
    --name <cluster-name> \
    --enable-node-hardening \
    --generate-ssh-keys

Para confirmar a alteração, consulte Verificar as configurações de hardening do nó.

Habilitar a proteção de nó em um cluster existente

Habilite o Node Hardening em um cluster existente usando o az aks update comando com o --enable-node-hardening parâmetro.

Esse comando requer a extensão aks-preview e o sinalizador de recurso CustomNodeConfigPreview. Para obter mais informações, veja Pré-requisitos.

az aks update \
    --resource-group <resource-group-name> \
    --name <cluster-name> \
    --enable-node-hardening

Para confirmar a alteração, consulte Verificar as configurações de endurecimento do nó.

Verificar as configurações de hardening de nó

  1. Obtenha as credenciais do cluster usando o az aks get-credentials comando.

    az aks get-credentials --resource-group <resource-group-name> --name <cluster-name>
    
  2. Examine as configurações efetivas de reserva de kubelet e remoção em um nó consultando o ponto de extremidade de configuração do kubelet.

    kubectl get --raw "/api/v1/nodes/<node-name>/proxy/configz" | jq '.kubeletconfig | {kubeReserved, systemReserved, evictionHard, evictionSoft, evictionSoftGracePeriod, evictionMaxPodGracePeriod, enforceNodeAllocatable}'
    

    Em um nó com reforço de segurança, systemReserved e evictionSoft contêm valores, e enforceNodeAllocatable inclui kube-reserved e system-reserved.

  3. Compare a capacidade do nó com seus recursos alocáveis.

    kubectl get node <node-name> -o jsonpath='{.status.capacity}{"\n"}{.status.allocatable}{"\n"}'
    

    Em um nó com reforço de segurança, a CPU alocável, a memória e o armazenamento efêmero são menores que a capacidade. A diferença é igual aos valores reservados ao kube e reservados ao sistema em Reservas de recursos, além dos limites de remoção rígidos em Limites de remoção. Por exemplo, em um nó com 4 vCPUs e 16 GiB de memória que usa Azure CNI, a CPU alocável é 240 millicores menor que a capacidade: 140 millicores de CPU reservada para o kube e 100 millicores de CPU reservada para o sistema.

Personalizar configurações de hardening de nó

Você pode substituir os padrões de kube-reserved e eviction para um pool de nós do Linux usando uma configuração personalizada do kubelet. Essas configurações exigem o sinalizador de recursos CustomNodeConfigPreview. Você pode usá-los esteja o Reforço de Segurança do Nó habilitado ou não no cluster. O AKS gerencia valores reservados pelo sistema e a imposição de cgroup, e você não pode personalizá-los.

Cada configuração substitui uma linha nas tabelas Reservas de recursos ou Limites de remoção. As linhas reservadas ao Kube correspondem às configurações kubeReserved. As linhas de remoção correspondem às configurações hardEvictionThreshold. As linhas de remoção temporária correspondem às configurações softEvictionThreshold e softEvictionGracePeriod. O período máximo de tolerância para encerramento do pod corresponde a evictionMaxPodGracePeriodInSeconds.

Você pode configurar as seguintes definições:

Setting Overrides Description
kubeReserved.cpuMillicores CPU reservada para o Kube CPU reservada para daemons do sistema Kubernetes, em milicores.
kubeReserved.memoryMB Memória reservada do Kube Memória reservada para daemons do sistema kubernetes, no MiB.
hardEvictionThreshold.memoryAvailable Remoção permanente: memory.available Limite da remoção permanente para a memória disponível.
hardEvictionThreshold.nodeFsAvailable Despejo forçado: nodefs.available Limite da remoção permanente para o espaço disponível do sistema de arquivos do nó.
hardEvictionThreshold.nodeFsInodesFree Despejo forçado: nodefs.inodesFree Limite da remoção permanente para inodes livres do sistema de arquivos do nó.
softEvictionThreshold.memoryAvailable Remoção temporária: memory.available Limite da remoção temporária para a memória disponível.
softEvictionThreshold.nodeFsAvailable Remoção temporária: nodefs.available Limite da remoção temporária para o espaço disponível do sistema de arquivos do nó.
softEvictionThreshold.nodeFsInodesFree Remoção temporária: nodefs.inodesFree Limite da remoção temporária para inodes livres do sistema de arquivos do nó.
softEvictionGracePeriod.memoryAvailable Remoção temporária: período de carência de memory.available Por quanto tempo a memória disponível deve ficar abaixo de seu limite flexível antes que o kubelet remova pods.
softEvictionGracePeriod.nodeFsAvailable Remoção temporária: período de carência de nodefs.available Por quanto tempo o espaço do sistema de arquivos de nó disponível deve permanecer abaixo do limite flexível antes que o kubelet remova os pods.
softEvictionGracePeriod.nodeFsInodesFree Remoção temporária: período de carência de nodefs.inodesFree Por quanto tempo os inodes livres do sistema de arquivos do nó devem ficar abaixo do limite flexível antes que o kubelet remova os pods.
evictionMaxPodGracePeriodInSeconds Período máximo de carência de término do pod durante a remoção temporária Número máximo de segundos que o kubelet permite que os pods terminem durante uma remoção temporária.
  • Para valores, mínimos e regras de validação permitidos para cada configuração, consulte parâmetros de configuração de nó personalizado para AKS.
  • Para cada sinal de remoção, defina o limite de remoção suave e seu período de carência correspondente, e garanta que cada limite de remoção suave seja maior do que o limite de remoção rígido para o mesmo sinal.
  1. Crie um arquivo de configuração kubelet, como nodehardening-kubelet.json, com as configurações que você deseja personalizar. O exemplo a seguir define cada valor configurável. Ele define o kube-reserved como 200 millicores de CPU e 1.024 MiB de memória. Define limites de remoção permanente de 512Mi da memória disponível, 10% do espaço disponível do sistema de arquivos e 5% de inodes gratuitos. Ele define limites de remoção suave de 1Gi, 12%e 7% com períodos de carência de 30 segundos, 2 minutos e 2 minutos. Ele também define um período de tolerância máximo para encerramento do pod de 60 segundos.

    {
      "kubeReserved": {
        "cpuMillicores": 200,
        "memoryMB": 1024
      },
      "hardEvictionThreshold": {
        "memoryAvailable": "512Mi",
        "nodeFsAvailable": "10%",
        "nodeFsInodesFree": "5%"
      },
      "softEvictionThreshold": {
        "memoryAvailable": "1Gi",
        "nodeFsAvailable": "12%",
        "nodeFsInodesFree": "7%"
      },
      "softEvictionGracePeriod": {
        "memoryAvailable": "30s",
        "nodeFsAvailable": "2m",
        "nodeFsInodesFree": "2m"
      },
      "evictionMaxPodGracePeriodInSeconds": 60
    }
    
  2. Crie um pool de nós do Linux que use o arquivo de configuração usando o az aks nodepool add comando com o --kubelet-config parâmetro.

    az aks nodepool add \
        --resource-group <resource-group-name> \
        --cluster-name <cluster-name> \
        --name <node-pool-name> \
        --kubelet-config ./nodehardening-kubelet.json
    

    Você também pode usar o --kubelet-config parâmetro com o az aks create comando para aplicar a configuração ao pool de nós inicial do cluster.

Desabilitar o hardening do nó

Desabilite a Proteção de Nó usando o az aks update comando com o --disable-node-hardening parâmetro.

Esse comando requer a extensão aks-preview e a feature flag CustomNodeConfigPreview. Para obter mais informações, veja Pré-requisitos.

az aks update \
    --resource-group <resource-group-name> \
    --name <cluster-name> \
    --disable-node-hardening

Desabilitar o Node Hardening desativa a configuração no nível do cluster, mas não altera imediatamente os nós existentes. Os nós existentes mantêm todas as configurações de reforço de segurança até receberem nova imagem, por exemplo, durante uma atualização da imagem do nó. Depois que um nó é reimageado, as seguintes alterações se aplicam:

  • Revertido para os padrões do AKS: recursos Kube-reserved e system-reserved, limites de remoção permanente e imposição de cgroup. A capacidade alocável do nó aumenta consequentemente.
  • Mantido: os limites de remoção temporária, os períodos de carência de remoção temporária e o período máximo de carência de término do pod durante a remoção temporária.

Você pode definir uma configuração personalizada do kubelet somente ao criar um cluster ou pool de nós, portanto, não é possível remover as configurações de evicção leve (soft eviction) retidas de um pool de nós existente. Para removê-los, crie um novo pool de nós que remova explicitamente essa configuração, mova as cargas de trabalho para o novo pool de nós e exclua o pool de nós antigo.

  1. Crie um arquivo de configuração de kubelet, como remove-soft-eviction.json. O exemplo a seguir define cada limite de soft eviction e período de carência como uma cadeia de caracteres vazia, o que desativa a soft eviction desse sinal. Ele também define o período máximo de carência de término do pod como 0, que é o padrão do AKS padrão.

    {
      "softEvictionThreshold": {
        "memoryAvailable": "",
        "nodeFsAvailable": "",
        "nodeFsInodesFree": ""
      },
      "softEvictionGracePeriod": {
        "memoryAvailable": "",
        "nodeFsAvailable": "",
        "nodeFsInodesFree": ""
      },
      "evictionMaxPodGracePeriodInSeconds": 0
    }
    
  2. Crie um pool de nós do Linux que use o arquivo de configuração usando o az aks nodepool add comando com o --kubelet-config parâmetro.

    az aks nodepool add \
        --resource-group <resource-group-name> \
        --cluster-name <cluster-name> \
        --name <node-pool-name> \
        --kubelet-config ./remove-soft-eviction.json
    
  3. Mova suas cargas de trabalho para o novo pool de nós e exclua o pool de nós antigo. Para obter mais informações, consulte Redimensionar pools de nós no AKS.

Para confirmar as configurações em um nó, consulte Verificar configurações de hardening do nó. Nos nós do novo pool de nós, evictionSoft está vazio.