This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Pods

Pods são as menores unidades computacionais implantáveis que você pode criar e gerenciar no Kubernetes.

Um Pod é um grupo de um ou mais contêineres, com recursos de armazenamento e rede compartilhados e uma especificação de como executar os contêineres. O conteúdo de um Pod é sempre colocalizado e coalocado, e executado em um contexto compartilhado. Um Pod modela um "host lógico" específico da aplicação: ele contém um ou mais contêineres de aplicação que são relativamente fortemente acoplados. Em contextos fora da nuvem, aplicações executadas na mesma máquina física ou virtual são análogas a aplicações em nuvem executadas no mesmo host lógico.

Além dos contêineres de aplicação, um Pod pode conter contêineres de inicialização que são executados durante a inicialização do Pod. Você também pode injetar contêineres efêmeros para depurar um Pod em execução.

O que é um Pod?

O contexto compartilhado de um Pod é um conjunto de namespaces do Linux, cgroups e potencialmente outras facetas de isolamento - as mesmas coisas que isolam um contêiner. Dentro do contexto de um Pod, as aplicações individuais podem ter sub-isolamentos adicionais aplicados.

Um Pod é semelhante a um conjunto de contêineres com namespaces compartilhados e volumes de sistema de arquivos compartilhados.

Pods em um cluster Kubernetes são usados de duas maneiras principais:

  • Pods que executam um único contêiner. O modelo "um-contêiner-por-Pod" é o caso de uso mais comum do Kubernetes; neste caso, você pode pensar em um Pod como um invólucro em torno de um único contêiner; o Kubernetes gerencia Pods ao invés de gerenciar os contêineres diretamente.

  • Pods que executam múltiplos contêineres que precisam trabalhar juntos. Um Pod pode encapsular uma aplicação composta por múltiplos contêineres colocalizados que são fortemente acoplados e precisam compartilhar recursos. Esses contêineres colocalizados formam uma única unidade coesa.

    Agrupar múltiplos contêineres colocalizados e cogerenciados em um único Pod é um caso de uso relativamente avançado. Você deve usar esse padrão apenas em instâncias específicas nas quais seus contêineres são fortemente acoplados.

    Você não precisa executar múltiplos contêineres para fornecer replicação (para resiliência ou capacidade); se você precisa de múltiplas réplicas, consulte Gerenciamento de carga de trabalho.

Usando Pods

O seguinte é um exemplo de um Pod que consiste em um contêiner executando a imagem nginx:1.14.2.

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

Para criar o Pod mostrado acima, execute o seguinte comando:

kubectl apply -f https://k8s.io/examples/pods/simple-pod.yaml

Pods geralmente não são criados diretamente e são criados usando recursos de carga de trabalho. Consulte Trabalhando com Pods para mais informações sobre como os Pods são usados com recursos de carga de trabalho.

Recursos de carga de trabalho para gerenciar pods

Normalmente você não precisa criar Pods diretamente, nem mesmo Pods únicos. Em vez disso, crie-os usando recursos de carga de trabalho como Deployment ou Job. Se seus Pods precisam rastrear estado, considere o recurso StatefulSet.

Cada Pod é destinado a executar uma única instância de uma determinada aplicação. Se você deseja escalar sua aplicação horizontalmente (para fornecer mais recursos gerais executando mais instâncias), você deve usar múltiplos Pods, um para cada instância. No Kubernetes, isso é tipicamente referido como replicação. Pods replicados são geralmente criados e gerenciados como um grupo por um recurso de carga de trabalho e seu controlador.

Consulte Pods e controladores para mais informações sobre como o Kubernetes usa recursos de carga de trabalho, e seus controladores, para implementar escalonamento de aplicação e autorrecuperação.

Pods nativamente fornecem dois tipos de recursos compartilhados para seus contêineres constituintes: rede e armazenamento.

Trabalhando com Pods

Você raramente criará Pods individuais diretamente no Kubernetes—nem mesmo Pods únicos. Isso ocorre porque os Pods são projetados como entidades relativamente efêmeras e descartáveis. Quando um Pod é criado (diretamente por você, ou indiretamente por um controlador), o novo Pod é alocado para ser executado em um no seu cluster. O Pod permanece naquele nó até que o Pod termine a execução, o objeto Pod seja excluído, o Pod seja removido por falta de recursos, ou o nó falhe.

O nome de um Pod deve ser um valor de subdomínio DNS válido, mas isso pode produzir resultados inesperados para o hostname do Pod. Para melhor compatibilidade, o nome deve seguir as regras mais restritivas para um rótulo DNS.

SO do Pod

ESTADO DA FUNCIONALIDADE: Kubernetes v1.25 [stable]

Você deve definir o campo .spec.os.name como windows ou linux para indicar o sistema operacional no qual você deseja que o pod seja executado. Esses dois são os únicos sistemas operacionais suportados até o momento pelo Kubernetes. No futuro, esta lista pode ser expandida.

No Kubernetes v1.35, o valor de .spec.os.name não afeta como o kube-scheduler escolhe um nó para o Pod ser executado. Em qualquer cluster onde há mais de um sistema operacional para executar nós, você deve definir o rótulo kubernetes.io/os corretamente em cada nó, e definir pods com um nodeSelector baseado no rótulo do sistema operacional. O kube-scheduler aloca seu pod para um nó com base em outros critérios e pode ou não ter sucesso em escolher uma alocação de nó adequada onde o sistema operacional do nó seja adequado para os contêineres naquele Pod. Os padrões de segurança de Pod também usam este campo para evitar impor políticas que não sejam relevantes para o sistema operacional.

Pods e controladores

Você pode usar recursos de carga de trabalho para criar e gerenciar múltiplos Pods para você. Um controlador para o recurso lida com replicação e implantação e recuperação automática em caso de falha do Pod. Por exemplo, se um nó falha, um controlador percebe que os Pods naquele nó pararam de funcionar e cria um Pod substituto. O alocador coloca o Pod substituto em um nó íntegro.

Aqui estão alguns exemplos de recursos de carga de trabalho que gerenciam um ou mais Pods:

Modelos de Pod

Controladores para recursos de carga de trabalho criam Pods a partir de um modelo de Pod e gerenciam esses Pods em seu nome.

PodTemplates são especificações para criar Pods, e estão incluídos em recursos de carga de trabalho como Deployments, Jobs, e DaemonSets.

Cada controlador para um recurso de carga de trabalho usa o PodTemplate dentro do objeto de carga de trabalho para criar Pods reais. O PodTemplate é parte do estado desejado de qualquer recurso de carga de trabalho que você usou para executar sua aplicação.

Quando você cria um Pod, você pode incluir variáveis de ambiente no modelo de Pod para os contêineres que são executados no Pod.

O exemplo abaixo é um manifesto para um Job simples com um template que inicia um contêiner. O contêiner naquele Pod imprime uma mensagem e então pausa.

apiVersion: batch/v1
kind: Job
metadata:
  name: hello
spec:
  template:
    # Este é o modelo de Pod
    spec:
      containers:
      - name: hello
        image: busybox:1.28
        command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
      restartPolicy: OnFailure
    # O modelo de Pod termina aqui

Modificar o modelo de Pod ou alternar para um novo modelo de Pod não tem efeito direto nos Pods que já existem. Se você alterar o modelo de Pod para um recurso de carga de trabalho, esse recurso precisa criar Pods substitutos que usem o modelo atualizado.

Por exemplo, o controlador StatefulSet garante que os Pods em execução correspondam ao modelo de Pod atual para cada objeto StatefulSet. Se você editar o StatefulSet para alterar seu modelo de Pod, o StatefulSet começa a criar novos Pods baseados no modelo atualizado. Eventualmente, todos os Pods antigos são substituídos por novos Pods, e a atualização é concluída.

Cada recurso de carga de trabalho implementa suas próprias regras para lidar com alterações no modelo de Pod. Se você quiser ler mais sobre StatefulSet especificamente, leia Estratégia de atualização no tutorial Básico de StatefulSet.

