Voltar ao blog

Proxies para Kubernetes Ingress Controller: configuração completa em cluster K8s com exemplos de configuração

Analisamos como configurar corretamente um servidor proxy no Kubernetes Ingress Controller — desde a configuração básica do NGINX até a rotação de IPs residenciais para contornar bloqueios.

📅10 de agosto de 2026
```html

Se o seu cluster K8s faz solicitações externas — para APIs de parceiros, para marketplaces, para plataformas de publicidade — mais cedo ou mais tarde você enfrentará bloqueios por IP. O Ingress Controller por si só gerencia o tráfego de entrada, mas para solicitações de saída através dos pods é necessário um esquema separado com proxy. Neste artigo, analisamos como configurá-lo corretamente: desde a escolha do tipo de proxy até configurações YAML específicas para NGINX Ingress e Traefik.

Por que usar proxy no Kubernetes: cenários reais

Kubernetes é um orquestrador, e a maioria dos artigos sobre ele fala sobre tráfego de entrada: como configurar o Ingress, como emitir um certificado TLS, como rotear solicitações para serviços. Mas há outro lado: o tráfego de saída dos pods. É aqui que surgem problemas com bloqueios, geobloqueios e limites de IP.

Vamos considerar tarefas específicas onde um proxy no cluster K8s se torna uma necessidade:

  • Raspagem e monitoramento de preços. Seu cluster executa um CronJob a cada 15 minutos e coleta dados do Wildberries, Ozon, Amazon. Sem rotação de IP, após 2–3 horas você receberá um bloqueio em todo o intervalo de IP do seu provedor de nuvem.
  • Trabalho com APIs de publicidade. Facebook Marketing API, TikTok Ads API, Google Ads API — todos eles rastreiam a origem das solicitações. Se dezenas de pods enviam solicitações de um único IP de data center, isso é um gatilho para bloqueio automático.
  • Teste de geolocalização. Seu serviço deve mostrar conteúdo diferente para usuários de diferentes países. Através de um proxy, os pods podem simular solicitações das regiões necessárias para testes automatizados.
  • Contornando restrições corporativas. Em algumas infraestruturas, todo o tráfego de saída deve passar por um proxy corporativo — isso é um requisito de conformidade.
  • Trabalho com APIs de parceiros com lista branca de IP. Quando um parceiro permite solicitações apenas de IPs específicos, e seu cluster está escalando e mudando endereços — um proxy com IPs estáticos resolve o problema.

É importante entender a separação arquitetônica: Ingress Controller gerencia o tráfego de entrada (dos usuários para seus serviços), enquanto o proxy para solicitações de saída é uma tarefa separada. No entanto, eles estão interligados: a configuração do proxy é frequentemente definida no nível do mesmo Ingress Controller ou através de anotações que ele lê.

💡 Distinção chave

Neste artigo, analisamos dois cenários: (1) configuração do Ingress Controller como um proxy reverso para servidores upstream externos, e (2) roteamento de tráfego de saída dos pods através de um servidor proxy externo. Ambos os cenários são encontrados em produção.

Qual tipo de proxy escolher para o cluster K8s

A escolha do tipo de proxy afeta diretamente quanto tempo seu cluster poderá operar sem bloqueios. IPs de data center são os mais baratos, mas são facilmente identificáveis e bloqueáveis. IPs residenciais e móveis são mais caros, mas significativamente mais confiáveis para tarefas onde a simulação de um usuário real é importante.

Tipo de proxy Velocidade Risco de bloqueio Melhor cenário no K8s
Data center Alta Alto APIs internas, conformidade corporativa, integrações de parceiros com lista branca de IP
Residenciais Média Baixo Raspagem de marketplaces, trabalho com APIs de publicidade, geoteste
Móveis Média Mínimo Facebook Ads API, TikTok API, tarefas de alta carga com risco de banimento

Para a maioria das tarefas no cluster K8s relacionadas à raspagem ou trabalho com plataformas de publicidade, a escolha ideal é proxies residenciais com rotação. Eles fornecem IPs reais de usuários domésticos, e os algoritmos de proteção dos sites percebem tais solicitações como tráfego de navegador comum.

Do ponto de vista do protocolo, o proxy HTTP/HTTPS é o mais versátil para K8s — é suportado por todos os clientes HTTP populares em qualquer linguagem de programação através das variáveis de ambiente padrão HTTP_PROXY e HTTPS_PROXY. SOCKS5 é necessário apenas para protocolos não padrão ou quando é necessário proxy não apenas HTTP.

Configuração de proxy através do NGINX Ingress Controller

O NGINX Ingress Controller é a opção mais comum no K8s. Vamos considerar dois cenários: configuração do NGINX como um proxy reverso para um upstream externo através de um servidor proxy, e configuração global de proxy de saída para o próprio controlador.

Anotações para proxy de solicitações para upstream

O NGINX Ingress suporta anotações para gerenciar o comportamento do proxy. Se você precisa que o Ingress envie solicitações para um serviço externo através de um proxy intermediário, use um ConfigMap com uma configuração personalizada:

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
data:
  # Proxy HTTP global para solicitações de saída do NGINX
  http-snippet: |
    proxy_connect_timeout 10s;
    proxy_read_timeout 30s;
    proxy_send_timeout 30s;
  # Configuração de upstream através de proxy
  use-proxy-protocol: "false"
  proxy-real-ip-cidr: "0.0.0.0/0"

Recurso Ingress com anotações para proxy

Para um recurso Ingress separado, você pode definir parâmetros de proxy através de anotações. Isso é útil quando diferentes serviços exigem diferentes timeouts e configurações:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-service-ingress
  namespace: production
  annotations:
    kubernetes.io/ingress.class: "nginx"
    # Timeouts do proxy
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "10"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
    # Tamanho do buffer
    nginx.ingress.kubernetes.io/proxy-buffer-size: "16k"
    nginx.ingress.kubernetes.io/proxy-buffers-number: "8"
    # Transmitir o IP real do cliente
    nginx.ingress.kubernetes.io/use-forwarded-headers: "true"
    nginx.ingress.kubernetes.io/forwarded-for-header: "X-Forwarded-For"
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              number: 80

Configuração de proxy externo para solicitações de saída do pod NGINX

Se o próprio NGINX Ingress Controller deve fazer solicitações de saída através de um proxy externo (por exemplo, para verificação de saúde de endpoints externos), você precisa definir variáveis de ambiente no Deployment do controlador:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  template:
    spec:
      containers:
      - name: controller
        image: registry.k8s.io/ingress-nginx/controller:v1.9.4
        env:
        - name: HTTP_PROXY
          valueFrom:
            secretKeyRef:
              name: proxy-credentials
              key: http-proxy-url
        - name: HTTPS_PROXY
          valueFrom:
            secretKeyRef:
              name: proxy-credentials
              key: https-proxy-url
        - name: NO_PROXY
          value: "localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.cluster.local"

Preste atenção à variável NO_PROXY — ela é criticamente importante. Sem ela, todo o tráfego intra-cluster também passará pelo proxy externo, o que quebrará a interação entre os serviços. Em NO_PROXY, sempre inclua os intervalos RFC-1918 e o sufixo .cluster.local.

Configuração de proxy no Traefik Ingress Controller

Traefik é uma alternativa popular ao NGINX Ingress, especialmente em conjunto com Helm e em clusters gerenciados (k3s, Docker Swarm, Nomad). O Traefik possui seu próprio sistema de configuração através de CRD (Custom Resource Definitions) e configurações estáticas/dinâmicas.

Configuração estática do Traefik com proxy

apiVersion: v1
kind: ConfigMap
metadata:
  name: traefik-config
  namespace: traefik
data:
  traefik.yaml: |
    # Configuração estática do Traefik
    entryPoints:
      web:
        address: ":80"
      websecure:
        address: ":443"
    
    # Configurações para operação atrás de um proxy
    serversTransport:
      insecureSkipVerify: false
      maxIdleConnsPerHost: 200
      dialTimeout: 10s
      responseHeaderTimeout: 30s
    
    # Registro para diagnóstico de proxy
    log:
      level: INFO
    
    accessLog:
      fields:
        headers:
          defaultMode: keep
          names:
            X-Forwarded-For: keep
            X-Real-IP: keep

Middleware para adicionar cabeçalhos de proxy

No Traefik, você pode criar um Middleware que adiciona ou modifica cabeçalhos ao passar solicitações. Isso é útil para transmitir corretamente o IP real do cliente através da cadeia de proxies:

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: proxy-headers
  namespace: production
spec:
  headers:
    customRequestHeaders:
      X-Forwarded-Proto: "https"
    # Remover cabeçalhos que podem revelar a infraestrutura
    customResponseHeaders:
      X-Powered-By: ""
      Server: ""
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: my-app-route
  namespace: production
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`myapp.example.com`)
    kind: Rule
    middlewares:
    - name: proxy-headers
    services:
    - name: my-service
      port: 80

Variáveis de ambiente para o Deployment do Traefik

Assim como no NGINX, para o Traefik definimos variáveis de ambiente através de valores do Helm ou diretamente no Deployment. Ao usar o Helm Chart, isso é feito através do values.yaml:

# values.yaml para o Helm chart do Traefik
deployment:
  enabled: true
  kind: Deployment
  
env:
  - name: HTTP_PROXY
    valueFrom:
      secretKeyRef:
        name: proxy-credentials
        key: http-proxy-url
  - name: HTTPS_PROXY
    valueFrom:
      secretKeyRef:
        name: proxy-credentials
        key: https-proxy-url
  - name: NO_PROXY
    value: "localhost,127.0.0.1,10.96.0.0/12,10.244.0.0/16,.cluster.local,.svc"

Proxy através de variáveis de ambiente nos pods

A maneira mais versátil de configurar um proxy de saída para qualquer pod é através de variáveis de ambiente padrão. Este método funciona independentemente da linguagem de programação e do framework: Python requests, Go net/http, Node.js axios, Java HttpClient — todos eles leem HTTP_PROXY e HTTPS_PROXY automaticamente.

Opção 1: Diretamente no Pod Spec

apiVersion: v1
kind: Pod
metadata:
  name: scraper-pod
  namespace: production
spec:
  containers:
  - name: scraper
    image: mycompany/scraper:latest
    env:
    - name: HTTP_PROXY
      value: "http://username:[email protected]:8080"
    - name: HTTPS_PROXY
      value: "http://username:[email protected]:8080"
    - name: NO_PROXY
      value: "localhost,127.0.0.1,10.0.0.0/8,.cluster.local"
    resources:
      requests:
        memory: "128Mi"
        cpu: "100m"
      limits:
        memory: "256Mi"
        cpu: "500m"

⚠️ Não armazene credenciais em texto claro!

O exemplo acima é mostrado para fins ilustrativos. Em produção, as credenciais do proxy sempre devem ser armazenadas em Kubernetes Secret e passadas através de secretKeyRef. Mais detalhes — na seção sobre Secrets abaixo.

Opção 2: Através de ConfigMap para vários pods

Se o proxy for utilizado por vários Deployments, é conveniente extrair as configurações para um ConfigMap e conectá-lo através de envFrom:

apiVersion: v1
kind: ConfigMap
metadata:
  name: proxy-config
  namespace: production
data:
  NO_PROXY: "localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,.cluster.local,.svc.cluster.local"
  PROXY_TIMEOUT: "30"
  PROXY_MAX_RETRIES: "3"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: price-monitor
  namespace: production
spec:
  replicas: 5
  selector:
    matchLabels:
      app: price-monitor
  template:
    metadata:
      labels:
        app: price-monitor
    spec:
      containers:
      - name: monitor
        image: mycompany/price-monitor:v2.1
        envFrom:
        - configMapRef:
            name: proxy-config
        - secretRef:
            name: proxy-credentials
        ports:
        - containerPort: 8080

Opção 3: Mutating Webhook Admission Controller

Para clusters corporativos, onde todos os pods são obrigados a usar proxy, pode-se configurar um webhook de admissão mutante que adiciona automaticamente as variáveis de ambiente do proxy a todos os pods criados. Esta solução é utilizada em infraestruturas empresariais, onde a conformidade exige que todo o tráfego de saída passe por um proxy corporativo. A implementação de tal webhook está além do escopo deste artigo, mas vale a pena saber de sua existência.

Rotação de IP e gerenciamento do pool de proxies no K8s

Um proxy estático é bom para conformidade corporativa, mas ruim para tarefas onde é necessário evitar bloqueios. Se 50 dos seus pods enviam solicitações através do mesmo IP, esse IP será bloqueado muito rapidamente. A solução é a rotação de proxies.

Esquema com Proxy Sidecar

Um dos padrões é executar um agente proxy como um contêiner sidecar ao lado do aplicativo principal. O sidecar aceita solicitações em localhost:8080 e as reencaminha através de um pool rotativo de proxies externos:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: scraper-with-proxy-sidecar
  namespace: production
spec:
  replicas: 10
  selector:
    matchLabels:
      app: scraper
  template:
    metadata:
      labels:
        app: scraper
    spec:
      containers:
      # Aplicativo principal
      - name: scraper
        image: mycompany/scraper:latest
        env:
        - name: HTTP_PROXY
          value: "http://localhost:8080"
        - name: HTTPS_PROXY
          value: "http://localhost:8080"
        - name: NO_PROXY
          value: "localhost,127.0.0.1,.cluster.local"
      
      # Sidecar: agente proxy local com rotação
      - name: proxy-rotator
        image: mycompany/proxy-rotator:latest
        ports:
        - containerPort: 8080
        env:
        - name: PROXY_LIST_URL
          valueFrom:
            secretKeyRef:
              name: proxy-credentials
              key: api-endpoint
        - name: ROTATION_INTERVAL
          value: "60"  # rotação a cada 60 segundos
        resources:
          requests:
            memory: "64Mi"
            cpu: "50m"
          limits:
            memory: "128Mi"
            cpu: "200m"

Esquema com Proxy Service centralizado

Uma abordagem alternativa é ter um único Proxy Service dentro do cluster, ao qual todos os pods se conectam. Isso é mais fácil de gerenciar: basta atualizar um Secret com as credenciais do proxy, e todos os pods começarão automaticamente a usar os novos dados.

apiVersion: v1
kind: Service
metadata:
  name: proxy-gateway
  namespace: proxy-system
spec:
  selector:
    app: proxy-gateway
  ports:
  - name: http
    port: 8080
    targetPort: 8080
  - name: socks5
    port: 1080
    targetPort: 1080
  type: ClusterIP
---
# Os pods usam proxy através do DNS interno
# HTTP_PROXY=http://proxy-gateway.proxy-system.svc.cluster.local:8080

Para tarefas onde a anonimidade e o risco mínimo de bloqueios são críticos (por exemplo, raspagem de marketplaces ou trabalho com APIs de publicidade), recomendamos usar proxies residenciais com rotação — eles fornecem IPs reais de usuários domésticos, tornando o tráfego do seu cluster indistinguível do tráfego de um navegador comum.

Armazenamento de credenciais de proxy em Kubernetes Secrets

O armazenamento seguro de credenciais é um requisito obrigatório para qualquer cluster de produção. Nunca insira login/senha do proxy diretamente nos manifestos YAML que são armazenados em repositórios Git.

Criação de Secret para proxy

# Criação através do kubectl (os valores são codificados em base64 automaticamente)
kubectl create secret generic proxy-credentials \
  --namespace=production \
  --from-literal=http-proxy-url='http://user:[email protected]:8080' \
  --from-literal=https-proxy-url='http://user:[email protected]:8080' \
  --from-literal=socks5-proxy-url='socks5://user:[email protected]:1080'

# Verificação do Secret criado
kubectl get secret proxy-credentials -n production -o yaml

Manifesto YAML do Secret

apiVersion: v1
kind: Secret
metadata:
  name: proxy-credentials
  namespace: production
  labels:
    app: proxy-config
    managed-by: ops-team
type: Opaque
# Valores codificados em base64
# echo -n 'http://user:pass@proxy:8080' | base64
stringData:
  # stringData permite especificar valores em texto claro
  # Kubernetes os codifica automaticamente em base64
  http-proxy-url: "http://user:[email protected]:8080"
  https-proxy-url: "http://user:[email protected]:8080"
  proxy-host: "gate.proxycove.com"
  proxy-port: "8080"
  proxy-username: "user"
  proxy-password: "password"

Uso do Secret no Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-worker
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api-worker
  template:
    metadata:
      labels:
        app: api-worker
    spec:
      containers:
      - name: worker
        image: mycompany/api-worker:latest
        env:
        - name: HTTP_PROXY
          valueFrom:
            secretKeyRef:
              name: proxy-credentials
              key: http-proxy-url
        - name: HTTPS_PROXY
          valueFrom:
            secretKeyRef:
              name: proxy-credentials
              key: https-proxy-url
        - name: NO_PROXY
          value: "localhost,127.0.0.1,10.0.0.0/8,.cluster.local"
        # Para aplicativos que leem host/porta separadamente
        - name: PROXY_HOST
          valueFrom:
            secretKeyRef:
              name: proxy-credentials
              key: proxy-host
        - name: PROXY_PORT
          valueFrom:
            secretKeyRef:
              name: proxy-credentials
              key: proxy-port

Integração com armazenamentos externos de segredos

Em um ambiente corporativo, é recomendável usar o External Secrets Operator para sincronizar segredos do HashiCorp Vault, AWS Secrets Manager ou Azure Key Vault. Isso permite atualizar automaticamente as credenciais do proxy sem intervenção manual e reinicialização dos pods:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: proxy-credentials-ext
  namespace: production
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-backend
    kind: ClusterSecretStore
  target:
    name: proxy-credentials
    creationPolicy: Owner
  data:
  - secretKey: http-proxy-url
    remoteRef:
      key: secret/proxy/proxycove
      property: http_proxy_url
  - secretKey: https-proxy-url
    remoteRef:
      key: secret/proxy/proxycove
      property: https_proxy_url

Diagnóstico e erros comuns ao configurar proxy no K8s

Mesmo com a configuração correta, podem surgir problemas. Vamos analisar os mais comuns e as formas de diagnóstico.

Problema 1: O tráfego intra-cluster passa pelo proxy

Sintoma: os pods param de se ver, a resolução DNS dentro do cluster falha, os serviços não respondem. A causa — a variável NO_PROXY não está configurada.

O valor mínimo necessário para NO_PROXY para um cluster K8s padrão:

NO_PROXY=localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.cluster.local,.svc,.svc.cluster.local,kubernetes.default.svc

Problema 2: O proxy não é aplicado a um pod específico

Diagnóstico: entre no pod e verifique as variáveis de ambiente:

# Verificar variáveis de ambiente no pod
kubectl exec -it <pod-name> -n production -- env | grep -i proxy

# Testar conexão através do proxy a partir do pod
kubectl exec -it <pod-name> -n production -- curl -v --proxy http://proxy:8080 https://httpbin.org/ip

# Verificar se o Secret está montado corretamente
kubectl exec -it <pod-name> -n production -- env | grep PROXY

Problema 3: Erros TLS ao usar proxy HTTPS

Se o proxy usa um certificado autoassinado ou CA corporativa, os aplicativos receberão erros de verificação TLS. A solução — adicionar o certificado CA do proxy aos confiáveis:

# Criar ConfigMap com o certificado CA
kubectl create configmap proxy-ca-cert \
  --from-file=proxy-ca.crt=./proxy-ca.crt \
  -n production

# Montar no pod
spec:
  containers:
  - name: app
    volumeMounts:
    - name: proxy-ca
      mountPath: /etc/ssl/certs/proxy-ca.crt
      subPath: proxy-ca.crt
  volumes:
  - name: proxy-ca
    configMap:
      name: proxy-ca-cert

Problema 4: Solicitações lentas através do proxy

Se as solicitações através do proxy são significativamente mais lentas do que as diretas — verifique:

  • Resolução DNS: certifique-se de que as solicitações DNS não estão passando pelo proxy (adicione ao NO_PROXY)
  • Conexões Keep-alive: configure o pool de conexões para o servidor proxy
  • Localização geográfica: o servidor proxy deve estar fisicamente próximo ao recurso de destino
  • Tipo de proxy: para tarefas de alta velocidade, considere proxies de data center — eles oferecem a menor latência

Comandos úteis para diagnóstico

# Verificar logs do Ingress Controller
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=100

# Verificar eventos do pod
kubectl describe pod <pod-name> -n production

# Testar conexão proxy a partir do pod
kubectl run test-proxy --image=curlimages/curl --rm -it --restart=Never -- \
  curl -x http://user:pass@proxy:8080 -v https://httpbin.org/ip

# Verificar se o Secret existe e contém as chaves necessárias
kubectl get secret proxy-credentials -n production -o jsonpath='{.data}' | python3 -c "
import sys, json, base64
data = json.load(sys.stdin)
for k, v in data.items():
    print(f'{k}: {base64.b64decode(v).decode()[:20]}...')
"

Conclusão e recomendações

Configurar um proxy no Kubernetes não é uma tarefa única, mas parte da arquitetura de segurança da rede do cluster. Vamos resumir:

  • Para NGINX Ingress Controller — use anotações para configurar os parâmetros do proxy no nível de recursos Ingress individuais, e variáveis de ambiente no Deployment para configurações globais de tráfego de saída.
  • Para Traefik — combine configuração estática através de ConfigMap com Middleware para gerenciar cabeçalhos.
  • Para pods — as variáveis padrão HTTP_PROXY / HTTPS_PROXY através de Secrets — é a abordagem mais versátil e segura.
  • Sempre configure NO_PROXY — caso contrário, o tráfego intra-cluster será quebrado.
  • Nunca armazene credenciais do proxy em texto claro em manifestos ou no Git.
  • Para produção — use o External Secrets Operator para rotação automática de credenciais.

Se o seu cluster K8s executa tarefas onde a estabilidade do IP e o risco mínimo de bloqueios são críticos — raspagem, trabalho com APIs de publicidade, geoteste — recomendamos usar proxies residenciais. Eles fornecem IPs reais de usuários domésticos, que os algoritmos de proteção percebem como tráfego legítimo. Para tarefas com altas exigências de velocidade e riscos mínimos de bloqueios por parte de plataformas móveis, os proxies móveis são uma excelente opção — eles operam através de redes reais 4G/5G de operadoras.

```