您好,登錄后才能下訂單哦!
這篇文章給大家介紹Calico 網(wǎng)絡(luò)通信的原理是什么,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
下面我們通過具體的例子來幫助大家理解 Calico 網(wǎng)絡(luò)的通信原理。任意選擇 k8s 集群中的一個(gè)節(jié)點(diǎn)作為實(shí)驗(yàn)節(jié)點(diǎn),進(jìn)入容器 A,查看容器 A 的 IP 地址:
$ ip a 1: lo: <loopback,up,lower_up> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 3: eth0@if771: <broadcast,multicast,up,lower_up,m-down> mtu 1440 qdisc noqueue state UP link/ether 66:fb:34:db:c9:b4 brd ff:ff:ff:ff:ff:ff inet 172.17.8.2/32 scope global eth0 valid_lft forever preferred_lft forever
這里容器獲取的是 /32 位主機(jī)地址,表示將容器 A 作為一個(gè)單點(diǎn)的局域網(wǎng)。
瞄一眼容器 A 的默認(rèn)路由:
$ ip route default via 169.254.1.1 dev eth0 169.254.1.1 dev eth0 scope link
現(xiàn)在問題來了,從路由表可以知道 169.254.1.1
是容器的默認(rèn)網(wǎng)關(guān),但卻找不到任何一張網(wǎng)卡對(duì)應(yīng)這個(gè) IP 地址,這是個(gè)什么鬼?
莫慌,先回憶一下,當(dāng)一個(gè)數(shù)據(jù)包的目的地址不是本機(jī)時(shí),就會(huì)查詢路由表,從路由表中查到網(wǎng)關(guān)后,它首先會(huì)通過 ARP
獲得網(wǎng)關(guān)的 MAC 地址,然后在發(fā)出的網(wǎng)絡(luò)數(shù)據(jù)包中將目標(biāo) MAC 改為網(wǎng)關(guān)的 MAC,而網(wǎng)關(guān)的 IP 地址不會(huì)出現(xiàn)在任何網(wǎng)絡(luò)包頭中。也就是說,沒有人在乎這個(gè) IP 地址究竟是什么,只要能找到對(duì)應(yīng)的 MAC 地址,能響應(yīng) ARP 就行了。
想到這里,我們就可以繼續(xù)往下進(jìn)行了,可以通過 ip neigh
命令查看一下本地的 ARP 緩存:
$ ip neigh 169.254.1.1 dev eth0 lladdr ee:ee:ee:ee:ee:ee REACHABLE
這個(gè) MAC 地址應(yīng)該是 Calico 硬塞進(jìn)去的,而且還能響應(yīng) ARP。但它究竟是怎么實(shí)現(xiàn)的呢?
我們先來回想一下正常情況,內(nèi)核會(huì)對(duì)外發(fā)送 ARP 請(qǐng)求,詢問整個(gè)二層網(wǎng)絡(luò)中誰擁有 169.254.1.1
這個(gè) IP 地址,擁有這個(gè) IP 地址的設(shè)備會(huì)將自己的 MAC 地址返回給對(duì)方。但現(xiàn)在的情況比較尷尬,容器和主機(jī)都沒有這個(gè) IP 地址,甚至連主機(jī)上的端口 calicba2f87f6bb
,MAC 地址也是一個(gè)無用的 ee:ee:ee:ee:ee:ee
。按道理容器和主機(jī)網(wǎng)絡(luò)根本就無法通信才對(duì)呀!所以 Calico 是怎么做到的呢?
這里我就不繞彎子了,實(shí)際上 Calico 利用了網(wǎng)卡的代理 ARP 功能。代理 ARP 是 ARP 協(xié)議的一個(gè)變種,當(dāng) ARP 請(qǐng)求目標(biāo)跨網(wǎng)段時(shí),網(wǎng)關(guān)設(shè)備收到此 ARP 請(qǐng)求,會(huì)用自己的 MAC 地址返回給請(qǐng)求者,這便是代理 ARP(Proxy ARP)。舉個(gè)例子:
上面這張圖中,電腦發(fā)送 ARP 請(qǐng)求服務(wù)器 8.8.8.8 的 MAC 地址,路由器(網(wǎng)關(guān))收到這個(gè)請(qǐng)求時(shí)會(huì)進(jìn)行判斷,由于目標(biāo) 8.8.8.8 不屬于本網(wǎng)段(即跨網(wǎng)段),此時(shí)便返回自己的接口 MAC 地址給 PC,后續(xù)電腦訪問服務(wù)器時(shí),目標(biāo) MAC 直接封裝為 MAC254。
現(xiàn)在我們知道,Calico 本質(zhì)上還是利用了代理 ARP 撒了一個(gè)“善意的謊言”,下面我們來確認(rèn)一下。
查看宿主機(jī)的網(wǎng)卡信息和路由信息:
$ ip addr ... 771: calicba2f87f6bb@if4: <broadcast,multicast,up,lower_up> mtu 1440 qdisc noqueue state UP group default link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 14 inet6 fe80::ecee:eeff:feee:eeee/64 scope link valid_lft forever preferred_lft forever ... $ ip route ... 172.17.8.2 dev calicba2f87f6bb scope link ...
查看是否開啟代理 ARP:
$ cat /proc/sys/net/ipv4/conf/calicba2f87f6bb/proxy_arp 1
如果還不放心,可以通過 tcpdump 抓包驗(yàn)證一下:
$ tcpdump -i calicba2f87f6bb -e -nn tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on calicba2f87f6bb, link-type EN10MB (Ethernet), capture size 262144 bytes 14:27:13.565539 ee:ee:ee:ee:ee:ee > 0a:58:ac:1c:ce:12, ethertype IPv4 (0x0800), length 4191: 10.96.0.1.443 > 172.17.8.2.36180: Flags [P.], seq 403862039:403866164, ack 2023703985, win 990, options [nop,nop,TS val 331780572 ecr 603755526], length 4125 14:27:13.565613 0a:58:ac:1c:ce:12 > ee:ee:ee:ee:ee:ee, ethertype IPv4 (0x0800), length 66: 172.17.8.2.36180 > 10.96.0.1.443: Flags [.], ack 4125, win 2465, options [nop,nop,TS val 603758497 ecr 331780572], length 0
總結(jié):
Calico 通過一個(gè)巧妙的方法將 workload 的所有流量引導(dǎo)到一個(gè)特殊的網(wǎng)關(guān) 169.254.1.1,從而引流到主機(jī)的 calixxx 網(wǎng)絡(luò)設(shè)備上,最終將二三層流量全部轉(zhuǎn)換成三層流量來轉(zhuǎn)發(fā)。
在主機(jī)上通過開啟代理 ARP 功能來實(shí)現(xiàn) ARP 應(yīng)答,使得 ARP 廣播被抑制在主機(jī)上,抑制了廣播風(fēng)暴,也不會(huì)有 ARP 表膨脹的問題。
既然我們已經(jīng)掌握了 Calico 的組網(wǎng)原理,接下來就可以手動(dòng)模擬驗(yàn)證了。架構(gòu)如圖所示:
先在 Host0 上執(zhí)行以下命令:
$ ip link add veth0 type veth peer name eth0 $ ip netns add ns0 $ ip link set eth0 netns ns0 $ ip netns exec ns0 ip a add 10.20.1.2/24 dev eth0 $ ip netns exec ns0 ip link set eth0 up $ ip netns exec ns0 ip route add 169.254.1.1 dev eth0 scope link $ ip netns exec ns0 ip route add default via 169.254.1.1 dev eth0 $ ip link set veth0 up $ ip route add 10.20.1.2 dev veth0 scope link $ ip route add 10.20.1.3 via 192.168.1.16 dev ens192 $ echo 1 > /proc/sys/net/ipv4/conf/veth0/proxy_arp
在 Host1 上執(zhí)行以下命令:
$ ip link add veth0 type veth peer name eth0 $ ip netns add ns1 $ ip link set eth0 netns ns1 $ ip netns exec ns1 ip a add 10.20.1.3/24 dev eth0 $ ip netns exec ns1 ip link set eth0 up $ ip netns exec ns1 ip route add 169.254.1.1 dev eth0 scope link $ ip netns exec ns1 ip route add default via 169.254.1.1 dev eth0 $ ip link set veth0 up $ ip route add 10.20.1.3 dev veth0 scope link $ ip route add 10.20.1.2 via 192.168.1.32 dev ens192 $ echo 1 > /proc/sys/net/ipv4/conf/veth0/proxy_arp
網(wǎng)絡(luò)連通性測(cè)試:
# Host0 $ ip netns exec ns1 ping 10.20.1.3 PING 10.20.1.3 (10.20.1.3) 56(84) bytes of data. 64 bytes from 10.20.1.3: icmp_seq=1 ttl=62 time=0.303 ms 64 bytes from 10.20.1.3: icmp_seq=2 ttl=62 time=0.334 ms
實(shí)驗(yàn)成功!
具體的轉(zhuǎn)發(fā)過程如下:
ns0 網(wǎng)絡(luò)空間的所有數(shù)據(jù)包都轉(zhuǎn)發(fā)到一個(gè)虛擬的 IP 地址 169.254.1.1,發(fā)送 ARP 請(qǐng)求。
Host0 的 veth 端收到 ARP 請(qǐng)求時(shí)通過開啟網(wǎng)卡的代理 ARP 功能直接把自己的 MAC 地址返回給 ns0。
ns0 發(fā)送目的地址為 ns1 的 IP 數(shù)據(jù)包。
因?yàn)槭褂昧?169.254.1.1 這樣的地址,Host 判斷為三層路由轉(zhuǎn)發(fā),查詢本地路由 10.20.1.3 via 192.168.1.16 dev ens192
發(fā)送給對(duì)端 Host1,如果配置了 BGP,這里就會(huì)看到 proto 協(xié)議為 BIRD。
當(dāng) Host1 收到 10.20.1.3 的數(shù)據(jù)包時(shí),匹配本地的路由表 10.20.1.3 dev veth0 scope link
,將數(shù)據(jù)包轉(zhuǎn)發(fā)到對(duì)應(yīng)的 veth0 端,從而到達(dá) ns1。
回程類似
關(guān)于Calico 網(wǎng)絡(luò)通信的原理是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。