Nos nós, o kubelet não observa ou gerencia diretamente nenhum dos detalhes relacionados a modelos de Pod e atualizações; esses detalhes são abstraídos. Essa abstração e separação de responsabilidades simplifica a semântica do sistema, e torna viável estender o comportamento do cluster sem alterar código existente.

Atualização e substituição de Pod

Como mencionado na seção anterior, quando o modelo de Pod para um recurso de carga de trabalho é alterado, o controlador cria novos Pods baseados no modelo atualizado em vez de atualizar ou corrigir os Pods existentes.

O Kubernetes não impede que você gerencie Pods diretamente. É possível atualizar alguns campos de um Pod em execução, diretamente na configuração aplicada. No entanto, operações de atualização de Pod como patch e replace, têm algumas limitações:

  • A maioria dos metadados sobre um Pod é imutável. Por exemplo, você não pode alterar os campos namespace, name, uid, ou creationTimestamp.

  • Se o metadata.deletionTimestamp estiver definido, nenhuma nova entrada pode ser adicionada à lista metadata.finalizers.

  • Atualizações de Pod não podem alterar campos além de spec.containers[*].image, spec.initContainers[*].image, spec.activeDeadlineSeconds, spec.terminationGracePeriodSeconds, spec.tolerations ou spec.schedulingGates. Para spec.tolerations, você só pode adicionar novas entradas.

  • Ao atualizar o campo spec.activeDeadlineSeconds, dois tipos de atualizações são permitidos:

    1. definir o campo não atribuído para um número positivo;
    2. atualizar o campo de um número positivo para um número menor, não negativo.

Subrecursos de Pod

As regras de atualização acima se aplicam a atualizações regulares de Pod, mas outros campos de Pod podem ser atualizados através de subrecursos.

  • Resize: O subrecurso resize permite que recursos de contêiner (spec.containers[*].resources) sejam atualizados. Consulte Redimensionar Recursos de Contêiner para mais detalhes.
  • Contêineres Efêmeros: O subrecurso ephemeralContainers permite que contêineres efêmeros sejam adicionados a um Pod. Consulte Contêineres Efêmeros para mais detalhes.
  • Status: O subrecurso status permite que o status do Pod seja atualizado. Isso é tipicamente usado apenas pelo Kubelet e outros controladores do sistema.
  • Binding: O subrecurso binding permite definir o spec.nodeName do Pod via uma requisição Binding. Isso é tipicamente usado apenas pelo escalonador.

Geração de Pod

  • O campo metadata.generation é único. Ele será automaticamente definido pelo sistema de forma que novos pods tenham um metadata.generation de 1, e cada atualização em campos mutáveis na especificação do pod incrementará o metadata.generation em 1.
ESTADO DA FUNCIONALIDADE: Kubernetes v1.35 [stable](habilitado por padrão)
  • observedGeneration é um campo que é capturado na seção status do objeto Pod. Se o feature gate PodObservedGenerationTracking estiver definido, o Kubelet definirá status.observedGeneration para rastrear o estado do Pod ao status atual do Pod. O status.observedGeneration do Pod refletirá a metadata.generation do Pod no ponto em que o status do Pod está sendo reportado.

Diferentes campos de status podem estar associados à metadata.generation do ciclo de sincronização atual, ou com a metadata.generation do ciclo de sincronização anterior. A distinção chave é se uma mudança na spec é refletida diretamente no status ou é um resultado indireto de um processo em execução.

Atualizações Diretas de Status

Para campos de status onde a especificação alocada é diretamente refletida, o observedGeneration será associado à metadata.generation atual (Geração N).

Este comportamento se aplica a:

  • Status de Redimensionamento: O status de uma operação de redimensionamento de recurso.
  • Recursos Alocados: Os recursos alocados ao Pod após um redimensionamento.
  • Contêineres Efêmeros: Quando um novo contêiner efêmero é adicionado, e ele está no estado Waiting.

Atualizações Indiretas de Status

Para campos de status que são um resultado indireto da execução da especificação, o observedGeneration será associado à metadata.generation do ciclo de sincronização anterior (Geração N-1).

