Um dos requisitos básicos do modelo de rede Kubernetes é que cada pod deve ter seu próprio endereço IP, e todos os outros pods do cluster devem ser capazes de acessá-lo nesse endereço. Existem muitos "provedores" de rede (Flanela, Calico, Canal, etc.) que ajudam a implementar este modelo de rede.
Quando comecei a trabalhar com o Kubernetes, não estava totalmente claro para mim como exatamente os pods obtêm seus endereços IP. Mesmo sabendo como os componentes individuais funcionavam, era difícil imaginá-los trabalhando juntos. Por exemplo, eu sabia para que serviam os plug-ins CNI, mas não tinha ideia de como eram chamados. Portanto, decidi escrever este artigo para compartilhar meu conhecimento sobre vários componentes de rede e como eles funcionam juntos em um cluster do Kubernetes, o que permite que cada pod obtenha seu próprio endereço IP exclusivo.
Existem diferentes maneiras de organizar a rede no Kubernetes, assim como existem diferentes opções de tempo de execução para contêineres. Esta postagem usará Flannel para rede de cluster e Containerd como o tempo de execução . Também parto do pressuposto de que você sabe como funciona a rede entre os contêineres, portanto, irei apenas abordá-lo brevemente, apenas para fins de contexto.
Alguns conceitos básicos
Recipientes e rede: uma visão geral
Existem muitas publicações excelentes na Internet que explicam como os containers se comunicam entre si pela rede. Portanto, darei apenas uma visão geral dos conceitos básicos e me limitarei a uma abordagem, que envolve a criação de uma ponte Linux e o encapsulamento de pacotes. Os detalhes são omitidos, uma vez que o próprio tópico de rede de contêineres merece um artigo separado. Links para algumas publicações particularmente informativas e informativas serão fornecidos abaixo.
Recipientes em um único host
Uma forma de estabelecer comunicação de endereço IP entre contêineres em execução no mesmo host é criar uma ponte Linux. Para isso, os dispositivos virtuais veth (ethernet virtual) são criados no Kubernetes (e no Docker ) . Uma extremidade do dispositivo veth se conecta ao namespace de rede do contêiner, a outra se conecta à ponte Linux na rede do host.
Todos os contêineres no mesmo host têm uma extremidade do veth conectada a uma ponte por meio da qual eles podem se comunicar usando endereços IP. A ponte Linux também tem um endereço IP e atua como um gateway para o tráfego de saída de pods para outros nós.
Recipientes em diferentes hosts
O encapsulamento de pacotes é uma maneira de permitir que contêineres em hosts diferentes se comuniquem usando endereços IP. Na Flanela , a tecnologia vxlan é responsável por esse recurso , que "embala" o pacote original em um pacote UDP e o envia ao seu destino.
Em um cluster Kubernetes, Flannel cria um dispositivo vxlan e aumenta a tabela de rota em cada nó de acordo. Cada pacote destinado a um contêiner em um host diferente passa pelo dispositivo vxlan e é encapsulado em um pacote UDP. No destino, o pacote aninhado é extraído e redirecionado para o pod desejado.
Observação: esta é apenas uma forma de rede entre contêineres.
O que é CRI?
CRI (Container Runtime Interface) é um plugin que permite ao kubelet usar diferentes ambientes de execução de contêiner. A API CRI é construída em vários ambientes de tempo de execução, para que os usuários possam escolher o tempo de execução de sua escolha.
O que é CNI?
O projeto CNI é uma especificação para organizar uma solução de rede universal para contêineres Linux. Além disso, inclui plug - ins responsáveis por várias funções ao configurar a rede de um pod. O plug-in CNI é um arquivo executável que está em conformidade com a especificação (discutiremos alguns dos plug-ins a seguir).
Sub-redes de hosts para atribuir endereços IP a pods
Como cada pod do cluster deve ter um endereço IP, é importante garantir que esse endereço seja exclusivo. Isso é feito atribuindo a cada host uma sub-rede exclusiva, a partir da qual os endereços IP são atribuídos aos pods desse host.
Controlador IPAM Host
Quando
nodeipampassado como um parâmetro para a --controllers sinalização kube-controller-manager , ele aloca uma sub-rede separada (podCIDR) para cada nó do cluster CIDR (ou seja, o intervalo de endereços IP para a rede do cluster). Como esses podCIDRs não se sobrepõem, é possível que cada pod atribua um endereço IP exclusivo.
Um nó do Kubernetes é atribuído a um podCIDR quando é registrado pela primeira vez no cluster. Para alterar o podCIDR dos nós, você precisa cancelar o registro e, em seguida, registrá-los novamente, enquanto isso, faz as alterações adequadas na configuração da camada de controle do Kubernetes. Você pode exibir o podCIDR de um nó usando o seguinte comando:
$ kubectl get no <nodeName> -o json | jq '.spec.podCIDR'
10.244.0.0/24
Kubelet, iniciador de contêiner e plug-ins CNI: como tudo funciona
O agendamento de um pod por nó envolve muitas etapas preparatórias. Nesta seção, vou me concentrar apenas naqueles que estão diretamente relacionados à rede de pod.
Agendar um pod para um nó aciona a seguinte cadeia de eventos:
Ajuda: Containerd CRI Plugin Architecture .
Interação entre o iniciador de contêiner e os plug-ins CNI
Cada provedor de rede possui seu próprio plugin CNI. O tempo de execução do contêiner o inicia para configurar a rede para o pod quando ele é inicializado. No caso do containerd, o plugin Containerd CRI é responsável por iniciar o plugin CNI .
Além disso, cada provedor tem seu próprio agente. Ele é instalado em todos os nós do Kubernetes e é responsável pela rede dos pods. Este agente vem com a configuração CNI ou o cria no nó por conta própria. A configuração ajuda o plug-in CRI a determinar qual plug-in CNI chamar.
A localização da configuração CNI pode ser personalizada; por padrão, ele está em
/etc/cni/net.d/<config-file>. Os administradores de cluster também são responsáveis por instalar plug-ins CNI em cada nó do cluster. Sua localização também é personalizável; o diretório padrão é /opt/cni/bin.
Ao usar o containerd, os caminhos para os binários de configuração e plug-in podem ser definidos em uma seção
[plugins.«io.containerd.grpc.v1.cri».cni]no arquivo de configuração do containerd .
Já que estamos usando a Flanela como nosso provedor de rede, vamos falar um pouco sobre como configurá-la:
- Flanneld (daemon do Flannel) geralmente é instalado no cluster como um DaemonSet com
install-cnium contêiner init . Install-cnicria um arquivo de configuração CNI (/etc/cni/net.d/10-flannel.conflist) em cada nó.- Flanneld cria um dispositivo vxlan, busca metadados de rede do servidor API e monitora atualizações de pod. À medida que são criados, ele distribui rotas para todos os pods em todo o cluster.
- Essas rotas permitem que os pods se comuniquem uns com os outros usando endereços IP.
Para obter mais informações sobre como funciona a flanela, recomendo usar os links no final do artigo.
Aqui está um diagrama da interação entre o plug-in Containerd CRI e os plug-ins CNI:
Como você pode ver acima, o kubelet chama o plug-in Containerd CRI para criar um pod, que já chama o plug-in CNI para configurar a rede do pod. Ao fazer isso, o plug-in CNI do provedor de rede invoca outros plug-ins CNI básicos para configurar vários aspectos da rede.
Interação entre plug-ins CNI
Existem vários plug-ins CNI projetados para ajudar a configurar a rede entre contêineres em um host. Este artigo se concentrará em três deles.
Plug-in de flanela CNI
Ao usar Flannel como provedor de rede, o componente Containerd CRI invoca o plugin Flannel CNI 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 Flannel CNI funciona em conjunto com o Flanneld. Na inicialização, Flanneld extrai o podCIDR e outros detalhes relacionados à rede do servidor API e os salva em um 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 Flannel CNI usa os dados de
/run/flannel/subnet.envpara configurar e invocar o plugin bridge CNI.
Ponte do plugin CNI
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 ponte Linux com
«name»: «cni0», que é indicada na configuração. Em seguida, um par veth é criado para cada pod. Uma extremidade dele se conecta ao namespace de rede do contêiner, a outra vai para a ponte Linux na rede do host. O plug-in CNI Bridge conecta todos os contêineres de host a uma ponte Linux na rede do host.
Quando terminar de configurar o par veth, o plug-in Bridge invoca o plug-in CNI IPAM local do host. O tipo de plugin IPAM pode ser configurado na configuração CNI, que o plugin CRI usa para chamar o plugin CNI Flannel.
Plug-ins CNI do IPAM local do host
O CNI do Bridge chama o plug - in CNI do IPAM local do host com a seguinte configuração:
{
"name": "cni0",
"ipam": {
"type": "host-local",
"subnet": "10.244.0.0/24",
"dataDir": "/var/lib/cni/networks"
}
}
Anfitrião-local IPAM-plug ( IP A ddress M anagement - Gestão de endereço IP) retorna o endereço IP para a sub-rede do recipiente e armazena o IP selecionado no hospedeiro em um diretório especificado no ponto
dataDir- /var/lib/cni/networks/<network-name=cni0>/<ip>. Este arquivo contém a ID do contêiner ao qual este endereço IP foi atribuído.
Quando o plug-in IPAM local do host é chamado, ele retorna os seguintes dados:
{
"ip4": {
"ip": "10.244.4.2",
"gateway": "10.244.4.3"
},
"dns": {}
}
Resumo
Kube-controller-manager atribui podCIDR a cada nó. Os pods de cada nó obtêm endereços IP do espaço de endereço no intervalo de podCIDR alocado. Como os podCIDRs dos nós não se sobrepõem, todos os pods recebem endereços IP exclusivos.
O administrador de cluster do Kubernetes configura e instala o kubelet, o iniciador de contêiner, o agente do provedor de rede e copia os plug-ins CNI para cada nó. Durante a inicialização, o agente do provedor de rede gera a configuração CNI. Quando um pod é programado para um nó, o kubelet chama o plug-in CRI para criá-lo. Além disso, se containerd for usado, o plug-in Containerd CRI chama o plug-in CNI especificado na configuração CNI para configurar a rede do pod. Isso dá ao pod um endereço IP.
Levei algum tempo para entender todas as sutilezas e nuances de todas essas interações. Espero que a experiência adquirida ajude você a entender melhor como o Kubernetes funciona. Se eu estiver errado sobre alguma coisa, entre em contato comigo no Twitter ou em hello@ronaknathani.com . Sinta-se à vontade para entrar em contato se desejar discutir aspectos deste artigo ou qualquer outra coisa. Ficarei feliz em falar com você!
Links
Recipientes e rede
Como funciona a flanela
CRI e CNI
PS do tradutor
Leia também em nosso blog: