1. 程式人生 > >Docker網路原理解析

Docker網路原理解析

在講Docker網路之前,我們先了解一下Linux中的一些網路概念和裝置,然後在看Docker是如何使用這些裝置實現容器網路的。

網路名稱空間

在 Linux 中,網路名字空間可以被認為是隔離的擁有單獨網路棧(網絡卡、路由轉發表、iptables)的環境。網路名字空間經常用來隔離網路裝置和服務,只有擁有同樣網路名字空間的裝置,才能看到彼此。如下圖所示
在這裡插入圖片描述

網路名稱空間常用命令
新增名稱空間

$ ip netns add net0

顯示所有名稱空間

ip netns list
或者
ls /var/run/netns/

進入虛擬網路環境

$ ip netns exec net0 `command`
例如:
$ ip netns exec net0 bash
$ ip ad
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

Veth裝置對

引入Veth裝置對是為了在不同的網路名稱空間之間進行通訊,利用它可以直接將兩個網路名稱空間連線起來。我們可以將Veth裝置對看成是一對乙太網卡,並且這兩張網絡卡之間有一根網線相連。如圖:
在這裡插入圖片描述

Veth裝置對的操作命令
建立Veth裝置對

ip link add veth0 type veth peer name veth1

建立好以後可以執行命令:ip link show檢視
在這裡插入圖片描述

移動一個Veth到另一個名稱空間:
ip link set veth1 netns myns
在這裡插入圖片描述
當前名稱空間已經看不到veth1了
然後在myns名稱空間中檢視
在這裡插入圖片描述
veth1已經成功移動過來了
但是現在還不能通訊,因為它們還沒有地址

給Veth裝置對分配IP地址
ip netns exec myns ip addr add 10.1.1.1/24 dev veth1
ip addr add 10.1.1.2/24 dev veth0
再啟動它們
ip netns exec myns ip link set dev veth1 up
ip link set dev veth0 up
現在兩個網路名稱空間就可以ping通了
在這裡插入圖片描述

Veth裝置對如何檢視對端
首先在一個名稱空間中查詢Veth裝置對端介面在裝置列表中的序列號
ip netns exec myns ethtool -S veth1
在這裡插入圖片描述
我們得到veth1對端介面裝置的序列號是7,在到另一名稱空間中檢視序號7代表什麼裝置
ip link | grep 7
在這裡插入圖片描述


這樣我們就找到了veth1的對端是veth0了

Linux 網橋

網橋的概念就不多說了,一個二層的網路裝置,根據MAC地址轉發報文,我們說一下Linux中的網橋的不同之處。

  • Linux網橋不但能夠轉發資料包,還能自己消耗資料包(如果資料包是發往主機本身的),所以既可以看成二層裝置,也可以看成一個三層裝置
  • Linux網橋可以有一個自己的IP地址

網橋的常用操作命令
新增網橋
brctl addbr br_name
將物理網絡卡與網橋相連
brctl addif br_name ethx
注意:網橋的物理網絡卡作為一個埠,由於工作在鏈路層,所以不再需要IP地址,上面的IP地址自然也就失效了。

給網橋配置IP地址
ifconfig br_name 10.100.0.1 up

brctl --help
在這裡插入圖片描述
delbr bridge的名稱 #刪除bridge;
addif bridge的名稱device的名稱#新增介面到bridge;
delif bridge的名稱device的名稱#從bridge中刪除介面
setageing bridge的名稱時間 #設定老化時間,即生存週期
setbridgeprio bridge的名稱 優先順序#設定bridge的優先順序
setfd bridge的名稱時間 #設定bridge轉發延遲時間
sethello bridge的名稱時間 #設定hello時間
setmaxage bridge的名稱時間 #設定訊息的最大生命週期
setpathcost bridge的名稱 埠 權重#設定路徑的權值
setportprio bridge的名稱 埠 優先順序#設定埠的優先順序
show #顯示bridge列表
showmacs bridge的名稱 #顯示MAC地址
showstp bridge的名稱 #顯示bridge的stp資訊
stp bridge的名稱{on|off} #開/關stp

Docker容器網路解析

docker服務啟動時會生成一個網橋docker0,連線生成的每一個容器,併為其分配IP地址
容器網路配置過程
第一步:,docker每啟動一個容器,都會生成一個名稱空間,但是這個名稱空間通過ip netns list是看不到的,因為ip netns只能看到/var/run/netns下面的網路名稱空間,但是docker建立網路名稱空間後不會自動在該檔案下建立網路名稱空間檔案。如果想通過ip netns list看到的話,需要執行下面的命令:

pid=`docker inspect -f '{{.State.Pid}}' $container_id`
ln -s /proc/$pid/ns/net /var/run/netns/$container_id

在這裡插入圖片描述

第二步:建立Veth裝置對,docker會為每一個容器建立一對Veth,並將一端連線到docker0,然後將從docker0分配到的IP分配給剩下的一個Veth裝置,並將其改名為eth0(以前一直以為是一個本地網絡卡,原來只是Veth裝置對中的一個,簡直以假亂真),再為本地容器生成一個MAC地址。
在這裡插入圖片描述
通過上面兩步,docker容器就可以通過docker0網橋和其他容器通訊了。