Este comportamento se aplica a:

  • Imagem do Contêiner: O ContainerStatus.ImageID reflete a imagem da geração anterior até que a nova imagem seja baixada e o contêiner seja atualizado.
  • Recursos atuais: Durante um redimensionamento em andamento, os recursos atuais em uso ainda pertencem à requisição da geração anterior.
  • Estado do contêiner: Durante um redimensionamento em andamento, com política de reinicialização necessária reflete a requisição da geração anterior.
  • activeDeadlineSeconds & terminationGracePeriodSeconds & deletionTimestamp: Os efeitos desses campos no status do Pod são resultado da especificação observada anteriormente.

Compartilhamento de recursos e comunicação

Pods permitem o compartilhamento de dados e comunicação entre seus contêineres constituintes.

Armazenamento em Pods

Um Pod pode especificar um conjunto de volumes de armazenamento compartilhados. Todos os contêineres no Pod podem acessar os volumes compartilhados, permitindo que esses contêineres compartilhem dados. Volumes também permitem que dados persistentes em um Pod sobrevivam caso um dos contêineres precise ser reiniciado. Consulte Armazenamento para mais informações sobre como o Kubernetes implementa armazenamento compartilhado e o torna disponível para Pods.

Rede do Pod

Cada Pod recebe um endereço IP único para cada família de endereços. Cada contêiner em um Pod compartilha o namespace de rede, incluindo o endereço IP e portas de rede. Dentro de um Pod (e somente então), os contêineres que pertencem ao Pod podem se comunicar uns com os outros usando localhost. Quando contêineres em um Pod se comunicam com entidades fora do Pod, eles devem coordenar como usam os recursos de rede compartilhados (como portas). Dentro de um Pod, contêineres compartilham um endereço IP e espaço de portas, e podem encontrar uns aos outros via localhost. Os contêineres em um Pod também podem se comunicar uns com os outros usando comunicações interprocessos padrão como semáforos SystemV ou memória compartilhada POSIX. Contêineres em Pods diferentes têm endereços IP distintos e não podem se comunicar por IPC em nível de sistema operacional sem configuração especial. Contêineres que desejam interagir com um contêiner executando em um Pod diferente podem usar rede IP para se comunicar.

Contêineres dentro do Pod veem o nome do host do sistema como sendo o mesmo que o name configurado para o Pod. Mais informações sobre isso na seção de rede.

Configurações de segurança de Pod

Para definir restrições de segurança em Pods e contêineres, você usa o campo securityContext na especificação do Pod. Este campo oferece controle granular sobre o que um Pod ou contêineres individuais podem fazer. Por exemplo:

  • Remover capacidades (capabilities) específicas do Linux para evitar o impacto de uma CVE.
  • Forçar todos os processos no Pod a serem executados como usuário não-root ou como um usuário específico ou ID de grupo.
  • Definir um perfil seccomp específico.
  • Definir opções de segurança do Windows, como se os contêineres são executados como HostProcess.

Pods Estáticos

Pods Estáticos são gerenciados diretamente pelo daemon kubelet em um nó específico, sem que o servidor de API os observe. Enquanto a maioria dos Pods são gerenciados pela camada de gerenciamento (por exemplo, um Deployment), para Pods estáticos, o kubelet supervisiona diretamente cada Pod estático (e o reinicia se falhar).

Pods estáticos estão sempre vinculados a um Kubelet em um nó específico. O uso principal para Pods estáticos é executar uma camada de gerenciamento auto-hospedada: em outras palavras, usar o kubelet para supervisionar os componentes da camada de gerenciamento individuais.

O kubelet tenta automaticamente criar um Pod espelho no servidor de API do Kubernetes para cada Pod estático. Isso significa que os Pods em execução em um nó são visíveis no servidor de API, mas não podem ser controlados de lá. Consulte o guia Criar Pods estáticos para mais informações.

Pods com múltiplos contêineres

Pods são projetados para suportar múltiplos processos cooperantes (como contêineres) que formam uma unidade coesa de serviço. Os contêineres em um Pod são automaticamente colocalizados e coalocados na mesma máquina física ou virtual no cluster. Os contêineres podem compartilhar recursos e dependências, comunicar-se uns com os outros, e coordenar quando e como são encerrados.

