Cómo un pod en Kubernetes obtiene una dirección IP

Nota de traducción.: este artículo, escrito por un ingeniero SRE de LinkedIn, detalla la 'magia interna' en Kubernetes — concretamente, la interacción entre CRI, CNI y kube-apiserver — que sucede cuando un pod requiere un asignación de dirección IP.

Uno de los requisitos básicos del modelo de red de Kubernetes es que cada pod debe tener su propia dirección IP y cualquier otro pod en el clúster debe poder comunicarse con él a través de esta dirección. Hay varios 'proveedores' de red (Flannel, Calico, Canal, etc.) que ayudan a implementar este modelo de red.

Cuando empecé a trabajar con Kubernetes, no tenía del todo claro cómo los pods obtienen sus direcciones IP. Incluso con el entendimiento de cómo funcionan los componentes individuales, era difícil imaginar su trabajo conjunto. Por ejemplo, sabía para qué sirven los plugins CNI, pero no tenía idea de cómo se invocan realmente. Por eso decidí escribir este artículo para compartir conocimientos sobre los diversos componentes de red y su colaboración en el clúster de Kubernetes, que permiten que cada pod obtenga su única dirección IP.

Existen diversas formas de organizar la interacción en red en Kubernetes —similar a las diferentes opciones de entornos de ejecución (runtime) para contenedores. En esta publicación se utilizará Flannel para organizar la red en el clúster, y como entorno de ejecución— Containerd. También partimos de la suposición de que usted sabe cómo funciona la interacción de red entre contenedores, por lo que solo lo tocaré brevemente, exclusivamente para contexto.

Algunos conceptos básicos

Contenedores y red: una breve visión

En Internet hay excelentes publicaciones que explican cómo los contenedores se conectan entre sí a través de la red. Por lo tanto, solo ofreceré un resumen general de los conceptos clave y me limitaré a un enfoque que implica la creación de un puente de Linux y la encapsulación de paquetes. Los detalles se omiten, ya que el tema de la interacción de red entre contenedores merece un artículo separado. Se proporcionarán enlaces a algunas publicaciones especialmente informativas y educativas a continuación.

Contenedores en un mismo host

Una de las formas de organizar la comunicación por direcciones IP entre contenedores que funcionan en el mismo host implica crear un puente de Linux. Para esto se crean dispositivos virtuales en Kubernetes (y Docker) veth (ethernet virtual). Un extremo del dispositivo veth se conecta al espacio de nombres de red del contenedor, el otro a el puente de Linux en la red del host.

Todos los contenedores en un mismo host tienen uno de los extremos veth conectado al puente, a través del cual pueden comunicarse entre sí por direcciones IP. El puente de Linux también tiene una dirección IP y actúa como puerta de enlace para el tráfico saliente (egress) de los pods, destinado a otros nodos.

Cómo un pod en Kubernetes obtiene una dirección IP

Contenedores en diferentes hosts

La encapsulación de paquetes es una de las maneras que permite a los contenedores en diferentes nodos comunicarse entre sí por direcciones IP. En Flannel, esta funcionalidad es proporcionada por la tecnología vxlan, que "empaqueta" el paquete original en un paquete UDP y luego lo envía a su destino.

En el clúster de Kubernetes, Flannel crea un dispositivo vxlan y complementa adecuadamente la tabla de rutas en cada uno de los nodos. Cada paquete destinado a un contenedor en otro host pasa a través del dispositivo vxlan y se encapsula en un paquete UDP. En el punto de destino, el paquete anidado se extrae y se dirige al pod correspondiente.

Cómo un pod en Kubernetes obtiene una dirección IP
Nota: Este es solo uno de los métodos para organizar la interacción de red entre contenedores.

¿Qué es CRI?

CRI (Interfaz de Ejecución de Contenedores) es un plugin que permite al kubelet utilizar diferentes entornos de ejecución de contenedores. La API CRI está integrada en varios entornos de ejecución, por lo que los usuarios pueden elegir el runtime a su conveniencia.

¿Qué es CNI?

