Controlar o tráfego de saída do pod usando políticas de rede FQDN


Nesta página, explicamos como controlar a comunicação de saída entre pods e recursos fora do cluster do Google Kubernetes Engine (GKE) usando nomes de domínio totalmente qualificados (FQDN, na sigla em inglês). O recurso personalizado usado para configurar os FQDNs é o FQDNNetworkPolicy.

Antes de começar

Antes de começar, veja se você realizou as seguintes tarefas:

  • Ative a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Se você quiser usar a CLI do Google Cloud para essa tarefa, instale e, em seguida, inicialize a CLI gcloud. Se você instalou a gcloud CLI anteriormente, instale a versão mais recente executando gcloud components update.

Requisitos e limitações

Os recursos do FQDNNetworkPolicy têm os seguintes requisitos e limitações:

  • Você precisa ter um cluster do GKE executando uma das seguintes versões:
    • 1.26.4-gke.500 ou mais recente
    • 1.27.1-gke.400 ou mais recente
  • O cluster precisa usar o GKE Dataplane V2.
    • Use um dos provedores de DNS no cluster do GKE, o kube-dns ou o Cloud DNS. Não é possível usar implantações personalizadas do kube-dns ou do Core DNS.
  • Google Cloud CLI versão 462.0.0 ou mais recente.
  • Os pools de nós do Windows não são compatíveis.
  • O Cloud Service Mesh não é compatível.
  • Se você tiver endereços IP codificados no aplicativo, use o campo IPBlock da política de rede do Kubernetes NetworkPolicy em vez de um FQDNNetworkPolicy.
  • Os resultados retornados por servidores de nomes DNS que não são de cluster, como servidores de nomes alternativos em resolv.conf, não são considerados válidos para serem programados na lista de permissões no plano de dados do GKE.
  • O número máximo de endereços IP IPv4 e IPv6 que um FQDNNetworkPolicy pode resolver é 50.
  • Não é possível permitir o tráfego para um ClusterIP ou Headless Service como um destino de saída em um FQDNNetworkPolicy porque o GKE converte o endereço IP virtual (VIP, na sigla em inglês) do Serviço em endereços IP do pod de back-end antes de avaliar as regras da política de rede. Em vez disso, use um NetworkPolicy baseado em rótulos do Kubernetes.
  • Há uma cota máxima de 100 endereços IP por nome de host.
  • A criptografia transparente entre nós não é compatível com políticas de rede FQDN.
  • As políticas de rede FQDN que usam a correspondência de padrões só correspondem a subdomínios no mesmo nível do caractere curinga. Por exemplo, pattern: *.company.com corresponde a api.company.com ou store.company.com, mas não a eu.api.company.com ou company.com.

Ativar política de rede FQDN

É possível ativar a política de rede FQDN em um cluster novo ou atual.

Ativar a política de rede FQDN em um novo cluster

Crie o cluster usando a sinalização --enable-fqdn-network-policy:

gcloud container clusters create CLUSTER_NAME  \
    --enable-fqdn-network-policy

Substitua CLUSTER_NAME pelo nome do cluster.

Ativar a política de rede FQDN em um cluster atual

  1. No caso dos clusters do Autopilot e do Standard, atualize-os usando a flag --enable-fqdn-network-policy:

    gcloud container clusters update CLUSTER_NAME  \
        --enable-fqdn-network-policy
    

    Substitua CLUSTER_NAME pelo nome do cluster.

  2. Apenas no caso dos clusters do Standard, reinicie o DaemonSet anetd do GKE Dataplane V2:

    kubectl rollout restart ds -n kube-system anetd
    

Criar um FQDNNetworkPolicy

  1. Salve o seguinte manifesto como fqdn-network-policy.yaml:

    apiVersion: networking.gke.io/v1alpha1
    kind: FQDNNetworkPolicy
    metadata:
      name: allow-out-fqdnnp
    spec:
      podSelector:
        matchLabels:
          app: curl-client
      egress:
      - matches:
        - pattern: "*.yourdomain.com"
        - name: "www.google.com"
        ports:
        - protocol: "TCP"
          port: 443
    

    Esse manifesto tem as seguintes propriedades:

    • name: www.google.com: o nome de domínio totalmente qualificado. Os endereços IP fornecidos pelo servidor de nomes associado a www.google.com são permitidos. É necessário especificar name, pattern ou ambos.
    • pattern: "*.yourdomain.com": endereços IP fornecidos por servidores de nomes correspondentes a esse padrão são permitidos. É possível usar as seguintes expressões regulares para a chave de padrão: ^([a-zA-Z0-9*]([-a-zA-Z0-9_*]*[a-zA-Z0-9*])*\.?)*$. Os critérios de correspondência são cumulativos. É possível usar vários campos pattern. É necessário especificar name, pattern ou ambos.
    • protocol: "TCP" e port: 443: especifica um protocolo e uma porta. Se um pod tentar estabelecer uma conexão com endereços IP usando essa combinação de porta e protocolo, a resolução de nome funcionará, mas o plano de dados bloqueará a conexão de saída. Este campo é opcional.
  2. Verifique se a política de rede está selecionando as cargas de trabalho:

    kubectl describe fqdnnp
    

    O resultado será assim:

    Name:         allow-out-fqdnnp
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1alpha1
    Kind:         FQDNNetworkPolicy
    Metadata:
    ...
    Spec:
      Egress:
        Matches:
          Pattern:  *.yourdomain.com
          Name:     www.google.com
        Ports:
          Port:      443
          Protocol:  TCP
      Pod Selector:
        Match Labels:
          App: curl-client
    Events:     <none>
    

Excluir um FQDNNetworkPolicy

É possível excluir um FQDNNetworkPolicy usando o comando kubectl delete fqdnnp:

kubectl delete fqdnnp FQDN_POLICY_NAME

Substitua FQDN_POLICY_NAME pelo nome do FQDNNetworkPolicy.

O GKE exclui as regras da aplicação da política, mas as conexões permanecem ativas até serem fechadas, seguindo as diretrizes de protocolo padrão do Conntrack.

Como funcionam as políticas de rede FQDN

FQDNNetworkPolicies são políticas somente de saída que controlam para quais endpoints os pods selecionados podem enviar tráfego. Semelhante ao NetworkPolicy do Kubernetes, um FQDNNetworkPolicy que seleciona uma carga de trabalho cria uma regra de negação implícita para endpoints não especificados como destinos de saída permitidos. FQDNNetworkPolicies pode ser usado com o Kubernetes NetworkPolicies, conforme descrito em FQDNNetworkPolicy e NetworkPolicy.

FQDNNetworkPolicies são aplicados no endereço IP e no nível da porta. Eles não são aplicados usando nenhuma informação de protocolo da camada 7 (por exemplo, Request-URI em uma solicitação HTTP). Os nomes de domínio especificados são convertidos em endereços IP usando as informações de DNS fornecidas pelo provedor de DNS do cluster do GKE.

Solicitações de DNS

Um FQDNNetworkPolicy ativo que seleciona cargas de trabalho não afeta a capacidade delas de fazer solicitações de DNS. Comandos como nslookup ou dig funcionam em qualquer domínio sem serem afetados pela política. No entanto, as solicitações subsequentes para os domínios de apoio do endereço IP que não estão no permitido serão descartadas.

Por exemplo, se um FQDNNetworkPolicy permitir a saída para www.github.com, as solicitações de DNS para todos os domínios serão permitidas, mas o tráfego enviado para um endereço IP de apoio twitter.com será descartado.

Expiração do TTL

FQDNNetworkPolicy respeita o TTL fornecido por um registro DNS. Se um pod tentar entrar em contato com um endereço IP expirado após o término do TTL do registro DNS, novas conexões serão rejeitadas. Conexões de longa duração com duração maior que o TTL do registro DNS não podem sofrer interrupções no tráfego, enquanto o conntrack considera a conexão ainda ativa.

FQDNNetworkPolicy e NetworkPolicy

Quando um FQDNNetworkPolicy e um NetworkPolicy se aplicam ao mesmo pod, o que significa que os rótulos do pod correspondem ao que está configurado nas políticas, o tráfego de saída é permitido, desde que corresponda a uma das políticas. Não há hierarquia entre a NetworkPolicies de saída especificando endereços IP ou seletores de rótulo e FQDNNetworkPolicies.

Endpoints de endereços IP compartilhados (balanceadores de carga, CDN, gateway de VPN etc.)

Muitos domínios não têm endereços IP dedicados como apoio e, em vez disso, são expostos usando endereços IP compartilhados. Isso é muito comum quando o aplicativo é atendido por um balanceador de carga ou CDN. Por exemplo, as APIs do Google Cloud (compute.googleapis.com, container.googleapis.com etc.) não têm endereços IP exclusivos para cada uma delas. Em vez disso, todas as APIs são expostas usando um intervalo compartilhado.

Ao configurar FQDNNetworkPolicies, é importante considerar se os domínios permitidos estão usando endereços IP dedicados ou compartilhados. Como FQDNNetworkPolicies são aplicados no nível do endereço IP e da porta, eles não podem distinguir entre vários domínios atendidos pelo mesmo endereço IP. Permitir acesso a um domínio respaldado por um endereço IP compartilhado permite que o pod se comunique com todos os outros domínios atendidos por esse endereço IP. Por exemplo, ao permitir o tráfego para compute.googleapis.com, o pod também se comunica com outras APIs do Google Cloud.

Como pesquisar CNAME

Se o objeto FQDN no FQDNNetworkPolicy incluir um domínio com CNAMEs no registro DNS, configure o FQDNNetworkPolicy com todos os nomes de domínio que o pod pode consultar diretamente, incluindo todos os possíveis aliases para garantir um comportamento FQDNNetworkPolicy confiável.

Se o pod consultar example.com, example.com será o que deverá ser escrito na regra. Mesmo que você recupere uma cadeia de aliases dos servidores DNS upstream (por exemplo, de example.com a example.cdn.com para 1.2.3.4), a política de rede do FQDN ainda permitirá a passagem do tráfego.

Problemas conhecidos

Nesta seção, listamos todos os problemas conhecidos dos nomes de domínio totalmente qualificados (FQDN, na sigla em inglês).

Especificar protocol: ALL faz com que a política seja ignorada

Esse problema conhecido foi corrigido nas versões do GKE 1.27.10-gke.1055000+ e 1.28.3-gke.1055000+

Se você criar um FQDNNetworkPolicy que especifica protocol: ALL na seção ports, o GKE não aplicará a política. Isso ocorre devido a um problema com a análise da política. Especificar TCP ou UDP não causa esse problema.

Como solução alternativa, se você não especificar um protocol na entrada ports, a regra corresponderá a todos os protocolos por padrão. A remoção de protocol: ALL ignora o problema de análise, e o GKE aplica o FQDNNetworkPolicy.

Nas versões 1.27.10-gke.1055000+ e 1.28.3-gke.1055000+ do GKE, as políticas com protocol: ALL são analisadas e aplicadas corretamente.

A geração de registros de NetworkPolicy causa registros incorretos ou ausentes

Esse problema conhecido foi corrigido nas versões do GKE 1.27.10-gke.1055000+ e 1.28.2-gke.1157000+

Se o cluster estiver usando a geração de registros de políticas de rede e políticas de rede FQDN, há um bug que pode causar entradas de registro ausentes ou incorretas.

Ao usar a geração de registros de políticas de rede sem delegar, os registros de política para conexões DNS que deixam uma carga de trabalho afirmam incorretamente que o tráfego foi descartado. O tráfego em si era permitido (de acordo com o FQDNNetworkPolicy), mas os registros estavam incorretos.

Ao usar o registro de política de rede com delegação, os registros de política estão ausentes. O tráfego em si não é afetado.

Nas versões 1.27.10-gke.105500+ e 1.28.2-gke.1157000+ do GKE, esse bug foi corrigido. As conexões DNS agora serão registradas corretamente como ALLOWED, quando o tráfego for selecionado por um NetworkPolicy ou um FQDNNetworkPolicy.

A seguir