Ciclo de Vida dos Pods no Kubernetes

Visão Geral do Ciclo de Vida de um Pod

O ciclo de vida de um Pod refere-se ao período desde sua criação até sua terminação. Durante esse intervalo, o Pod passa por vários estados e pode executar operações configuráveis. A operação principal é a execução do contêiner, mas outras como contêineres de inicialização, ganchos de ciclo de vida, e sondagens de saúde são opcionais e dependem da especificação do Pod.

Fases do Pod (Pod Phases)

Indepenedntemente de ser criado manualmente ou por controladores como Deployments, um Pod sempre se ancontra em uma das seguintes fases:

  • Pending: O objeto Pod foi criado e persistido no etcd, mas ainda não foi agendado ou está baixando a imagem do contêiner.
  • Running: O Pod foi agendado em um nó, e todos os seus contêineres foram criados pelo kubelet.
  • Succeeded: Todos os contêineres no Pod terminaram com sucesso e não serão reiniciados.
  • Failed: Todos os contêineres terminaram, mas pelo menos um terminou com falha (código de saída diferente de zero ou foi encerrado pelo sistema).
  • Unknown: O estado do Pod não pôde ser obtido, geralmente devido a uma falha de comunicação entre o kubelet e o API Server.

Diagnóstico Rápido de Problemas

Problemas comuns e suas verificações prioritárias:

  • Pod preso em Pending: Verifique os recursos do nó e tolerâncias com kubectl describe node <nome-do-no>.
  • CrashLoopBackOff: Inspecione os logs do contêiner anterior com kubectl logs --previous <nome-do-pod>.
  • Indisponibilidade intermitente: Valide a configuração da sonda de prontidão (readinessProbe) e os endpoints do serviço com kubectl get endpoints.
  • Terminação demorada: Observe os eventos em tempo real para verificar ganchos preStop com kubectl get events -w.
  • Falha ao montar volume: Verifique o estado do PersistentVolumeClaim com kubectl get pvc -o wide.

Criação do Pod

O fluxo de criação segue estas etapas principais:

  1. O cliente (ex: kubectl apply) envia uma requisição para o API Server, autenticado com certificados.
  2. O API Server valida a requisição e persiste a especificação do Pod no etcd.
  3. O Controller Manager observa (watch) a discrepância entre o estado desejado (ex: réplicas de um Deployment) e o atual, solicitando a criação de novos Pods.
  4. O Scheduler obtém Pods pendentes, avalia os recursos do cluster e os agendam em nós adequados.
  5. O agendamento é registrado no etcd via API Server.
  6. O kubelet no nó agendado recebe a tarefa, baixa as imagens e cria os contêineres do Pod.
  7. O kubelet reporta periodicamente o status do Pod e do nó de volta ao API Server.

Ganchos de Ciclo de Vida (Lifecycle Hooks)

Os ganchos permitem executar código customizado em eventos específicos do ciclo de vida do contêiner principal. Dois são fornecidos:

  • postStart: Executado imediatamente após a criação do contêiner.
  • preStop: Executado antes do contêiner ser encerrado.

Definição dos Ganchos

Os ganchos podem definir ações de duas maneiras:

Modo exec

Executa um comando diretamente dentro do contêiner. Sucesso é um código de saída 0.

lifecycle:
  postStart:
    exec:
      command: ["/bin/sh", "-c", "echo 'Contêiner inicializado' > /tmp/status.log"]

Modo httpGet

Realiza uma requisição HTTP GET. Sucesso é uma resposta com código de status entre 200 e 399.

lifecycle:
  postStart:
    httpGet:
      path: /health/startup
      port: 8080
      scheme: HTTP
      host: localhost

Sondas de Contêiner (Container Probes)

Existem três tipos de sondas que o kubelet pode executar para verificar a saúde do contêiner. A falha em uma sonda pode levar a reinicializações ou remoção do endpoint do serviço.

Sonda de Inicialização (Startup Probe)

Verifica se o contêiner completou sua inicialização. Enquanto esta sonda não for bem-sucedida, as outras sondas (liveness, readiness) ficam desabilitadas. É uma verificação única no início.

Sonda de Atividade (Liveness Probe)

Determina se o contêiner está em execução. Se falhar, o kubelet matará o contêiner, e a política de reinício definirá o que acontecerá em seguida.

Sonda de Prontidão (Readiness Probe)

Determina se o contêiner está pronto para aceitar tráfego de rede. Se falhar, o endereço IP do Pod será removido dos endpoints do(s) Service(s) associado(s), impedindo que ele receba requisições.

