前言
Docker系列文章:
此篇是Docker系列的第六篇,大家一定要按照我做的Demo都手敲一遍,印象會更加深刻的,加油!
網卡
網卡是一塊計算機硬件。其特點是每一個網卡都有獨立的MAC地址,用戶可以通過電纜進行相互之間的連接。其主要功能是將數據封裝成以太網中的幀,通過鏈路管理進行傳輸,接受數據后,對數據進行編碼和譯碼。其優點是提高了CPU的利用率通過鏈路管理進行傳輸,提升了CPU的性能。 再用通俗一點的話解釋,網卡其實就是七層或者四層網絡模型的門戶,復制接收和轉發數據如下圖:

Network Namespace介紹
Network Namespace在邏輯上是網絡堆棧的一個副本,它有自己的路由、防火牆規則和網絡設備。默認情況下,子進程繼承其父進程的Network Namespace。如果不顯式創建新的Network Namespace,所有進程都從 init 進程繼承相同的默認Network Namespace。
每個新創建的Network Namespace默認有一個本地回環接口 lo,除此之外,所有的其他網絡設備(物理/虛擬網絡接口,網橋等)只能屬於一個Network Namespace。每個Socket也只能和一個Network Namespace通信。

創建Network Namespace
備注:采用的環境為阿里雲CentOS 8.2
-
檢查默認的Network Namespace 的 ID;
readlink /proc/$$/ns/net
-
創建名為networknamespacetest的Network Namespace;
#創建名為networknamespacetest的Network Namespace
ip netns add networknamespacetest
#檢查netns是否創建成功
ls /var/run/netns -
在networknamespacetest中創建一個bash進程並且查看Network Namespace的ID;
#創建bash進程
ip netns exec networknamespacetest bash
#查看Network Namespace的ID
readlink /proc/$$/ns/net -
經過上面可以得出每個Network Namespace都是相互隔離的,接下來我們看下networknamespacetest有什么構成;
ip addr
-
Network Namespace由本地回環接口 lo構成,並且這個接口是處於關閉狀態的,接下來我們啟動這個回環接口;
ip link set lo up
-
測試lo的連通性;
兩個Network Namespace之間如何通信
Veth-Pair
什么是Veth-Pair
Veth是Linux中一種虛擬出來的網絡設備,Veth設備總是成對出現,所以一般也叫Veth-Pair。Veth-Pair特點就是無法單獨存在,刪除其中一個,另一個也會自動消失。Veth的兩頭都直接連着網絡協議棧,所以你創建一個Veth對,主機上就會多2個網卡。

Veth-Pair作用
Veth-Pair作用就是反向流轉數據,從一頭發數據,就會從另一頭收到數據。Veth-Pair常常充當着一個橋梁,連接着各種虛擬網絡設備。常見用途是連接兩個Netwok Namespace,或者連接Linux-Bridge、OVS 之類的。

實戰

-
創建兩個Network Namespace network01和network02;
ip netns add network01
ip netns add network02 -
創建一對Veth設備,默認情況下會自動為Veth-Pair生成名稱,這里為了方便我們測試,我們在創建時指定 Veth-Pair的名稱;
#創建Veth-Pair
ip link add veth01 type veth peer name veth02
#查看主機中Veth-Pair
ip link ls -
把這一對Veth-Pair分別放到Network Namespace network01 和 network02中;
#綁定
ip link set veth01 netns network01
ip link set veth02 netns network02
#查看namespace組成
ip netns exec network01 ip addr
ip netns exec network02 ip addr
#查看主機中是否存在Veth-Pair
ip link ls查看network01和network02中的網絡資源,發現各自多了一個網卡,也就是veth設備的兩個端點,如下圖:
當我們把Veth-Pair分配到Network Namespace中后,在主機上就看不到它們了,如下圖:

-
給這些Veth-Pair分配IP並啟用它們;
#啟動設備veth01
ip netns exec network01 ip link set veth01 up
#綁定IP
ip netns exec network01 ip addr add 10.0.1.1/24 dev veth01
#設置IP路由
ip netns exec network01 ip route
#啟動設備veth02
ip netns exec network02 ip link set veth02 up
#綁定IP
ip netns exec network02 ip addr add 10.0.1.2/24 dev veth02
#設置IP路由
ip netns exec network02 ip route
-
通過ping命令來驗證兩個Network Namespace是否可以通信;
ip netns exec network01 ping -c 3 10.0.1.2
至此我們就完成兩個Network Namespace之間的通信。
Bridge
什么是Bridge
Linux Bridge(網橋)是工作於二層的虛擬網絡設備,功能類似於物理的交換機。Bridge可以綁定其他Linux網絡設備作為從設備,並將這些設備虛擬化為端口,當一個從設備被綁定到Bridge上時,就相當於真實網絡中的交換機端口插入了一個連接有終端的網線。Bridge有多個端口,數據可以從任何端口進來,進來之后從哪個口出去和物理交換機的原理差不多。
Bridge作用
Veth-Pair可以實現兩個Network Namespace之間的通信,但是當需要在多個Network Namespace之間通信的時候,光靠Veth-Pair就顯得有一些麻煩了,我們需要在Network Namespace創建很多個Veth才能和多個Network Namespace通信,我們可以把很多Veth-Pair綁定到Bridge上面,Network Namespace就能連通了多個Network Namespace,當需要通信的時候,Network Namespace只要往Bridge發報文,所有Veth-Pair全都可以收到報文信息。
實戰

-
創建一個br0的網橋,並設置上線;
ip link add br0 type bridge
ip link set dev br0 up
ip addr -
創建Veth-Pair;
#創建3個 veth pair
ip link add type veth
ip link add type veth
ip link add type veth -
創建Network Namespace;
#創建3個Network Namespace
ip netns add net0
ip netns add net1
ip netns add net2 -
將Veth-Pair的一邊掛到Network Namespace中,另一邊掛到bridge上,並設IP地址;
#配置net0
ip link set dev veth1 netns net0
ip netns exec net0 ip link set dev veth1 name eth0
ip netns exec net0 ip addr add 10.0.1.1/24 dev eth0
ip netns exec net0 ip link set dev eth0 up
ip link set dev veth0 master br0
ip link set dev veth0 up
#配置net1
ip link set dev veth3 netns net1
ip netns exec net1 ip link set dev veth3 name eth0
ip netns exec net1 ip addr add 10.220.1.2/24 dev eth0
ip netns exec net1 ip link set dev eth0 up
ip link set dev veth2 master br0
ip link set dev veth2 up
#配置net2
ip link set dev veth5 netns net2
ip netns exec net2 ip link set dev veth5 name eth0
ip netns exec net2 ip addr add 10.220.1.3/24 dev eth0
ip netns exec net2 ip link set dev eth0 up
ip link set dev veth4 master br0
ip link set dev veth4 up -
給br0設置IP;
ip link set dev br0 down
ip addr add 10.220.1.0/24 dev br0
ip link set dev br0 up
ip netns exec net0 ping -c 2 10.220.1.3 -
解決ping不通的問題,因為系統為bridge開啟了iptables功能,導致所有經過br0的數據包都要受iptables里面規則的限制,我在虛擬機已經安裝了Docker,Docker將iptables里面filter表的FORWARD鏈的默認策略設置成了drop,於是所有不符合docker規則的數據包都不會被forward,導致你這種情況ping不通;
解決辦法有兩個:
第一個就是關閉系統bridge的iptables功能,這樣數據包轉發就不受iptables影響了:
echo0 >/proc/sys/net/bridge/bridge-nf-call-iptables;
第二就是為br0添加一條iptables規則,讓經過br0的包能被forward:
iptables -A FORWARD -i br0 -j ACCEPT;
-
驗證;
以上涉及的Linux技術其實已經和ocker底層的網絡技術有些類似,這里先整體介紹一下,下篇我們對Docker的網絡進行探究一下。
結束
歡迎大家點點關注,點點贊!
