Nota do tradutor.: este artigo, escrito por um engenheiro de SRE do LinkedIn, detalha a 'magia interna' no Kubernetes – mais especificamente, a interação entre CRI, CNI e kube-apiserver, e o que acontece quando um pod precisa receber um endereço IP.
Um dos requisitos básicos é que cada pod deve ter seu próprio endereço IP, e qualquer outro pod no cluster deve ser capaz de se comunicar com ele por esse endereço. Existem muitos provedores de rede (Flannel, Calico, Canal etc.) que ajudam a implementar esse modelo de rede.
Quando comecei a trabalhar com Kubernetes, não estava claro para mim como os pods obtêm seus endereços IP. Mesmo entendendo como funcionam os componentes individuais, era difícil imaginar como eles trabalham juntos. Por exemplo, eu sabia para que serviam os plugins CNI, mas não tinha ideia de como eles eram invocados. Então decidi escrever este artigo para compartilhar conhecimentos sobre os vários componentes de rede e como eles colaboram no cluster Kubernetes para permitir que cada pod receba seu endereço IP único.
Existem várias maneiras de organizar a interação de rede no Kubernetes – assim como existem várias opções de ambientes de execução (runtime) para contêineres. Neste artigo, será utilizado para organizar a rede no cluster, e como ambiente de execução – . Também parto da suposição de que você entende como funciona a interação de rede entre contêineres, portanto, apenas abordarei brevemente, exclusivamente para o contexto.
Alguns conceitos básicos
Contêineres e rede: uma visão geral
Na internet, há muitas publicações excelentes que explicam como os contêineres se conectam entre si pela rede. Portanto, farei apenas uma visão geral dos conceitos principais e limitarei-me a uma abordagem que envolve a criação de uma ponte Linux e o encapsulamento de pacotes. Os detalhes são omitidos, pois o tema da interação de rede entre contêineres merece um artigo separado. Links para algumas publicações especialmente informativas e educativas serão fornecidos abaixo.
Contêineres em um único host
Uma das maneiras de organizar a comunicação por endereços IP entre contêineres que estão rodando no mesmo host é através da criação de uma ponte Linux. Para isso, no Kubernetes (e Docker) são criados dispositivos virtuais . Uma extremidade do dispositivo veth está conectada ao espaço de nomes de rede do contêiner, e a outra está conectada ao na rede do host.
Todos os contêineres em um mesmo host têm uma extremidade da veth conectada à ponte, através da qual eles podem se comunicar entre si por endereços IP. A ponte Linux também possui um endereço IP e atua como um gateway para o tráfego de saída (egress) dos pods, destinado a outros nós.

Contêineres em hosts diferentes
A encapsulação de pacotes é uma das maneiras que permite que contêineres em nós diferentes se comuniquem entre si por endereços IP. No Flannel, essa funcionalidade é gerenciada pela tecnologia , que "embala" o pacote original em um pacote UDP e o envia ao destino.
No cluster Kubernetes, o Flannel cria um dispositivo vxlan e complementa a tabela de rotas em cada um dos nós. Cada pacote destinado a um contêiner em outro host passa pelo dispositivo vxlan e é encapsulado em um pacote UDP. No destino, o pacote encapsulado é extraído e redirecionado para o pod desejado.

Nota: Este é apenas um dos modos de organizar a interação de rede entre contêineres.
O que é CRI?
é um plugin que permite que o kubelet utilize diferentes ambientes de execução de contêineres. A API CRI está embutida em vários ambientes de execução, permitindo que os usuários escolham o runtime de sua preferência.
O que é CNI?
representa para a implementação de uma solução de rede universal para contêineres Linux. Além disso, inclui , responsáveis por diversas funções na configuração da rede do pod. Um plugin CNI é um executável que está de acordo com a especificação (alguns plugins serão discutidos abaixo).
Atribuição de sub-redes aos nós para a alocação de endereços IP aos pods
Como cada pod do cluster deve ter um endereço IP, é importante garantir que esse endereço seja único. Isso é alcançado pela atribuição de uma sub-rede exclusiva a cada nó, a partir da qual então os endereços IP são alocados aos pods nesse nó.
O controlador IPAM do nó
Quando nodeipam é passado como um parâmetro de flag --controllers , ele atribui a cada nó uma sub-rede separada (podCIDR) do CIDR do cluster (ou seja, um intervalo de endereços IP para a rede do cluster). Como esses podCIDRs não se sobrepõem, é possível atribuir a cada pod um endereço IP único.
O nó Kubernetes recebe um podCIDR no momento de seu registro inicial no cluster. Para alterar o podCIDR dos nós, é necessário desregistrá-los e, em seguida, registrá-los novamente, fazendo as alterações necessárias na configuração da camada de gerenciamento do Kubernetes. O podCIDR de um nó pode ser exibido com o seguinte comando:
$ kubectl get no -o json | jq '.spec.podCIDR'
10.244.0.0/24
Kubelet, ambiente de execução de contêiner e plugins CNI: como tudo isso funciona
O agendamento de um pod em um nó está relacionado à execução de várias etapas preparatórias. Nesta seção, focarei apenas naquelas que estão diretamente ligadas à configuração da rede do pod.
O agendamento de um pod em um determinado nó inicia a seguinte cadeia de eventos:

Ajuda: .
Interação entre o ambiente de execução de contêineres e os plugins CNI
Cada provedor de rede tem seu próprio plugin CNI. O ambiente de execução do contêiner o chama para configurar a rede para o pod durante seu início. No caso do containerd, a execução do plugin CNI é feita pelo plugin .
Cada provedor também possui seu próprio agente. Ele é instalado em todos os nós do Kubernetes e é responsável pela configuração da rede dos pods. Este agente vem com a configuração do CNI ou cria-a sozinho no nó. A configuração ajuda o plugin CRI a determinar qual plugin CNI chamar.
O local do arquivo de configuração do CNI pode ser configurado; por padrão, ele fica em /etc/cni/net.d/<config-file>. Os administradores do cluster também são responsáveis pela instalação dos plugins CNI em cada nó do cluster. A localização deles também é configurável; o diretório padrão é /opt/cni/bin.
Ao usar o containerd, os caminhos para a configuração e os binários do plugin podem ser especificados na seção [plugins."io.containerd.grpc.v1.cri".cni] em .
Como estamos usando o Flannel como provedor de rede, vamos falar um pouco sobre sua configuração:
- Flanneld (o daemon do Flannel) geralmente é instalado no cluster como um DaemonSet com
install-cnicomo um . Install-cnicria (/etc/cni/net.d/10-flannel.conflist) em cada nó.- Flanneld cria o dispositivo vxlan, extrai os metadados de rede da API do servidor e monitora as atualizações dos pods. À medida que eles são criados, ele dissemina rotas para todos os pods em todo o cluster.
- Essas rotas permitem que os pods se comuniquem entre si por meio de endereços IP.
Para informações mais detalhadas sobre o funcionamento do Flannel, recomendo consultar os links no final do artigo.
Aqui está o esquema de interação entre o plugin Containerd CRI e os plugins CNI:

Como mostrado acima, o kubelet chama o plugin Containerd CRI para criar um pod, e este chama o plugin CNI para configurar a rede do pod. O plugin CNI do provedor de rede, por sua vez, chama outros plugins base CNI para configurar vários aspectos da rede.
Interação entre plugins CNI
Existem vários plugins CNI, cuja função é ajudar a configurar a comunicação de rede entre os contêineres no host. Este artigo abordará três deles.
Plugin CNI Flannel
Ao usar o Flannel como provedor de rede, o componente Containerd CRI chama , usando o arquivo de configuração CNI /etc/cni/net.d/10-flannel.conflist.
$ cat /etc/cni/net.d/10-flannel.conflist
{
"name": "cni0",
"plugins": [
{
"type": "flannel",
"delegate": {
"ipMasq": false,
"hairpinMode": true,
"isDefaultGateway": true
}
}
]
}
O plugin CNI Flannel opera em conjunto com o Flanneld. Durante a inicialização, o Flanneld extrai o podCIDR e outros detalhes relacionados à rede da API do servidor e os salva no arquivo /run/flannel/subnet.env.
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=false
O plugin CNI Flannel utiliza os dados de /run/flannel/subnet.env para configurar e invocar o plugin CNI bridge.
Plugin CNI Bridge
Este plugin é chamado com a seguinte configuração:
{
"name": "cni0",
"type": "bridge",
"mtu": 1450,
"ipMasq": false,
"isGateway": true,
"ipam": {
"type": "host-local",
"subnet": "10.244.0.0/24"
}
}
Na primeira chamada, ele cria uma bridge Linux com "name": "cni0", conforme especificado na configuração. Em seguida, uma par de veth é criada para cada pod. Uma ponta se conecta ao espaço de nomes de rede do contêiner, e a outra se conecta à bridge Linux na rede do host. conecta todos os contêineres do host à bridge Linux na rede do host.
Após finalizar a configuração do par de veth, o plugin Bridge chama o plugin IPAM local do host (host-local). O tipo de plugin IPAM pode ser configurado no arquivo de configuração CNI que o plugin CRI utiliza para invocar o plugin CNI Flannel.
Plugins IPAM locais do host CNI
Bridge CNI chama com a seguinte configuração:
{
"name": "cni0",
"ipam": {
"type": "host-local",
"subnet": "10.244.0.0/24",
"dataDir": "/var/lib/cni/networks"
}
}
Plugin IPAM host-local (IP Aendereço Mgestão — gerenciamento de endereços IP) retorna o endereço IP para o contêiner da sub-rede e armazena o IP atribuído no host no diretório especificado na seção dataDir — /var/lib/cni/networks/<network-name=cni0>/<ip>. Este arquivo contém o ID do contêiner ao qual o endereço IP foi atribuído.
Ao chamar o plugin IPAM host-local, ele retorna os seguintes dados:
{
"ip4": {
"ip": "10.244.4.2",
"gateway": "10.244.4.3"
},
"dns": {}
}
Resumo
O kube-controller-manager atribui podCIDR a cada nó. Os pods de cada nó obtêm endereços IP do espaço de endereços dentro da faixa de podCIDR designada. Como os podCIDRs dos nós não se sobrepõem, todos os pods recebem endereços IP únicos.
O administrador do cluster Kubernetes configura e instala o kubelet, o ambiente de execução de contêineres, o agente do provedor de rede e copia os plugins CNI em cada nó. Durante a inicialização, o agente do provedor de rede gera a configuração CNI. Quando um pod é agendado em um nó, o kubelet chama o plugin CRI para criá-lo. Em seguida, se o containerd estiver em uso, o plugin Containerd CRI chama o plugin CNI especificado na configuração CNI para configurar a rede do pod. Como resultado, o pod recebe um endereço IP.
Levei algum tempo para entender todas as sutilezas e nuances dessas interações. Espero que a experiência adquirida também ajude você a entender melhor como o Kubernetes funciona. Se eu cometer algum erro, por favor, entre em contato comigo no ou em . Sinta-se à vontade para entrar em contato se quiser discutir aspectos deste artigo ou qualquer outra coisa. Ficarei feliz em conversar com você!
Links
Contêineres e rede
Como funciona o Flannel
CRI e CNI
P.S. do tradutor
Confira também em nosso blog:
- «»;
- «Guia ilustrado para a estrutura da rede no Kubernetes»: , ;
- «».
Fonte: habr.com