Parâmetros Comuns das Sondas

  • initialDelaySeconds: Tempo de espera após a inicialização do contêiner antes de iniciar as sondas.
  • periodSeconds: Intervalo entre execuções da sonda.
  • timeoutSeconds: Tempo máximo de espera por uma resposta da sonda.
  • successThreshold: Número de sucessos consecutivos após uma falha para considerar o contêiner saudável novamente.
  • failureThreshold: Número de falhas consecutivas para considerar o contêiner não saudável.

Exemplos de Configuração

Sonda HTTP

apiVersion: v1
kind: Pod
metadata:
  name: web-app-probe
spec:
  containers:
  - name: app
    image: httpd:latest
    ports:
    - containerPort: 80
    livenessProbe:
      httpGet:
        path: /status
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 10
    readinessProbe:
      httpGet:
        path: /ready
        port: 80
      initialDelaySeconds: 2
      periodSeconds: 5

Sonda TCP

apiVersion: v1
kind: Pod
metadata:
  name: cache-service-probe
spec:
  containers:
  - name: memcached
    image: memcached:latest
    ports:
    - containerPort: 11211
    readinessProbe:
      tcpSocket:
        port: 11211
      initialDelaySeconds: 5
      periodSeconds: 10

Sonda Exec

apiVersion: v1
kind: Pod
metadata:
  name: data-sync-probe
spec:
  containers:
  - name: sync-agent
    image: busybox
    command: ["/bin/sh", "-c", "while true; do echo alive; sleep 60; done"]
    livenessProbe:
      exec:
        command: ["grep", "alive", "/tmp/heartbeat.log"]
      initialDelaySeconds: 10
      periodSeconds: 5

Diretrizes de Implementação

  • Sonda de Inicialização: Use para aplicações com tempo de inicialização longo ou variável. Defina um failureThreshold alto e periodSeconds adequado para dar tempo suficiente.
  • Sonda de Atividade: Essencial para detectar travamentos (ex: deadlock). Certifique-se de que a aplicação termine limpa quando a sonda falhar.
  • Sonda de Prontidão: Use para aplicações que dependem de recursos externos (banco de dados, cache) antes de estarem prontas. Isso evita erros 502 ou timeouts para os clientes.

As sondas de prontidão e atividade podem e devem ser combinadas no mesmo Pod para uma gestão robusta do tráfego e da saúde.

Política de Reinício (restartPolicy)

A política determina se o kubelet deve reiniciar um contêiner encerrado. É definida por Pod:

  • Always: Reinicia o contêiner sempre que ele encerrar. É o padrão.
  • OnFailure: Reinicia apenas se o contêinar terminar com um código de erro (diferente de 0).
  • Never: Nunca reinicia o contêiner, independentemente do motivo do encerramento.

Reinicializações subsequentes após a primeira falha têm um backoff exponencial (10s, 20s, 40s, ... até 300s).

Encerramento e Encerramento Gracioso

Ao deletar um Pod, segue-se este processo:

  1. O Pod recebe o sinal SIGTERM e é marcado como "Terminating".
  2. Simultaneamente, o Pod é removido da lista de endpoints dos Services.
  3. O gancho preStop (se definido) é executado.
  4. O contêiner tem o tempo de encerramento gracioso (terminationGracePeriodSeconds, padrão 30s) para encerrar suas aplicações.
  5. Se o processo não terminar dentro do período de graça, o kubelet enviará um sinal SIGKILL para forçar o encerramento.
  6. Finalmente, o kubelet solicita ao API Server a remoção definitiva do recurso do Pod.

Configurando um Encerramento Gracioso

Dois campos são críticos:

apiVersion: v1
kind: Pod
metadata:
  name: graceful-app
spec:
  terminationGracePeriodSeconds: 45  # Tempo total para encerramento
  containers:
  - name: main-app
    image: my-app:latest
    lifecycle:
      preStop:
        exec:
          command: ["/bin/sh", "-c", "sleep 15 && /app/shutdown.sh"]

Neste exemplo, o contêiner tem 45 segundos no total. Ao receber SIGTERM, primeiro executará o gancho preStop (que dorme por 15 segundos e executa um script de encerramento). Após o gancho, o contêiner principal tem os 30 segundos restantes para encerrar. Isso é útil para conexões de drenagem, salvamento de estado, etc.

Tags: kubernetes pods liveness-probe readiness-probe startup-probe

Publicado em 6-6 01:51 por Thomas