kube-proxy

每臺機器上都運行一個 kube-proxy 服務,它監聽 API server 中 service 和 endpoint 的變化情況,並通過 iptables 等來爲服務配置負載均衡(僅支持 TCP 和 UDP)。

kube-proxy 可以直接運行在物理機上,也可以以 static pod 或者 daemonset 的方式運行。

kube-proxy 當前支持以下幾種實現

  • userspace:最早的負載均衡方案,它在用戶空間監聽一個端口,所有服務通過 iptables 轉發到這個端口,然後在其內部負載均衡到實際的 Pod。該方式最主要的問題是效率低,有明顯的性能瓶頸。

  • iptables:目前推薦的方案,完全以 iptables 規則的方式來實現 service 負載均衡。該方式最主要的問題是在服務多的時候產生太多的 iptables 規則,非增量式更新會引入一定的時延,大規模情況下有明顯的性能問題

  • ipvs:爲解決 iptables 模式的性能問題,v1.11 新增了 ipvs 模式(v1.8 開始支持測試版,並在 v1.11 GA),採用增量式更新,並可以保證 service 更新期間連接保持不斷開

  • winuserspace:同 userspace,但僅工作在 windows 節點上

注意:使用 ipvs 模式時,需要預先在每臺 Node 上加載內核模塊 nf_conntrack_ipv4, ip_vs, ip_vs_rr, ip_vs_wrr, ip_vs_sh 等。

# load module <module_name>
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4

# to check loaded modules, use
lsmod | grep -e ip_vs -e nf_conntrack_ipv4
# or
cut -f1 -d " "  /proc/modules | grep -e ip_vs -e nf_conntrack_ipv4

Iptables 示例

Kube-proxy iptables 示意圖

(圖片來自cilium/k8s-iptables-diagram)

Kube-proxy NAT 示意圖

(圖片來自kube-proxy iptables "nat" control flow

Iptables 示例

如果服務設置了 externalTrafficPolicy: Local 並且當前 Node 上面沒有任何屬於該服務的 Pod,那麼在 KUBE-XLB-4N57TFCL4MD7ZTDA 中會直接丟掉從公網 IP 請求的包:

ipvs 示例

Kube-proxy IPVS mode 列出了各種服務在 IPVS 模式下的工作原理。

注意,IPVS 模式也會使用 iptables 來執行 SNAT 和 IP 僞裝(MASQUERADE),並使用 ipset 來簡化 iptables 規則的管理:

ipset 名
成員
用途

KUBE-CLUSTER-IP

All service IP + port

Mark-Masq for cases that masquerade-all=true or clusterCIDR specified

KUBE-LOOP-BACK

All service IP + port + IP

masquerade for solving hairpin purpose

KUBE-EXTERNAL-IP

service external IP + port

masquerade for packages to external IPs

KUBE-LOAD-BALANCER

load balancer ingress IP + port

masquerade for packages to load balancer type service

KUBE-LOAD-BALANCER-LOCAL

LB ingress IP + port with externalTrafficPolicy=local

accept packages to load balancer with externalTrafficPolicy=local

KUBE-LOAD-BALANCER-FW

load balancer ingress IP + port with loadBalancerSourceRanges

package filter for load balancer with loadBalancerSourceRanges specified

KUBE-LOAD-BALANCER-SOURCE-CIDR

load balancer ingress IP + port + source CIDR

package filter for load balancer with loadBalancerSourceRanges specified

KUBE-NODE-PORT-TCP

nodeport type service TCP port

masquerade for packets to nodePort(TCP)

KUBE-NODE-PORT-LOCAL-TCP

nodeport type service TCP port with externalTrafficPolicy=local

accept packages to nodeport service with externalTrafficPolicy=local

KUBE-NODE-PORT-UDP

nodeport type service UDP port

masquerade for packets to nodePort(UDP)

KUBE-NODE-PORT-LOCAL-UDP

nodeport type service UDP port withexternalTrafficPolicy=local

accept packages to nodeport service withexternalTrafficPolicy=local

啓動 kube-proxy 示例

kube-proxy 工作原理

kube-proxy 監聽 API server 中 service 和 endpoint 的變化情況,並通過 userspace、iptables、ipvs 或 winuserspace 等 proxier 來爲服務配置負載均衡(僅支持 TCP 和 UDP)。

kube-proxy 不足

kube-proxy 目前僅支持 TCP 和 UDP,不支持 HTTP 路由,並且也沒有健康檢查機制。這些可以通過自定義 Ingress Controller 的方法來解決。

Last updated