Redes de Kubernetes: Pods

El material, cuya traducción publicamos hoy, está dedicado a las características de la red de hogares Kubernetes. Está destinado a aquellos que ya tienen algo de experiencia con Kubernetes. Si no está muy versado en Kubernetes, entonces probablemente valga la pena leer este tutorial de Kubernetes antes de leer este material, donde trabajar con esta plataforma se considera para principiantes.



Vainas


¿Qué hay debajo de (pod) Kubernetes? Sub es una entidad que consta de uno o más contenedores alojados en el mismo host y configurados para compartir recursos de pila de red y otros recursos como volúmenes. Los pods son los componentes básicos que componen las aplicaciones que se ejecutan en la plataforma Kubernetes. Las vainas comparten una pila de red. En la práctica, esto significa que todos los contenedores que forman el hogar pueden comunicarse entre sí a través de localhost . Si hay un contenedor en el hogar que ejecuta nginx, escuchando en el puerto 80, y otro contenedor que ejecuta scrapyd, este contenedor puede acceder al primer contenedor en http://localhost:80 . No se ve tan difícil. Ahora preguntémonos cómo funciona esto realmente. Echemos un vistazo a una situación típica cuando el contenedor Docker se inicia en la máquina local.


Contenedor Docker ejecutándose en una máquina local

Si observa este esquema de arriba a abajo, resulta que hay una interfaz de red física eth0 . El puente docker0 está docker0 y la interfaz de red virtual docker0 está veth0 al puente. Tenga en cuenta que las veth0 docker0 y veth0 están en la misma red, en este ejemplo es 172.17.0.0/24 . En esta red, a docker0 asigna la dirección IP 172.17.0.1 , esta interfaz es la puerta de enlace predeterminada para veth0 , a la que se le asigna la dirección 172.17.0.2 . Debido a las peculiaridades de configurar espacios de nombres de red al iniciar el contenedor, los procesos dentro del contenedor solo ven la interfaz veth0 e interactúan con el mundo exterior a través de las interfaces docker0 y eth0 . Ahora ejecuta el segundo contenedor.


Dos contenedores Docker ejecutándose en la máquina local.

Como puede ver en el diagrama anterior, la nueva interfaz de red virtual veth1 se asigna al segundo contenedor, que está conectado al mismo puente que el primer contenedor, a docker0 . Esta es una descripción bastante concisa de lo que realmente está sucediendo. Además, debe tenerse en cuenta que la conexión entre el contenedor y el puente se establece gracias a un par de interfaces Ethernet virtuales conectadas, una de las cuales está en el espacio de nombres del contenedor y la otra en el espacio de nombres de la red raíz. Los detalles sobre esto se pueden encontrar aquí .

Todo esto es bueno, pero aún no describe lo que, cuando se aplica a los pods de Kubernetes, llamamos "pila de red compartida". Afortunadamente, los espacios de nombres son muy flexibles. Docker puede iniciar un contenedor y, en lugar de crear una nueva interfaz de red virtual para él, hacer que use la interfaz existente junto con otros contenedores. Con este enfoque, tendremos que cambiar el esquema anterior como se muestra a continuación.


Los contenedores usan una interfaz de red común

Ahora el segundo contenedor interactúa con la interfaz veth0 ya existente, y no con su propia interfaz veth1 , como lo fue en el ejemplo anterior. El uso de tal esquema conlleva varias consecuencias. Para empezar, ahora podemos decir que ambos contenedores son visibles externamente en la misma dirección: 172.17.0.2 , y dentro de cada uno de ellos pueden acceder a los puertos en localhost abiertos por otro contenedor. Además, esto significa que estos contenedores no pueden abrir los mismos puertos. Esto, por supuesto, es una limitación, pero no difiere de una limitación similar en la situación cuando varios procesos abren puertos en el mismo host. Con este enfoque, un conjunto de procesos obtiene todas las ventajas asociadas con la ejecución de estos procesos en contenedores, como la conectividad y el aislamiento deficientes, pero al mismo tiempo, los procesos pueden organizar la colaboración en los entornos de red existentes más simples.

Kubernetes implementa este patrón creando un contenedor especial para cada hogar cuyo único propósito es proporcionar una interfaz de red para otros contenedores de hogar. Si se conecta al nodo del clúster de Kubernetes al que ssh le asigna un sub específico y ejecuta el docker ps , verá al menos un contenedor ejecutándose con el comando de pause . Este comando detiene el proceso actual hasta que llega una señal SIGTERM . Dichos contenedores no hacen absolutamente nada, están en un estado de "suspensión" y están esperando esta señal. A pesar de que los contenedores "suspendidos" no hacen nada, son, por así decirlo, el "corazón" del hogar, proporcionando a otros contenedores una interfaz de red virtual que pueden usar para interactuar entre ellos o con el mundo exterior. Como resultado, resulta que en un entorno hipotético parecido a nuestro esquema anterior, se vería como el que se muestra a continuación.


Contenedores hipotéticos

Red de hogar


Uno debajo, lleno de contenedores, es el componente básico de un determinado sistema, pero hasta ahora no es este sistema en sí. La arquitectura de Kubernetes se basa en el requisito de que los pods puedan interactuar con otros pods independientemente de si se ejecutan en la misma computadora o en máquinas diferentes. Para aprender cómo funciona todo esto, necesitamos ir a un nivel más alto de abstracción y hablar sobre cómo funcionan los nodos en el clúster de Kubernetes. Aquí cubriremos el tema del enrutamiento y las rutas de la red. Este tema a menudo se evita en materiales como este, ya que lo considera demasiado complejo. No es fácil encontrar una guía comprensible y no demasiado larga para el enrutamiento IP, pero si desea ver una breve descripción general de este problema, puede echar un vistazo a este material.

El clúster de Kubernetes consta de un nodo o más nodos. Un nodo es un sistema host, físico o virtual, que contiene varias herramientas de software y sus dependencias (principalmente Docker), así como varios componentes del sistema Kubernetes. El nodo está conectado a la red, lo que le permite intercambiar datos con otros nodos en el clúster. Así es como podría verse un clúster simple de dos nodos.


Un clúster simple de dos nodos

Si el clúster en cuestión se ejecuta en un entorno de nube como GCP o AWS, entonces este esquema transmite con bastante precisión la esencia de la arquitectura de red predeterminada para proyectos individuales. Para fines de demostración, 10.100.0.0/24 utilizó la red privada 10.100.0.0/24 en este ejemplo. Como resultado, la dirección 10.100.0.1 asigna al 10.100.0.1 y las direcciones 10.100.0.2 y 10.100.0.3 dos nodos. Usando esta arquitectura, cada uno de los nodos puede interactuar con el otro usando su interfaz de red eth0 . Ahora recordemos que debajo, ejecutándose en el host, no está en esta red privada. Está conectado al puente en una red completamente diferente. Esta es una red virtual que existe solo dentro de un nodo específico. Para hacerlo más claro, redibujemos el esquema anterior, agregando lo que llamamos un hogar hipotético arriba.


Vainas y nodos

El host ubicado a la izquierda de este diagrama tiene una interfaz eht0 con la dirección 10.100.0.2 , 10.100.0.2 puerta de enlace predeterminada es el enrutador con la dirección 10.100.0.1 . El puente docker0 con la dirección 172.17.0.1 conectado a esta interfaz y, a través de la interfaz virtual veth0 con la dirección 172.17.0.2 , está conectado lo que aquí llamamos hogar. La interfaz veth0 se creó en un contenedor suspendido. Es visible en los tres contenedores a través de una pila de red compartida. Debido al hecho de que las reglas de enrutamiento local se configuran al crear el puente, cualquier paquete que llegue a eth0 y tenga la dirección de destino 172.17.0.2 será redirigido al puente, que lo reenviará a la interfaz virtual veth0 . Si bien todo esto parece bastante decente. Si se sabe que el host que estamos discutiendo tiene una dirección 172.17.0.2 , entonces podemos agregar una regla a la configuración del enrutador que describa que la próxima transición para esta dirección es 10.100.0.2 , después de lo cual los paquetes desde allí deben redirigirse a veth0 . Excelente Ahora echemos un vistazo a otro host.

El host que se muestra en el diagrama de la derecha tiene una interfaz física eth0 con la dirección 10.100.0.3 . Utiliza la misma puerta de enlace predeterminada: 10.100.0.1 y, de nuevo, está conectada al puente docker0 con la dirección 172.17.0.1 . Existe la sensación de que no todo va tan bien. Esta dirección, de hecho, puede diferir de la utilizada en el host ubicado a la izquierda. Las direcciones de los puentes aquí se hacen las mismas para demostrar el peor escenario posible, que, por ejemplo, puede ocurrir si acaba de instalar Docker y lo deja funcionar como le plazca. Pero incluso si las redes en cuestión son diferentes, nuestro ejemplo resalta un problema más profundo, que es que los nodos generalmente no saben nada sobre qué direcciones privadas se asignan a los puentes ubicados en otros nodos. Y necesitamos saber sobre esto, para poder enviar paquetes a estos puentes y asegurarnos de que llegarán a donde necesitan. Obviamente, aquí necesitamos algún tipo de entidad, que nos permita garantizar la configuración correcta de las direcciones en diferentes nodos.

La plataforma Kubernetes nos brinda una solución de dos pasos para este problema. Primero, esta plataforma asigna un espacio de dirección común para puentes en cada nodo y luego asigna a los puentes las direcciones en este espacio en función del nodo en el que se encuentra el puente. En segundo lugar, Kubernetes agrega reglas de enrutamiento a la puerta de enlace ubicada, en nuestro caso, en 10.100.0.1 . Estas reglas definen las reglas para enrutar paquetes destinados a cada uno de los puentes. Es decir, describen a través de qué interfaz física eth0 se puede contactar con cada uno de los puentes. Esta combinación de interfaces de red virtual, puentes y reglas de enrutamiento se denomina comúnmente red superpuesta . Hablando de Kubernetes, generalmente llamo a esta red una "red de hogar", ya que es una red superpuesta que permite que las unidades ubicadas en diferentes nodos se comuniquen entre sí. Así es como se verá el diagrama anterior después de que los mecanismos de Kubernetes se pongan manos a la obra.


Red de hogar

Inmediatamente llama la atención que los nombres de los puentes se cambian de docker0 a cbr0 . Kubernetes no utiliza puentes Docker estándar. Lo que llamamos cbr es una abreviatura de "puente personalizado", es decir, estamos hablando de algunos puentes especiales. No estoy listo para dar una lista completa de las diferencias entre lanzar contenedores Docker en pods y ejecutarlos en computadoras comunes, pero de lo que estamos hablando aquí es de una de las diferencias similares importantes. Además, debe prestar atención al hecho de que el espacio de direcciones asignado a los puentes en este ejemplo es 10.0.0.0/14 . Esta dirección está tomada de uno de nuestros clústeres de etapas, que se implementan en la plataforma Google Cloud, por lo que lo anterior es un ejemplo muy real de una red de hogares. A su clúster se le puede asignar un rango de direcciones completamente diferente. Desafortunadamente, en este momento no hay forma de obtener información sobre estas direcciones usando la utilidad kubectl , pero, por ejemplo, si usa GCP, puede ejecutar un comando como los gcloud container clusters describe <cluster> y eche un vistazo a la propiedad clusterIpv4Cidr .

En general, se puede observar que generalmente no tiene que pensar en cómo funciona la red de hogares. Cuando un subintercambio intercambia datos con otro hogar, la mayoría de las veces esto sucede a través de los servicios de Kubernetes. Este es un poco un proxy definido por software. Pero las direcciones de red de los hogares aparecen en los registros. En algunas situaciones, en particular durante la depuración, es posible que deba establecer explícitamente reglas de enrutamiento en redes de hogares. Por ejemplo, el tráfico que deja a Kubernetes vinculado a cualquier dirección en el rango 10.0.0.0/8 no se procesa de manera predeterminada mediante NAT. Por lo tanto, si interactúa con servicios ubicados en otra red privada que tiene el mismo rango de direcciones, es posible que necesite configurar reglas de enrutamiento que le permitirán organizar la entrega correcta de paquetes.

Resumen


Hoy hablamos sobre los pods de Kubernetes y las características de sus redes. Esperamos que este material lo ayude a dar los pasos correctos para implementar escenarios complejos de interacción de hogares en las redes de Kubernetes.

Estimados lectores! Este artículo es el primero de una serie de redes de Kubernetes. La segunda parte de este ciclo ya ha sido traducida . Estamos pensando en traducir la tercera parte. Le pedimos que comente sobre esto en los comentarios.

Source: https://habr.com/ru/post/441576/


All Articles