Por que os pods do GKE não alcançam hosts locais pela VPN
O nó alcança a rede local, o pod não. As exclusões de masquerade do GKE deixam os endereços dos pods sem tradução para destinos 10.x.
O ping funciona a partir do nó e falha a partir do pod, e nada chega ao local. O túnel e a rota estão bem; o endereço de origem no fio não. O que distingue os dois casos é o que o pacote afirma ser ao deixar o cluster, e o GKE tem uma opinião sobre isso. O mecanismo é uma lista de exclusões de masquerade, e lê-la exige um único comando.
Leia a lista efetiva antes de mudar qualquer coisa
O GKE fornece um agente que decide, para cada faixa de destino, se o tráfego dos pods é reescrito para o endereço do nó na saída. A configuração padrão nomeia os três blocos RFC1918, 10.0.0.0/8, 172.16.0.0/12 e 192.168.0.0/16, como destinos isentos. Por isso tudo o que você envia de um pod para um host 10.x local sai do nó com o endereço do próprio pod ainda anexado. O tráfego do próprio nó não é reescrito, e é exatamente por isso que o ping dele funciona.
Leia a configuração pretendida e as regras instaladas, porque podem discordar. kubectl -n kube-system get configmap ip-masq-agent -o yaml mostra o que foi dito ao agente, e kubectl -n kube-system get pods -l k8s-app=ip-masq-agent mostra se algo está rodando para aplicá-lo. Em um nó, iptables-save | grep -i masq mostra as regras que realmente existem no kernel. Quando o ConfigMap diz uma coisa e as regras outra, o suspeito é o agente, não a rede.
Confirme o endereço de origem com uma captura
Faça uma captura antes de mudar uma lista. Um filtro no único destino mantém a saída legível: tcpdump -ni any host 10.20.30.40.
Compare isso com o que o outro lado relata. Uma captura no local que mostra o endereço do pod e nenhuma resposta fecha o ciclo: a lista de exclusões explica a assimetria sem qualquer falha do túnel. Duas observações de um mesmo endereço de origem bastam para parar de especular sobre a CNI.
Estreite a exclusão para o CIDR dos pods
O reparo suportado estreita a isenção em vez de removê-la: mantenha o CIDR dos pods isento e descarte o resto do espaço 10.x. Essa lista fica no ConfigMap do agente sob nonMasqueradeCIDRs, e alterá-la é uma edição seguida de uma implantação. Substitua a entrada ampla pela faixa real de pods do cluster, mantenha os outros blocos privados se o tráfego interno do cluster ainda precisar deles, e deixe resyncInterval em paz a menos que tenha um motivo. Aplique, confirme que os pods do agente reiniciaram e confirme que as regras do kernel mudaram.
Esta é uma mudança em todo o cluster com um raio de impacto real. Depois de aplicada, o tráfego que antes mantinha a origem do pod agora chega reescrito para o nó, então tudo o que dependia desses endereços de pod vê um emissor diferente. As vítimas são registros, listas de permissão e regras de firewall locais que nomeiam endereços de pod, e elas falham silenciosamente. Anuncie a mudança como mudança de comportamento, não como correção.
Em um cluster com vários pools de nós, verifique se o agente está agendado nos nós onde os pods afetados realmente rodam. Um pool sem o DaemonSet mantém suas regras antigas, e nada no ConfigMap mostrará isso.
A alternativa e seu custo
A outra opção mantém os endereços dos pods intactos e ensina o caminho sobre eles. O CIDR dos pods entra nos seletores de tráfego do Cloud VPN, e o lado local precisa de uma rota de retorno para ele, para que as respostas saibam para onde ir. Isso preserva a identidade do pod, que alguns modelos de segurança querem, e amplia tanto o escopo de roteamento quanto o de firewall que o outro lado precisa aceitar.
A troca é legibilidade contra escopo. A tradução faz o lado local ver um endereço por nó, o que é fácil de colocar em uma lista de permissão e esconde qual pod enviou o quê. Sem tradução, o endereço do pod é mantido de ponta a ponta, o que é melhor para atribuição e pior para cada dispositivo do caminho que precisa aprender uma faixa nova. Nenhuma das opções é um defeito do Docker ou da CNI; ambas são decisões de roteamento com uma conta operacional. Escolha aquela cuja conta sua equipe consegue pagar, e escreva por quê.
Verifique e reverta
Execute a mesma captura de novo. Uma captura em nível de nó que ainda imprime o endereço do pod depois da sua edição significa que as regras nunca mudaram, diga o que disser o ConfigMap. O fio é o fato; todo o resto é inferência.
Depois verifique a direção inversa, porque metade dessas mudanças só é verificada na saída. Confirme que a resposta chega ao nó ou ao pod que enviou a requisição, e confirme que a aplicação terminou em vez de apenas receber um SYN. Uma captura mostrando uma requisição sem resposta é um problema de roteamento do outro lado, não um problema de masquerade deste lado.
Reverter é o ConfigMap anterior, aplicado da mesma forma, com a mesma confirmação de que o agente reiniciou e as regras mudaram. Guarde o endereço de origem antes e depois para uma requisição conhecida no registro de mudanças, pois é essa única linha que prova que a mudança fez o que você disse. O guia do agente de masquerade IP do GKE documenta os padrões e os campos do ConfigMap. Se o endereço de origem não mudar após a implantação, o agente não está rodando naquele nó e nenhuma edição de YAML vai consertar isso.