Pods em um cluster Kubernetes são usados de duas maneiras principais:

  • Pods que executam um único contêiner. O modelo "um-contêiner-por-Pod" é o caso de uso mais comum do Kubernetes; neste caso, você pode pensar em um Pod como um invólucro em torno de um único contêiner; o Kubernetes gerencia Pods ao invés de gerenciar os contêineres diretamente.
  • Pods que executam múltiplos contêineres que precisam trabalhar juntos. Um Pod pode encapsular uma aplicação composta por múltiplos contêineres colocalizados que são fortemente acoplados e precisam compartilhar recursos. Esses contêineres colocalizados formam uma única unidade coesa de serviço—por exemplo, um contêiner servindo dados armazenados em um volume compartilhado para o público, enquanto um contêiner sidecar separado atualiza ou renova esses arquivos. O Pod envolve esses contêineres, recursos de armazenamento e uma identidade de rede efêmera juntos como uma única unidade.

Por exemplo, você pode ter um contêiner que atua como um servidor web para arquivos em um volume compartilhado, e um contêiner sidecar separado que atualiza esses arquivos de uma fonte remota, como no diagrama a seguir:

Diagrama de criação de Pod

Alguns Pods têm contêineres de inicialização assim como contêineres de aplicação. Por padrão, contêineres de inicialização são executados e concluídos antes que os contêineres de aplicação sejam iniciados.

Você também pode ter contêineres sidecar que fornecem serviços auxiliares ao Pod de aplicação principal (por exemplo: uma malha de serviços).

ESTADO DA FUNCIONALIDADE: Kubernetes v1.33 [stable](habilitado por padrão)

Habilitado por padrão, o feature gate SidecarContainers permite que você especifique restartPolicy: Always para contêineres de inicialização. Definir a política de reinicialização Always garante que os contêineres onde você a define sejam tratados como sidecars que são mantidos em execução durante todo o tempo de vida do Pod. Contêineres que você define explicitamente como contêineres sidecar iniciam antes do Pod de aplicação principal e permanecem em execução até que o Pod seja encerrado.

Verificações de contêiner

Uma verificação é um diagnóstico realizado periodicamente pelo kubelet em um contêiner. Para realizar um diagnóstico, o kubelet pode invocar diferentes ações:

  • ExecAction (realizada com a ajuda do agente de execução de contêiner)
  • TCPSocketAction (verificada diretamente pelo kubelet)
  • HTTPGetAction (verificada diretamente pelo kubelet)

Você pode ler mais sobre verificações na documentação de Ciclo de Vida do Pod.

Próximos passos

Para entender o contexto de por que o Kubernetes envolve uma API de Pod comum em outros recursos (como StatefulSets ou Deployments), você pode ler sobre trabalhos anteriores, incluindo:

1 - Interrupções

Este guia é destinado a proprietários de aplicações que desejam construir aplicações altamente disponíveis e, portanto, precisam entender quais tipos de interrupções podem acontecer com os Pods.

Também é destinado a administradores de cluster que desejam executar ações automatizadas no cluster, como atualização e escalonamento automático de clusters.

Interrupções voluntárias e involuntárias

Os Pods não desaparecem até que alguém (uma pessoa ou um controlador) os destrua, ou ocorra um erro inevitável de hardware ou software do sistema.

Chamamos esses casos inevitáveis de interrupções involuntárias para uma aplicação. Exemplos incluem:

  • uma falha de hardware da máquina física que sustenta o nó.
  • administrador do cluster exclui a VM (instância) por engano.
  • falha do provedor de nuvem ou do hipervisor faz a VM desaparecer.
  • um kernel panic.
  • o nó desaparece do cluster devido a uma partição de rede do cluster.
  • remoção de um Pod devido ao nó estar sem recursos.

Exceto pela condição de falta de recursos, todas essas condições devem ser familiares para a maioria dos usuários; elas não são específicas do Kubernetes.

