kube-proxy IPVS 模式的工作原理

原文鏈接:https://fuckcloudnative.io/posts/ipvs-how-kubernetes-services-direct-traffic-to-pods/

Kubernetes 中的 Service 就是一組同 label 類型 Pod 的服務(wù)抽象,為服務(wù)提供了負(fù)載均衡和反向代理能力,在集群中表示一個微服務(wù)的概念。kube-proxy 組件則是 Service 的具體實(shí)現(xiàn),了解了 kube-proxy 的工作原理,才能洞悉服務(wù)之間的通信流程,再遇到網(wǎng)絡(luò)不通時也不會一臉懵逼。

kube-proxy 有三種模式:userspace、iptablesIPVS,其中 userspace 模式不太常用。iptables 模式最主要的問題是在服務(wù)多的時候產(chǎn)生太多的 iptables 規(guī)則,非增量式更新會引入一定的時延,大規(guī)模情況下有明顯的性能問題。為解決 iptables 模式的性能問題,v1.11 新增了 IPVS 模式(v1.8 開始支持測試版,并在 v1.11 GA),采用增量式更新,并可以保證 service 更新期間連接保持不斷開。

目前網(wǎng)絡(luò)上關(guān)于 kube-proxy 工作原理的文檔幾乎都是以 iptables 模式為例,很少提及 IPVS,本文就來破例解讀 kube-proxy IPVS 模式的工作原理。為了理解地更加徹底,本文不會使用 Docker 和 Kubernetes,而是使用更加底層的工具來演示。

我們都知道,Kubernetes 會為每個 Pod 創(chuàng)建一個單獨(dú)的網(wǎng)絡(luò)命名空間 (Network Namespace) ,本文將會通過手動創(chuàng)建網(wǎng)絡(luò)命名空間并啟動 HTTP 服務(wù)來模擬 Kubernetes 中的 Pod。

本文的目標(biāo)是通過模擬以下的 Service 來探究 kube-proxy 的 IPVSipset 的工作原理:

apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  clusterIP: 10.100.100.100
  selector:
    component: app
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080

跟著我的步驟,最后你就可以通過命令 curl 10.100.100.100:8080 來訪問某個網(wǎng)絡(luò)命名空間的 HTTP 服務(wù)。為了更好地理解本文的內(nèi)容,推薦提前閱讀以下的文章:

  1. How do Kubernetes and Docker create IP Addresses?!
  2. iptables: How Docker Publishes Ports
  3. iptables: How Kubernetes Services Direct Traffic to Pods

注意:本文所有步驟皆是在 Ubuntu 20.04 中測試的,其他 Linux 發(fā)行版請自行測試。

準(zhǔn)備實(shí)驗(yàn)環(huán)境

首先需要開啟 Linux 的路由轉(zhuǎn)發(fā)功能:

$ sysctl --write net.ipv4.ip_forward=1

接下來的命令主要做了這么幾件事:

  • 創(chuàng)建一個虛擬網(wǎng)橋 bridge_home
  • 創(chuàng)建兩個網(wǎng)絡(luò)命名空間 netns_dustinnetns_leah
  • 為每個網(wǎng)絡(luò)命名空間配置 DNS
  • 創(chuàng)建兩個 veth pair 并連接到 bridge_home
  • netns_dustin 網(wǎng)絡(luò)命名空間中的 veth 設(shè)備分配一個 IP 地址為 10.0.0.11
  • netns_leah 網(wǎng)絡(luò)命名空間中的 veth 設(shè)備分配一個 IP 地址為 10.0.021
  • 為每個網(wǎng)絡(luò)命名空間設(shè)定默認(rèn)路由
  • 添加 iptables 規(guī)則,允許流量進(jìn)出 bridge_home 接口
  • 添加 iptables 規(guī)則,針對 10.0.0.0/24 網(wǎng)段進(jìn)行流量偽裝
$ ip link add dev bridge_home type bridge
$ ip address add 10.0.0.1/24 dev bridge_home

$ ip netns add netns_dustin
$ mkdir -p /etc/netns/netns_dustin
echo "nameserver 114.114.114.114" | tee -a /etc/netns/netns_dustin/resolv.conf
$ ip netns exec netns_dustin ip link set dev lo up
$ ip link add dev veth_dustin type veth peer name veth_ns_dustin
$ ip link set dev veth_dustin master bridge_home
$ ip link set dev veth_dustin up
$ ip link set dev veth_ns_dustin netns netns_dustin
$ ip netns exec netns_dustin ip link set dev veth_ns_dustin up
$ ip netns exec netns_dustin ip address add 10.0.0.11/24 dev veth_ns_dustin

$ ip netns add netns_leah
$ mkdir -p /etc/netns/netns_leah
echo "nameserver 114.114.114.114" | tee -a /etc/netns/netns_leah/resolv.conf
$ ip netns exec netns_leah ip link set dev lo up
$ ip link add dev veth_leah type veth peer name veth_ns_leah
$ ip link set dev veth_leah master bridge_home
$ ip link set dev veth_leah up
$ ip link set dev veth_ns_leah netns netns_leah
$ ip netns exec netns_leah ip link set dev veth_ns_leah up
$ ip netns exec netns_leah ip address add 10.0.0.21/24 dev veth_ns_leah

$ ip link set bridge_home up
$ ip netns exec netns_dustin ip route add default via 10.0.0.1
$ ip netns exec netns_leah ip route add default via 10.0.0.1

$ iptables --table filter --append FORWARD --in-interface bridge_home --jump ACCEPT
$ iptables --table filter --append FORWARD --out-interface bridge_home --jump ACCEPT

$ iptables --table nat --append POSTROUTING --source 10.0.0.0/24 --jump MASQUERADE

在網(wǎng)絡(luò)命名空間 netns_dustin 中啟動 HTTP 服務(wù):

$ ip netns exec netns_dustin python3 -m http.server 8080

打開另一個終端窗口,在網(wǎng)絡(luò)命名空間 netns_leah 中啟動 HTTP 服務(wù):

$ ip netns exec netns_leah python3 -m http.server 8080

測試各個網(wǎng)絡(luò)命名空間之間是否能正常通信:

$ curl 10.0.0.11:8080
$ curl 10.0.0.21:8080
$ ip netns exec netns_dustin curl 10.0.0.21:8080
$ ip netns exec netns_leah curl 10.0.0.11:8080

整個實(shí)驗(yàn)環(huán)境的網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)如圖:

安裝必要工具

為了便于調(diào)試 IPVS 和 ipset,需要安裝兩個 CLI 工具:

$ apt install ipset ipvsadm --yes

本文使用的 ipset 和 ipvsadm 版本分別為 7.5-1~exp11:1.31-1。

通過 IPVS 來模擬 Service

下面我們使用 IPVS 創(chuàng)建一個虛擬服務(wù) (Virtual Service) 來模擬 Kubernetes 中的 Service :

$ ipvsadm \
  --add-service \
  --tcp-service 10.100.100.100:8080 \
  --scheduler rr
  • 這里使用參數(shù) --tcp-service 來指定 TCP 協(xié)議,因?yàn)槲覀冃枰M的 Service 就是 TCP 協(xié)議。
  • IPVS 相比 iptables 的優(yōu)勢之一就是可以輕松選擇調(diào)度算法,這里選擇使用輪詢調(diào)度算法。

目前 kube-proxy 只允許為所有 Service 指定同一個調(diào)度算法,未來將會支持為每一個 Service 選擇不同的調(diào)度算法,詳情可參考文章 IPVS-Based In-Cluster Load Balancing Deep Dive。

創(chuàng)建了虛擬服務(wù)之后,還得給它指定一個后端的 Real Server,也就是后端的真實(shí)服務(wù),即網(wǎng)絡(luò)命名空間 netns_dustin 中的 HTTP 服務(wù):

$ ipvsadm \
  --add-server \
  --tcp-service 10.100.100.100:8080 \
  --real-server 10.0.0.11:8080 \
  --masquerading

該命令會將訪問 10.100.100.100:8080 的 TCP 請求轉(zhuǎn)發(fā)到 10.0.0.11:8080。這里的 --masquerading 參數(shù)和 iptables 中的 MASQUERADE 類似,如果不指定,IPVS 就會嘗試使用路由表來轉(zhuǎn)發(fā)流量,這樣肯定是無法正常工作的。

譯者注:由于 IPVS 未實(shí)現(xiàn) POST_ROUTING Hook 點(diǎn),所以它需要 iptables 配合完成 IP 偽裝等功能。

測試是否正常工作:

$ curl 10.100.100.100:8080

實(shí)驗(yàn)成功,請求被成功轉(zhuǎn)發(fā)到了后端的 HTTP 服務(wù)!

在網(wǎng)絡(luò)命名空間中訪問虛擬服務(wù)

上面只是在 Host 的網(wǎng)絡(luò)命名空間中進(jìn)行測試,現(xiàn)在我們進(jìn)入網(wǎng)絡(luò)命名空間 netns_leah 中進(jìn)行測試:

$ ip netns exec netns_leah curl 10.100.100.100:8080

哦豁,訪問失?。?/p>

要想順利通過測試,只需將 10.100.100.100 這個 IP 分配給一個虛擬網(wǎng)絡(luò)接口。至于為什么要這么做,目前我還不清楚,我猜測可能是因?yàn)榫W(wǎng)橋 bridge_home 不會調(diào)用 IPVS,而將虛擬服務(wù)的 IP 地址分配給一個網(wǎng)絡(luò)接口則可以繞過這個問題。

譯者注

Netfilter 是一個基于用戶自定義的 Hook 實(shí)現(xiàn)多種網(wǎng)絡(luò)操作的 Linux 內(nèi)核框架。Netfilter 支持多種網(wǎng)絡(luò)操作,比如包過濾、網(wǎng)絡(luò)地址轉(zhuǎn)換、端口轉(zhuǎn)換等,以此實(shí)現(xiàn)包轉(zhuǎn)發(fā)或禁止包轉(zhuǎn)發(fā)至敏感網(wǎng)絡(luò)。

針對 Linux 內(nèi)核 2.6 及以上版本,Netfilter 框架實(shí)現(xiàn)了 5 個攔截和處理數(shù)據(jù)的系統(tǒng)調(diào)用接口,它允許內(nèi)核模塊注冊內(nèi)核網(wǎng)絡(luò)協(xié)議棧的回調(diào)功能,這些功能調(diào)用的具體規(guī)則通常由 Netfilter 插件定義,常用的插件包括 iptables、IPVS 等,不同插件實(shí)現(xiàn)的 Hook 點(diǎn)(攔截點(diǎn))可能不同。另外,不同插件注冊進(jìn)內(nèi)核時需要設(shè)置不同的優(yōu)先級,例如默認(rèn)配置下,當(dāng)某個 Hook 點(diǎn)同時存在 iptables 和 IPVS 規(guī)則時,iptables 會被優(yōu)先處理。

Netfilter 提供了 5 個 Hook 點(diǎn),系統(tǒng)內(nèi)核協(xié)議棧在處理數(shù)據(jù)包時,每到達(dá)一個 Hook 點(diǎn),都會調(diào)用內(nèi)核模塊中定義的處理函數(shù)。調(diào)用哪個處理函數(shù)取決于數(shù)據(jù)包的轉(zhuǎn)發(fā)方向,進(jìn)站流量和出站流量觸發(fā)的 Hook 點(diǎn)是不一樣的。

內(nèi)核協(xié)議棧中預(yù)定義的回調(diào)函數(shù)有如下五個:

  1. NF_IP_PRE_ROUTING: 接收的數(shù)據(jù)包進(jìn)入?yún)f(xié)議棧后立即觸發(fā)此回調(diào)函數(shù),該動作發(fā)生在對數(shù)據(jù)包進(jìn)行路由判斷(將包發(fā)往哪里)之前。
  2. NF_IP_LOCAL_IN: 接收的數(shù)據(jù)包經(jīng)過路由判斷后,如果目標(biāo)地址在本機(jī)上,則將觸發(fā)此回調(diào)函數(shù)。
  3. NF_IP_FORWARD: 接收的數(shù)據(jù)包經(jīng)過路由判斷后,如果目標(biāo)地址在其他機(jī)器上,則將觸發(fā)此回調(diào)函數(shù)。
  4. NF_IP_LOCAL_OUT: 本機(jī)產(chǎn)生的準(zhǔn)備發(fā)送的數(shù)據(jù)包,在進(jìn)入?yún)f(xié)議棧后立即觸發(fā)此回調(diào)函數(shù)。
  5. NF_IP_POST_ROUTING: 本機(jī)產(chǎn)生的準(zhǔn)備發(fā)送的數(shù)據(jù)包或者經(jīng)由本機(jī)轉(zhuǎn)發(fā)的數(shù)據(jù)包,在經(jīng)過路由判斷之后,將觸發(fā)此回調(diào)函數(shù)。

iptables 實(shí)現(xiàn)了所有的 Hook 點(diǎn),而 IPVS 只實(shí)現(xiàn)了 LOCAL_INLOCAL_OUT、FORWARD 這三個 Hook 點(diǎn)。既然沒有實(shí)現(xiàn) PRE_ROUTING,就不會在進(jìn)入 LOCAL_IN 之前進(jìn)行地址轉(zhuǎn)換,那么數(shù)據(jù)包經(jīng)過路由判斷后,會進(jìn)入 LOCAL_IN Hook 點(diǎn),IPVS 回調(diào)函數(shù)如果發(fā)現(xiàn)目標(biāo) IP 地址不屬于該節(jié)點(diǎn),就會將數(shù)據(jù)包丟棄。

如果將目標(biāo) IP 分配給了虛擬網(wǎng)絡(luò)接口,內(nèi)核在處理數(shù)據(jù)包時,會發(fā)現(xiàn)該目標(biāo) IP 地址屬于該節(jié)點(diǎn),于是可以繼續(xù)處理數(shù)據(jù)包。

dummy 接口

當(dāng)然,我們不需要將 IP 地址分配給任何已經(jīng)被使用的網(wǎng)絡(luò)接口,我們的目標(biāo)是模擬 Kubernetes 的行為。Kubernetes 在這里創(chuàng)建了一個 dummy 接口,它和 loopback 接口類似,但是你可以創(chuàng)建任意多的 dummy 接口。它提供路由數(shù)據(jù)包的功能,但實(shí)際上又不進(jìn)行轉(zhuǎn)發(fā)。dummy 接口主要有兩個用途:

  • 用于主機(jī)內(nèi)的程序通信
  • 由于 dummy 接口總是 up(除非顯式將管理狀態(tài)設(shè)置為 down),在擁有多個物理接口的網(wǎng)絡(luò)上,可以將 service 地址設(shè)置為 loopback 接口或 dummy 接口的地址,這樣 service 地址不會因?yàn)槲锢斫涌诘臓顟B(tài)而受影響。

看來 dummy 接口完美符合實(shí)驗(yàn)需求,那就創(chuàng)建一個 dummy 接口吧:

$ ip link add dev dustin-ipvs0 type dummy

將虛擬 IP 分配給 dummy 接口 dustin-ipvs0 :

$ ip addr add 10.100.100.100/32 dev dustin-ipvs0

到了這一步,仍然訪問不了 HTTP 服務(wù),還需要另外一個黑科技:bridge-nf-call-iptables。在解釋 bridge-nf-call-iptables 之前,我們先來回顧下容器網(wǎng)絡(luò)通信的基礎(chǔ)知識。

基于網(wǎng)橋的容器網(wǎng)絡(luò)

Kubernetes 集群網(wǎng)絡(luò)有很多種實(shí)現(xiàn),有很大一部分都用到了 Linux 網(wǎng)橋:

  • 每個 Pod 的網(wǎng)卡都是 veth 設(shè)備,veth pair 的另一端連上宿主機(jī)上的網(wǎng)橋。
  • 由于網(wǎng)橋是虛擬的二層設(shè)備,同節(jié)點(diǎn)的 Pod 之間通信直接走二層轉(zhuǎn)發(fā),跨節(jié)點(diǎn)通信才會經(jīng)過宿主機(jī) eth0。

Service 同節(jié)點(diǎn)通信問題

不管是 iptables 還是 ipvs 轉(zhuǎn)發(fā)模式,Kubernetes 中訪問 Service 都會進(jìn)行 DNAT,將原本訪問 ClusterIP:Port 的數(shù)據(jù)包 DNAT 成 Service 的某個 Endpoint (PodIP:Port),然后內(nèi)核將連接信息插入 conntrack 表以記錄連接,目的端回包的時候內(nèi)核從 conntrack 表匹配連接并反向 NAT,這樣原路返回形成一個完整的連接鏈路:

但是 Linux 網(wǎng)橋是一個虛擬的二層轉(zhuǎn)發(fā)設(shè)備,而 iptables conntrack 是在三層上,所以如果直接訪問同一網(wǎng)橋內(nèi)的地址,就會直接走二層轉(zhuǎn)發(fā),不經(jīng)過 conntrack:

  1. Pod 訪問 Service,目的 IP 是 Cluster IP,不是網(wǎng)橋內(nèi)的地址,走三層轉(zhuǎn)發(fā),會被 DNAT 成 PodIP:Port。

  2. 如果 DNAT 后是轉(zhuǎn)發(fā)到了同節(jié)點(diǎn)上的 Pod,目的 Pod 回包時發(fā)現(xiàn)目的 IP 在同一網(wǎng)橋上,就直接走二層轉(zhuǎn)發(fā)了,沒有調(diào)用 conntrack,導(dǎo)致回包時沒有原路返回 (見下圖)。

    由于沒有原路返回,客戶端與服務(wù)端的通信就不在一個 “頻道” 上,不認(rèn)為處在同一個連接,也就無法正常通信。

開啟 bridge-nf-call-iptables

啟用 bridge-nf-call-iptables 這個內(nèi)核參數(shù) (置為 1),表示 bridge 設(shè)備在二層轉(zhuǎn)發(fā)時也去調(diào)用 iptables 配置的三層規(guī)則 (包含 conntrack),所以開啟這個參數(shù)就能夠解決上述 Service 同節(jié)點(diǎn)通信問題。

所以這里需要啟用 bridge-nf-call-iptables :

$ modprobe br_netfilter
$ sysctl --write net.bridge.bridge-nf-call-iptables=1

現(xiàn)在再來測試一下連通性:

$ ip netns exec netns_leah curl 10.100.100.100:8080

終于成功了!

開啟 Hairpin(發(fā)夾彎)模式

雖然我們可以從網(wǎng)絡(luò)命名空間 netns_leah 中通過虛擬服務(wù)成功訪問另一個網(wǎng)絡(luò)命名空間 netns_dustin 中的 HTTP 服務(wù),但還沒有測試過從 HTTP 服務(wù)所在的網(wǎng)絡(luò)命名空間 netns_dustin 中直接通過虛擬服務(wù)訪問自己,話不多說,直接測一把:

$ ip netns exec netns_dustin curl 10.100.100.100:8080

啊哈?竟然失敗了,這又是哪里的問題呢?不要慌,開啟 hairpin 模式就好了。那么什么是 hairpin 模式呢? 這是一個網(wǎng)絡(luò)虛擬化技術(shù)中常提到的概念,也即交換機(jī)端口的VEPA模式。這種技術(shù)借助物理交換機(jī)解決了虛擬機(jī)間流量轉(zhuǎn)發(fā)問題。很顯然,這種情況下,源和目標(biāo)都在一個方向,所以就是從哪里進(jìn)從哪里出的模式。

怎么配置呢?非常簡單,只需一條命令:

$ brctl hairpin bridge_home veth_dustin on

再次進(jìn)行測試:

$ ip netns exec netns_dustin curl 10.100.100.100:8080

還是失敗了。。。

然后我花了一個下午的時間,終于搞清楚了啟用混雜模式后為什么還是不能解決這個問題,因?yàn)榛祀s模式和下面的選項(xiàng)要一起啟用才能對 IPVS 生效:

$ sysctl --write net.ipv4.vs.conntrack=1

最后再測試一次:

$ ip netns exec netns_dustin curl 10.100.100.100:8080

這次終于成功了,但我還是不太明白為什么啟用 conntrack 能解決這個問題,有知道的大神歡迎留言告訴我!

譯者注:IPVS 及其負(fù)載均衡算法只針對首個數(shù)據(jù)包,后繼的包必須被 conntrack 表優(yōu)先反轉(zhuǎn),如果沒有 conntrack,IPVS 對于回來的包是沒有任何辦法的??梢酝ㄟ^ conntrack -L 查看。

開啟混雜模式

如果想讓所有的網(wǎng)絡(luò)命名空間都能通過虛擬服務(wù)訪問自己,就需要在連接到網(wǎng)橋的所有 veth 接口上開啟 hairpin 模式,這也太麻煩了吧。有一個辦法可以不用配置每個 veth 接口,那就是開啟網(wǎng)橋的混雜模式。

什么是混雜模式呢?普通模式下網(wǎng)卡只接收發(fā)給本機(jī)的包(包括廣播包)傳遞給上層程序,其它的包一律丟棄?;祀s模式就是接收所有經(jīng)過網(wǎng)卡的數(shù)據(jù)包,包括不是發(fā)給本機(jī)的包,即不驗(yàn)證MAC地址。

如果一個網(wǎng)橋開啟了混雜模式,就等同于將所有連接到網(wǎng)橋上的端口(本文指的是 veth 接口)都啟用了 hairpin 模式??梢酝ㄟ^以下命令來啟用 bridge_home 的混雜模式:

$ ip link set bridge_home promisc on

現(xiàn)在即使你把 veth 接口的 hairpin 模式關(guān)閉:

$ brctl hairpin bridge_home veth_dustin off

仍然可以通過連通性測試:

$ ip netns exec netns_dustin curl 10.100.100.100:8080

優(yōu)化 MASQUERADE

在文章開頭準(zhǔn)備實(shí)驗(yàn)環(huán)境的章節(jié),執(zhí)行了這么一條命令:

$ iptables \
  --table nat \
  --append POSTROUTING \
  --source 10.0.0.0/24 \
  --jump MASQUERADE

這條 iptables 規(guī)則會對所有來自 10.0.0.0/24 的流量進(jìn)行偽裝。然而 Kubernetes 并不是這么做的,它為了提高性能,只對來自某些具體的 IP 的流量進(jìn)行偽裝。

為了更加完美地模擬 Kubernetes,我們繼續(xù)改造規(guī)則,先把之前的規(guī)則刪除:

$ iptables \
  --table nat \
  --delete POSTROUTING \
  --source 10.0.0.0/24 \
  --jump MASQUERADE

然后添加針對具體 IP 的規(guī)則:

$ iptables \
  --table nat \
  --append POSTROUTING \
  --source 10.0.0.11/32 \
  --jump MASQUERADE

果然,上面的所有測試都能通過。先別急著高興,又有新問題了,現(xiàn)在只有兩個網(wǎng)絡(luò)命名空間,如果有很多個怎么辦,每個網(wǎng)絡(luò)命名空間都創(chuàng)建這樣一條 iptables 規(guī)則?我用 IPVS 是為了啥?就是為了防止有大量的 iptables 規(guī)則拖垮性能啊,現(xiàn)在豈不是又繞回去了。

不慌,繼續(xù)從 Kubernetes 身上學(xué)習(xí),使用 ipset 來解決這個問題。先把之前的 iptables 規(guī)則刪除:

$ iptables \
  --table nat \
  --delete POSTROUTING \
  --source 10.0.0.11/32 \
  --jump MASQUERADE

然后使用 ipset 創(chuàng)建一個集合 (set) :

$ ipset create DUSTIN-LOOP-BACK hash:ip,port,ip

這條命令創(chuàng)建了一個名為 DUSTIN-LOOP-BACK 的集合,它是一個 hashmap,里面存儲了目標(biāo) IP、目標(biāo)端口和源 IP。

接著向集合中添加條目:

$ ipset add DUSTIN-LOOP-BACK 10.0.0.11,tcp:8080,10.0.0.11

現(xiàn)在不管有多少網(wǎng)絡(luò)命名空間,都只需要添加一條 iptables 規(guī)則:

$ iptables \
  --table nat \
  --append POSTROUTING \
  --match set \
  --match-set DUSTIN-LOOP-BACK dst,dst,src \
  --jump MASQUERADE

網(wǎng)絡(luò)連通性測試也沒有問題:

$ curl 10.100.100.100:8080
$ ip netns exec netns_leah curl 10.100.100.100:8080
$ ip netns exec netns_dustin curl 10.100.100.100:8080

新增虛擬服務(wù)的后端

最后,我們把網(wǎng)絡(luò)命名空間 netns_leah 中的 HTTP 服務(wù)也添加到虛擬服務(wù)的后端:

$ ipvsadm \
  --add-server \
  --tcp-service 10.100.100.100:8080 \
  --real-server 10.0.0.21:8080 \
  --masquerading

再向 ipset 的集合 DUSTIN-LOOP-BACK 中添加一個條目:

$ ipset add DUSTIN-LOOP-BACK 10.0.0.21,tcp:8080,10.0.0.21

終極測試來了,試著多運(yùn)行幾次以下的測試命令:

$ curl 10.100.100.100:8080

你會發(fā)現(xiàn)輪詢算法起作用了:

總結(jié)

相信通過本文的實(shí)驗(yàn)和講解,大家應(yīng)該理解了 kube-proxy IPVS 模式的工作原理。在實(shí)驗(yàn)過程中,我們還用到了 ipset,它有助于解決在大規(guī)模集群中出現(xiàn)的 kube-proxy 性能問題。如果你對這篇文章有任何疑問,歡迎和我進(jìn)行交流。

參考文章

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容