什么是Bridge
Bridge是一種虛擬網(wǎng)絡(luò)設(shè)備,所以具備虛擬網(wǎng)絡(luò)設(shè)備的所有特性宣增,比如可以配置 IP车遂、MAC 等封断。除此之外,Bridge 還是一個虛擬交換機(jī)舶担,具有交換機(jī)所有的功能坡疼。
對于普通的網(wǎng)絡(luò)設(shè)備,就像一個管道衣陶,只有兩端柄瑰,數(shù)據(jù)從一端進(jìn),從另一端出剪况,如物理網(wǎng)卡從外面網(wǎng)絡(luò)中收到數(shù)據(jù)轉(zhuǎn)發(fā)給內(nèi)核網(wǎng)絡(luò)協(xié)議棧教沾,從網(wǎng)絡(luò)協(xié)議棧過來的數(shù)據(jù)轉(zhuǎn)發(fā)到外部網(wǎng)絡(luò)。而 Bridge 有多個端口拯欧,數(shù)據(jù)可以從多個端口進(jìn)详囤,從多個端口出,原理和交換機(jī)類似。
Bridge 的這個特性讓它可以接入其他的網(wǎng)絡(luò)設(shè)備藏姐,比如物理設(shè)備隆箩、虛擬設(shè)備。Bridge 通常充當(dāng)主設(shè)備羔杨,其他設(shè)備為從設(shè)備捌臊,這樣的效果就等同于物理交換機(jī)的端口連接了一根網(wǎng)線。Bridge是和主機(jī)的網(wǎng)絡(luò)協(xié)議棧相連的兜材,也就是說通過bridge的網(wǎng)絡(luò)數(shù)據(jù)理澎,是要經(jīng)過host主機(jī)的內(nèi)核協(xié)議棧的進(jìn)行處理的(我的理解就是net_filter通過iptables設(shè)置的rules進(jìn)行處理)
什么是veth-pair
veth-pair 就是一對的虛擬設(shè)備接口,它都是成對出現(xiàn)的曙寡。一端連著協(xié)議棧糠爬,一端彼此相連著
正因?yàn)橛羞@個特性,它常常充當(dāng)著一個橋梁举庶,連接著各種虛擬網(wǎng)絡(luò)設(shè)備执隧。例如在docker中,他們連接容器所處網(wǎng)絡(luò)namespace和bridge户侥。
此圖中veth-pair一個是連接在bridge上的veth,另一個是連接在容器網(wǎng)絡(luò)namespace上的eth0镀琉。veth和eth0彼此相連,veth通過bridge與host的網(wǎng)絡(luò)協(xié)議棧相連蕊唐,eth0通過容器namespace和容器的網(wǎng)絡(luò)協(xié)議棧相連屋摔。這里的容器是在host內(nèi)部的容器,不考慮跨節(jié)點(diǎn)的容器替梨。
模擬容器和bridge連接
安裝docker成功后钓试,我們可以看到docker在host機(jī)器上默認(rèn)的創(chuàng)建一個docker0的bridge,這個bridge也是容器的默認(rèn)的連接方式副瀑。在這里我們將用將創(chuàng)建網(wǎng)絡(luò)namespace來模擬容器亚侠,讓namespace和我們創(chuàng)建好的bridge連接起來,容器之間可以相互訪問俗扇,容器可以和host所在網(wǎng)絡(luò)訪問。
首先我們要打開host機(jī)器上的ip_forwarding功能箕别,這樣host的物理網(wǎng)卡和bridge之間才能forward數(shù)據(jù)包铜幽。IP_FORWARD可以使連接在同一個網(wǎng)絡(luò)協(xié)議棧上的網(wǎng)絡(luò)接口間進(jìn)行數(shù)據(jù)包的轉(zhuǎn)發(fā),適合host上有多塊物理網(wǎng)卡串稀,虛擬設(shè)備接口除抛,結(jié)合iptables的 forward鏈一起使用。例如主機(jī)網(wǎng)絡(luò)協(xié)議棧上連接了30.0/24這個物理網(wǎng)卡和88.0/24這個bridge虛擬設(shè)備母截,一個數(shù)據(jù)包從30.0/24這塊網(wǎng)卡進(jìn)入網(wǎng)絡(luò)協(xié)議棧到忽,數(shù)據(jù)包的destination是88.0/24這個網(wǎng)段上的某一個IP地址,內(nèi)核協(xié)議棧發(fā)現(xiàn)這個包是去bridge子網(wǎng)的,于是就會把這個數(shù)據(jù)包forward給bridge連在網(wǎng)絡(luò)協(xié)議棧上的端口并進(jìn)行處理喘漏。如果forward功能沒有打開护蝶,數(shù)據(jù)包無法轉(zhuǎn)發(fā)到bridge,只能在drop掉翩迈。
這個重啟后就失效了持灰,要想永久有效請修改文件/etc/sysctl.conf
創(chuàng)建一個bridge br0,激活這個device负饲,并給他分配一個IP地址及掩碼192.168.88.1/24堤魁。
創(chuàng)建一個網(wǎng)絡(luò)的namespace ns0,然后在這個網(wǎng)絡(luò)namespace中執(zhí)行bash命令(另外起一個terminal做這個事情)返十,如果你還不清楚什么是linux內(nèi)核namespace妥泉,請google相關(guān)資料。
執(zhí)行命令后洞坑,我這個terminal已經(jīng)進(jìn)入到ns0這個namespace了盲链,這和docker容器的網(wǎng)絡(luò)namespace是一致的。通過ip命令查詢检诗,現(xiàn)在這個命令空間里面只有一個loopback的網(wǎng)絡(luò)設(shè)備匈仗,沒有其他網(wǎng)絡(luò)設(shè)備相連。然后通過命令使loopback設(shè)備active
接下來我們就要創(chuàng)建veth pair逢慌,一邊和這個ns0連接悠轩,一邊和br0連接,并給他們分配IP地址攻泼。(這些操作不要在ns0里執(zhí)行bash命令的terminal里面做)
這里創(chuàng)建一個veth pair火架,veth0和veth0p,并且把veth0和ns0相連忙菠,并分配和br0同一個網(wǎng)段的IP地址192.168.88.2何鸡,啟動veth0p這個設(shè)備。返回到ns0下bash的terminal牛欢,可以看到多出一個網(wǎng)卡信息并分配到IP地址骡男,但是這個dev是處于LOWERLAYDOWN的狀態(tài),這是由于pair另一端還沒有接入到br0.
接下來就是把veth0連接到br0上傍睹,并啟動這個設(shè)備隔盛。
我們可以看到br0上有一個veth設(shè)備連接上來,返回去看ns0下的bash拾稳,我們可以看到veth0p的狀態(tài)已經(jīng)變成UP吮炕。
現(xiàn)在br0的IP是192.168.88.1,ns0的IP地址為192.168.88.2访得,我們可以在ns0下去ping 192.168.88.1是可以通的龙亲,我們可以通過同樣的步驟在創(chuàng)建另外一個namespace ns1并分配IP192.168.88.3。ns0,ns1鳄炉, br0都是可以相互連接的杜耙,這里就不重復(fù)創(chuàng)建了。
目前為止連接在bridge上的namespace都是可以相互訪問迎膜,這個體現(xiàn)了bridge虛擬交換機(jī)的功能泥技。如果我們還需要容器能訪問host所在的網(wǎng)絡(luò),我們需要繼續(xù)配置下面步驟磕仅。
在ns0下的bash命令行下設(shè)置默認(rèn)路由珊豹,不屬于192.168.88.0/24這個網(wǎng)段的數(shù)據(jù)包全部路由到默認(rèn)網(wǎng)關(guān)br0 192.168.88.1.
由于192.168.88.0/24這個網(wǎng)段和host所在的網(wǎng)路不是一個網(wǎng)絡(luò),一切從88.0/24這個網(wǎng)絡(luò)的數(shù)據(jù)包要訪問外部網(wǎng)絡(luò)都是要通過host的主機(jī)IP去訪問的榕订,對于遠(yuǎn)端服務(wù)連接它是不知道88.0/24這個網(wǎng)絡(luò)的店茶,他接收的數(shù)據(jù)包的src地址都是host的IP地址,在這里我們需要對88.0/24這個網(wǎng)段的數(shù)據(jù)包做SNAT劫恒。在host的terminal下通過iptables的命令設(shè)置贩幻。
iptables必須是enable的,并對NAT table的POSTROUTING chain添加一條規(guī)則两嘴,所有src地址為88.0/24這個網(wǎng)段的數(shù)據(jù)包丛楚,全部走h(yuǎn)ost機(jī)器上的物理網(wǎng)卡,通過MASQUERADE選項(xiàng)修改src地址為網(wǎng)卡eno16777736的IP地址憔辫。你也可以用SNAT這個參數(shù)代替指定一個特殊IP地址趣些。
請自行參考iptables的用法和原理,如果你的host主機(jī)上實(shí)現(xiàn)設(shè)置了其他iptables rules從而阻止了88.0/24這個網(wǎng)絡(luò)的forward或者routing贰您,需要自行檢查一下坏平,每一個機(jī)器的網(wǎng)絡(luò)狀態(tài)是不一樣的沒辦法全部覆蓋。這里推薦一個系列博客很詳細(xì)的講解了iptables锦亦。?
這里可以看到我們在ns0下的bash命令行舶替,可以ping通host所在網(wǎng)絡(luò)的機(jī)器30.134和internet上的baidu。現(xiàn)在就完成了整個模擬實(shí)驗(yàn)杠园。