Plugins de rede
Plugins de redes no Kubernetes podem ser dos seguintes tipos:
- Plugins CNI: Aderentes à especificação Container Network Interface (CNI), desenhados para interoperabilidade.
- Kubernetes usa a versão v0.4.0 da especificação CNI.
- Plugin kubenet: Implementa o
cbr0
básico usando os plugins CNIbridge
ehost-local
Instalação
O kubelet possui um plugin único padrão, e um plugin padrão comum para todo o cluster. Ele verifica o plugin quando inicia, se lembra o que encontrou, e executa o plugin selecionado em momentos oportunos dentro do ciclo de vida de um Pod (isso é verdadeiro apenas com o Docker, uma vez que o CRI gerencia seus próprios plugins de CNI). Existem dois parâmetros de linha de comando no Kubelet para se ter em mente quando usando plugins:
cni-bin-dir
: O Kubelet verifica esse diretório por plugins na inicializaçãonetwork-plugin
: O plugin de rede que deve ser utilizado do diretório configurado emcni-bin-dir
. Deve ser igual ao nome configurado por um plugin no diretório de plugins. Para plugins de CNI, isso equivale ao valorcni
.
Requisitos de plugins de Rede
Além de prover a interface NetworkPlugin
para configuração da rede do pod, o plugin pode necessitar de suporte específico ao
kube-proxy.
O proxy iptables obviamente depende do iptables, e o plugin deve garantir que o
tráfego do contêiner esteja disponível para o iptables. Por exemplo, se o plugin
conecta os contêineres à Linux bridge, o plugin deve configurar a diretiva de
sysctl net/bridge/bridge-nf-call-iptables
com o valor 1
para garantir que o
proxy iptables opere normalmente. Se o plugin não faz uso da Linux Bridge (mas outro
mecanismo, como Open vSwitch) ele deve garantir que o tráfego do contêiner é roteado
apropriadamente para o proxy.
Por padrão, se nenhum plugin de rede é configurado no kubelet, o plugin noop
é utilizado,
que configura net/bridge/bridge-nf-call-iptables=1
para garantir que configurações simples
(como Docker com bridge Linux) operem corretamente com o proxy iptables.
CNI
O plugin de CNI é selecionado utilizando-se da opção --network-plugin=cni
no início do Kubeket.
O Kubelet lê um arquivo do diretório especificado em --cni-conf-dir
(padrão /etc/cni/net.d
)
e usa a configuração de CNI desse arquivo para configurar a rede de cada Pod. O arquivo de
configuração do CNI deve usar a especificação de CNI,
e qualquer plugin referenciado nesse arquivo deve estar presente no diretório
--cni-bin-dir
(padrão /opt/cni/bin
).
Se existirem múltiplos arquivos de configuração no diretório, o kubelet usa o arquivo de configuração que vier primeiro pelo nome, em ordem alfabética.
Adicionalmente ao plugin de CNI especificado no arquivo de configuração, o Kubernetes requer
o plugin CNI padrão lo
ao menos na versão 0.2.0.
Suporte a hostPort
O plugin de redes CNI suporta hostPort
. Você pode utilizar o plugin oficial
portmap
ou usar seu próprio plugin com a funcionalidade de portMapping.
Caso você deseje habilitar o suporte a hostPort
, você deve especificar
portMappings capability
no seu cni-conf-dir
.
Por exemplo:
{
"name": "k8s-pod-network",
"cniVersion": "0.4.0",
"plugins": [
{
"type": "calico",
"log_level": "info",
"datastore_type": "kubernetes",
"nodename": "127.0.0.1",
"ipam": {
"type": "host-local",
"subnet": "usePodCidr"
},
"policy": {
"type": "k8s"
},
"kubernetes": {
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
}
},
{
"type": "portmap",
"capabilities": {"portMappings": true}
}
]
}
Suporte a controle de banda
Funcionalidade experimental
O plugin de rede CNI também suporta o controle de banda de entrada e saída. Você pode utilizar o plugin oficial bandwidth desenvolvido ou usar seu próprio plugin de controle de banda.
Se você habilitar o suporte ao controle de banda, você deve adicionar o plugin bandwidth
no seu arquivo de configuração de CNI (padrão /etc/cni/net.d
) e garantir que o programa
exista no diretório de binários do CNI (padrão /opt/cni/bin
).
{
"name": "k8s-pod-network",
"cniVersion": "0.4.0",
"plugins": [
{
"type": "calico",
"log_level": "info",
"datastore_type": "kubernetes",
"nodename": "127.0.0.1",
"ipam": {
"type": "host-local",
"subnet": "usePodCidr"
},
"policy": {
"type": "k8s"
},
"kubernetes": {
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
}
},
{
"type": "bandwidth",
"capabilities": {"bandwidth": true}
}
]
}
Agora você pode adicionar as anotações kubernetes.io/ingress-bandwidth
e
kubernetes.io/egress-bandwidth
em seu pod.
Por exemplo:
apiVersion: v1
kind: Pod
metadata:
annotations:
kubernetes.io/ingress-bandwidth: 1M
kubernetes.io/egress-bandwidth: 1M
...
kubenet
Kubenet é um plugin de rede muito simples, existente apenas no Linux. Ele não implementa funcionalidades mais avançadas, como rede entre nós ou políticas de rede. Ele é geralmente utilizado junto a um provedor de nuvem que configura as regras de roteamento para comunicação entre os nós, ou em ambientes com apenas um nó.
O Kubenet cria uma interface bridge no Linux chamada cbr0
e cria um par veth
para cada um dos pods com o host como a outra ponta desse par, conectado à cbr0
.
Na interface no lado do Pod um endereço IP é alocado de uma faixa associada ao nó,
sendo parte de alguma configuração no nó ou pelo controller-manager. Na interface cbr0
é associado o MTU equivalente ao menor MTU de uma interface de rede do host.
Esse plugin possui alguns requisitos:
- Os plugins CNI padrão
bridge
,lo
ehost-local
são obrigatórios, ao menos na versão 0.2.0. O Kubenet buscará inicialmente esses plugins no diretório/opt/cni/bin
. Especifique a opçãocni-bin-dir
no kubelet para fornecer um diretório adicional de busca. O primeiro local equivalente será o utilizado. - O kubelet deve ser executado com a opção
--network-plugin=kubenet
para habilitar esse plugin. - O Kubelet deve ainda ser executado com a opção
--non-masquerade-cidr=<clusterCidr>
para garantir que o tráfego de IPs para fora dessa faixa seja mascarado. - O nó deve possuir uma subrede associada, através da opção
--pod-cidr
configurada na inicialização do kubelet, ou as opções--allocate-node-cidrs=true --cluster-cidr=<cidr>
utilizadas na inicialização do controller-manager.
Customizando o MTU (com kubenet)
O MTU deve sempre ser configurado corretamente para obter-se a melhor performance de rede. Os plugins de rede geralmente tentam detectar uma configuração correta de MTU, porém algumas vezes a lógica não irá resultar em uma configuração adequada. Por exemplo, se a Docker bridge ou alguma outra interface possuir um MTU pequeno, o kubenet irá selecionar aquela MTU. Ou caso você esteja utilizando encapsulamento IPSEC, o MTU deve ser reduzido, e esse cálculo não faz parte do escopo da maioria dos plugins de rede.
Sempre que necessário, você pode configurar explicitamente o MTU com a opção network-plugin-mtu
no kubelet. Por exemplo, na AWS o MTU da eth0
geralmente é 9001 então você deve
especificar --network-plugin-mtu=9001
. Se você estiver usando IPSEC você deve reduzir
o MTU para permitir o encapsulamento excedente; por exemplo: --network-plugin-mtu=8773
.
Essa opção faz parte do plugin de rede. Atualmente apenas o kubenet suporta a configuração
network-plugin-mtu
.
Resumo de uso
--network-plugin=cni
especifica que devemos usar o plugin de redescni
com os binários do plugin localizados em--cni-bin-dir
(padrão/opt/cni/bin
) e as configurações do plugin localizadas em--cni-conf-dir
(default/etc/cni/net.d
).--network-plugin=kubenet
especifica que iremos usar o plugin de redekubenet
com os plugins CNIbridge
,lo
ehost-local
localizados em/opt/cni/bin
oucni-bin-dir
.--network-plugin-mtu=9001
especifica o MTU a ser utilizado, atualmente apenas em uso pelo plugin de redekubenet