Todos os produtos
Search
Central de documentação

Container Service for Kubernetes:NGINX Ingress FAQ

Última atualização: Sep 02, 2026

Resolva problemas comuns do NGINX Ingress Controller relacionados a TLS, configuração, desempenho e atualizações.

Quais são os problemas conhecidos em versões anteriores do NGINX Ingress Controller?

Versões anteriores apresentam os seguintes problemas conhecidos. Atualize para a versão mais recente para garantir maior estabilidade.

Quais versões de TLS são suportadas?

O ingress-nginx suporta TLS 1,2 e TLS 1,3. Clientes que utilizam versões do TLS anteriores à 1,2 podem encontrar erros de handshake.

Para oferecer suporte a outras versões do TLS, adicione o seguinte ao ConfigMap nginx-configuration no namespace kube-system. Consulte TLS/HTTPS.

Nota

Para ative o TLS 1,0 ou 1,1 no NGINX Ingress Controller 1.7.0 e posteriores, especifique @SECLEVEL=0 no parâmetro ssl-ciphers.

server-tokens: "false"
ssl-ciphers: '@SECLEVEL=0:ECDHE-ECDSA-AES128-GCM-SHA256:E...
ssl-protocols: TLSv1 TLSv1.1 TLSv1.2 TLSv1.3
ssl-redirect: "false"
ssl-ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA"
ssl-protocols: "TLSv1 TLSv1.1 TLSv1.2 TLSv1.3"

Os cabeçalhos de requisição são passados aos servidores de backend?

Por padrão, o ingress-nginx encaminha cabeçalhos de requisição da Camada 7 para os servidores de backend, mas filtra cabeçalhos HTTP não padronizados (como Mobile Version). Para manter esses cabeçalhos, execute kubectl edit cm -n kube-system nginx-configuration e atualize o ConfigMap. Consulte ConfigMap.

enable-underscores-in-headers: true

Como encaminhar requisições para servidores de backend HTTPS?

Para encaminhar requisições a servidores de backend HTTPS via ingress-nginx, adicione as seguintes anotações ao Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: xxxx
  annotations:
    # You must specify HTTPS as the protocol used by the backend server. 
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"

Como passar endereços IP de cliente na Camada 7?

Por padrão, o ingress-nginx adiciona os cabeçalhos X-Forwarded-For e X-Real-IP para transmitir os endereços IP dos clientes. No entanto, se o cliente já incluir esses cabeçalhos, o servidor de backend não conseguirá obter o IP original do cliente.

Execute kubectl edit cm -n kube-system nginx-configuration para modifique o ConfigMap nginx-configuration e permitir que o ingress-nginx passe os endereços IP dos clientes na Camada 7:

compute-full-forwarded-for: "true"
forwarded-for-header: "X-Forwarded-For"
use-forwarded-headers: "true"

Se o tráfego passar por vários servidores proxy upstream antes de chegar a um NGINX Ingress, adicione o campo proxy-real-ip-cidr ao ConfigMap nginx-configuration e defina proxy-real-ip-cidr com os blocos CIDR dos servidores proxy upstream (separados por vírgula). Consulte Use WAF.

proxy-real-ip-cidr:  "0.0.0.0/0,::/0"  

Em cenários IPv6 nos quais o NGINX Ingress recebe um cabeçalho X-Forwarded-For vazio atrás de uma instância de Classic Load Balancer (CLB), ative o protocolo Proxy no CLB para recuperar o IP do cliente. Consulte Obtaining client IP addresses through a CLB Layer 4 listener.

Como configure o HSTS?

O HTTP Strict Transport Security (HSTS) vem ativado por padrão. Quando um navegador acessa o service pela primeira vez via http simples, o servidor dispara uma resposta HSTS. Nas ferramentas de desenvolvedor, você verá um cabeçalho de resposta Non-Authoritative-Reason: HSTS. Navegadores compatíveis com HSTS mudam automaticamente para HTTPS nas requisições subsequentes, resultando em um código de status 307 Internal Redirect.

General
  Request URL: http://xxx.bizprodmng xxx .com/crmhome/pageListQuery.json?pageNum=1&pageName=&pageSize=20&platform=
  Request Method: GET
  Status Code: 307 Internal Redirect
Response Headers
  Access-Control-Allow-Credentials: true
  Access-Control-Allow-Origin: http://zhbyak xxx net:3001
  Location: https://bizprodmng xxx .com/crmhome/pageListQuery.json?pageNum=1&pageName=&pageSize=20&platform=
  Non-Authoritative-Reason: HSTS
Request Headers
  Provisional headers are shown
  Referer: http://zhbyak xxx .net:3001/searchPage
  User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Saf...
Query String Parameters
  pageNum: 1
  pageName:

Para impedir que os navegadores atualizem automaticamente as requisições subsequentes para HTTPS, desative o HSTS no nginx-ingress-controller. Consulte HSTS.

Nota

Os navegadores armazenam a configuração do HSTS em cache. Limpe manualmente o cache do navegador após desativar o HSTS no nginx-ingress-controller.

Quais regras de reescrita são suportadas?

O Ingress-nginx suporta apenas regras simples de reescrita. Para regras complexas, utilize:

Outros snippets adicionam configurações globais. Consulte main-snippet.

Quais recursos são atualizados durante uma atualização do NGINX Ingress Controller?

Se a versão do NGINX Ingress Controller for anterior à 0,44, os seguintes recursos estão incluídos:

  • serviceaccount/ingress-nginx

  • configmap/nginx-configuration

  • configmap/tcp-services

  • configmap/udp-services

  • clusterrole.rbac.authorization.k8s.io/ingress-nginx

  • clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx

  • role.rbac.authorization.k8s.io/ingress-nginx

  • rolebinding.rbac.authorization.k8s.io/ingress-nginx

  • service/nginx-ingress-lb

  • deployment.apps/nginx-ingress-controller

Caso a versão seja 0,44 ou posterior, além dos recursos mencionados anteriormente, os seguintes também são incluídos:

  • validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission

  • service/ingress-nginx-controller-admission

  • serviceaccount/ingress-nginx-admission

  • clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission

  • clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission

  • role.rbac.authorization.k8s.io/ingress-nginx-admission

  • rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission

  • job.batch/ingress-nginx-admission-create

  • job.batch/ingress-nginx-admission-patch

Ao atualizar o NGINX Ingress Controller pela página Add-ons do console ACK, os seguintes recursos permanecem inalterados:

  • configmap/nginx-configuration

  • configmap/tcp-services

  • configmap/udp-services

  • service/nginx-ingress-lb

Todas as outras configurações de recursos serão redefinidas para seus valores padrão. Por exemplo, o valor padrão de replicas no recurso deployment.apps/nginx-ingress-controller é 2. Se você definiu replicas como 5 antes de atualizar o NGINX Ingress Controller, ele retornará ao valor padrão de 2 após a atualização.

Como alternar de listeners da Camada 4 para a Camada 7?

Por padrão, o LoadBalancer do ingress-nginx escuta nas portas TCP 80 e 443. Alterne para listeners da Camada 7 mudando o protocolo para http ou HTTPS.

Nota

Ocorre interrupção do service durante a alteração dos listeners. Execute este procedimento fora do horário de pico.

  1. Crie um certificado e anote o ID do certificado (cert-id). Consulte Use a certificate from Certificate Management Service.

  2. Altere os listeners do LoadBalancer usados pelo Ingress da Camada 4 para a Camada 7 por meio de anotações.

    1. Faça login no console ACK. No painel de navegação à esquerda, clique em Clusters.

    2. Na página Clusters, clique no nome do seu cluster. No painel de navegação à esquerda, clique em Network > Services.

    3. Na parte superior da página Services, defina Namespace como kube-system. Localize o Service ingress-nginx-lb e clique em Edit YAML na coluna Actions.

    4. No painel Edit YAML, atualize o targetPort para 80 na porta chamada https (porta 443).

        - name: https
          port: 443
          protocol: TCP
          targetPort: 80 # Set targetPort to 80 for port 443.

      Adicione o seguinte ao campo annotations e clique em OK.

      service.beta.kubernetes.io/alibaba-cloud-loadbalancer-protocol-port: "http:80,https:443"
      service.beta.kubernetes.io/alibaba-cloud-loadbalancer-cert-id: "${YOUR_CERT_ID}"
  3. Verifique o resultado.

    1. Na página Services, localize o Service ingress-nginx-lb e clique no ícone image na coluna Type.

    2. Clique na aba Listener. Se tanto HTTP:80 quanto HTTPS:443 forem exibidos na coluna Frontend Protocol/Port, os listeners do LoadBalancer foram alterados da Camada 4 para a Camada 7.

