Mi artículo anterior mostró cómo los contenedores se comunican dentro de los pods a través del mismo espacio de nombres de red. Este artículo analiza cómo los pods se comunican entre sí cuando existen en diferentes nodos de Kubernetes.
Kubernetes define un modelo de red llamado Container Networking Interface (CNI), pero la implementación real se basa en complementos de red. Los complementos de red son responsables de asignar direcciones de protocolo de Internet (IP) a los pods y permitir que los pods se comuniquen entre sí dentro de un clúster de Kubernetes. Kubernetes tiene una variedad de complementos de red, pero este artículo usará franelaFlannel es muy simple y utiliza la superposición de LAN virtual extensible (VXLAN) de forma predeterminada.
A menudo escuchas sobre redes superpuestas en el contexto de las redes de Kubernetes. Si bien esto suena complicado, la superposición de redes es solo otra capa de encapsulación del tráfico de red. Por ejemplo, el complemento de red Flannel toma el tráfico de los pods y lo encapsula en el protocolo VXLAN. Este artículo profundiza en cómo funciona este encapsulamiento y cómo aparece el tráfico en la red.
[ Learn how to manage your Linux environment for success. ]
Tabla de Contenidos
Configuración del entorno
El entorno de este artículo utiliza un clúster minikube de dos nodos con el complemento de red Flannel. Puede iniciar el entorno minikube necesario con:
$ minikube start --nodes 2 --network-plugin=cni --cni=flannel
😄 minikube v1.25.2 on Ubuntu 20.04
✨ Automatically selected the kvm2 driver. Other choices: virtualbox, ssh
❗ With --network-plugin=cni, you will need to provide your own CNI. See --cni flag as a user-friendly alternative
👍 Starting control plane node minikube in cluster minikube
🔥 Creating kvm2 VM (CPUs=2, Memory=2200MB, Disk=20000MB) ...
🐳 Preparing Kubernetes v1.23.3 on Docker 20.10.12 ...
▪ kubelet.housekeeping-interval=5m
▪ Generating certificates and keys ...
▪ Booting up control plane ...
▪ Configuring RBAC rules ...
🔗 Configuring Flannel (Container Networking Interface) ...
🔎 Verifying Kubernetes components...
▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟 Enabled addons: storage-provisioner, default-storageclass
👍 Starting worker node minikube-m02 in cluster minikube
🔥 Creating kvm2 VM (CPUs=2, Memory=2200MB, Disk=20000MB) ...
🌐 Found network options:
▪ NO_PROXY=192.168.50.43
🐳 Preparing Kubernetes v1.23.3 on Docker 20.10.12 ...
▪ env NO_PROXY=192.168.50.43
🔎 Verifying Kubernetes components...
🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
# Verify that nodes are up and ready
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane,master 65s v1.23.3
minikube-m02 Ready 34s v1.23.3
El siguiente diagrama muestra la topología básica de este entorno. Describiré cada componente de esta topología con más detalle a lo largo del artículo.
A continuación se muestra la definición fedora-1
y fedora-2
vaina.Una nodeSelector
Se utiliza para garantizar que cada pod se ejecute en un host independiente para este experimento.
Esto es k8s_flannel_fedora_1_definition.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: fedora-1
spec:
nodeSelector:
kubernetes.io/hostname: minikube
containers:
- command:
- sleep
- infinity
image: fedora
name: fedora
y k8s_flannel_fedora_2_definition.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: fedora-2
spec:
nodeSelector:
kubernetes.io/hostname: minikube-m02
containers:
- command:
- sleep
- infinity
image: fedora
name: fedora
Tenga en cuenta que, en este artículo, entraré en pods y ejecutaré comandos en su espacio de nombres. Muchos de estos comandos no están instalados de forma predeterminada, pero puede instalarlos mediante DNF. Solo entraré en el pod por las razones explicadas, debe evitar «iniciar sesión» en el pod e instalar las utilidades directamente en producción.
El modelo OSI es el estándar principal para describir las comunicaciones entre computadoras o sistemas de telecomunicaciones. El modelo se divide en siete capas, cada capa cubre diferentes responsabilidades en el proceso de comunicación de la red. Este artículo se centra en la capa 2 (capa de enlace de datos) y la capa 3 (capa de red).
Red de capa 2
Este ejercicio parte de fedora-1
vainas a fedora-2
pods y rastrearlos a través de la pila de red.Conectado a fedora-1
pod e inspeccionar su pila de red descubre que tiene un eth0@if10
interfaz.Esta interfaz es una ethernet virtuales un par.
Un par de ethernet virtual permite conexiones entre espacios de nombres de red, como entre el espacio de nombres de un pod y el espacio de nombres predeterminado de un host.Este @if10
y salida ethtool
Indica que el índice de interfaz de pares en el host es 10
.
# Enter the fedora-1 pod
$ kubectl exec -it fedora-1 -- /bin/bash
# Inspect the network configuration within the fedora-1 pod
[root@fedora-1 /]# ip link sh
1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: sit0@NONE: mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/sit 0.0.0.0 brd 0.0.0.0
4: eth0@if10: mtu 1450 qdisc noqueue state UP mode DEFAULT group default
link/ether 92:73:8f:43:67:1b brd ff:ff:ff:ff:ff:ff link-netnsid 0
[root@fedora-1 /]# ethtool -S eth0
NIC statistics:
peer_ifindex: 10
Ahora puede verificar la configuración de la red en el host de minikube.Hay varias interfaces adicionales, pero en la configuración de red fedora-1
pod representa una interfaz indexada 10
es el extremo remoto de un par Ethernet virtual.interfaz indexada 10
en el host minikube es vetheaa97948@if4
y @if4
y salida ethtool
Ambos indican que el índice de pares remotos es 4
El índice corresponde a eth0
desde la interfaz fedora-1
pod, cuyo índice de interfaz es 4
.
# Inspect the network configuration on the minikube host
$ ip link sh
1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 52:54:00:37:09:5c brd ff:ff:ff:ff:ff:ff
3: eth1: mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 52:54:00:ea:1b:4a brd ff:ff:ff:ff:ff:ff
4: sit0@NONE: mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/sit 0.0.0.0 brd 0.0.0.0
5: docker0: mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
link/ether 02:42:7e:1b:3c:46 brd ff:ff:ff:ff:ff:ff
6: cni-podman0: mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000
link/ether aa:8b:b8:3b:ae:0d brd ff:ff:ff:ff:ff:ff
8: flannel.1: mtu 1450 qdisc noqueue state UNKNOWN mode DEFAULT group default
link/ether 3e:7d:76:2a:39:82 brd ff:ff:ff:ff:ff:ff
9: cni0: mtu 1450 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether c6:ae:d0:e6:66:cc brd ff:ff:ff:ff:ff:ff
$ ethtool -S vetheaa97948
NIC statistics:
peer_ifindex: 4
10: vetheaa97948@if4: mtu 1450 qdisc noqueue master cni0 state UP mode DEFAULT group default
link/ether 0e:52:e0:c4:14:74 brd ff:ff:ff:ff:ff:ff link-netnsid 0
El par ethernet virtual también está conectado al puente en el host minikube. Esto permite que los Pods en el mismo host se comuniquen directamente entre sí a través del puente.Este cni0
Una interfaz de puente tiene asignada una dirección IP, que es importante durante el enrutamiento de capa 3:
# Bridge configuration on minikube host
$ brctl show
bridge name bridge id STP enabled interfaces
cni-podman0 8000.aa8bb83bae0d no
cni0 8000.c6aed0e666cc no vetheaa97948
docker0 8000.02427e1b3c46 no
# Bridge interface IP address on minikube host
$ ip -br addr sh cni0
cni0 UP 10.244.0.1/24
Después de investigar la pila de red interna flannel-1
host pod y minikube, el diagrama de red es el siguiente:
Red de capa 3
En este punto, una gran parte de la capa 2 del diagrama está completa. Sin embargo, esto solo proporciona conectividad local para pods.A continuación, considere cómo fedora-1
existir 10.244.0.2/24
puede comunicar fedora-2
existir 10.244.1.3/24
que está en una red de Capa 3 diferente.
[ Get the guide to installing applications on Linux. ]
primero, fedora-1
El pod debe decidir dónde enviar el tráfico a la red remota.La tabla de enrutamiento no contiene una ruta específica que contenga 10.244.1.3
asi que fedora-1
enviará tráfico a su puerta de enlace predeterminada.La puerta de enlace predeterminada está en 10.244.0.1
que es la dirección IP cni0
Puente en host minikube:
# The default route is 10.244.0.1, which is the cni0 bridge on the Minikube host
[root@fedora-1 /]# ip route sh
default via 10.244.0.1 dev eth0
10.244.0.0/24 dev eth0 proto kernel scope link src 10.244.0.2
10.244.0.0/16 via 10.244.0.1 dev eth0
Una vez que el tráfico llega a la puerta de enlace predeterminada, la siguiente decisión de enrutamiento determina cómo reenviar ese tráfico a la red deseada (10.244.10/24
).La tabla de enrutamiento del host muestra que 10.244.1.0/24
La red enviará 10.244.1.0
existir flannel.1
interfaz:
# Routing table on minikube node
$ ip route sh
default via 192.168.122.1 dev eth1 proto dhcp src 192.168.122.215 metric 1024
10.88.0.0/16 dev cni-podman0 proto kernel scope link src 10.88.0.1 linkdown
10.244.0.0/24 dev cni0 proto kernel scope link src 10.244.0.1
10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
192.168.61.0/24 dev eth0 proto kernel scope link src 192.168.61.95
192.168.122.0/24 dev eth1 proto kernel scope link src 192.168.122.215
192.168.122.1 dev eth1 proto dhcp scope link src 192.168.122.215 metric 1024
Este flannel.1
interface es una interfaz VXLAN cuyo ID de VXLAN es 1 y una dirección IP 10.244.0.0/32
:
# flannel.1 interface on minikube host
$ ip -d link sh flannel.1
8: flannel.1: mtu 1450 qdisc noqueue state UNKNOWN mode DEFAULT group default
link/ether 3e:7d:76:2a:39:82 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65535
vxlan id 1 local 192.168.122.215 dev eth1 srcport 0 0 dstport 8472 nolearning ttl auto ageing 300 udpcsum noudp6zerocsumtx noudp6zerocsumrx addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
$ ip -br addr sh flannel.1
flannel.1 UNKNOWN 10.244.0.0/32
El siguiente salto del paquete proviene de fedora-1
a fedora-2
Sí 10.244.1.0
Sin embargo, ninguna interfaz en la red contiene 10.244.1.0
Dirección. En su lugar, hay una entrada estática de Protocolo de resolución de direcciones (ARP) en la tabla ARP en el host de minikube.Esta entrada estática indica la dirección MAC 10.244.1.0
Sí d2:d8:a1:85:9e:38
La base de datos de reenvío de puente dirige el tráfico para esta dirección MAC a 192.168.122.7
Esta dirección remota, que es la interfaz física en el dispositivo minikube-m02
nodo, que es el otro extremo del túnel VXLAN.
# ARP table on minikube host. Note that some entries have been removed for brevity.
$ arp -a
? (10.244.1.0) at d2:d8:a1:85:9e:38 [ether] PERM on flannel.1
# Determine the container ID of the Flannel container and obtain a shell within the container.
$ docker ps | grep flannel
ee112410bd61 4e9f801d2217 "/opt/bin/flanneld -…" 8 hours ago Up 8 hours k8s_kube-flannel_kube-flannel-ds-amd64-2qqld_kube-system_bc079a14-d045-44ce-9dc2-fa1369a20c30_0
11eee23ddcb0 k8s.gcr.io/pause:3.6 "/pause" 8 hours ago Up 8 hours k8s_POD_kube-flannel-ds-amd64-2qqld_kube-system_bc079a14-d045-44ce-9dc2-fa1369a20c30_0
$ docker exec -it ee112410bd61 /bin/bash
# Bridge forwarding database information within the Flannel container on the minikube host. Irrelevant entries have been removed for brevity.
bash-5.0# bridge fdb show
d2:d8:a1:85:9e:38 dev flannel.1 dst 192.168.122.7 self permanent
Esta información adicional proporciona un gráfico de tráfico general en el lado de la topología:
Puede ver la imagen completa mirando la configuración en el otro lado de la conexión fedora-2
vainas y minikube-m02
nodo:
# MAC and IP addresses within fedora-2 pod
[root@fedora-2 /]# ip -br link sh
lo UNKNOWN 00:00:00:00:00:00
sit0@NONE DOWN 0.0.0.0
eth0@if9 UP 1e:59:e5:f0:89:56
[root@fedora-2 /]# ip -br addr sh
lo UNKNOWN 127.0.0.1/8
sit0@NONE DOWN
eth0@if9 UP 10.244.1.3/24
# Peer interface within fedora-2 pod for veth
[root@fedora-2 /]# ethtool -S eth0
NIC statistics:
peer_ifindex: 9
# MAC and IP addresses on the minikube-m02 node
$ ip -br link sh
lo UNKNOWN 00:00:00:00:00:00
eth0 UP 52:54:00:4b:22:10
eth1 UP 52:54:00:b4:90:59
sit0@NONE DOWN 0.0.0.0
docker0 DOWN 02:42:df:f0:b5:92
flannel.1 UNKNOWN d2:d8:a1:85:9e:38
cni0 UP ba:b6:aa:32:0a:ed
vethd63c7e02@if4 UP 96:ba:a1:c6:7c:b8
veth4427a55c@if4 UP 6a:df:dc:89:7a:7f
$ ip -br addr sh
lo UNKNOWN 127.0.0.1/8
eth0 UP 192.168.61.149/24
eth1 UP 192.168.122.7/24
sit0@NONE DOWN
docker0 DOWN 172.17.0.1/16
flannel.1 UNKNOWN 10.244.1.0/32
cni0 UP 10.244.1.1/24
vethd63c7e02@if4 UP
veth4427a55c@if4 UP
# Peer interface on host for veth
$ ethtool -S veth4427a55c
NIC statistics:
peer_ifindex: 4
El flujo de tráfico completo ahora se puede entender a un alto nivel: el Pod envía tráfico a su próximo salto, el puente CNI en el host.El host reenvía este tráfico localmente a través de flannel.1
interfaz para flannel.1
Interfaz en el nodo remoto. Este tráfico se encapsula en un túnel VXLAN. Una vez que el nodo remoto lo recibe, se desencapsula y se reenvía al pod de destino:
comunicación por cable
Ahora que comprende cómo funciona la pila de redes, es hora de verlo en acción. La mejor manera de llevar este conocimiento de lo conceptual a lo concreto es enviar tráfico entre pods y observar el tráfico en el cable.
Para esto, estoy fedora-1
y fedora-2
Al ejecutar una captura de paquetes Wireshark en una red física. En mi configuración, minikube se ejecuta en un host Linux, lo que requiere capturar paquetes en el controlador de interfaz de red virtual (NIC) de la máquina virtual minikube.Con la captura de paquetes en ejecución, configuré un ping desde fedora-1
a fedora-2
:
[root@fedora-1 /]# ping 10.244.1.3
PING 10.244.1.3 (10.244.1.3) 56(84) bytes of data.
64 bytes from 10.244.1.3: icmp_seq=1 ttl=62 time=0.301 ms
64 bytes from 10.244.1.3: icmp_seq=2 ttl=62 time=0.771 ms
64 bytes from 10.244.1.3: icmp_seq=3 ttl=62 time=0.762 ms
Una vez que capturo algunos paquetes, uso Wireshark para analizarlos. Tenga en cuenta que el tráfico aparece como tráfico normal del Protocolo de datagramas de usuario (UDP), no como tráfico del Protocolo de mensajes de control de Internet (ICMP). Esto se debe a que está encapsulado en un túnel VXLAN.
Puede decirle a Wireshark que decodifique el tráfico como tráfico VXLAN haciendo clic con el botón derecho en cualquier tráfico, seleccionando decodificado a…y especificar VXLAN Protocolo actual como puerto UDP 8472 (el puerto utilizado por el túnel VXLAN):
Cuando la decodificación está configurada correctamente, el tráfico aparecerá como tráfico ICMP. Expandir un paquete específico muestra la imagen completa:
Comenzaré desde la parte más interna del paquete.Este es un paquete ICMP de 10.244.0.2
(fedora-1
) a 10.244.1.3
(fedora-2
).El encabezado Ethernet más interno especifica una dirección MAC de origen 3e:7d:76:2a:39:82
(flannel.1
superior minikube
) y la dirección MAC de destino d2:d8:a1:85:9e:38
(flannel.1
superior minikube-m02
).
A continuación, puede ver un identificador de red VXLAN 1que corresponde a la configuración que viste anteriormente flannel.1
interfaz. Este es el encabezado de VXLAN que habilita la parte superpuesta de esta red. El tráfico interno se encapsula en este encabezado de VXLAN y los pods que se comunican entre sí no conocen la topología de la red física.
Moviéndose hacia arriba en la pila, puede ver que este es un 192.168.122.215
(eth1
superior minikube
) a 192.168.122.7
(eth1
superior minikube-m02
). La dirección MAC también se cambia de 52:54:00:ea:1b:4a
(eth1
superior minikube
) a 52:54:00:b4:90:59
(eth1
superior minikube-m02
) porque estos nodos de minikube están en la misma red física.
Estos paquetes muestran fedora-1
a fedora-2
vaina. El tráfico se encapsula con encabezados VXLAN y se envía directamente entre los dos nodos minikube. Cuando un nodo recibe tráfico, elimina el encabezado VXLAN y reenvía el paquete interno al pod correspondiente. Esto permite una comunicación completa de extremo a extremo entre los pods sin necesidad de que conozcan la red física subyacente.
envolver
Este artículo muestra cómo viajan los paquetes de un pod de Kubernetes a otro a través de la red de superposición VXLAN. El proceso es bastante complejo y este artículo proporciona los comandos detallados necesarios para realizar un seguimiento completo de este tráfico. Si bien Flannel es solo un ejemplo de un complemento de red de Kubernetes, los comandos y conceptos generales de este artículo pueden ayudarlo a comprender el tráfico en un clúster de Kubernetes utilizando diferentes métodos de red.