Visão geral da rede


Nesta página, você encontra um guia dos principais aspectos da rede do Google Kubernetes Engine (GKE). Estas informações são úteis para aqueles que estão apenas começando a usar o Kubernetes, bem como operadores de cluster ou desenvolvedores de aplicativos experientes que precisam de mais conhecimento sobre a rede do Kubernetes para melhor projetar aplicativos ou configurar cargas de trabalho do Kubernetes.

O Kubernetes permite que você defina, de forma declarativa, como os aplicativos são implantados e como eles se comunicam entre si e com o plano de controle do Kubernetes, além de como os clientes podem alcançá-los. Nesta página, você também verá informações sobre como o GKE configura os serviços do Google Cloud em que ele é relevante para a rede.

Ao usar o Kubernetes para orquestrar seus aplicativos, é importante mudar a maneira como você pensa sobre o design de rede dos aplicativos e dos hosts deles. Com o Kubernetes, você pensa em como pods, Serviços e clientes externos se comunicam, em vez de pensar em como seus hosts ou VMs estão conectados.

A avançada rede definida por software (SDN, na sigla em inglês) do Kubernetes permite o roteamento e o encaminhamento de pacotes para pods, Serviços e nós em diferentes zonas no mesmo cluster regional. O Kubernetes e o Google Cloud também configuram dinamicamente as regras de filtragem de IP, as tabelas de roteamento e as regras de firewall em cada nó, dependendo do modelo declarativo das implantações do Kubernetes e da configuração do cluster no Google Cloud.

Pré-requisitos

Nesta página, é usada a terminologia relacionada a camadas de transporte, Internet e aplicativo do conjunto de protocolo da Internet, incluindo HTTP e DNS (todos os links em inglês), mas você não precisa ser especialista nesses tópicos.

Além disso, é possível achar este conteúdo mais fácil de entender se você tiver um conhecimento básico dos utilitários e conceitos de gerenciamento de rede do Linux, como roteamento e regras de iptables.

O modelo de rede do Kubernetes depende muito de endereços IP. Serviços, pods, contêineres e nós se comunicam usando endereços IP e portas. O Kubernetes fornece diferentes tipos de balanceamento de carga para direcionar o tráfego para os pods corretos. Todos esses mecanismos são descritos em mais detalhes posteriormente. Lembre dos seguintes termos ao ler:

  • ClusterIP: o endereço IP atribuído a um Serviço. Em outros documentos, pode ser chamado de "IP do cluster". Esse endereço é estável durante a vida útil do serviço, conforme discutido em Serviços.
  • Endereço IP do pod: o endereço IP atribuído a um determinado pod. Ele é temporário, conforme discutido em Pods.
  • Endereço IP do nó: o endereço IP atribuído a um determinado nó.

Requisitos de rede de cluster

Os clusters públicos e privados exigem conectividade com *.googleapis.com, *.gcr.io e o endereço IP do plano de controle. Esse requisito é atendido pelas regras de permissão implícitas de saída e pelas regras de firewall criadas automaticamente pelo GKE.

Para clusters públicos, se você adicionar regras de firewall que negam a saída com prioridade mais alta, precisará criar regras de firewall para permitir *.googleapis.com, *.gcr.io e o endereço IP do plano de controle.

Para mais informações sobre requisitos de cluster particular, consulte Requisitos, restrições e limitações

Rede dentro do cluster

Nesta seção, falaremos sobre a rede em um cluster do Kubernetes, no que se refere à alocação de IP, pods, serviços, DNS e o plano de controle.

Alocação de IP

O Kubernetes usa vários intervalos de IP para atribuir endereços IP a nós, pods e Serviços.

  • Cada nó tem um endereço IP atribuído a partir da rede de nuvem privada virtual (VPC) do cluster. Esse IP de nó oferece conectividade a partir de componentes de controle, como kube-proxy e kubelet, ao servidor da API Kubernetes. Esse endereço IP é a conexão do nó com o restante do cluster.
  • Cada nó tem um pool de endereços IP a que o GKE atribui pods em execução nesse nó. Por padrão, é um bloco CIDR /24. Se preferir, especifique o intervalo de IPs ao criar o cluster. O recurso de intervalo flexível de CIDR de pods permite reduzir o tamanho do intervalo de endereços IP de pod para nós em um pool.
  • Cada pod tem um único endereço IP atribuído a partir do intervalo CIDR de pod do respectivo nó. Esse endereço IP é compartilhado por todos os contêineres em execução no pod e os conecta a outros pods em execução no cluster.
  • Cada Serviço tem um endereço IP, denominado ClusterIP, atribuído com base na rede VPC do cluster. Se preferir, é possível personalizar a rede VPC ao criar o cluster.
  • Cada plano de controle tem um endereço IP interno público ou particular com base no tipo de cluster, versão e data de criação. Para mais informações, consulte a descrição do plano de controle.

