[Nativo en la nube | Aprenda Kubernetes desde cero] 20. Explicación detallada de los componentes kube-proxy del proxy del servicio

Este artículo se ha incluido en la columna " Aprende k8s desde cero "
Artículo anterior: Tecnología central de Kubernetes Servicio de combate real Haga clic saltar

inserte la descripción de la imagen aquí

Introducción a los componentes de kube-proxy

El servicio de Kubernetes simplemente abstrae la forma en que la aplicación brinda servicios al mundo exterior. La aplicación real se ejecuta en el contenedor en el Pod. Nuestra solicitud va al nodePort correspondiente a los nodos de Kubernetes, luego, ¿cómo va más allá la solicitud en el nodePort para proporcionar servicios en segundo plano ¿Qué pasa con los Pod's? Se consigue mediante kube-proxy

kube-proxy se implementa en cada nodo Node de k8s y es el componente principal de Kubernetes.Cuando creamos un servicio, kube-proxy agregará algunas reglas a iptables para implementar funciones de enrutamiento y balanceo de carga para nosotros. Antes de k8s1.8, kube-proxy usaba el modo iptables de forma predeterminada y realizaba el equilibrio de carga de los servicios a través de las reglas de iptables en cada nodo, pero con el aumento de la cantidad de servicios, el modo iptables debido a la coincidencia de búsqueda lineal, completo actualización, etc. características, su rendimiento se reducirá significativamente. Desde la versión 1.8 de k8s, kube-proxy ha introducido el modo IPVS. El modo IPVS se basa en Netfilter y en iptables, pero usa una tabla hash. Por lo tanto, cuando la cantidad de servicios alcanza una cierta escala, la ventaja de velocidad de la tabla hash Aparecerá la búsqueda, para que Mejore el rendimiento del servicio del servicio.

kubectl get pods -n kube-system -o wide

Un servicio es una abstracción de servicio para un grupo de pods, equivalente al LB de un grupo de pods, responsable de distribuir solicitudes a los pods correspondientes. El servicio proporcionará una IP para este LB, generalmente llamada IP de clúster. El rol de kube-proxy es el principal responsable de la implementación del servicio, específicamente, realiza el acceso interno desde el pod al servicio y el acceso externo desde el puerto del nodo al servicio.

1. kube-proxy es en realidad la entrada de acceso para administrar servicios, incluido el acceso desde Pods en el clúster a servicios y acceso a servicios fuera del clúster.

2. El kube-proxy administra los puntos finales del servicio. El servicio expone una IP virtual, que también se puede llamar IP de clúster. Al acceder a la IP de clúster: Puerto en el clúster, puede acceder al Pod bajo el servicio correspondiente en el racimo

Tres modos de trabajo de kube-proxy

1. Método de espacio de usuario:

inserte la descripción de la imagen aquí

Cuando el módulo de cliente desea acceder al módulo de servidor, primero envía la solicitud a la regla de iptables del servicio en el espacio del núcleo, que luego reenvía la solicitud al puerto del kube-proxy que escucha en el socket especificado. procesa la solicitud. Después de distribuir la solicitud al Server Pod especificado, la solicitud se reenvía a la ip del servicio en el espacio del kernel, y las iptables del servicio reenviarán la solicitud al Server Pod en cada nodo.

Hay un gran problema con este modo. El cliente solicita ingresar primero al espacio del kernel y luego ingresa al espacio del usuario para acceder a kube-proxy. Una vez que se completa el paquete kube-proxy, ingresa a las iptables del espacio del kernel y luego lo distribuye a cada nodo de acuerdo con las reglas de iptables.Userspace pods. Dado que necesita comunicarse de un lado a otro entre el espacio del usuario y el espacio del kernel, es muy ineficiente. Antes de la versión 1.1 de Kubernetes, el espacio de usuario era el modelo de proxy predeterminado.

2. método iptables:

inserte la descripción de la imagen aquí

Cuando la IP del cliente solicita, solicita directamente la IP del servicio del kernel local y reenvía directamente la solicitud a cada pod de acuerdo con las reglas de iptables. Debido a que iptable NAT se usa para completar el reenvío, también hay una pérdida de rendimiento no despreciable. Además, si hay decenas de miles de servicios/puntos finales en el clúster, las reglas de iptables en el nodo serán muy grandes y el rendimiento se reducirá aún más. El modo proxy de iptables fue introducido por Kubernetes versión 1.1 y se ha convertido en el predeterminado. tipo desde la versión 1.2.

3. método ipvs:

inserte la descripción de la imagen aquí

Kubernetes introdujo el modo proxy ipvs desde la versión 1.9-alpha y ha sido el predeterminado desde la versión 1.11. Cuando las solicitudes del cliente llegan al espacio del kernel, se distribuyen directamente a cada pod de acuerdo con las reglas de ipvs. kube-proxy monitorea los objetos y Endpoints de Kubernetes Service, llama a la interfaz netlink para crear reglas de ipvs en consecuencia y sincroniza periódicamente las reglas de ipvs con los objetos de Kubernetes Service y los objetos de Endpoints para garantizar que el estado de ipvs sea el esperado. Al acceder al servicio, el tráfico se redirigirá a uno de los pods de back-end. Similar a iptables, ipvs se basa en la funcionalidad de enlace de netfilter, pero usa una tabla hash como estructura de datos subyacente y funciona en el espacio del kernel. Esto significa que ipvs puede redirigir el tráfico más rápido y tiene un mejor rendimiento al sincronizar las reglas de proxy. Además, ipvs ofrece más opciones para algoritmos de equilibrio de carga, como:

rr:轮询调度  

lc:最小连接数  

dh:目标哈希  

sh:源哈希  

sed:最短期望延迟  

nq:不排队调度 

Si un pod de back-end de servicio cambia y el selector de etiquetas se adapta a un pod más, la información adaptada se reflejará inmediatamente en el servidor ap, y kube-proxy debe poder ver el cambio en la información en etc., y convertirlo inmediatamente a Reglas en ipvs o iptables, todo es dinámico y en tiempo real, y lo mismo ocurre con la eliminación de un pod.

inserte la descripción de la imagen aquí

Independientemente de lo anterior, kube-proxy monitorea la información de estado más reciente sobre Pods escrita por apiserver en etcd a través de watch. Una vez que detecta que un recurso de Pod se eliminó o se creó recientemente, reflejará inmediatamente estos cambios en iptables o en la regla ipvs, para que iptables e ipvs no tengan la situación de que el Server Pod no existe al programar la solicitud de Clinet Pod al Server Pod. Desde k8s1.11, el servicio usa las reglas de ipvs de manera predeterminada. Si ipvs no está activado, se degradará para usar las reglas de iptables.

Análisis de reglas de iptables generadas por kube-proxy

1. El tipo de servicio es ClusterIp, análisis de reglas de iptables

Aunque el servicio creado en k8s tiene una dirección ip, la ip del servicio es virtual y no existe en la máquina física, está en las reglas de iptables o ipvs.

[root@k8smaster service]# kubectl apply -f pod_test.yaml 
[root@k8smaster service]# kubectl apply -f service_test.yaml 
[root@k8smaster node]# kubectl get svc -l run=my-nginx
NAME       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
my-nginx   ClusterIP   10.105.254.244   <none>        80/TCP    15s
[root@k8smaster node]# kubectl get pods -l run=my-nginx -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE  
my-nginx-5898cf8d98-5trvw   1/1     Running   0          40s   10.244.1.5   k8snode2   <none>          
my-nginx-5898cf8d98-phfqr   1/1     Running   0          40s   10.244.1.4   k8snode2   <none>          
[root@k8smaster node]# iptables -t nat -L | grep 10.105.254.244
KUBE-MARK-MASQ  tcp  -- !10.244.0.0/16        10.105.254.244       /* default/my-nginx: cluster IP */ tcp dpt:http
KUBE-SVC-BEPXDJBUHFCSYIC3  tcp  --  anywhere             10.105.254.244       /* default/my-nginx: cluster IP */ tcp dpt:http

[root@k8smaster node]# iptables -t nat -L | grep KUBE-SVC-BEPXDJBUHFCSYIC3
KUBE-SVC-BEPXDJBUHFCSYIC3  tcp  --  anywhere             10.105.254.244       /* default/my-nginx: cluster IP */ tcp dpt:http			#把service关联的pod做了转发
Chain KUBE-SVC-BEPXDJBUHFCSYIC3 (1 references)		

[root@k8smaster node]# iptables -t nat -L | grep 10.244.1.5
KUBE-MARK-MASQ  all  --  10.244.1.5           anywhere             /* default/my-nginx: */
DNAT       tcp  --  anywhere             anywhere             /* default/my-nginx: */ tcp to:10.244.1.5:80
#DNAT转发 kubesvc接收请求,在过滤podip的时候有个mark也会标记ip,然后做了一个dnat转发到10.244.1.5:80这个pod上

#通过上面可以看到之前创建的 service,会通过 kube-proxy 在 iptables 中生成一个规则,来实现流量路由,有一系列目标为 KUBE-SVC-xxx 链的规则,每条规则都会匹配某个目标 ip 与端口。也就是说访问某个 serivce的ip和端口请求会由 KUBE-SVC-xxx 链来通过DNAT转发到对应的podip和端口上。

2. El tipo de servicio es nodePort, análisis de reglas de iptables

[root@k8smaster node]# kubectl apply -f pod_nodeport.yaml 
deployment.apps/my-nginx-nodeport created
[root@k8smaster node]# kubectl apply -f service_nodeport.yaml 
service/my-nginx-nodeport created

[root@k8smaster node]# kubectl get pods -l run=my-nginx-nodeport -o wide
NAME                                 READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED
my-nginx-nodeport-5fccbb754b-m4csx   1/1     Running   0          34s   10.244.1.7   k8snode2   <none>      
my-nginx-nodeport-5fccbb754b-rg48l   1/1     Running   0          34s   10.244.1.6   k8snode2   <none>
[root@k8smaster node]# kubectl get svc -l run=my-nginx-nodeport 
NAME                TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
my-nginx-nodeport   NodePort   10.105.58.82   <none>        80:30380/TCP   39s
 
[root@k8smaster node]# iptables -t nat -S | grep 30380 
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/my-nginx-nodeport:" -m tcp --dport 30380 -j KUBE-MARK-MASQ
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/my-nginx-nodeport:" -m tcp --dport 30380 -j KUBE-SVC-6JXEEPSEELXY3JZG
#一个是mark链一个是svc 在访问物理机ip和端口,访问会先经过这两个链

[root@k8smaster node]# iptables -t nat -S | grep KUBE-SVC-6JXEEPSEELXY3JZG
-N KUBE-SVC-6JXEEPSEELXY3JZG
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/my-nginx-nodeport:" -m tcp --dport 30380 -j KUBE-SVC-6JXEEPSEELXY3JZG
-A KUBE-SERVICES -d 10.105.58.82/32 -p tcp -m comment --comment "default/my-nginx-nodeport: cluster IP" -m tcp --dport 80 -j KUBE-SVC-6JXEEPSEELXY3JZG
-A KUBE-SVC-6JXEEPSEELXY3JZG -m comment --comment "default/my-nginx-nodeport:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-36FBCF7ZW3VDH33Q
-A KUBE-SVC-6JXEEPSEELXY3JZG -m comment --comment "default/my-nginx-nodeport:" -j KUBE-SEP-K2MGI3AJIGBK3IJ5
#会通过iptables的probability机制有0.50的概率进入KUBE-SEP-36FBCF7ZW3VDH33Q这个链,剩下50%还是最后那个GBK3IJ5这个链

[root@k8smaster node]# iptables -t nat -S | grep KUBE-SEP-36FBCF7ZW3VDH33
-N KUBE-SEP-36FBCF7ZW3VDH33Q
-A KUBE-SEP-36FBCF7ZW3VDH33Q -s 10.244.1.6/32 -m comment --comment "default/my-nginx-nodeport:" -j KUBE-MARK-MASQ
-A KUBE-SEP-36FBCF7ZW3VDH33Q -p tcp -m comment --comment "default/my-nginx-nodeport:" -m tcp -j DNAT --to-destination 10.244.1.6:80
-A KUBE-SVC-6JXEEPSEELXY3JZG -m comment --comment "default/my-nginx-nodeport:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-36FBCF7ZW3VDH33Q

#-A KUBE-SEP-36FBCF7ZW3VDH33Q -p tcp -m comment --comment "default/my-nginx-nodeport:" -m tcp -j DNAT --to-destination 10.244.1.6:80 是做了一个dnat把请求给10.244.1.6这个pod的80端口了 下面可以看到ip是相同的
[root@k8smaster node]# kubectl get pods -l run=my-nginx-nodeport -o wide
NAME                                 READY   STATUS    RESTARTS   AGE     IP           NODE       NOMINATED
my-nginx-nodeport-5fccbb754b-m4csx   1/1     Running   0          8m24s   10.244.1.7   k8snode2   <none>    
my-nginx-nodeport-5fccbb754b-rg48l   1/1     Running   0          8m24s   10.244.1.6   k8snode2   <none>    

 
[root@k8smaster node]# iptables -t nat -S | grep KUBE-SEP-K2MGI3AJIGBK3IJ5
-N KUBE-SEP-K2MGI3AJIGBK3IJ5
-A KUBE-SEP-K2MGI3AJIGBK3IJ5 -s 10.244.1.7/32 -m comment --comment "default/my-nginx-nodeport:" -j KUBE-MARK-MASQ
-A KUBE-SEP-K2MGI3AJIGBK3IJ5 -p tcp -m comment --comment "default/my-nginx-nodeport:" -m tcp -j DNAT --to-destination 10.244.1.7:80
-A KUBE-SVC-6JXEEPSEELXY3JZG -m comment --comment "default/my-nginx-nodeport:" -j KUBE-SEP-K2MGI3AJIGBK3IJ5
#也是一个dnat,把请求分给另外一个pod,通过这两个链50%的概率来转发到两个pod上

escribir al final

No es fácil de crear, si crees que el contenido es útil para ti, ¡por favor dame un seguimiento de tres enlaces para apoyarme! Si hay algún error, indíquelo en los comentarios y lo cambiaré a tiempo.
La serie que se está actualizando actualmente: aprende k8s desde cero.
Gracias por mirar. El artículo se mezcla con la comprensión personal. Si hay algún error, comuníquese conmigo e indíquelo ~
inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_45400861/article/details/126850632
Recomendado
Clasificación