Red de conocimiento informático - Aprendizaje de programación - IPVS desde el inicio hasta el dominio de los principios de implementación de kube-proxy

IPVS desde el inicio hasta el dominio de los principios de implementación de kube-proxy

Sabemos que los contenedores se crean y destruyen rápidamente. Los Pods de Kubernetes, al igual que los contenedores, solo tienen un ciclo de vida temporal. Un Pod puede cancelarse o desviarse en cualquier momento y cambiar según su estado. el clúster cambia una vez que el Pod cambia, los servicios proporcionados por el Pod tampoco serán accesibles. Si se accede directamente al Pod, no se puede lograr la continuidad del servicio y la alta disponibilidad. Por lo tanto, es obvio que la dirección del Pod no se puede utilizar como dirección. puerto de exposición al servicio.

La solución a este problema es exactamente la misma que la solución tradicional del centro de datos: la alta disponibilidad de servicios sin estado se logra mediante el equilibrio de carga y VIP.

Este equilibrio de carga se llama Servicio en Kubernetes, y VIP es Service ClusterIP. Por lo tanto, se puede considerar que el Servicio de Kubernetes es un equilibrio de carga de cuatro capas que también corresponde a la carga de siete capas. Equilibrio de Ingress Este artículo solo presenta el servicio Kubernetes.

Este servicio es implementado por kube-proxy. ClusterIP no cambiará debido a cambios en el estado de Podz. Cabe señalar que VIP, ClusterIP, es una IP falsa no existe en todo el clúster. Por supuesto, por lo tanto, no se puede enrutar a través de la pila de protocolos IP y el dispositivo subyacente no puede detectar la existencia de esta IP. Por lo tanto, ClusterIP solo puede ser visible en el alcance de un solo host (solo host). Otros nodos o fuera del clúster no pueden acceder a la IP.

Para que Kubernetes permita que todos los nodos del clúster accedan al Servicio, kube-proxy creará este VIP en todos los nodos del Nodo de forma predeterminada e implementará la carga. Por lo tanto, se encuentra después de implementar Kubernetes. ese kube-proxy es un DaemonSet.

La razón por la que la carga de servicio se puede implementar en los nodos de Nodo es que, sin importar qué modelo de red utilice Kubernetes, debe garantizar que se cumplan las siguientes tres condiciones:

Al menos un punto 2 debe cumplirse. Sí, con los supuestos anteriores, el servicio Kubernetes se puede implementar en Node. De lo contrario, si Node no puede comunicarse con Pod IP, no se implementará.

Algunas personas dicen que, dado que kube-proxy es un equilibrio de carga de cuatro capas, entonces kube-proxy debería poder usar haproxy, nginx, etc. como backend de carga.

De hecho, no hay ningún problema, pero lo único que debe considerarse es el problema de rendimiento. Las funciones de equilibrio de carga anteriores son poderosas, pero después de todo, todavía se basan en el reenvío en modo de usuario o. proxy inverso, y el rendimiento inevitablemente no es tan bueno como en el modo kernel.

Por lo tanto, kube-proxy dará prioridad a la carga basada en kernel como mecanismo de implementación back-end de forma predeterminada. Actualmente, kube-proxy implementa la carga a través de iptables de forma predeterminada. Antes de esto, había otro modo llamado. El modo de espacio de usuario, de hecho, también se implementa en base a iptables. Se puede considerar que el modo de espacio de usuario actual es una optimización del modo de espacio de usuario anterior.

Esta sección presentará en detalle el principio de implementación del modo iptables kube-proxy.

Primero se crea un Servicio de tipo ClusterIP:

El ClusterIP es 10.106.224.41 Podemos verificar que esta IP no existe localmente:

Entonces. No intente hacer ping a ClusterIP, no funcionará.

En este momento, al acceder al Servicio en el nodo 192.168.193.172, el primer tráfico llega a la cadena de SALIDA. Aquí solo nos importa la cadena de SALIDA de la tabla nat:

. Esta cadena salta Vaya a la subcadena KUBE-SERVICES:

Encontramos dos reglas relacionadas con ella:

Entre ellas, las reglas de la subcadena KUBE-SVC-RPP7DHNHMGOIIFDC son como sigue:

Estas reglas pueden parecer complicadas, pero en realidad las funciones que implementan son muy simples:

Veamos la regla de una de las subcadenas KUBE-SEP-FTIQ6MSD3LWO5HZX :

Se puede ver que el propósito de esta regla es que se realizó una DNAT y el objetivo de DNAT era uno de los Endpoints, es decir, el servicio Pod.

Se puede observar que la función de la subcadena KUBE-SVC-RPP7DHNHMGOIIFDC es hacer DNAT a una de las IP del Endpoint, es decir la IP del Pod, suponiendo que sea 10.244.1.2, según el principio de igual probabilidad.

Esto es equivalente a:

Luego pasemos a la cadena POSTROUTING:

Estas dos reglas solo hacen una cosa, es decir, Siempre que los paquetes marcados con 0x4000/0x4000 sean MASQUERADE (SNAT), dado que 10.244.1.2 se reenvía desde flannel.1 de forma predeterminada, la IP de origen se cambiará a la IP 10.244.0.0 de flannel.1.

El resto es el proceso de reenvío del túnel Vxlan convencional. No entraré en detalles aquí. Si está interesado, puede consultar mi artículo anterior Una breve discusión sobre los principios de implementación de varios Docker convencionales. redes.

A continuación, estudiemos el proceso de NodePort. Primero, cree el siguiente Servicio:

El puerto NodePort del Servicio es 30419.

Supongamos que existe una IP externa 192.168.193.197, accediendo al servicio a través de 192.168.193.172:30419.

Primero llegue a la cadena PREROUTING:

Las reglas de PREROUTING son muy simples. Todos los paquetes que se envíen a usted mismo se entregarán a la subcadena KUBE-NODEPORTS para su procesamiento. Tenga en cuenta que anteriormente se han omitido algunas reglas para determinar ClusterIP.

Las reglas de KUBE-NODEPORTS son las siguientes:

Esta regla primero marca el paquete con 0x4000/0x4000 y luego lo entrega a la subcadena KUBE-SVC-RPP7DHNHMGOIIFDC para su procesamiento. KUBE-SVC-RPP7DHNHMGOIIFDC acaba de conocerse y su función es realizar DNAT a una de las IP del Endpoint, es decir, la IP del Pod, basándose en el principio de igual probabilidad, suponiendo que sea 10.244.1.2.

En ese momento, se descubrió que 10.244.1.2 no era su propia IP, por lo que se determinó mediante enrutamiento que el objetivo era 10.244.1.2 y debía enviarse desde flannel.1.

Luego viene la cadena FORWARD

La tabla FORWARD es solo para juicio. Aquí solo se permite reenviar los paquetes marcados 0x4000/0x4000.

Finalmente llegamos a la cadena POSTROUTING, que es exactamente igual que ClusterIP. Haz una MASQUERADE (SNAT) en KUBE-POSTROUTING, y el resultado final es:

Encontramos. ese kube basado en el modo iptables -proxy ClusterIP y NodePort se implementan según las reglas de iptables. Encontramos al menos los siguientes problemas:

A continuación, este artículo presentará la implementación ipvs de kube-proxy. No estoy familiarizado con ipvs antes, nunca lo he usado antes. Estudié ipvs específicamente, así que los presento brevemente en el Capítulo 2. Si ya está familiarizado con ipvs, puede omitirlo directamente. Este capítulo casi no tiene nada que ver con Kubernetes.

Además, como también soy principiante en ipvs y mi nivel es limitado, inevitablemente cometeré errores. ¡Las correcciones son bienvenidas!

Estamos más expuestos al equilibrio de carga de la capa de aplicación, como haproxy, nginx, F5, etc. Estos equilibrios de carga funcionan en modo usuario, por lo que habrá procesos correspondientes y sockets de escucha, y generalmente pueden admitir La carga de 4 capas al mismo tiempo y la carga de 7 capas también son más cómodas de usar.

LVS fue desarrollado y contribuido a la comunidad por el Dr. Zhang Wensong en China (el Dr. Zhang Wensong y el imperio de equilibrio de carga detrás de él está compuesto principalmente por ipvs e ipvsadm es un 4-). El equilibrio de carga de la capa funciona en el estado del kernel, e Iptables también se implementa en función del netfilter subyacente del kernel. Netfilter implementa principalmente el procesamiento y reenvío de paquetes a través de ganchos en cada cadena. La relación entre ipvsadm e ipvs es como la relación entre netfilter e iptables. Se ejecuta en modo de usuario y proporciona una interfaz CLI simple para la configuración de ipvs.

Dado que ipvs funciona en el estado del kernel y maneja el reenvío de paquetes directamente según el kernel, su característica más importante es que su rendimiento es muy bueno. Y debido a que funciona en la capa 4, no procesa datos de la capa de aplicación. La gente suele preguntar si ipvs puede desinstalar certificados SSL o modificar datos de encabezado HTTP. Obviamente, esto es imposible.

Sabemos que la mayor parte del equilibrio de carga de la capa de aplicación se basa en un proxy inverso para lograr la carga. Funciona en la capa de aplicación. Cuando el paquete del usuario llega al escucha de equilibrio de carga, se entregará desde el backend. en un determinado algoritmo Seleccione uno de los servicios de backend en la lista para reenviar. Por supuesto, puede haber algunas operaciones adicionales en el medio, la más común es la desinstalación del certificado SSL.

IPvs funciona en modo kernel y solo maneja protocolos de cuatro capas. Por lo tanto, solo puede reenviar datos según el enrutamiento o NAT. Puede considerarse como una puerta de enlace de enrutador especial. según un determinado algoritmo, seleccione el siguiente salto, o trate ipvs como un DNAT múltiple y DNAT la dirección de destino del paquete IP a la IP de destino del servicio real de acuerdo con un determinado algoritmo. Las dos situaciones anteriores corresponden a los dos modos de ipvs: modo puerta de enlace y modo NAT. Además, el modo ipip es una extensión del modo puerta de enlace. Este artículo presentará en detalle los principios de implementación de estos modos.

El uso de la línea de comando de ipvsadm es muy similar al uso de la línea de comando de iptables. Después de todo, son hermanos, como -L para enumerar, -A para agregar y -D para eliminar.

Pero, de hecho, ipvsadm es demasiado simple en comparación con el comando iptables, porque no hay varias tablas como iptables. Las tablas están anidadas en varias cadenas, y solo hay un montón de reglas en la cadena. tiene dos entidades centrales, respectivamente servicio y servidor, el servicio es una instancia de equilibrio de carga y el servidor es el miembro de back-end. En la terminología de IPVS, se llama servidor real, o RS para abreviar.

Utilice el siguiente comando para crear una instancia de servicio 172.17.0.1:32016, -t especifica el puerto TCP de escucha, -s especifica el algoritmo como algoritmo de sondeo rr (Round Robin), ipvs admite sondeo simple ( rr), sondeo ponderado (wrr), conexión mínima (lc), hash de dirección de origen o dirección de destino (sh, dh) y otros 10 algoritmos de programación.

Luego agregue 10.244.1.2:8080, 10.244.1.3:8080, 10.244.3.2:8080 al miembro del backend del servicio.

Entre ellos, -t especifica la instancia del servicio, -r especifica la dirección del servidor, -w especifica el peso, -m es el modo de reenvío mencionado anteriormente, donde -m significa enmascaramiento, que es el modo NAT. y -g significa puerta de enlace, es decir, modo de enrutamiento directo, -i es ipip, ji es modo de túnel IPIP.

Las herramientas ipvs correspondientes a iptables-save e iptables-restore también incluyen ipvsadm-save e ipvsadm-restore.

El significado literal del modo NAT es que se implementa a través de NAT, pero cómo lo reenvía NAT, lo verificamos a través del entorno experimental.

En el entorno actual, la IP del nodo LB es 192.168.193.197 y los tres nodos RS son los siguientes:

Para simular la situación en la que la IP del nodo LB y RS no están en la misma red, agregue una dirección IP virtual:

Cree un servicio de equilibrio de carga y agregue RS al servicio:

Lo que hay que tener en cuenta aquí es que es diferente desde el equilibrio de carga de la capa de aplicación, como haproxy y nginx, los procesos haproxy y nginx se ejecutan en modo de usuario, por lo que se crearán sockets y los puertos se escucharán localmente. Sin embargo, la carga de ipvs se ejecuta directamente en modo kernel, por lo que habrá. sin puerto de escucha:

Se puede ver que no hay escucha en 10.222.0.1: 8080 Socket.

La IP del nodo Cliente es 192.168.193.226 Para comunicarnos con la IP virtual 10.222.0.1 del nodo LB, agregamos manualmente una ruta estática de la siguiente manera:

En este momento, el nodo Cliente puede hacer ping al nodo LB VIP:

Se puede ver que no hay problema con el enlace del nodo Cliente al VIP.

Comprobemos:

El resultado tan inesperado no tiene sentido.

La captura de paquetes en el nodo RS es la siguiente:

Encontramos que la IP de origen del paquete de datos es la IP del Cliente y la IP de destino es la IP de RS. el IPVS del nodo LB solo hace DNAT. La IP de destino se cambió a RS IP sin modificar la IP de origen. En este momento, aunque RS y el Cliente están en la misma subred y no hay ningún problema con la conectividad del enlace, debido a que la IP de destino del paquete enviado por el nodo del Cliente no coincide con la IP de origen del paquete recibido, se descartará directamente. , lo que equivale a enviar una carta a Zhang San. Obviamente, no se confiaba en la carta escrita por Li Si.

Dado que IPVS no hizo SNAT por nosotros, lo natural es que hagamos SNAT manualmente y agreguemos las siguientes reglas de iptables al nodo LB:

Verifique nuevamente si el Se puede acceder al servicio:

El servicio aún no está disponible.

Y el registro de iptables en el nodo LB está vacío:

En otras palabras, ¿los paquetes ipvs no pasarán por la cadena POSTROUTING de la tabla nat de iptables?

¿Qué pasa con la mesa de mangle? Abramos el REGISTRO y verifiquemos:

En este momento, el registro es el siguiente:

Descubrimos que el paquete después de DNAT se puede ver en la tabla de mangle.

Desafortunadamente, el POSTROUTING de la tabla mangle no admite la función NAT:

Al comparar la configuración de Kubernetes, encontramos que es necesario configurar los siguientes parámetros del sistema:

Verifique nuevamente:

Finalmente funcionó, verifique la captura del paquete RS:

Como se esperaba, la IP de origen se cambió a IP LB.

Resulta que es necesario configurar el parámetro net.ipv4.vs.conntrack=1. Luché con este problema toda la noche. Debo decir que los documentos ipvs actuales son demasiado antiguos.

Anteriormente, SNAT se implementaba a través de iptables manuales, lo que puede causar pérdidas de rendimiento. Por lo tanto, los siguientes proyectos de código abierto realizan SNAT directamente modificando lvs:

Además de SNAT, existen. ¿Algún otro método? ¿Paño de lana? Piense en nuestro problema original. La IP de destino del paquete enviado por el nodo Cliente no coincide con la IP de origen del paquete recibido, lo que hace que el paquete se descarte. La solución al problema es redirigir el paquete al nodo LB. Todo lo que se necesita es redirigir el paquete al nodo LB. Simplemente agregue la siguiente ruta al nodo:

En este momento, verificamos nuevamente si nuestro Servicio se puede conectar: ​​

. El resultado no es ningún problema.

Sin embargo, logramos esto agregando manualmente la IP del Cliente a las rutas detalladas de todos los RS. Si el Cliente no está reparado, esta solución aún no es factible, por lo que el enfoque habitual es simplemente señalar todos los RS. rutas predeterminadas al nodo LB, es decir, el nodo LB se utiliza como puerta de enlace predeterminada para todos los RS.

Se puede ver que cuando el usuario accede al servicio a través de la dirección LB, el IPVS del nodo LB cambiará la IP de destino del usuario de IP LB a IP RS, la IP de origen permanece sin cambios y el paquete se envía directamente. llega a POSTROUTING para reenviar sin pasar por la SALIDA de iptables. Cuando el paquete sale y regresa, primero debe ir al nodo LB. El nodo LB cambia la IP de destino a la IP de origen del usuario y finalmente la reenvía al usuario.

Obviamente, este modo necesita pasar por el nodo LB de un lado a otro, por lo que también se le llama modo de brazo dual.

El modo de puerta de enlace también se denomina modo de enrutamiento directo y modo de transmisión transparente. La llamada transmisión transparente significa que el nodo LB no modificará la IP de origen, el puerto y la IP de destino y el puerto. El nodo LB solo realiza reenvío de enrutamiento. El nodo LB puede considerarse como una puerta de enlace de enrutador especial, y el nodo RS es el siguiente salto de la puerta de enlace. Esto equivale a tener múltiples saltos siguientes para la misma dirección de destino. Esta puerta de enlace del enrutador es que puede seleccionar uno de los RS como el siguiente salto de acuerdo con un determinado algoritmo para lograr efectos de redundancia y equilibrio de carga.

Dado que se reenvía mediante enrutamiento directo, es obvio que el nodo LB debe estar en la misma subred que todos los nodos RS y no puede cruzar subredes; de lo contrario, la ruta será inalcanzable. En otras palabras, este modo solo admite Internal LoadBalancer.

Además, como se mencionó anteriormente, el nodo LB no modificará el puerto de origen y el puerto de destino, por lo que este modo no puede admitir la asignación de puertos. En otras palabras, el puerto monitoreado por el nodo LB y los puertos monitoreados. por todos los nodos RS debe ser consistente.

Ahora suponga que la IP del nodo LB es 192.168.193.197 y hay tres nodos RS de la siguiente manera:

Cree un servicio de equilibrio de carga y agregue RS al servicio:

Observe que el puerto 30620 que escucha nuestro Servicio es el mismo que el puerto de RS, y el modo de enrutamiento directo (modo puerta de enlace) se especifica mediante el parámetro -g.

La IP del nodo del Cliente es 192.168.193.226. Verificamos si el Servicio se puede conectar: ​​

Descubrimos que no funcionaba y capturamos el paquete en uno de los nodos RS 192.168. .193.172:

Como se mencionó anteriormente, el LB se reenvía mediante enrutamiento. Según el principio de enrutamiento, la dirección MAC de origen se modifica a la dirección MAC del LB y la dirección MAC de destino se modifica a la dirección MAC. Dirección MAC de RS, que equivale a que RS sea el siguiente salto del LB.

Y no se modificará ni la IP de origen ni la IP de destino. Surge el problema. Nuestro cliente espera acceder a RS, pero la IP de destino recibida por RS es la IP de LB. Se descubre que la IP de destino no es su propia IP, por lo que no se reenviará al espacio del usuario a través de INPUT. En este caso, descartar el paquete directamente o reenviarlo a otros lugares según la ruta. En resumen, ninguna de las dos situaciones es la que esperamos.

¿Qué hacer? Para que RS reciba este paquete, RS debe tener esta IP de destino. Entonces también puedes agregar una IP virtual en lo, y la dirección IP se disfraza como LB IP 192.168.193.197:

El problema vuelve a aparecer. Esto equivale a tener dos IP idénticas. ¿Qué debo hacer? si las IP se repiten? La solución es ocultar esta tarjeta de red virtual y evitar que responda a ARP. Los vecinos de otros hosts no podrán conocer la existencia de dicha tarjeta de red. Consulte Uso de arp anuncio/arp ignorar para desactivar ARP.

Ahora curl desde el cliente nuevamente:

Finalmente funcionó.

Sabemos por la captura de paquetes anterior que la IP de origen es la IP del Cliente 192.168.193.226, por lo que es suficiente devolver el paquete directamente al Cliente. Es imposible y no es necesario volver al Cliente. Nodo LB, es decir, A-gt; B, B-gt; C, C-gt; A, la dirección del flujo es triangular, por lo que este modo también se llama modo triangular.

No es difícil para nosotros sacar las siguientes conclusiones del principio:

El modo de enrutamiento directo de la puerta de enlace se introdujo anteriormente, que requiere que todos los nodos estén en la misma subred, mientras que el modo de túnel ipip resuelve principalmente este problema. Debido a esta limitación, es posible que la IP y el RS del nodo LB no estén en la misma subred. En este caso, es necesario transmitirlos a través del túnel ipip.

Ahora suponga que la IP del nodo LB es 192.168.193.77/25, agregue una dirección VIP en este nodo:

ip addr add 192.168.193.48/25 dev eth0

Hay tres nodos RS de la siguiente manera:

Las máscaras de subred de los tres nodos RS anteriores son todas 255.255.255.128, que es una subred de 25 bits, que obviamente no es la misma subred que VIP. 192.168.193.48/25.

Cree un servicio de equilibrio de carga y agregue RS al servicio:

Observe que el puerto 30620 que escucha nuestro servicio es el mismo que el puerto de RS y se especifica con el - i parámetro.modo de túnel ipip.

Cargue el módulo ipip en todos los nodos RS y agregue VIP (y tipo de enrutamiento directo):

La IP del nodo Cliente es 192.168.193.226/25, verificamos si el Servicio puede ser conectado:

Se puede acceder al servicio. Capturamos paquetes en el nodo RS de la siguiente manera:

Descubrimos que, al igual que la ruta directa, la IP de origen y la IP de destino no se han modificado.

Por lo tanto, los principios del modo IPIP y del modo Gateway son básicamente los mismos. La única diferencia es que el modo Gateway requiere que todos los nodos RS y LB estén en la misma subred, mientras que el modo IPIP puede admitir conexiones cruzadas. subred En el caso de la red, para resolver el problema de la comunicación entre subredes, se utiliza el túnel ipip para la transmisión de datos.

ipvs es un equilibrio de carga de cuatro capas en modo kernel que admite los modos de túnel NAT, Gateway y IPIP. El modo Gateway tiene el mejor rendimiento, pero LB y RS no pueden cruzar subredes, y el rendimiento de IPIP ocupa el segundo lugar. túnel ipip Resuelve el problema de la transmisión de segmentos entre redes, por lo que puede admitir subredes cruzadas. El modo NAT no tiene restricciones y es el único modo que admite la asignación de puertos.

No es difícil adivinar que, dado que el servicio Kubernetes necesita usar la función de mapeo de puertos, kube-proxy solo debe usar el modo NAT de ipvs.

Para utilizar kubeadm para instalar Kubernetes, consulte el documento Clúster creado por Kubeadm. Sin embargo, hay un problema con la configuración de instalación de este documento kubeadm #1182. La siguiente configuración oficial no tiene efecto:

Debe modificarse a la siguiente configuración:

Puede utilizar el siguiente comando para confirmar si kube-proxy se ha modificado a ipvs:

Crear un Servicio similar a ClusterIP de la siguiente manera:

ClusterIP 10.96.54.11 verifica ipvs por nosotros. La configuración es la siguiente:

Se puede ver que la IP LB de ipvs es ClusterIP, la El algoritmo es rr y RS es la IP del Pod.

Además, descubrimos que el modo utilizado es el modo NAT. Esto es obvio, porque excepto el modo NAT, que admite la asignación de puertos, los otros dos modos no admiten la asignación de puertos, por lo que el modo NAT debe ser. seleccionado.

Según el conocimiento teórico previo, el VIP de ipvs debe existir localmente. Podemos verificar:

Se puede ver que kube-proxy primero creará una tarjeta de red virtual ficticia kube. -ipvs0, y luego toda la IP del servicio se agrega a kube-ipvs0.

Sabemos que para el servicio basado en iptables, ClusterIP es una IP virtual, por lo que no se puede hacer ping a esta IP. Sin embargo, en ipvs, esta IP realmente existe en cada nodo, por lo que se puede hacer ping:

p>