O modelo de rede do GKE não permite que os endereços IP sejam reutilizados na rede. Ao migrar para o GKE, você precisa planejar a alocação de endereços IP para Reduzir o uso de endereços IP internos no GKE.

MTU

A MTU selecionada para uma interface de pod depende da interface de rede de contêiner (CNI, na sigla em inglês) usada pelos nós do cluster e da configuração de MTU da VPC subjacente. Para mais informações, consulte Pods.

O valor da MTU da interface do pod é 1460 ou herdado da interface principal do nó.

CNI MTU GKE Standard
kubenet 1460 Default
kubenet
(GKE versão 1.26.1 e posterior)
Herdado Default
Calico 1460

Ativado usando --enable-network-policy.

Para detalhes, consulte Controlar a comunicação entre pods e Serviços usando políticas de rede.

netd Herdado Ativado usando uma destas opções:
GKE Dataplane V2 Herdado

Ativado usando --enable-dataplane-v2.

Para mais detalhes, consulte Como usar o GKE Dataplane V2.

Para mais informações, consulte Clusters nativos de VPC.

Pods

No Kubernetes, um pod é a unidade implantável mais básica dentro de um cluster do Kubernetes. Um pod executa um ou mais contêineres. Zero ou mais pods são executados em um nó. Cada nó no cluster faz parte de um pool de nós.

No GKE, esses nós são máquinas virtuais, cada uma sendo executada como uma instância no Compute Engine.

Os pods também podem ser anexados a volumes de armazenamento externos e outros recursos personalizados. Este diagrama mostra um único nó executando dois pods, cada um anexado a dois volumes.

image

Quando o Kubernetes agenda um pod para ser executado em um nó, ele cria um namespace de rede para o pod no kernel Linux do nó. Esse namespace conecta a interface de rede física do nó, como eth0, com o pod usando uma interface de rede virtual para que os pacotes possam fluir do e para o pod. A interface de rede virtual associada no namespace de rede raiz do nó se conecta a uma ponte do Linux que permite a comunicação entre pods no mesmo nó. Um pod também pode enviar pacotes fora do nó usando a mesma interface virtual.

O Kubernetes atribui um endereço IP (o endereço IP do pod) à interface de rede virtual no namespace de rede do pod a partir de um intervalo de endereços reservado para pods no nó. Esse intervalo de endereços é um subconjunto do intervalo de endereços IP atribuído ao cluster para pods, que você pode configurar ao criar um cluster.

Um contêiner em execução em um pod usa o namespace de rede do pod. Do ponto de vista do contêiner, o pod parece ser uma máquina física com uma interface de rede. Todos os contêineres no pod veem essa mesma interface de rede. O localhost de cada contêiner está conectado por meio do pod à interface de rede física do nó, como eth0.

Observe que essa conectividade varia muito se você usa a CNI do GKE ou se escolhe usar a implementação da Calico habilitando a política de rede ao criar o cluster.

  • Se você usar a CNI do GKE, uma extremidade do par de Virtual Ethernet Device (verth) será anexada ao pod no respectivo namespace e a outra será conectada ao dispositivo ponte cbr0 do Linux.1 Nesse caso, o comando a seguir mostra os vários endereços MAC de pods anexados a cbr0:

    arp -n
    

    A execução do seguinte comando no contêiner da caixa de ferramentas mostra a extremidade do namespace raiz de cada par veth anexado a cbr0:

    brctl show cbr0
    
  • Se a política de rede estiver ativada, uma extremidade do par veth será anexada ao pod e a outra a eth0. Nesse caso, o comando a seguir mostra os vários endereços MAC de pods conectados a diferentes dispositivos veth.

    arp -n
    

    A execução do seguinte comando no contêiner da caixa de ferramentas mostra que não há um dispositivo de ponte do Linux chamado cbr0:

    brctl show
    

As regras de iptables que facilitam o encaminhamento dentro do cluster variam de um cenário para outro. É importante ter essa distinção em mente durante a solução detalhada de problemas relacionados à conectividade.

Por padrão, cada pod tem acesso não filtrado a todos os outros pods em execução em todos os nós do cluster, mas é possível limitar o acesso entre os pods. O Kubernetes regularmente derruba e recria os pods. Isso acontece quando um pool de nós é atualizado, ao alterar a configuração declarativa do pod ou ao alterar a imagem de um contêiner ou quando um nó fica indisponível. Dessa forma, o endereço IP de um pod é um detalhe de implementação e não é recomendável depender dele. O Kubernetes fornece endereços IP estáveis usando Serviços.

  1. A ponte de rede virtual cbr0 só será criada se houver pods que definam hostNetwork: false.

Serviços

No Kubernetes, você pode atribuir pares arbitrários de valores-chave denominados rótulos a qualquer recurso do Kubernetes. O Kubernetes usa rótulos para agrupar vários pods relacionados em uma unidade lógica denominada Serviço. Um Serviço tem portas e um endereço IP estáveis e fornece balanceamento de carga entre o conjunto de pods com rótulos correspondentes a todos os definidos no seletor de rótulos durante a criação do Serviço.

O diagrama a seguir mostra dois Serviços separados, cada um composto por vários pods. Cada um dos pods no diagrama tem o rótulo app=demo, mas os outros rótulos são diferentes. O "front-end" do Serviço corresponde a todos os pods com app=demo e component=frontend, enquanto os "usuários" do Serviço correspondem a todos os pods com app=demo e component=users. Como o pod cliente não corresponde exatamente ao seletor do Serviço, ele não faz parte de nenhum dos Serviços. Porém, ele pode se comunicar com qualquer um dos Serviços porque é executado no mesmo cluster.

image

O Kubernetes atribui um endereço IP estável e confiável a cada Serviço recém-criado, o ClusterIP (em inglês), do pool de endereços IP de Serviço disponíveis no cluster. O Kubernetes também atribui um nome de host ao ClusterIP. Para isso, ele adiciona uma entrada DNS (em inglês). O ClusterIP e o nome do host são exclusivos no cluster e não são alterados durante todo o ciclo de vida do serviço. O Kubernetes apenas libera o ClusterIP e o nome do host se o Serviço for excluído da configuração do cluster. Para alcançar um pod íntegro, execute seu aplicativo usando o ClusterIP ou o nome do host do Serviço.

À primeira vista, um Serviço pode parecer um ponto único de falha para seus aplicativos. No entanto, o Kubernetes distribui o tráfego do modo mais uniforme possível em todo o conjunto de pods, sendo executado em muitos nós, para que um cluster possa resistir a uma interrupção que afeta um ou mais (mas não todos os) nós.

Kube-Proxy

O Kubernetes gerencia a conectividade entre pods e serviços usando o componente kube-proxy, que tradicionalmente é executado como um pod estático em cada nó.

kube-proxy não é um proxy alinhado e sim um controlador de balanceamento de carga baseado em saída. Ele vigia o servidor da API Kubernetes e mapeia continuamente o ClusterIP para pods íntegros adicionando e removendo regras NAT de destino (DNAT, na sigla em inglês) do subsistema iptables. Quando um contêiner em execução em um pod envia tráfego para o ClusterIP de um Serviço, o nó seleciona um pod aleatoriamente e direciona o tráfego para esse pod.

Ao configurar um Serviço, é possível remapear a porta de detecção de atividade dele definindo valores para port e targetPort.

  • port dá acesso ao aplicativo.
  • targetPort é a porta em que o aplicativo está realmente detectando tráfego no pod.

kube-proxy adiciona e remove regras iptables no nó para gerenciar esse remapeamento de porta.

Este diagrama ilustra o fluxo de tráfego de um pod cliente para um pod servidor em um nó diferente. O cliente se conecta ao Serviço em 172.16.12.100:80. O servidor da API Kubernetes mantém uma lista de pods que executam o aplicativo. O processo kube-proxy em cada nó usa essa lista para criar uma regra iptables e direcionar o tráfego para um pod apropriado (como 10.255.255.202:8080). O pod cliente não precisa estar ciente da topologia do cluster ou de detalhes sobre pods individuais ou contêineres dentro deles.

image

A forma como kube-proxy é implantado depende da versão do GKE do cluster:

  • Para o GKE versões 1.16.0 e 1.16.8-gke.13, kube-proxy é implantado como um DaemonSet.
  • Para as versões do GKE posteriores à 1.16.8-gke.13, kube-proxy é implantado como um pod estático para nós.

DNS

O GKE fornece as seguintes opções de DNS do cluster para resolver nomes de serviço e nomes externos:

  • kube-dns: um complemento de cluster implantado por padrão em todos os clusters do GKE. Para mais informações, consulte Como usar o kube-dns.

  • Cloud DNS: uma infraestrutura de DNS do cluster gerenciada na nuvem que substitui o kube-dns no cluster. Para mais informações, consulte Usar o Cloud DNS para GKE.

O GKE também fornece o NodeLocal DNSCache como um complemento opcional com o kube-dns ou o Cloud DNS para melhorar o desempenho do DNS do cluster.

Para saber mais sobre como o GKE fornece DNS, consulte Descoberta de serviços e DNS.

Plano de controle

No Kubernetes, o plano de controle gerencia os processos do plano de controle, incluindo o servidor da API Kubernetes. A forma de acessar o plano de controle depende da versão do cluster Autopilot ou Standard do GKE.

Clusters com o Private Service Connect

Clusters particulares ou públicos que atendam a qualquer uma das condições a seguir usam o Private Service Connect para conectar nós e o plano de controle de maneira particular:

  • Novos clusters públicos na versão 1.23 a partir de 15 de março de 2022.
  • Novos clusters particulares na versão 1.29 após 28 de janeiro de 2024.

Os clusters públicos que não atendem às condições anteriores estão sendo migrados para o Private Service Connect. Portanto, talvez esses clusters já usem o Private Service Connect. Para verificar se o cluster usa o Private Service Connect, execute o comando gcloud container clusters describe. Se o cluster público usar o Private Service Connect, o recurso privateClusterConfig terá estes valores:

  • O campo peeringName está vazio ou não existe.
  • O campo privateEndpoint tem um valor atribuído.

No entanto, os clusters privados que não atendem às condições anteriores ainda não foram migrados.

É possível criar clusters que usam o Private Service Connect e alterar o isolamento do cluster.

Use redes autorizadas para restringir o acesso ao plano de controle do cluster definindo as origens que podem alcançar esse plano.

Rede fora do cluster

Esta seção explica como o tráfego de fora do cluster alcança os aplicativos em execução em um cluster do Kubernetes. Essas informações são importantes ao projetar aplicativos e cargas de trabalho do seu cluster.

Você já viu como o Kubernetes usa os Serviços para fornecer endereços IP estáveis a aplicativos em execução nos pods. Por padrão, os pods não expõem um endereço IP externo porque kube-proxy gerencia todo o tráfego em cada nó. Os pods e seus contêineres podem se comunicar livremente, mas as conexões fora do cluster não podem acessar o serviço. Por exemplo, na ilustração anterior, os clientes fora do cluster não podem acessar o Serviço de front-end usando o ClusterIP.

O GKE fornece três tipos diferentes de balanceadores de carga para controlar o acesso e distribuir o tráfego de entrada no seu cluster da forma mais uniforme possível. É possível configurar um Serviço para usar vários tipos de balanceadores de carga simultaneamente.

  • Balanceadores de carga externos gerenciam o tráfego de fora do cluster e de fora da sua rede VPC do Google Cloud. Eles usam regras de encaminhamento associadas à rede do Google Cloud para rotear o tráfego a um nó do Kubernetes.
  • Balanceadores de carga internos gerenciam o tráfego proveniente de dentro da mesma rede VPC. Como os balanceadores de carga externos, eles usam regras de encaminhamento associadas à rede do Google Cloud para rotear o tráfego a um nó do Kubernetes.
  • Balanceadores de carga de aplicativo são balanceadores de carga externos e especializados usados para tráfego HTTP(S). Eles usam um recurso Ingress em vez de uma regra de encaminhamento para rotear o tráfego para um nó do Kubernetes.

Quando o tráfego alcança um nó do Kubernetes, ele é tratado da mesma maneira, qualquer que seja o tipo de balanceador de carga. O balanceador de carga não sabe quais nós do cluster estão executando os pods do respectivo serviço. Em vez disso, ele balanceia o tráfego em todos os nós do cluster, mesmo aqueles que não executam um pod relevante. Em um cluster regional, a carga é distribuída por todos os nós de todas as zonas da região do cluster. Quando o tráfego é encaminhado para um nó, o nó o encaminha para um pod, que pode estar em execução no mesmo nó ou em um nó diferente. O nó encaminha o tráfego para um pod escolhido aleatoriamente usando as regras de iptables que kube-proxy gerencia no nó.

No diagrama a seguir, o balanceador de carga de rede de passagem externa direciona o tráfego para o nó do meio, e o tráfego é redirecionado para um pod no primeiro nó.

image

Quando um balanceador de carga envia tráfego para um nó, ele pode ser encaminhado para um pod em um nó diferente. Isso requer saltos de rede adicionais. Se você quiser evitar os saltos extras, especifique que o tráfego precisa ir a um pod localizado no mesmo nó que inicialmente recebe o tráfego.

Para fazer isso, defina externalTrafficPolicy como Local no manifesto de Serviço:

apiVersion: v1
kind: Service
metadata:
  name: my-lb-service
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  selector:
    app: demo
    component: users
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

Quando você define externalTrafficPolicy como Local, o balanceador de carga envia tráfego somente para nós que têm um pod íntegro pertencente ao Serviço. O balanceador de carga usa uma verificação de integridade para determinar quais nós têm os pods apropriados.

Balanceador de carga externo

Se o Serviço precisar estar acessível fora do cluster e fora da rede VPC, configure-o como um LoadBalancer. Basta definir o campo type como Loadbalancer ao definir o Serviço. O GKE provisiona então um balanceador de carga de rede de passagem externa na frente do Serviço. O balanceador de carga de rede de passagem externa está ciente de todos os nós no cluster e configura as regras de firewall da rede VPC para permitir conexões com o Serviço fora da rede VPC usando o endereço IP externo do Serviço. É possível atribuir um endereço IP externo estático ao Serviço.

Para saber mais sobre as regras de firewall, consulte esta página.

Detalhes técnicos

Ao usar o balanceador de carga externo, o tráfego que chega é inicialmente encaminhado para um nó usando uma regra de encaminhamento associada à rede do Google Cloud. Depois que ele chega ao nó, esse nó usa a tabela NAT iptables para escolher um pod. kube-proxy gerencia as regras de iptables no nó.

Balanceador de carga interno

Para o tráfego que precisa alcançar seu cluster de dentro da mesma rede VPC, configure o Serviço para provisionar um balanceador de carga de rede de passagem interna. O balanceador de carga de rede de passagem interna escolhe um endereço IP da sub-rede VPC do cluster em vez de um endereço IP externo. Aplicativos ou serviços na rede VPC podem usar esse endereço IP para se comunicar com os serviços dentro do cluster.

Detalhes técnicos

O balanceamento de carga interno é fornecido pelo Google Cloud. Quando o tráfego alcança determinado nó, esse nó usa a tabela NAT iptables para escolher um pod, mesmo se o pod estiver em um nó diferente. kube-proxy gerencia as regras de iptables no nó.

Para mais informações sobre balanceadores de carga internos, consulte Como usar um balanceador de carga de rede de passagem interna.

Balanceador de carga de aplicativo

Muitos aplicativos, como APIs de serviço da Web RESTful, se comunicam usando HTTP(S). É possível permitir que clientes externos à sua rede VPC acessem esse tipo de aplicativo usando uma entrada do Kubernetes.

Uma entrada permite mapear nomes de host e caminhos de URL para Serviços no cluster. Ao usar um balanceador de carga de aplicativo, configure o Serviço para usar um NodePort e um ClusterIP. Quando o tráfego acessa o Serviço no IP de um nó no NodePort, o GKE roteia o tráfego para um pod íntegro do Serviço. Especifique um NodePort ou permita que o GKE atribua uma porta aleatória não utilizada.

Quando você cria o recurso Ingress, o GKE provisiona um balanceador de carga de aplicativo externo no projeto do Google Cloud. O balanceador de carga envia uma solicitação para o endereço IP de um nó no NodePort. Depois que a solicitação chega ao nó, o nó usa a tabela NAT iptables para escolher um pod. kube-proxy gerencia as regras de iptables no nó.

Esta definição de Entrada encaminha o tráfego de demo.example.com para um Serviço chamado frontend na porta 80 e demo-backend.example.com para um Serviço chamado users na porta 8080.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo
spec:
  rules:
  - host: demo.example.com
    http:
      paths:
      - backend:
          service:
            name: frontend
            port:
              number: 80
  - host: demo-backend.example.com
    http:
      paths:
      - backend:
          service:
            name: users
            port:
              number: 8080

Acesse Entrada do GKE para balanceador de carga de aplicativo para mais informações.

Detalhes técnicos

Quando você cria um objeto de entrada, o controlador da entrada do GKE configura um balanceador de carga de aplicativo de acordo com as regras no manifesto da entrada e nos manifestos de serviço associados. O cliente envia uma solicitação ao balanceador de carga de aplicativo. O balanceador de carga é um proxy real. Ele escolhe um nó e encaminha a solicitação para a combinação NodeIP:NodePort desse nó. O nó usa a tabela NAT iptables para escolher um pod. kube-proxy gerencia as regras de iptables no nó.

Como limitar a conectividade entre nós

Criar regras de firewall de entrada ou saída que segmentam nós no cluster talvez gere efeitos adversos. Por exemplo, aplicar regras "deny" de saída aos nós no cluster pode interromper recursos, como NodePort e kubectl exec.

Como limitar a conectividade com pods e Serviços

Por padrão, todos os pods em execução no mesmo cluster podem se comunicar livremente. No entanto, você pode limitar a conectividade dentro de um cluster de maneiras diferentes, dependendo das necessidades.

Como limitar o acesso entre pods

Você pode limitar o acesso entre os pods usando uma política de rede. Com as definições de política de rede, é possível restringir a entrada e a saída de pods com base em uma combinação arbitrária de rótulos, intervalos de IP e números de porta.

Por padrão, não há política de rede, portanto, todo o tráfego entre os pods no cluster é permitido. Assim que você cria a primeira política de rede em um namespace, todo o restante do tráfego é negado.

Depois de criar uma política de rede, você precisa ativá-la explicitamente para o cluster. Para mais informações, acesse Como configurar políticas de rede para aplicativos.

Como limitar o acesso a um balanceador de carga externo

Se seu Serviço usar um balanceador de carga externo, ele poderá ser acessado pelo tráfego de qualquer endereço IP externo por padrão. Para restringir quais intervalos de endereços IP podem acessar os endpoints no cluster, configure a opção loadBalancerSourceRanges ao configurar o Serviço. É possível especificar vários intervalos e atualizar a configuração de um Serviço em execução a qualquer momento. A instância kube-proxy em execução em cada nó configura as regras de iptables para negar todo o tráfego que não corresponde ao loadBalancerSourceRanges especificado. Nenhuma regra de firewall VPC é criada.

Como limitar o acesso a um balanceador de carga de aplicativo

Se o serviço usa um balanceador de carga de aplicativo, é possível usar uma política de segurança do Google Cloud Armor para limitar quais endereços IP externos podem acessar seu serviço e quais respostas a retornar quando o acesso for negado devido à política de segurança. Configure o Cloud Logging para registrar informações sobre essas interações.

Se uma política de segurança do Google Cloud Armor não for refinada o suficiente, ative o Identity-Aware Proxy nos seus endpoints para implementar autenticação e autorização de usuário para o aplicativo. Para mais informações, veja o tutorial detalhado para configurar o IAP.

Problemas conhecidos

Esta seção aborda os problemas conhecidos.

Nó ativado para contêiner não consegue se conectar ao intervalo 172.17/16

Uma VM de nó com o Containerd ativado não pode se conectar a um host com IP dentro de 172.17/16. Para mais informações, consulte Conflito com o intervalo de endereços IP 172.17/16.

A seguir