Como usar uma instância SLB existente com ack-ingress-nginx?

  1. Faça login no console ACK. No painel de navegação à esquerda, clique em Marketplace > Marketplace.

  2. Na aba App Catalog, selecione ack-ingress-nginx ou ack-ingress-nginx-v1 conforme a versão do seu cluster:

    • Se o seu cluster executa Kubernetes 1.20 ou anterior, selecione ack-ingress-nginx.

    • Caso seu cluster execute uma versão do Kubernetes posterior à 1.20, escolha ack-ingress-nginx-v1.

  3. Implante um controlador de Ingress. Consulte Deploy multiple Ingress controllers for traffic isolation.

    Na página do assistente Parameters:

    1. Exclua todas as anotações na seção controller.service.annotations.

      # enable additional internal slb
      internal:
        enabled: false
        annotations:
          service.beta.kubernetes.io/alibaba-cloud-loadbalancer-address-type: "intranet"
          service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: "slb.s1.small"
    2. Adicione novas anotações.

      # Specify the SLB instance that you want to use.
      service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: "${YOUR_LOADBALANCER_ID}"
      # Overwrite the listeners.
      service.beta.kubernetes.io/alibaba-cloud-loadbalancer-force-override-listeners: "true"
  4. Clique em OK para implantar o controlador de Ingress.

  5. Após a implantação do controlador de Ingress, configure uma classe de Ingress. Consulte Deploy multiple Ingress controllers for traffic isolation.

Como coletar logs de acesso de múltiplos controladores de Ingress?

Pré-requisitos

Procedimento:

  1. Faça login no console ACK. No painel de navegação à esquerda, clique em Clusters.

  2. Na página Clusters, clique no nome do cluster desejado e, em seguida, clique em Cluster Information no painel de navegação à esquerda.

  3. Na página Cluster Information, clique na aba Basic Information e depois clique no hiperlink à direita de Log Service Project na seção Cluster Resources.

  4. Na página Logstores, crie um Logstore (consulte Manage Logstores). Crie um Logstore separado por controlador de Ingress para evitar coleta duplicada.

    • Nomeie o Logstore de acordo com o controlador de Ingress que o utiliza.

    • Na mensagem exibida, clique em Data Collection Wizard.

  5. Na caixa de diálogo Quick Data Import, escolha K8S - Stdout and Stderr - Old Version > Integrate Now. Na mensagem Note, clique em Continue. Na página Kubernetes Stdout and Stderr, realize o seguinte:

    1. Na etapa Create Machine Group, clique em Use Existing Machine Groups.

    2. Na etapa Machine Group Configurations, selecione o grupo de máquinas k8s-group-<YOUR_CLUSTER_ID> e clique em > para mover o grupo de máquinas para a seção Applied Server Groups. Em seguida, clique em Next.

    3. Na etapa Logtail Configuration:

      1. Clique em Import Other Configuration. Selecione o projeto usado pelo cluster e a configuração k8s-nginx-ingress. Depois, clique em OK.

      2. Na seção Global Configurations, modifique o nome da configuração. Ative a opção Container Filtering e adicione os rótulos dos containers do controlador de Ingress como pares chave-valor.

      3. Na seção Processor Configurations, clique em Extract Field (Regex Mode) na coluna Processor Name para visualize os campos de processamento de log.

        Nota

        Se diferentes NGINX Ingress Controllers usarem formatos de log distintos, configure as chaves de campo de log e as expressões regulares correspondentes.

    4. Na etapa Query and Analysis Configurations, clique em Next.

    5. Na etapa End, clique em Query Log para visualize os logs coletados.

Como ative listeners TCP para o nginx-ingress-controller?

Por padrão, os Ingresses encaminham apenas requisições http e HTTPS. Configure o ingress-nginx para encaminhar requisições TCP externas nas portas especificadas no ConfigMap relevante.

  1. Utilize o modelo tcp-echo para implantar um Service e um Deployment.

  2. Use o modelo a seguir para crie um ConfigMap.

    1. Modifique o arquivo tcp-services-cm.yaml, salve as alterações e saia.

      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: tcp-services
        namespace: kube-system 
      data:
        9000: "default/tcp-echo:9000" # This configuration indicates that external TCP requests received on port 9000 are forwarded to the tcp-echo Service in the default namespace. 
        9001: "default/tcp-echo:9001" 
    2. Crie o ConfigMap.

      kubectl apply -f tcp-services-cm.yaml
  3. Adicione portas TCP ao Service usado pelo nginx-ingress-controller, salve as alterações e saia.

    kubectl edit svc nginx-ingress-lb -n kube-system 
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: nginx-ingress-lb
      name: nginx-ingress-lb
      namespace: kube-system
    spec:
      allocateLoadBalancerNodePorts: true
      clusterIP: 192.168.xx.xx
      ipFamilies:
      - IPv4
      ports:
      - name: http
        nodePort: 30xxx
        port: 80
        protocol: TCP
        targetPort: 80
      - name: https
        nodePort: 30xxx
        port: 443
        protocol: TCP
        targetPort: 443
      - name: tcp-echo-9000       # The port name.
        port: 9000                # The port number.
        protocol: TCP             # The protocol.
        targetPort: 9000          # The destination port.
      - name: tcp-echo-9001       # The port name.
        port: 9001                # The port number.
        protocol: TCP             # The protocol.
        targetPort: 9001
      selector:
        app: ingress-nginx
      sessionAffinity: None
      type: LoadBalancer
  4. Verifique a configuração:

    1. Consulte o Ingress para obter o endereço IP da instância SLB:

       kubectl get svc -n kube-system| grep nginx-ingress-lb 

      Saída esperada:

      nginx-ingress-lb      LoadBalancer   192.168.xx.xx  172.16.xx.xx   80:31246/TCP,443:30298/TCP,9000:32545/TCP,9001:31069/TCP   
    2. Envie helloworld para o endereço IP na porta 9000 usando nc. Se nenhuma resposta for retornada, a configuração entrou em vigor.

      echo "helloworld" |  nc <172.16.xx.xx> 9000
      
      echo "helloworld" |  nc <172.16.xx.xx> 9001

Como o NGINX Ingress Controller associa um certificado TLS a uma requisição?

Em um recurso Kubernetes Ingress, o certificado TLS é definido no campo spec.tls, mas o hostname ao qual ele se aplica é especificado no campo spec.rules.host.

O NGINX Ingress Controller processa essas regras e armazena o mapeamento entre cada hostname e seu certificado correspondente em uma tabela Lua interna.

Fluxo da requisição

  1. Quando um cliente inicia uma requisição HTTPS, ele inclui o hostname solicitado na extensão Server Name Indication (SNI) do handshake tls.

  2. O NGINX Ingress Controller recebe essa requisição e usa a função certificate.call() para procurar o hostname SNI em sua tabela de mapeamento Lua.

  3. Se um certificado correspondente for encontrado, ele será apresentado ao cliente para concluir o handshake tls.

  4. Caso nenhum certificado correspondente seja encontrado para o hostname solicitado, o controlador apresenta um certificado fake padrão e autoassinado.

A configuração relevante do NGINX que implementa essa lógica é mostrada abaixo:


    ## Start server _
    server {
        server_name _ ;
        listen 80 default_server reuseport backlog=65535 ;
        listen [::]:80 default_server reuseport backlog=65535 ;
        listen 443 default_server reuseport backlog=65535 ssl http2 ;
        listen [::]:443 default_server reuseport backlog=65535 ssl http2 ;
        set $proxy_upstream_name "-";
        ssl_reject_handshake off;
        ssl_certificate_by_lua_block {
            certificate.call()
        }
   ...
   }
    
    
    ## Start server www.example.com
    server {
        server_name www.example.com ;
        listen 80  ;
        listen [::]:80  ;
        listen 443  ssl http2 ;
        listen [::]:443  ssl http2 ;
        set $proxy_upstream_name "-";
        ssl_certificate_by_lua_block {
            certificate.call()
        }
    ...
    }

O ingress-nginx suporta Online Certificate Status Protocol (OCSP) Stapling, o que elimina o contato direto com a CA para verificações de revogação e reduz o tempo inicial de conexão. Consulte Configure OCSP stapling.

O que fazer se nenhum certificado corresponder a um NGINX Ingress?

Erros de acesso HTTPS podem ocorrer se o certificado TLS e sua chave privada não corresponderem, ou se o nome de domínio no certificado não coincidir com o hostname usado pelo cliente. Execute as operações a seguir para solucionar esse problema:

  • Verifique se o certificado e a chave privada correspondem

    Extraia o certificado e a chave privada do Secret do Kubernetes e compare seus módulos criptográficos:

    # Replace <YOUR-SECRET-NAME> and <SECRET-NAMESPACE> with your values
    kubectl get secret <YOUR-SECRET-NAME>  -n <SECRET-NAMESPACE> -o jsonpath='{.data.tls\.crt}' | base64 -d > /tmp/tls.crt && \ # Replace with <YOUR-SECRET-NAME> with the Secret you use.
    kubectl get secret <YOUR-SECRET-NAME>  -n <SECRET-NAMESPACE> -o jsonpath='{.data.tls\.key}' | base64 -d > /tmp/tls.key && \
    
    # Calculate and compare the MD5 hash of the moduli for the certificate and the key
    openssl x509 -noout -modulus -in /tmp/tls.crt | openssl md5 && \
    openssl rsa -noout -modulus -in /tmp/tls.key | openssl md5

    Esses comandos extraem o certificado e a chave para /tmp/tls.crt e /tmp/tls.key, respectivamente. Os comandos openssl calculam o hash MD5 do módulo público para ambos.

    Se os valores de hash não forem idênticos, o certificado e a chave privada não correspondem. Atualize o Secret com um par de chaves válido e correspondente.

  • Verifique se o certificado corresponde ao nome de domínio

    Inspecione o certificado e verifique os nomes de domínio que ele cobre:

    kubectl get secret  <YOUR-SECRET-NAME>  -n <SECRET-NAMESPACE>  -o jsonpath={.data."tls\.crt"} | base64 -d  | openssl x509  -text -noout

    Revise a saída:

    • Subject: Procure o campo Common Name (CN), que estará em um formato semelhante a CN = example.com.

    • Subject Alternative Name (SAN): Procure as entradas DNS:.

    Se o seu hostname não estiver listado no CN ou nas entradas SAN, o certificado é inválido para esse domínio. Obtenha um novo certificado que cubra o(s) hostname(s) correto(s).

O que fazer se os pods do NGINX falharem nas verificações de integridade sob alto tráfego?

Contexto

A verificação de integridade do NGINX Ingress Controller acessa o caminho /healthz na porta 10246, verificando se o processo do NGINX está saudável.

Sintoma

Quando as verificações de integridade falham, os logs indicam que o endpoint healthz está inacessível:

I0412 11:01:52.581960       7 healthz.go:261] nginx-ingress-controller check failed: healthz
[-]nginx-ingress-controller failed: the ingress controller is shutting down
2024/04/12 11:01:55 Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
W0412 11:01:55.895683       7 nginx_status.go:171] unexpected error obtaining nginx status info: Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
I0412 11:02:02.582247       7 healthz.go:261] nginx-ingress-controller check failed: healthz
[-]nginx-ingress-controller failed: the ingress controller is shutting down
2024/04/12 11:02:05 Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
W0412 11:02:05.896126       7 nginx_status.go:171] unexpected error obtaining nginx status info: Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
I0412 11:02:12.582687       7 healthz.go:261] nginx-ingress-controller check failed: healthz
[-]nginx-ingress-controller failed: the ingress controller is shutting down
2024/04/12 11:02:15 Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
W0412 11:02:15.895719       7 nginx_status.go:171] unexpected error obtaining nginx status info: Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
I0412 11:02:22.582516       7 healthz.go:261] nginx-ingress-controller check failed: healthz
[-]nginx-ingress-controller failed: the ingress controller is shutting down
2024/04/12 11:02:25 Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
W0412 11:02:25.896955       7 nginx_status.go:171] unexpected error obtaining nginx status info: Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
I0412 11:02:28.983016       7 nginx.go:408] "NGINX process has stopped"
I0412 11:02:28.983033       7 sigterm.go:44] Handled quit, delaying controller exit for 10 seconds
I0412 11:02:32.582587       7 healthz.go:261] nginx-ingress-controller check failed: healthz
[-]nginx-ingress-controller failed: the ingress controller is shutting down
2024/04/12 11:02:35 Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
W0412 11:02:35.895853       7 nginx_status.go:171] unexpected error obtaining nginx status info: Get "http://127.0.0.1:10246/nginx_status": dial tcp 127.0.0.1:10246: connect: connection refused
I0412 11:02:38.986048       7 sigterm.go:47] "Exiting" code=0

Causa

Sob alto tráfego, os processos worker do NGINX podem atingir quase 100% de utilização da CPU, deixando recursos insuficientes para responder às sondas de verificação de integridade a tempo.

Solução

Increase the number of pod replicas for the NGINX Ingress Controller para distribuir o tráfego e reduzir a pressão da CPU por pod.

O que fazer se o cert-manager falhar ao emitir um certificado?

Isso ocorre quando o Web Application Firewall (WAF) está habilitado. O WAF pode interceptar as requisições HTTP01 que o cert-manager usa para verificação de propriedade do domínio, impedindo a emissão do certificado.

Para resolver isso, desative temporariamente o WAF para permitir que o desafio HTTP-01 seja concluído com sucesso.

Importante

Antes de desativar seu WAF, avalie completamente as possíveis implicações de segurança para evitar expor sua aplicação a riscos desnecessários.

Por que o NGINX está usando uma grande quantidade de memória sob alto tráfego?

Sintoma

Sob alto tráfego, o uso de memória do NGINX Ingress Controller aumenta significativamente, causando eventualmente um evento de Out-of-Memory (OOM).

Causa

Se o processo do controlador consumir memória excessiva, o problema provavelmente é um vazamento de memória na coleta de métricas do Prometheus.

Este é um problema conhecido na versão 1.6.4 do NGINX Ingress Controller, frequentemente ligado a métricas de alta cardinalidade, como nginx_ingress_controller_ingress_upstream_latency_seconds.

Solução

Atualize o NGINX Ingress Controller para a versão mais recente, que corrige esse problema. Ao configuring NGINX Ingress for high-traffic environments, monitore as métricas que impactam significativamente o uso de memória.

Recursos da comunidade:

O que fazer se o NGINX Ingress Controller estiver em um estado de atualização travado?

Sintoma

Durante uma implementação gradual (canary upgrade) do NGINX Ingress Controller, o processo fica preso na fase de validação. Você pode ver: Operation is forbidden for task in a failed state.

Causa

Isso ocorre quando a tarefa de atualização do add-on é limpa pelo sistema após exceder seu período de expiração de 4 dias. Redefina manualmente o estado de implantação do add-on para resolver isso.

Nota: Se o add-on já atingiu a fase final Released da atualização, nenhuma ação é necessária. Simplesmente aguarde a tarefa atual expirar e terminar automaticamente.

Procedimento

Redefina o Deployment e permita que a atualização prossiga.

  1. Abra o manifesto do Deployment para edição:

    kubectl edit deploy -n kube-system  nginx-ingress-controller
  2. No editor, localize os seguintes campos na seção spec e restaure-os para seus valores padrão conforme mostrado abaixo:

    • spec.minReadySeconds: 0

    • spec.progressDeadlineSeconds: 600

    • spec.strategy.rollingUpdate.maxSurge: 25%

    • spec.strategy.rollingUpdate.maxUnavailable: 25%

    spec:
      minReadySeconds:0
      progressDeadlineSeconds: 600
      replicas: 2
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: ingress-nginx
      strategy:
        rollingUpdate:
          maxSurge: 25%
          maxUnavailable: 25%
  3. Salve as alterações e saia do editor.

Resultado esperado

Após salvar, a atualização do add-on é retomada automaticamente e os pods antigos são substituídos para concluir a implementação gradual.

Importante

A atualização é concluída em segundo plano, mas o status do add-on na página Add-ons do console ACK pode mostrar Upgrading por até duas semanas antes de ser resolvido automaticamente.

Por que a codificação de transferência fragmentada (Transfer-Encoding: chunked) parou de funcionar desde a versão 1.10 do controlador?

Sintoma

Sua aplicação define Transfer-Encoding: chunked, e os logs do controlador mostram erros relacionados a cabeçalhos duplicados.

Causa

A partir da v1.10, a versão subjacente do NGINX (consulte logs de atualização do NGINX) impõe uma validação mais rigorosa das respostas http. Se um backend retornar múltiplos cabeçalhos Transfer-Encoding: chunked, o NGINX agora trata a resposta como inválida.

Solução

Garanta que seu backend retorne apenas um único cabeçalho Transfer-Encoding: chunked. Consulte GitHub Issue #11162.

Como configure uma lista de permissões/bloqueios de IP para controle de acesso?

O NGINX Ingress suporta controle de acesso baseado em IP usando anotações em um recurso Ingress ou pares chave-valor no ConfigMap global.

  • ConfigMap: Aplica-se globalmente a todos os Ingresses.

  • Anotação de Ingress: Aplica-se apenas ao recurso Ingress específico.

Nota

As anotações em um recurso Ingress sempre terão precedência sobre a configuração global do ConfigMap.

Use as seguintes anotações no manifesto do seu Ingress:

Anotação

Descrição

nginx.ingress.kubernetes.io/denylist-source-range

Uma lista de bloqueios de endereços IP de cliente ou blocos CIDR. Múltiplos valores podem ser fornecidos, separados por vírgulas (,).

nginx.ingress.kubernetes.io/whitelist-source-range

Uma lista de permissões de endereços IP de cliente ou blocos CIDR. Múltiplos valores podem ser fornecidos, separados por vírgulas (,).

Consulte a documentação oficial para Denylist Source Range e Whitelist Source Range.

Problema conhecido no NGINX Ingress v1.2.1 com defaultBackend

Sintoma

Configure um defaultBackend em um recurso Ingress pode sobrescrever incorretamente a configuração defaultBackend do servidor padrão.

Solução

Este é um problema conhecido (consulte GitHub Issue #8823). Atualize o NGINX Ingress Controller para a versão 1,3 ou posterior. Consulte Upgrade the NGINX Ingress Controller.

Por que recebo um erro Connection reset by peer ao usar curl?

Sintoma

Ao usar curl para acessar um service público externo via http, você recebe o erro: curl: (56) Recv failure: Connection reset by peer.

Causa

Isso geralmente ocorre quando uma requisição http em texto simples contém palavras-chave sinalizadas como sensíveis por intermediários de rede, fazendo com que a conexão seja bloqueada ou redefinida.

Solução

Configure a TLS certificate for your Ingress route e use HTTPS para todas as comunicações para garantir que o tráfego seja criptografado.

Como funciona a prioridade de correspondência de caminho?

Os caminhos de expressão regular do NGINX são avaliados na ordem em que são definidos, e a primeira correspondência é usada. Para permitir uma correspondência de caminho mais precisa, o ingress-nginx primeiro classifica todos os caminhos em ordem decrescente por comprimento e depois os escreve como blocos location no arquivo nginx.conf.

Consulte Ingress Path Matching.

Por que requisições não idempotentes não são tentadas novamente?

A partir da versão 1.9.13, o NGINX não tentará novamente requisições não idempotentes (POST, LOCK e PATCH) quando ocorrer um erro.

Para restaurar o comportamento anterior, defina retry-non-idempotent: "true" no ConfigMap nginx-configuration.

Como suportar requisições com cabeçalhos ou cookies de cliente grandes?

Sintoma

Ao acessar seu service via NGINX Ingress, você recebe um erro 400 Bad Request com a mensagem Request Header Or Cookie Too Large.

Causa

Esse erro ocorre quando o tamanho dos cabeçalhos de requisição ou cookies do cliente excede os tamanhos de buffer padrão configurados no Nginx.

Solução

Aumente os tamanhos de buffer relevantes. Os dois parâmetros principais são:

  • client-header-buffer-size: O tamanho do buffer para cabeçalhos de requisição do cliente. O padrão é 1k.

  • large-client-header-buffers: O número máximo e o tamanho dos buffers para leitura de cabeçalhos de requisição grandes do cliente. O padrão é 4 8k.

Modifique esses parâmetros edite o ConfigMap nginx-configuration: kubectl edit cm -n kube-system nginx-configuration

Exemplo:

client-header-buffer-size: "16k"
large-client-header-buffers: "4 32k" 

Após aplicar as alterações, verifique se elas entraram em vigor na configuração do NGINX. Você pode inspecionar o arquivo nginx.conf dentro de um dos pods do controlador de Ingress: kubectl exec <nginx-ingress-pod> -n kube-system -- cat /etc/nginx/nginx.conf

Por que meus caminhos Exact ou Prefix ainda são tratados como expressões regulares?

Se qualquer regra de Ingress para um determinado host usar a anotação use-regex ou rewrite-target, todos os caminhos sob esse mesmo host serão forçados a usar correspondência de expressão regular sem distinção entre maiúsculas e minúsculas. Esta é a lógica de implementação atual do NGINX Ingress Controller. Consulte a documentação da comunidade.

image.png

Por que o webhook de validação demora a responder ao adicionar um Ingress em um cluster com muitos Ingresses ?

Este é um problema de desempenho conhecido no NGINX Ingress Controller V1.12 e anteriores. O webhook de validação realiza uma verificação completa contra todos os Ingresses existentes, o que pode ser lento em ambientes grandes. Consulte #11115.

Solução:

  • Opção 1: Aumentar o tempo limite do webhook Se você puder tolerar tempos de resposta mais longos e não quiser usar validação incremental, aumente o tempo limite do webhook de validação. O padrão é 10s.

    • Ação: Edite o objeto validatingwebhookconfigurations chamado ingress-nginx-admission e aumente o valor de timeoutSeconds (máximo 30s).

    • Atenção: Este valor será sobrescrito durante uma atualização de add-on.

  • Opção 2: Habilitar validação incremental Modifique o Deployment do NGINX Ingress Controller para adicionar o argumento de inicialização --disable-full-test=true.

    • Efeito: Com este sinalizador, o webhook realizará apenas uma validação incremental na nova regra de Ingress. Isso melhora significativamente a velocidade de validação, mas não detectará conflitos entre diferentes recursos de Ingress.

Uma nota sobre o uso de snippets

Problema

Se você configure anotações server-snippet para o mesmo domínio em múltiplos recursos de Ingress, poderá encontrar um aviso nos logs, e apenas o primeiro snippet será aplicado. Isso pode levar a comportamentos inesperados.

Exemplo de aviso no log:

W0619 14:58:49.323721       7 controller.go:1314] Server snippet already configured for server "test.example.com", skipping (Ingress "default/test.example.com")
W0619 14:58:49.323727       7 controller.go:1314] Server snippet already configured for server "test.example.com", skipping (Ingress "default/test.example.com")
W0619 14:58:49.323734       7 controller.go:1314] Server snippet already configured for server "test.example.com", skipping (Ingress "default/test.example.com")

Este aviso indica que um snippet para test.example.com já foi definido, e as definições subsequentes de outros recursos Ingress estão sendo ignoradas.

Por que o certificado TLS que configurei em um Secret não está funcionando?

Verifique os logs do controlador

Inspecione os logs do seu pod NGINX Ingress Controller em busca de erros relacionados a certificados.

kubectl -n kube-system logs <nginx-ingress-controller-pod-name> | grep "Error getting SSL certificate"

Se você vir um erro semelhante ao abaixo, isso indica um problema ao carregar seu Secret de certificado (onde xxxx é o nome do seu Secret).

Error getting SSL certificate "xxxx": local SSL certificate xxxx tls was not found. Using default certificate

Este erro pode ter três causas principais:

Causa 1: O Secret não existe

Verifique se o Secret mencionado na mensagem de log realmente existe no namespace correto.

Causa 2: O certificado e a chave privada não correspondem

O tls.crt (chave pública) e o tls.key (chave privada) armazenados no Secret devem ser um par correspondente.

  • Se você tentar crie um Secret tls com um par incompatível usando kubectl create secret tls, o comando falhará com um erro: error: tls: private key does not match public key

  • Para verificar se um Secret existente possui incompatibilidade, execute o seguinte script:

    export SECRET_NAME=<Your Secret Name>
    export NAME_SPACE=<Your Secret Namespace>
    diff <(kubectl get secret $SECRET_NAME -n $NAME_SPACE -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -modulus | openssl md5) <(kubectl get secret $SECRET_NAME -n $NAME_SPACE -o jsonpath='{.data.tls\.key}' | base64 -d | openssl rsa -noout -modulus | openssl md5) && echo "Certificate and Key match" || echo "Certificate and Key do not match"

    Este comando compara os módulos do certificado e da chave. Se a chave e o certificado não corresponderem, a saída mostrará dois valores de hash diferentes e a mensagem Certificate and Key do not match. Atualize o Secret com um par de chaves válido.

    root@Aliyun ~/ssl # export SECRET_NAME=test
    root@Aliyun ~/ssl # export NAME_SPACE=default
    root@Aliyun ~/ssl # diff <(kubectl get secret $SECRET_NAME -n $NAME_SPACE -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -modulus | openssl md5) <(kubectl get secret $SECRET_NAME -n $NAME_SPACE -o jsonpath='{.data.tls\.key}' | base64 -d | openssl rsa -noout -modulus | openssl md5) && echo "Certificate and Key match" || echo "Certificate and Key do not match"
    1c1
    < (stdin)= 66a309089e87e32d1b6fe361ebf8cd88
    ---
    > (stdin)= 12e15c5fe35585b6fd9920abc8e8706d
    Certificate and Key do not match

Causa 3: Uma entrada TLS mal configurada em outro Ingress para o mesmo domínio

Se você definiu seções tls para o mesmo domínio em múltiplos recursos de Ingress, um erro em apenas uma dessas configurações pode impedir que o certificado seja carregado corretamente. Revise todos os recursos de Ingress que referenciam o domínio e corrija quaisquer configurações incorretas.

Por que ainda recebo alertas de expiração de certificado após atualizar meu certificado?

Causa

Versões mais antigas possuem um bug conhecido onde a métrica nginx_ingress_controller_ssl_expire_time_seconds não é atualizada após a renovação do certificado, causando alertas obsoletos de certificate expired.

Solução

Limpe a métrica obsoleta realizando uma reinicialização gradual dos pods do NGINX Ingress Controller.

Upgrade NGINX Ingress Controller para a versão 1.11.4 ou posterior, pois esse problema foi resolvido nas versões mais novas.

Como posso encontrar a configuração padrão para uma versão específica do NGINX Ingress Controller?

Os valores padrão dos parâmetros de configuração mudam entre as versões do NGINX Ingress Controller. Por exemplo, use-gzip estava habilitado por padrão nas versões 0.35.0 e anteriores, mas está desabilitado por padrão na versão 1.11.4.

Para encontrar o comportamento padrão de um parâmetro específico em uma determinada versão, consulte o arquivo configmap.md na branch da versão correspondente da documentação oficial.

Exemplo: Para controller-v1.8.0, use o seletor de versão no lado esquerdo da página para alternar para outras versões.