Por supuesto, dado que esta IP está configurada en la tarjeta de red virtual local, no es útil para diagnosticar el problema.

Estudiemos cómo se pasa ClusterIP.

Cuando nos conectamos al servicio mediante el siguiente comando:

En este momento, como 10.96.54.11 es local, esta IP se utilizará como dirección de salida, es decir, ambas la IP de origen y la IP de destino son 10.96.54.11, lo que equivale a:

donde xxxx es un puerto aleatorio.

Luego, a través de ipvs, ipvs seleccionará una de las ips del Pod de la columna RS ip como la IP de destino, asumiendo que es 10.244.2.2:

Podemos verificar desde el LOG de iptables :

Vemos las reglas del grupo de seguridad de SALIDA de la siguiente manera:

Entre ellas, la colección ipsetj KUBE-CLUSTER-IP guarda todas las ClusterIP y los puertos de escucha.

Las reglas anteriores significan que todos los paquetes que acceden a ClusterIP, excepto Pod, están marcados con 0x4000/0x4000.

Llegue a la cadena POSTROUTING:

Las reglas anteriores significan que mientras los paquetes que coincidan con la marca 0x4000/0x4000 sean SNATed, dado que 10.244.2.2 sale de flannel.1, el IP de origen Se cambiará a la ip de flannel.1 10.244.0.0:

Finalmente, se envía al Nodo del Pod a través del túnel Vxlan y se reenvía al veth del Pod. El paquete de retorno llega al origen. Nodo a través del enrutamiento, y el nodo de origen pasa antes de MASQUERADE y luego restaura la IP de destino a 10.96.54.11.

Vea el Servicio de la siguiente manera:

El NodePort del Servicio kubernetes-bootcamp-v1 es 32016.

Ahora supongamos que una IP 192.168.193.197 fuera del cluster accede a 192.168.193.172:32016:

El primero en llegar a la cadena PREROUTING:

Los cuatro anteriores Las reglas parecen complicadas. De hecho, solo haga una cosa. Si la dirección de destino es NodeIP, marque el paquete con 0x4000, 0x4000.

Revisemos ipvs:

Descubrimos que el principio de implementación es muy similar a ClusterIP. El VIP del servicio ipvs es Node IP y el puerto es NodePort. ipvs seleccionará una de las IP del Pod como destino DNAT, asumiendo que es 10.244.3.2:

El resto de la cadena POSTROUTING será exactamente igual que el Service ClusterIP siempre que el paquete coincida con 0x4000. /0x4000 será SNATizado.

ClusterIP y NodePort de Kubernetes se implementan a través del servicio ipvs. Pod se utiliza como servidor del servicio ipvs y el reenvío se implementa a través de NAT MQSQ.

En pocas palabras, kube-proxy hace principalmente las siguientes tres cosas en todos los nodos de Node:

Usar ipvs como backend de kube-proxy no solo mejora el rendimiento de reenvío, sino que también lo combina. con ipset Haga que las reglas de iptables sean "más limpias" y claras, y ya no le tendrá miedo a iptables.

Para obtener más información sobre kube-proxy ipvs, consulte Análisis profundo del equilibrio de carga en el clúster basado en IPVS.

Este artículo presenta primero las funciones de kube-proxy y la implementación de. kube-proxy basado en iptables Principio, luego presentó brevemente ipvs, aprendió sobre los tres modos de reenvío admitidos por ipvs y finalmente presentó el principio de implementación de kube-proxy basado en ipvs.

ipvs está especialmente diseñado para el equilibrio de carga de cuatro capas en modo kernel. Debido a que utiliza la estructura de datos de la tabla hash, su rendimiento será mejor que el de iptables. Basado en ipvs para implementar el reenvío de servicios, Kubernetes puede tener capacidades de expansión horizontal casi ilimitadas. A medida que la escala de implementación de Kubernetes se hace cada vez mayor y sus aplicaciones se vuelven cada vez más generalizadas, ipvs inevitablemente reemplazará a iptables y se convertirá en el backend de implementación predeterminado del servicio Kubernetes.

Reimpreso de /p/94418251