Configurar um gateway NAT de saída

Neste documento, descrevemos como configurar um gateway NAT de saída para o GKE em bare metal. Esse gateway fornece endereços IP SNAT permanentes e determinísticos para o tráfego de saída dos clusters. Quando você executa cargas de trabalho que têm tráfego de saída do usuário (fora dos clusters), seus clientes querem identificar esse tráfego usando alguns endereços IP determinísticos. Isso permite que os clientes estabeleçam medidas de segurança baseadas em IP, como políticas de listas de permissão.

O gateway NAT de saída é ativado usando dois recursos personalizados. Para um determinado namespace, o recurso personalizado NetworkGatewayGroup especifica endereços IP flutuantes que podem ser configurados na interface de rede de um nó escolhido para atuar como um gateway. O recurso personalizado EgressNatPolicy permite especificar políticas de roteamento de saída para controlar o tráfego no gateway de saída.

Se você não configurar um gateway NAT de saída ou se o tráfego de saída não atender às regras de seleção de tráfego, o tráfego de saída de um determinado pod para um destino fora do seu cluster será mascarado para o endereço IP do nó em que o pod está em execução. Nesse cenário, não há garantia de que todo o tráfego de saída de um determinado pod terá o mesmo endereço IP de origem ou se mascarará para o mesmo endereço IP do nó.

O gateway NAT de saída é uma oferta de rede avançada criada com base no Dataplane V2.

Como funciona o gateway NAT de saída

A lógica de seleção de tráfego de saída tem como base um seletor de namespace, um seletor de pod e um conjunto de intervalos de endereços IP de destino na notação de bloco CIDR. Para ilustrar como o gateway NAT de saída funciona, vamos pensar no fluxo de um pacote de um pod para um consumidor externo e a resposta correspondente. Suponha que a sub-rede do nó tenha endereços IP no bloco CIDR 192.168.1.0/24.

O diagrama a seguir mostra a arquitetura de rede para o tráfego de saída por um nó de gateway.

Diagrama do gateway NAT de saída para o GKE em bare metal

O fluxo de pacotes pelo gateway NAT de saída pode ser assim:

  1. O tráfego de saída é gerado a partir de um pod com endereço IP 10.10.10.1 em um nó com endereço IP 192.168.1.1.

    O endereço de destino do tráfego é um endpoint fora do cluster.

  2. Se o tráfego corresponder a uma regra de saída, o programa eBPF o roteará para o nó do gateway, em vez de mascarar-se diretamente com o endereço IP do nó.

  3. O nó de gateway recebe o tráfego de saída.

  4. O nó de gateway mascara o endereço IP de origem do tráfego de origem, 10.10.10.1, com o endereço IP de saída da origem, 192.168.1.100 especificado no recurso personalizado EgressNATPolicy.

  5. O tráfego de retorno volta para o nó de gateway com o destino como 192.168.1.100.

  6. O nó de gateway corresponde ao conntrack do tráfego de retorno com o do tráfego de saída original e reescreve o endereço IP de destino como 10.10.10.1.

  7. 10.10.10.1 é tratado como tráfego no cluster, roteado para o nó original e entregue de volta ao pod original.

Configurar endereços IP flutuantes para tráfego de nós

O recurso personalizado do grupo de gateway de rede é um componente em pacote do GKE em bare metal. O recurso gerencia um ou mais endereços IP flutuantes usados para o tráfego de saída dos nós do cluster. Os nós participantes são determinados pelo namespace especificado. O grupo de gateways de rede disponibiliza sempre um endereço IP flutuante, da melhor maneira possível. Se um nó que usa um endereço IP flutuante ficar inativo, o gateway de rede avançado moverá o endereço IP atribuído para o próximo nó disponível. Todo o tráfego de saída da carga de trabalho que usar esse endereço IP também será movido.

Inclua os detalhes do grupo de gateway de rede (anotação e especificação) no arquivo de configuração ao criar um novo cluster 1.28.400-gke.77.

Criar o recurso personalizado NetworkGatewayGroup

Para ativar o grupo de gateways de rede, defina o campo spec.clusterNetwork.advancedNetworking como true no arquivo de configuração do cluster ao criar um cluster, conforme mostrado no exemplo a seguir:

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: cluster1
  namespace: cluster-cluster1
spec:
  clusterNetwork:
    ...
    advancedNetworking: true
    ...

Ao criar o recurso personalizado NetworkGatewayGroup, defina o namespace dele como o namespace de cluster e especifique uma lista de endereços IP flutuantes, como mostrado no exemplo a seguir:

kind: NetworkGatewayGroup
apiVersion: networking.gke.io/v1
metadata:
  namespace: cluster-cluster1
  name: default
spec:
  floatingIPs:
  - 192.168.1.100
  - 192.168.1.101
  - 192.168.1.102

O operador de rede avançado atribui os IPs flutuantes aos nós com base nos seguintes critérios:

  • Sub-rede de nós: o endereço IP flutuante precisa corresponder à sub-rede do nó.
  • Papel de nó (plano de controle, worker): os nós de trabalho têm preferência sobre os nós do plano de controle ao atribuir endereços IP flutuantes.
  • Se um nó tiver um endereço IP flutuante, o operador irá priorizar atribuições para nós que ainda não têm um IP flutuante atribuído.

O mapeamento de endereço/nó pode ser encontrado na seção status quando você recebe o objeto NetworkGatewayGroup. O objeto NetworkGatewayGroup está no namespace kube-system. Se um nó de gateway estiver inativo, o operador de rede avançado atribuirá os endereços IP flutuantes ao próximo nó disponível.

Verificar a configuração do gateway

Depois de aplicar as alterações de configuração do gateway, use kubectl para verificar o status do gateway e recuperar os endereços IP flutuantes especificados para o gateway.

  1. Use o comando a seguir para verificar o status de NetworkGatewayGroup e ver como os endereços IP flutuantes são alocados:

    kubectl -n kube-system get networkgatewaygroups.networking.gke.io default -o yaml
    

    A resposta de um cluster com dois nós, worker1 e worker2, pode ser semelhante a:

    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: default
    spec:
      floatingIPs:
      - 192.168.1.100
      - 192.168.1.101
      - 192.168.1.102
    status:
      nodes:
        worker1: Up
        worker2: Up // Or Down
      floatingIPs:
        192.168.1.100: worker1
        192.168.1.101: worker2
        192.168.1.102: worker1
    

Definir regras de seleção de tráfego

O recurso personalizado EgressNATPolicy especifica regras de seleção de tráfego e atribui um endereço IP determinístico para o tráfego de saída que sai do cluster. Ao especificar o recurso personalizado, egress (com pelo menos uma regra), destinationCIDRs e egressSourceIP são obrigatórios.

Use kubectl apply para criar o recurso personalizado EgressNATPolicy. As seções a seguir fornecem detalhes e exemplos para definir a especificação.

Especificar regras de roteamento de saída

O recurso personalizado EgressNatPolicy permite especificar as seguintes regras para o tráfego de saída:

  • Você precisa especificar uma ou mais regras de seleção de tráfego de saída na seção egress.

    • Cada regra consiste em um podSelector e um namespaceSelector.
    • A seleção é baseada em um rótulo de namespace, namespaceSelector.matchLabels.user, e um rótulo de pod, podSelector.matchLabels.role.
    • Se um pod corresponder a qualquer uma das regras (a correspondência usa uma relação OR), ele será selecionado para o tráfego de saída.
  • Especifique os endereços de destino permitidos na seção destinationCIDRs.

    • destinationCIDRs usa uma lista de blocos CIDR.
    • Se o tráfego de saída de um pod tiver um endereço IP de destino que esteja dentro do intervalo de qualquer um dos blocos CIDR especificados, ele será selecionado para o tráfego de saída.

No exemplo a seguir, o tráfego de saída de um pod é permitido quando os seguintes critérios são atendidos:

  • O pod é rotulado com role: frontend.
  • O pod está em um namespace rotulado como user: alice ou user: paul.
  • O pod está se comunicando com endereços IP no bloco CIDR 8.8.8.0/24.
kind: EgressNATPolicy
apiVersion: networking.gke.io/v1
metadata:
  name: egress
spec:
  sources:
  - namespaceSelector:
      matchLabels:
        user: alice
    podSelector:
      matchLabels:
        role: frontend
  - namespaceSelector:
      matchLabels:
        user: paul
    podSelector:
      matchLabels:
        role: frontend
  action: SNAT
  destinations:
    - cidr: 8.8.8.0/24
  gatewayRef:
    name: default
    namespace: kube-system

Para mais informações sobre o uso de rótulos, consulte Rótulos e seletores na documentação do Kubernetes.

Receber um endereço IP de origem para o tráfego de saída

O recurso personalizado EgressNATPolicy (política) usa os valores gatewayRef.name e gatewayRef.namespace para encontrar um objeto NetworkGatewayGroup (gateway). A política usa um dos endereços IP flutuantes do gateway como o endereço IP de origem para o tráfego de saída. Se houver vários endereços IP flutuantes no gateway correspondente, a política usará o primeiro endereço IP na lista floatingIPs e ignorará os outros endereços IP. Para o gateway de exemplo, o primeiro endereço na lista floatingIPs é 192.168.1.100. O uso de campos ou valores inválidos na seção gatewayRef resultará na falha de aplicar o objeto de política.

Várias políticas de saída e vários objetos de gateway

Conforme descrito na seção anterior, cada objeto egressNATPolicy (política) usa o primeiro endereço IP na lista floatingIPs do objeto de gateway que corresponde a gatewayRef.name e gatewayRef.namespace. É possível criar várias políticas e, se você pretende usar endereços IP diferentes, precisará criar vários objetos NetworkGatewayGroup e referenciá-los, respectivamente.

Cada recurso NetworkGatewayGroup precisa conter endereços IP flutuantes exclusivos. Para configurar vários objetos EgressNATPolicy para usar o mesmo endereço IP, use os mesmos gatewayRef.name e gatewayRef.namespace para ambos.

Para configurar várias políticas de saída e vários objetos de gateway:

  1. Crie objetos de gateway no namespace kube-system para gerenciar cada endereço IP flutuante. Normalmente, cada política de saída precisa ter um objeto de gateway correspondente para garantir que o endereço IP correto seja alocado.

    Em seguida, verifique cada objeto de gateway com kubectl para ver o status de alocação dos endereços IP flutuantes:

    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway1
    spec:
      floatingIPs:
      - 192.168.1.100
    status:
      ...
      floatingIPs:
        192.168.1.100: worker1
    ---
    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway2
    spec:
      floatingIPs:
      - 192.168.1.101
    status:
      ...
      floatingIPs:
        192.168.1.101: worker2
    ---
    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway3
    spec:
      floatingIPs:
      - 192.168.1.102
    status:
      ...
      floatingIPs:
        192.168.1.102: worker1
    
  2. Crie várias políticas que se refiram aos objetos de gateway, como a gateway1 criada na etapa anterior:

    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egress1
    spec:
      ...
      gatewayRef:
        name: gateway1
        namespace: kube-system
    ---
    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egress2
    spec:
      ...
      gatewayRef:
        name: gateway2
        namespace: kube-system
    ---
    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egress3
    spec:
      ...
      gatewayRef:
        name: gateway3
        namespace: kube-system
    

(Opcional) Especificar nós nos quais colocar endereços IP flutuantes

Os recursos NetworkGatewayGroup oferecem suporte a seletores de nós. Para especificar um subconjunto de nós considerados para hospedar um endereço IP flutuante, adicione o seletor de nós ao objeto NetworkGatewayGroup, conforme mostrado no exemplo abaixo:

kind: NetworkGatewayGroup
apiVersion: networking.gke.io/v1
metadata:
  namespace: cluster-cluster1
  name: default
spec:
  floatingIPs:
  - 192.168.1.100
  - 192.168.1.101
  - 192.168.1.102
  nodeSelector:
    node-type: "egressNat"

O seletor de nós corresponde aos nós que têm o rótulo especificado e apenas esses nós são considerados para hospedar um endereço IP flutuante. Se você especificar vários seletores, a lógica deles será cumulativa. Portanto, um nó precisará corresponder a cada rótulo para ser considerado para hospedar um endereço IP flutuante. Se não houver muitos nós com rótulos correspondentes, um seletor de nós poderá reduzir as qualidades de alta disponibilidade (HA) do posicionamento de endereços IP flutuantes.

Regras de seleção de tráfego de saída e políticas de rede

O gateway NAT de saída é compatível com APIs de política de rede. As políticas de rede são avaliadas primeiro e têm precedência sobre as regras de seleção de tráfego do gateway NAT de saída. Por exemplo, se o tráfego de saída acionar uma política de rede que resulte na queda do pacote, as regras do gateway de saída não verificarão o pacote. Somente quando a política de rede permitir a saída do pacote, as regras de seleção do tráfego de saída serão avaliadas para decidir como o tráfego será processado, usando o gateway NAT de saída ou mascarando diretamente o endereço IP do Nó em que o pod está em execução.

Limitações

As limitações atuais do gateway NAT de saída incluem:

  • O gateway NAT de saída só está ativado para o modo IPv4.

  • Os endereços IP de saída precisam estar no mesmo domínio da camada 2 com endereços IP do nó.

  • Os upgrades não são compatíveis com clusters configurados para usar a visualização do gateway NAT de saída. Para o GKE em Bare Metal versão 1.28.0 e mais recentes, o gateway NAT de saída está em pré-lançamento apenas no Ubuntu 18.04. Não há cobrança para usar esse recurso enquanto ele estiver em Visualização.