Chamamos os outros casos de interrupções voluntárias. Estas incluem tanto ações iniciadas pelo proprietário da aplicação quanto aquelas iniciadas por um Administrador de Cluster. Ações típicas do proprietário da aplicação incluem:

  • excluir o deployment ou outro controlador que gerencia o Pod.
  • atualizar o template do Pod de um deployment causando uma reinicialização.
  • excluir diretamente um Pod (por exemplo, por acidente).

As ações do administrador de cluster incluem:

Essas ações podem ser executadas diretamente pelo administrador do cluster, ou por automação executada pelo administrador do cluster, ou pelo seu provedor de hospedagem do cluster.

Consulte seu administrador de cluster ou consulte a documentação do seu provedor de nuvem ou distribuição para determinar se alguma fonte de interrupções voluntárias está habilitada para o seu cluster. Se nenhuma estiver habilitada, você pode pular a criação de Orçamentos de Interrupção de Pods.

Lidando com interrupções

Aqui estão algumas maneiras de mitigar interrupções involuntárias:

  • Certifique-se de que seu Pod solicita os recursos de que necessita.
  • Replique sua aplicação se precisar de maior disponibilidade. (Saiba mais sobre executar aplicações replicadas sem estado e com estado).
  • Para uma disponibilidade ainda maior ao executar aplicações replicadas, distribua as aplicações entre racks (usando antiafinidade) ou entre zonas (se estiver usando um cluster multizona).

A frequência de interrupções voluntárias varia. Em um cluster Kubernetes básico, não há interrupções voluntárias automatizadas (apenas aquelas acionadas pelo usuário). No entanto, seu administrador de cluster ou provedor de hospedagem pode executar alguns serviços adicionais que causam interrupções voluntárias. Por exemplo, atualizar o software do nó pode causar interrupções voluntárias. Além disso, algumas implementações de escalonamento automático de cluster (nó) podem causar interrupções voluntárias para desfragmentar e compactar nós. Seu administrador de cluster ou provedor de hospedagem deve ter documentado qual nível de interrupções voluntárias, se houver, esperar. Certas opções de configuração, como usar PriorityClasses na especificação do seu Pod também podem causar interrupções voluntárias (e involuntárias).

Orçamentos de Interrupção de Pods

ESTADO DA FUNCIONALIDADE: Kubernetes v1.21 [stable]

O Kubernetes oferece funcionalidades para ajudá-lo a executar aplicações altamente disponíveis mesmo quando você introduz interrupções voluntárias frequentes.

Como proprietário de uma aplicação, você pode criar um PodDisruptionBudget (PDB) para cada aplicação. Um PDB limita o número de Pods de uma aplicação replicada que estão inativos simultaneamente devido a interrupções voluntárias. Por exemplo, uma aplicação baseada em quórum gostaria de garantir que o número de réplicas em execução nunca seja reduzido abaixo do número necessário para um quórum. Um front-end web pode querer garantir que o número de réplicas atendendo a carga nunca caia abaixo de uma certa porcentagem do total.

Administradores de cluster e provedores de hospedagem devem usar ferramentas que respeitem PodDisruptionBudgets através do uso da API de Remoção em vez de excluir diretamente Pods ou Deployments.

Por exemplo, o subcomando kubectl drain permite marcar um nó como sendo retirado de serviço. Quando você executa kubectl drain, a ferramenta tenta remover todos os Pods do nó que você está retirando de serviço. A solicitação de remoção que o kubectl envia em seu nome pode ser temporariamente rejeitada, então a ferramenta repete periodicamente todas as solicitações com falha até que todos os Pods no nó de destino sejam encerrados, ou até que um tempo limite configurável seja atingido.

Um PDB especifica o número de réplicas que uma aplicação pode tolerar ter, em relação a quantas ela pretende ter. Por exemplo, um Deployment que tem .spec.replicas: 5 deve ter 5 Pods a qualquer momento. Se seu PDB permite que existam 4 por vez, então a API de Remoção permitirá a interrupção voluntária de um (mas não dois) Pods por vez.

O grupo de Pods que compõem a aplicação é especificado usando um seletor de rótulos, o mesmo usado pelo controlador da aplicação (deployment, stateful-set, etc.).

O número "pretendido" de Pods é calculado a partir do .spec.replicas do recurso de carga de trabalho que está gerenciando esses Pods. A camada de gerenciamento descobre o recurso de carga de trabalho proprietário examinando o .metadata.ownerReferences do Pod.

Interrupções involuntárias não podem ser evitadas por PDBs; no entanto, elas contam contra o orçamento.

Pods que são excluídos ou indisponíveis devido a uma atualização gradual de uma aplicação contam contra o orçamento de interrupção, mas recursos de carga de trabalho (como Deployment e StatefulSet) não são limitados por PDBs ao realizar atualizações graduais. Em vez disso, o tratamento de falhas durante atualizações de aplicações é configurado na especificação do recurso de carga de trabalho específico.

É recomendado definir AlwaysAllow como Política de Remoção de Pods Não Íntegros em seus PodDisruptionBudgets para suportar a remoção de aplicações com comportamento inadequado durante a drenagem de um nó. O comportamento padrão é aguardar que os Pods da aplicação se tornem íntegros antes que a drenagem possa prosseguir.

Quando um Pod é removido usando a API de remoção, ele é controladamente encerrado, respeitando a configuração terminationGracePeriodSeconds em sua PodSpec.

Exemplo de PodDisruptionBudget

Considere um cluster com 3 nós, node-1 a node-3. O cluster está executando várias aplicações. Uma delas tem 3 réplicas inicialmente chamadas pod-a, pod-b e pod-c. Outro Pod não relacionado, sem um PDB, chamado pod-x, também é mostrado. Inicialmente, os Pods estão distribuídos da seguinte forma:

node-1 node-2 node-3
pod-a available pod-b available pod-c available
pod-x available

Todos os 3 Pods fazem parte de um Deployment, e coletivamente têm um PDB que exige que pelo menos 2 dos 3 Pods estejam disponíveis o tempo todo.

Por exemplo, suponha que o administrador do cluster queira reiniciar em uma nova versão do kernel para corrigir um bug no kernel. O administrador do cluster primeiro tenta drenar node-1 usando o comando kubectl drain. Essa ferramenta tenta remover pod-a e pod-x. Isso é bem-sucedido imediatamente. Ambos os Pods entram no estado terminating ao mesmo tempo. Isso coloca o cluster neste estado:

node-1 draining node-2 node-3
pod-a terminating pod-b available pod-c available
pod-x terminating

O Deployment percebe que um dos Pods está sendo encerrado, então cria uma substituição chamada pod-d. Como node-1 está isolado, ele é alocado em outro nó. Algo também criou pod-y como substituição para pod-x.

(Nota: para um StatefulSet, pod-a, que seria chamado de algo como pod-0, precisaria ser totalmente encerrado antes que sua substituição, que também é chamada de pod-0 mas tem um UID diferente, pudesse ser criada. Caso contrário, o exemplo também se aplica a um StatefulSet.)

Agora o cluster está neste estado:

node-1 draining node-2 node-3
pod-a terminating pod-b available pod-c available
pod-x terminating pod-d starting pod-y

Em algum momento, os Pods são encerrados, e o cluster fica assim:

node-1 drained node-2 node-3
pod-b available pod-c available
pod-d starting pod-y

Neste ponto, se um administrador de cluster impaciente tentar drenar node-2 ou node-3, o comando drain será bloqueado, porque há apenas 2 Pods disponíveis para o Deployment, e seu PDB exige pelo menos 2. Depois de algum tempo, pod-d se torna disponível.

O estado do cluster agora fica assim:

node-1 drained node-2 node-3
pod-b available pod-c available
pod-d available pod-y

Agora, o administrador do cluster tenta drenar node-2. O comando drain tentará remover os dois Pods em alguma ordem, digamos pod-b primeiro e depois pod-d. Ele terá sucesso ao remover pod-b. Mas, quando tentar remover pod-d, será recusado porque isso deixaria apenas um Pod disponível para o Deployment.

O Deployment cria uma substituição para pod-b chamada pod-e. Como não há recursos suficientes no cluster para alocar pod-e, a drenagem será bloqueada novamente. O cluster pode acabar neste estado:

node-1 drained node-2 node-3 no node
pod-b terminating pod-c available pod-e pending
pod-d available pod-y

Neste ponto, o administrador do cluster precisa adicionar um nó de volta ao cluster para prosseguir com a atualização.

Você pode ver como o Kubernetes varia a taxa na qual as interrupções podem acontecer, de acordo com:

  • quantas réplicas uma aplicação precisa
  • quanto tempo leva para encerrar controladamente uma instância
  • quanto tempo leva para uma nova instância iniciar
  • o tipo de controlador
  • a capacidade de recursos do cluster

Condições de interrupção de Pods

ESTADO DA FUNCIONALIDADE: Kubernetes v1.31 [stable](habilitado por padrão)

Uma condição dedicada DisruptionTarget do Pod condition é adicionada para indicar que o Pod está prestes a ser excluído devido a uma interrupção. O campo reason da condição adicionalmente indica um dos seguintes motivos para o encerramento do Pod:

PreemptionByScheduler
O Pod deve sofrer preempção por um escalonador para acomodar um novo Pod com uma prioridade mais alta. Para mais informações, consulte Preempção por prioridade de Pod.
DeletionByTaintManager
O Pod deve ser excluído pelo Taint Manager (que faz parte do controlador de ciclo de vida do nó dentro do kube-controller-manager) devido a um taint NoExecute que o Pod não tolera; veja remoções baseadas em taint.
EvictionByEvictionAPI
O Pod foi marcado para remoção usando a API do Kubernetes.
DeletionByPodGC
O Pod, que está vinculado a um nó que não existe mais, deve ser excluído pela coleta de lixo de Pod.
TerminationByKubelet
O Pod foi encerrado pelo kubelet, devido a remoção por pressão no nó, o desligamento controlado do nó, ou substituição para Pods críticos do sistema.

Em todos os outros cenários de interrupção, como remoção devido a exceder limites de contêiner do Pod, os Pods não recebem a condição DisruptionTarget porque as interrupções provavelmente foram causadas pelo Pod e ocorreriam novamente em uma nova tentativa.

Juntamente com a limpeza dos Pods, o coletor de lixo de Pods (PodGC) também os marcará como falhados se estiverem em uma fase não terminal (veja também coleta de lixo de Pod).

Ao usar uma tarefa (ou CronJob), você pode querer usar essas condições de interrupção de Pod como parte da política de falha de Pod da sua tarefa.

Separando os Papéis de Proprietário do Cluster e Proprietário da Aplicação

Frequentemente, é útil pensar no Administrator do cluster e no Proprietário da aplicação como papéis separados com conhecimento limitado um do outro. Esta separação de responsabilidades pode fazer sentido nestes cenários:

  • quando há muitas equipes de aplicação compartilhando um cluster Kubernetes, e há uma especialização natural de papéis.
  • quando ferramentas ou serviços de terceiros são usados para automatizar o gerenciamento do cluster.

Os Orçamentos de Interrupção de Pods apoiam esta separação de papéis fornecendo uma interface entre os papéis.

Se você não tem essa separação de responsabilidades em sua organização, você pode não precisar usar Orçamentos de Interrupção de Pods.

Como Realizar Ações Disruptivas no seu Cluster

Se você é um Administrador de cluster e precisa realizar uma ação disruptiva em todos os nós do seu cluster, como uma atualização de nó ou software do sistema, aqui estão algumas opções:

  • Aceitar tempo de inatividade durante a atualização.
  • Fazer failover para outro cluster de réplica completo.
    • Sem tempo de inatividade, mas pode ser custoso tanto pelos nós duplicados quanto pelo esforço humano para orquestrar a troca.
  • Escrever aplicações tolerantes a interrupções e usar PDBs.
    • Sem tempo de inatividade.
    • Duplicação mínima de recursos.
    • Permite mais automação da administração do cluster.
    • Escrever aplicações tolerantes a interrupções é complicado, mas o trabalho para tolerar interrupções voluntárias se sobrepõe em grande parte ao trabalho de suportar escalonamento automático e tolerar interrupções involuntárias.

Próximos passos