kube-proxy工作原理

kube-proxy 以 DaemonSet 的形式运行在集群的所有节点中,负责管理集群外到 Service,以及 Service 到 Pod 的流量转发。

kube-proxy 有三种模式:

  1. userspace
  2. iptables
  3. ipvs

在运行了 kube-proxy 的节点上,可以通过下面的命令查看 kube-proxy 的运行模式:

1
curl localhost:10249/proxyMode

iptables

通过 kube-proxy 的 cm 可以查看 mode
iptables-mode

我们都知道 SVC 有多种类型,常用的有 ClusterIP、NodePort、Headless、LoadBalancer 等等,这里我们通过创建类型的 SVC,查看 kube-proxy 下发的iptables 规则

ClusterIP
clusterip-svc

通过 iptables-save 命令打印这个 SVC 的规则
clusterip-iptables

PodIP: 10.233.74.106
ClusterIP: 10.233.54.175

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 将来自 Pod IP 10.233.74.106 的流量标记为服务 default/nginx,并转发到 KUBE-MARK-MASQ 链中
-A KUBE-SEP-EUB75IW55XDW6EHN -s 10.233.74.106/32 -m comment --comment "default/nginx:tcp-80" -j KUBE-MARK-MASQ

# 将匹配的 TCP 流量进行 DNAT,转发到后端 Pod 10.233.74.106:80
-A KUBE-SEP-EUB75IW55XDW6EHN -p tcp -m comment --comment "default/nginx:tcp-80" -m tcp -j DNAT --to-destination 10.233.74.106:80

# 匹配目标地址为服务 default/nginx 的 cluster IP 10.233.54.175 的 TCP 80 端口流量
-A KUBE-SERVICES -d 10.233.54.175/32 -p tcp -m comment --comment "default/nginx:tcp-80 cluster IP" -m tcp --dport 80 -j KUBE-SVC-XX3NNXKPRC7N6OJH

# 标记来自外部网络(除了 PodCIDR 10.233.64.0/18)的、目标地址为服务 default/nginx 的 cluster IP 10.233.54.175 的 TCP 80 端口的流量
-A KUBE-SVC-XX3NNXKPRC7N6OJH ! -s 10.233.64.0/18 -d 10.233.54.175/32 -p tcp -m comment --comment "default/nginx:tcp-80 cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ

# 将匹配的流量转发到 KUBE-SEP-EUB75IW55XDW6EHN 链中,进行 DNAT 地址转换
-A KUBE-SVC-XX3NNXKPRC7N6OJH -m comment --comment "default/nginx:tcp-80 -> 10.233.74.106:80" -j KUBE-SEP-EUB75IW55XDW6EHN

NodePort

把这个 SVC 类型改成 NodePort
nodeport-svc

通过 iptables-save 命令打印这个 SVC 的规则,多了两条规则
nodeport-iptables

1
2
3
4
5
# 用于标记来自外部的、目标地址为服务 default/nginx 的 NodePort 流量
-A KUBE-EXT-XX3NNXKPRC7N6OJH -m comment --comment "masquerade traffic for default/nginx:tcp-80 external destinations" -j KUBE-MARK-MASQ

# 用于匹配目标端口为 32594 的 TCP 流量,并将该流量转发到上面的规则进行 MASQ 标记
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/nginx:tcp-80" -m tcp --dport 32594 -j KUBE-EXT-XX3NNXKPRC7N6OJH

IPVS

通过 kube-proxy 的 cm 可以查看 mode
ipvs-mode

来自 GPT 的回答: IPVS 是 Linux 内核中实现的虚拟服务器技术,它可以将网络流量负载均衡到多台服务器上,从而提高服务性能和可靠性。

ClusterIP

PodIP: 10.233.76.138
ClusterIP: 10.233.27.36

通过 ipvsadm 命令查看这个虚拟服务器
clusterip-ipvs

1
2
3
4
5
6
7
8
9
10
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn

# 将目标地址为 nginx.default.svc.cluster.lo:80 的 TCP 流量转发到后端 Pod 10.233.76.138:80
TCP nginx.default.svc.cluster.lo rr
-> 10-233-76-138.nginx.default. Masq 1 0 0

# 将目标地址为 10.233.27.36:80 的 TCP 流量转发到后端 Pod 10.233.76.138:80
TCP 10.233.27.36:80 rr
-> 10.233.76.138:80 Masq 1 0 0

NodePort

通过 ipvsadm 命令查看这个虚拟服务器,多了三条规则
nodeport-ipvs

1
2
3
4
5
6
7
8
9
10
11
# 10.233.74.64 为 nodelocaldns 网卡的 IP,由于 NodePort 是全监听,所以也有对应的规则
TCP 169.254.25.10:30229 rr
-> 10.233.76.138:80 Masq 1 0 0

# 节点IP
TCP 192.168.159.11:30229 rr
-> 10.233.76.138:80 Masq 1 0 0

# 10.233.74.64 为 tun0 网卡的 IP,由于 NodePort 是全监听,所以也有对应的规则
TCP 10.233.74.64:30229 rr
-> 10.233.76.138:80 Masq 1 0
Author

Warner Chen

Posted on

2024-03-30

Updated on

2024-12-04

Licensed under

You need to set install_url to use ShareThis. Please set it in _config.yml.
You forgot to set the business or currency_code for Paypal. Please set it in _config.yml.

Comments

You forgot to set the shortname for Disqus. Please set it in _config.yml.