Todos os produtos
Search
Central de documentação

Container Service for Kubernetes:Use preStop hooks to prevent 502/504 errors during ALB Ingress rolling updates

Última atualização: Jun 27, 2026

Uma pausa preStop atrasa o sinal SIGTERM, permitindo que o controlador do ALB Ingress cancele o registro do pod antes do desligamento.

Pré-requisitos

Antes de começar, verifique se você possui:

Para usar um ALB Ingress com um cluster dedicado ACK, autorize o cluster para o controlador do ALB Ingress primeiro.

Como funciona

Ciclo de vida do pod

Um pod contém dois tipos de contêineres:

  • Contêiner de inicialização: Executa antes do contêiner principal para inicialização.

  • Contêiner principal: Executa a aplicação. O postStart roda após a inicialização, as verificações de atividade e prontidão ocorrem durante a vida útil do contêiner e o preStop executa antes do encerramento.

A figura a seguir ilustra o ciclo de vida do pod.

image

Por que ocorrem erros: dois procedimentos em paralelo

A exclusão de um pod aciona dois procedimentos paralelos — o encerramento do pod e a atualização das rotas de tráfego — o que causa erros 502/504.

Procedimento de encerramento do pod

  1. O kube-apiserver marca o pod como Terminating.

  2. O sistema executa o hook preStop, caso esteja configurado.

  3. O cluster envia um sinal SIGTERM para o contêiner.

  4. O sistema aguarda o contêiner parar ou o período de tolerância (terminationGracePeriodSeconds, padrão: 30 segundos) expirar.

  5. Se o pod ainda estiver em execução após o período de tolerância, o kubelet espera mais 2 segundos e envia um sinal SIGKILL.

  6. O pod é excluído.

Procedimento de atualização da regra de roteamento de tráfego

  1. O kube-apiserver marca o pod como Terminating.

  2. O controlador de endpoints remove o endereço IP do pod do endpoint.

  3. O controlador do ALB Ingress reconcilia os servidores de backend e remove o endpoint do Service do grupo de servidores de backend.

Como ambos os procedimentos rodam em paralelo, o controlador do ALB Ingress pode não concluir a reconciliação antes do desligamento do pod, direcionando tráfego para um pod em fase de encerramento.

Como um hook preStop previne erros

Sem um hook preStop, estes erros podem ocorrer durante atualizações contínuas:

Código de status

Causa

504

O pod estava processando uma requisição não idempotente quando foi encerrado.

502

O pod desligou após receber SIGTERM, mas o controlador do ALB Ingress ainda não o havia removido do grupo de servidores de backend.

Um hook preStop adiciona um atraso de espera iniciado quando o kube-apiserver marca o pod como Terminating, concedendo tempo ao controlador do ALB Ingress para cancelar o registro do pod antes que ele receba o sinal SIGTERM.

Orçamento de tempo

A espera do preStop e o desligamento do contêiner compartilham o mesmo período de tolerância (terminationGracePeriodSeconds). Com sleep 10 e um desligamento de programa de 5 segundos, defina terminationGracePeriodSeconds para pelo menos 15, mais uma margem de segurança. Este tópico utiliza sleep 10 e terminationGracePeriodSeconds: 45.

Se a duração do preStop somada ao tempo de desligamento do programa exceder terminationGracePeriodSeconds , o desligamento contínuo atinge o tempo limite e o kubelet envia SIGKILL após uma espera de 2 segundos. Aumente o valor de terminationGracePeriodSeconds para cobrir ambas as etapas.

Etapa 1: Implantar a aplicação com um hook preStop

  1. Crie o arquivo tea-service.yaml com o conteúdo abaixo. O campo lifecycle.preStop configura o hook.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: tea
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: tea
      template:
        metadata:
          labels:
            app: tea
        spec:
          containers:
          - name: tea
            image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginxdemos:latest
            ports:
            - containerPort: 80
            lifecycle:
              preStop:          # Delay SIGTERM by 10 seconds to allow the ALB Ingress controller
                exec:           # to finish deregistering the pod from the backend server group.
                  command:
                  - /bin/sh
                  - -c
                  - "sleep 10"
          terminationGracePeriodSeconds: 45   # Must exceed preStop duration + program shutdown time.
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: tea-svc
    spec:
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: tea
      type: NodePort
  2. Implante o Deployment e o Service.

    kubectl apply -f tea-service.yaml
  3. Crie o arquivo tea-ingress.yaml com o conteúdo a seguir.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: tea-ingress
    spec:
      ingressClassName: alb
      rules:
      - host: demo.ingress.top
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: tea-svc
                port:
                  number: 80
  4. Crie o Ingress.

    kubectl apply -f tea-ingress.yaml
  5. Obtenha o endereço do ALB para o Ingress.

    kubectl get ingress

    Saída esperada:

    NAME          CLASS   HOSTS              ADDRESS                                              PORTS   AGE
    tea-ingress   alb     demo.ingress.top   alb-110zvs5nhsvfv*****.cn-chengdu.alb.aliyuncs.com   80      7m5s

    Anote o valor de ADDRESS para a próxima etapa.

Etapa 2: Verificar se o hook preStop evita interrupções de serviço

  1. Crie o arquivo test.sh com o conteúdo seguinte. O script envia uma requisição por segundo e registra cada código de status HTTP.

    #!/bin/bash
    HOST="demo.ingress.top"
    DNS="alb-110zvs5nhsvfv*****.cn-chengdu.alb.aliyuncs.com"  # Replace with your ADDRESS value.
    printf "Response Code|| TIME \n" >> log.txt
    
    while true; do
      RESPONSE=$(curl -H Host:$HOST -s -o /dev/null -w "%{http_code}" -m 1 http://$DNS/)
      TIMESTAMP=$(date +%Y-%m-%d_%H:%M:%S)
      echo "$TIMESTAMP - $RESPONSE" >> log.txt
      sleep 1
    done
  2. Execute o script.

    bash test.sh
  3. Acione uma reinicialização contínua.

    kubectl rollout restart deploy tea
  4. Acompanhe o progresso da atualização. As capturas de tela a seguir mostram os estados esperados dos pods durante cada fase da atualização.

    image

    image

    image

    image

  5. Verifique o log de teste. Todas as requisições devem retornar 200, confirmando zero interrupções de serviço.

    cat log.txt

    Saída esperada:

    image

Próximas etapas