El proyecto CNI representa un especificación para proporcionar una solución de red universal para contenedores de Linux. Además, incluye complementos, responsables de diversas funciones al configurar la red del pod. Un plugin CNI es un archivo ejecutable que cumple con la especificación (algunos plugins que discutiremos más adelante).

Asignación de subredes a los nodos para asignar direcciones IP a los pods

Dado que cada pod del clúster debe tener una dirección IP, es importante asegurarse de que esta dirección sea única. Esto se logra asignando a cada nodo una subred única, de la cual luego se asignan direcciones IP a los pods en ese nodo.

Controlador IPAM del nodo

Cuando nodeipam se pasa como parámetro de bandera --controllers del kube-controller-manager, asigna a cada nodo una subred separada (podCIDR) del CIDR del clúster (es decir, el rango de direcciones IP para la red del clúster). Dado que estos podCIDR no se superponen, cada pod puede tener una dirección IP única.

Al nodo de Kubernetes se le asigna un podCIDR en el momento de su registro inicial en el clúster. Para cambiar el podCIDR de los nodos, es necesario desregistrarlos y luego volver a registrarlos, realizando los cambios correspondientes en la configuración de la capa de control de Kubernetes. El podCIDR del nodo se puede obtener con el siguiente comando:

$ kubectl get no  -o json | jq '.spec.podCIDR'
10.244.0.0/24

Kubelet, entorno de ejecución de contenedores y plugins CNI: cómo funciona todo esto

La programación de un pod en un nodo implica realizar una serie de acciones preparatorias. En esta sección, me concentraré únicamente en aquellas que están directamente relacionadas con la configuración de la red del pod.

La programación de un pod en un nodo inicia la siguiente cadena de eventos:

Cómo un pod en Kubernetes obtiene una dirección IP

Ayuda: Arquitectura de plugins CRI de Containerd.

Interacción entre el entorno de ejecución de contenedores y los plugins CNI

Cada proveedor de red tiene su propio plugin CNI. El entorno de ejecución del contenedor lo inicia para configurar la red del pod durante su lanzamiento. En el caso de containerd, el plugin de CNI es manejado por el plugin Containerd CRI.

Cada proveedor tiene su propio agente. Este se instala en todos los nodos de Kubernetes y es responsable de la configuración de la red de los pods. Este agente puede venir incluido con la configuración de CNI o crearla de manera independiente en el nodo. La configuración ayuda al plugin CRI a determinar qué plugin de CNI invocar.

La ubicación de la configuración de CNI se puede ajustar; por defecto, se encuentra en /etc/cni/net.d/<config-file>. Los administradores del clúster también son responsables de instalar los plugins de CNI en cada nodo del clúster. Su ubicación también se configura; el directorio por defecto es /opt/cni/bin.

Al usar containerd, las rutas para la configuración y los binarios del plugin se pueden definir en la sección [plugins."io.containerd.grpc.v1.cri".cni] en del archivo de configuración de containerd.

Dado que estamos utilizando Flannel como proveedor de red, hablemos un poco sobre su configuración:

  • Flanneld (el demonio de Flannel) normalmente se instala en el clúster como un DaemonSet con install-cni como init-container.
  • Install-cni crea el archivo de configuración de CNI (/etc/cni/net.d/10-flannel.conflist) en cada nodo.
  • Flanneld crea un dispositivo vxlan, extrae metadatos de red de la API del servidor y monitorea las actualizaciones de los pods. A medida que se crean, difunde rutas para todos los pods a lo largo del clúster.
  • Estas rutas permiten que los pods se conecten entre sí a través de direcciones IP.

Para más información sobre el funcionamiento de Flannel, recomiendo consultar los enlaces al final del artículo.

Aquí hay un diagrama de interacción entre el plugin Containerd CRI y los plugins CNI:

Cómo un pod en Kubernetes obtiene una dirección IP

Como se puede ver arriba, kubelet llama al plugin Containerd CRI para crear un pod, y este a su vez llama al plugin CNI para configurar la red del pod. En este proceso, el plugin de red CNI llama a otros plugins base de CNI para configurar varios aspectos de la red.

Interacción entre plugins CNI

Existen varios plugins CNI cuyo propósito es ayudar a configurar la interacción de red entre los contenedores en el host. En este artículo, abordaremos tres de ellos.

Plugin CNI Flannel

Al usar Flannel como proveedor de red, el componente Containerd CRI llama Plugin CNI Flannel, utilizando un archivo de configuración 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
      }
    }
  ]
}

El plugin CNI Flannel trabaja junto con Flanneld. Durante el inicio, Flanneld extrae podCIDR y otros detalles relacionados con la red de la API del servidor y los guarda en el archivo /run/flannel/subnet.env.

FLANNEL_NETWORK=10.244.0.0/16 
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450 
FLANNEL_IPMASQ=false

El plugin CNI Flannel utiliza datos de /run/flannel/subnet.env para configurar y llamar al plugin CNI bridge.

Plugin CNI Bridge

Este plugin se invoca con la siguiente configuración:

{
  "name": "cni0",
  "type": "bridge",
  "mtu": 1450,
  "ipMasq": false,
  "isGateway": true,
  "ipam": {
    "type": "host-local",
    "subnet": "10.244.0.0/24"
  }
}

En la primera llamada, crea un puente Linux con "name": "cni0", que se indica en la configuración. Luego, para cada pod, se crea un par veth. Un extremo se conecta al espacio de nombres de red del contenedor, y el otro entra en el puente Linux en la red del host. Plugin CNI Bridge conecta todos los contenedores del host al puente Linux en la red del host.

Una vez finalizada la configuración del par veth, el plugin Bridge llama al plugin IPAM local del host (host-local) CNI. El tipo de plugin IPAM puede configurarse en la configuración CNI que el plugin CRI utiliza para llamar al plugin CNI Flannel.

Plugins IPAM locales del host CNI

Bridge CNI llama al plugin IPAM local del host CNI con la siguiente configuración:

{
  "name": "cni0",
  "ipam": {
    "type": "host-local",
    "subnet": "10.244.0.0/24",
    "dataDir": "/var/lib/cni/networks"
  }
}

Plugin IPAM local de host (IP Adirección Mgestión — administración de direcciones IP) devuelve una dirección IP para el contenedor de la subred y guarda la IP asignada en el host en el directorio indicado en la sección dataDir — /var/lib/cni/networks/<network-name=cni0>/<ip>. Este archivo contiene el ID del contenedor al que se le ha asignado esta dirección IP.

Al invocar el plugin IPAM local de host, devuelve los siguientes datos:

{
  "ip4": {
    "ip": "10.244.4.2",
    "gateway": "10.244.4.3"
  },
  "dns": {}
}

Currículum

El kube-controller-manager asigna podCIDR a cada nodo. Los pods de cada nodo obtienen direcciones IP del espacio de direcciones en el rango asignado podCIDR. Dado que los podCIDR de los nodos no se superponen, todos los pods reciben direcciones IP únicas.

El administrador del clúster de Kubernetes configura e instala kubelet, el entorno de ejecución de contenedores, el agente del proveedor de red y copia los plugins CNI en cada nodo. Durante el inicio, el agente del proveedor de red genera la configuración CNI. Cuando un pod se planea en un nodo, kubelet llama al plugin CRI para su creación. Luego, si se usa containerd, el plugin Containerd CRI llama al plugin CNI especificado en la configuración CNI para configurar la red del pod. Como resultado, el pod recibe una dirección IP.

Me tomó un tiempo comprender todos los detalles y matices de todas estas interacciones. Espero que la experiencia adquirida también te ayude a entender mejor cómo funciona Kubernetes. Si cometo algún error, por favor contáctame en Twitter o a hello@ronaknathani.com. No dudes en comunicarte si deseas discutir aspectos de este artículo o cualquier otra cosa. ¡Estaré encantado de conversar contigo!

Enlaces

Contenedores y red

Cómo funciona Flannel

CRI y CNI

P.D. del traductor

También puedes leer en nuestro blog:

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster