docker 網(wǎng)絡(luò)-bridge

主要內(nèi)容介紹

[重點(diǎn)章節(jié)]docker默認(rèn)網(wǎng)絡(luò)模式

1、實(shí)現(xiàn)基礎(chǔ)
1.1、namespace + veth 連通性測試
1.2、namespace +bridge 連通性測試

2、docker bridge
2.1、docker bridge 網(wǎng)絡(luò)模型介紹
2.2、docker bridge 網(wǎng)絡(luò)創(chuàng)建測試
2.3、docker bridge 命令背后的操作
2.4 、docker 命名后面為何看不到ns?
2.5、 docker bridge DNS 功能,服務(wù)發(fā)現(xiàn)?

3、總結(jié)
bridge 優(yōu)缺點(diǎn)以及適用的業(yè)務(wù)場景

namespace + veth 連通性測試

1、需要完成的功能(如圖網(wǎng)絡(luò)連接情況)

1.1、三個(gè)命名空間 server ,gw ,client
1.2、server ping gw /client ping gw
1.3、server ping client / client ping server
1.4、server ping host eth0,server ping host eth1
1.5、server ping www.baidu.com

測試網(wǎng)絡(luò)拓?fù)?png

備注:網(wǎng)卡命名@符號,vethsl@if9 表示一對 ,if 9 表示 9號接口,所有命名空間的接口ID 值唯一可以通過@符號找到對應(yīng)的設(shè)備對。

2、測試命名以及步驟
1、創(chuàng)建三個(gè)命名空間

sudo ip netns add server
sudo ip netns add gw
sudo ip netns add client
#查看已創(chuàng)建的命名空間
ip netns ls

2、創(chuàng)建veth-pair

`#client-gw 連接對
sudo ip link add vethcl type veth peer name vethcg
#server-gw 連接對
sudo ip link add vethsl type veth peer name vethsg
#查看已創(chuàng)建的設(shè)備
ip a

3、veth-pair 連接network namespace

sudo ip link set vethsl netns server
sudo ip link set vethsg netns gw
sudo ip link set vethcg netns gw
sudo ip link set vethcl netns client
#查看主機(jī)設(shè)備情況
ip a
#查看命名空間里面的設(shè)備
sudo ip netns exec server ip a
sudo ip netns exec gw ip a
sudo ip netns exec client ip a

4、激活設(shè)備,并且分配ip地址

由于:手動創(chuàng)建的ns 不會自動分配ip,激活設(shè)備,配置路由。這些相關(guān)操作都需要手動執(zhí)行

.
# 4.1 server ns 設(shè)備激活分配ip
sudo ip netns exec server ip link set vethsl up
sudo ip netns exec server ip addr add 192.168.100.3/24 dev vethsl
sudo ip netns exec server ip link set lo up
sudo ip netns exec server ip a
#4.2 client ns 設(shè)備激活分配ip
sudo ip netns exec client ip link set vethcl up
sudo ip netns exec client ip addr add 172.31.100.3/24 dev vethcl
sudo ip netns exec client ip link set lo up
sudo ip netns exec client ip a
#4.3 gw ns 激活分配ip
sudo ip netns exec gw ip link set vethsg up
sudo ip netns exec gw ip addr 192.168.100.1/24 dev vethsg
sudo ip netns exec gw ip link set lo up
sudo ip netns exec gw ip link set vethcg up
sudo ip netns exec gw ip addr add 172.31.100.1/24 dev vethcg
sudo ip netns exec gw ip a

5、測試網(wǎng)絡(luò)連通

問題1,問題2,問題3?

.
# server ping gw ,ok
sudo ip netns exec server ping 192.168.100.1
# client ping gw,ok
sudo ip netns exec server ping 172.31.100.1
# server ping client,提示:Network is unreachable
# 問題1,解決方案 見 6點(diǎn)
sudo ip netns exec server ping 172.31.100.3
# server ping 主機(jī) eth0 , 提示 :Network is unreachable
# 問題2,解決方案 見 7點(diǎn)
sudo ip netns exec server ping 10.0.2.15
# server ping 主機(jī) eth0 , 提示 :Network is unreachable
# 問題3,解決方案 見 8點(diǎn)
sudo ip netns exec server ping www.baidu.com

6、解決 問題1

1、提示 Network is unreachable,一般情況下 是找不到對應(yīng)的路由。
2、輸入ping 命令后,如果長時(shí)間沒有返回,一般情況下只有單邊的路由。或者是arp 中找不對對應(yīng)的mac 地址
3、ping 命名需要來回兩條路都有正確的路由才能ping 通。

.
#查看server ns 路由,發(fā)現(xiàn)只有到gw一個(gè)接口 的路由
sudo ip netns exec server ip r
# 添加默認(rèn)路由,所有數(shù)據(jù)都通過vethsl 接口,gw 表示下跳,所以應(yīng)該為
# veth 的另一端
sudo ip netns exec server ip route add default gw 192.168.100.1
#再次ping,無應(yīng)答,單邊通
sudo ip netns exec server ping 172.31.100.3
# 查看 gw 路由,正確(目前)
sudo ip netns exec gw ip r
#查看client 路由,發(fā)現(xiàn)也只有到gw 直接連接的接口路由。
sudo ip netns exec client ip r
# 與server 一樣添加 默認(rèn)路由
sudo ip netns exec client route add default gw 172.31.100.1
# ping 再次測試,正常ping 通
sudo ip netns exec server ping 172.31.100.3
sudo ip netns exec client ping 192.168.100.3

7、解決問題2,命名空間無法與主機(jī)通信

思路:創(chuàng)建一對veth對,一端放入 gw 中,一端放入 主機(jī)中,并且配置相關(guān)路由
注意:ip 地址設(shè)置,盡量使用與主機(jī)不同的網(wǎng)段,避免路由沖突
備注:刪除ip 地址,重新配置命名sudo ip addr del

.
# 創(chuàng)建veth-pair,放入gw 中
sudo ip link add vethgo type veth peer name vethgi
sudo ip link set vethgi netns gw
sudo ip netns exec gw ip link set vethgi up
sudo ip netns exec gw ip addr add 192.168.98.1/24 dev vethgi
#設(shè)置主機(jī)中veth
sudo ip link set vethgo up
sudo ip addr add 192.168.98.3/24 dev vethgo
# 主機(jī) ping gw 直連接口,ok
ping 192.168.98.1
# 主機(jī) ping gw 其他端口,無響應(yīng)。
ping 172.31.100.1
ping 192.168.100.1
# 同理配置主機(jī)路由,client & server 網(wǎng)段
sudo ip route add 172.31.100.0/24 via 192.168.98.1 dev vethgo
sudo ip route add 192.168.100.0/24 via 192.168.98.1 dev vethgo
#為gw 配置默認(rèn)路由,連接到主機(jī)的vethgo 接口
sudo ip netns exec gw ip route add default via 192.168.98.3 dev vethgi
# ping 測試 主機(jī)ping server ,主機(jī)ping client ,ok
ping 172.31.100.3
ping 192.168.100.3

8、問題3,ns 無法連通外部網(wǎng)絡(luò)

理解:主機(jī)里面的網(wǎng)絡(luò)在一個(gè)局網(wǎng)內(nèi),有自己的局網(wǎng)ip,(比如 192.168.100.3),如果從主機(jī)發(fā)送出去的數(shù)據(jù)包的源地址為192.168.100.3,收到該數(shù)據(jù)包的主機(jī),有可能沒辦法 回應(yīng)消息。比如 host-A(172.10.1.2) 有自己的ns ,里面有一個(gè)ip 為192.168.100.3, host-B(172.10.1.3) 有自己的ns ,里面有一個(gè)ip 也為192.168.100.3,那么 host-a-ns 與host-b-ns 是無法直接連通的。host-a 收到host-b 的ping ,host-a 會應(yīng)答給host-a-ns。

解決方案:SNAT(修改數(shù)據(jù)包源地址)

所有ns 出口的數(shù)據(jù)包 都修改原地址為主機(jī)的ip 兒不是ns 的ip,這樣相當(dāng)于兩個(gè)主機(jī)通信。主機(jī)收到消息后在分發(fā)給自己ns

修改了原地址,怎么知道回來的消息改發(fā)給哪個(gè)ns?iptables 會記錄每次nat 會話(“連接”)的信息,所以回來的消息,能夠正確發(fā)送到正確的ns。

備注:iptables 功能以及詳情使用,見docker-網(wǎng)絡(luò) 準(zhǔn)備 推薦閱讀

.
#開啟 linux kernel ip forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# -t :指明iptables 的表名稱
# -A :添加一條nat 規(guī)則
# 將數(shù)據(jù)包源ip 地址為192.168.45.0 這個(gè)網(wǎng)段的地址 ,替換為 eth0 的ip 地址
# MASQUERADE 自動獲取[eth0] 網(wǎng)絡(luò)接口的IP地址
# server namespace nat
sudo iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o eth0 -j MASQUERADE
# 在默認(rèn) FORWARD 規(guī)則為 DROP 時(shí)顯式地允許 veth1 和 eth0 之間的 forwarding
sudo iptables -t filter -A FORWARD -i eth0 -o vethgo -j ACCEPT
sudo iptables -t filter -A FORWARD -o eth0 -i vethgo -j ACCEPT
# 查看iptables配置詳細(xì)情況
sudo iptables -L FORWARD -v
sudo iptables -t nat -L POSTROUTING -v
# ping 外網(wǎng),ok
sudo ip netns exec server ping www.baidu.com

namespace +bridge 連通性測試

0、創(chuàng)建虛擬機(jī)

docker-machine create --driver virtualbox bridge
docker-machine ls
ssh docker@192.168.99.105 -i ~/.docker/machine/machines/bridge/id_rsa

1、創(chuàng)建bridge 設(shè)備

sudo ip link add br0 type bridge
sudo ip link set dev br0 up
ip l

2、創(chuàng)建veth 設(shè)備

sudo ip link add veth0 type veth peer name veth1

3、將一端連接 bridge

sudo ip link set dev veth0 master br0
sudo ip link set dev veth0 up

4、創(chuàng)建ns-net1,連接veth

sudo ip netns add net1
sudo ip link set veth1 netns net1
sudo ip netns exec net1 ip link set veth1 up
sudo ip netns exec net1 ip addr add 192.168.101.3/24 dev veth1
sudo ip netns exec net1 ip link set lo up

5、查看結(jié)果,以及ping 測試

sudo ip addr add 192.168.101.1/24 dev br0
sudo ip netns exec net1 route add default gw 192.168.101.1
ping 192.168.101.3

6、bridge 其他命令 bridge,brctl (略)

備注:其他ns 連接bridge 同樣操作,連接外網(wǎng)配置NAT

docker bridge

1、docker bridge 網(wǎng)絡(luò)模型介紹 如圖 ,實(shí)現(xiàn)功能

1、每一個(gè)容器使用自己的網(wǎng)絡(luò)命名空間
2、每個(gè)容器的網(wǎng)絡(luò)與主機(jī)的bridge 設(shè)備連接(主機(jī)與容器通信,容器間通信)
3、主機(jī)NAT(端口映射) 容器里面的數(shù)據(jù)包ip 與外部通信
4、官網(wǎng)推薦使用自定義bridge 網(wǎng)絡(luò),不使用默認(rèn)的docker0。
自定義的bridge 比docker 默認(rèn)的bridge 網(wǎng)絡(luò)有更多功能和靈活性,詳情見官網(wǎng)
5、各個(gè)bridge 里面的網(wǎng)絡(luò)隔離,如圖 docker 里面網(wǎng)絡(luò) 與 my_bridge 不能連通。
實(shí)現(xiàn)了自己局網(wǎng)連通,隔離其他局網(wǎng)

docker-bridge.png
2、docker bridge 測試

docker-bridge.png

#測試命令
# 1 創(chuàng)建bridge99 網(wǎng)絡(luò)
docker network create -d bridge --subnet 172.31.99.0/24 bridge99
# 查看docker 網(wǎng)絡(luò)
docker network ls
docker network inspect bridge99
docker run -itd --name 99c1 --net bridge99 hub.c.163.com/library/busybox sh
docker run -itd --name 99c2 --net bridge99 hub.c.163.com/library/busybox sh
# 查看容器ip, -f docker inspect 99c1 可以查看輸入文件結(jié)構(gòu),用{{}} 定位字段值
docker inspect -f "{{.NetworkSettings.Networks.bridge99.IPAddress}}" 99c1
# host ping container 99c1
ping docker inspect -f "{{.NetworkSettings.Networks.bridge99.IPAddress}}" 99c1
# container ping 外網(wǎng)
docker exec -it 99c1 ping www.baidu.com
# 1、創(chuàng)建bridge98 網(wǎng)絡(luò)
docker network create -d bridge --subnet 172.31.98.0/24 bridge98
docker run -itd --name 98c1 --net bridge98 hub.c.163.com/library/busybox sh
docker inspect -f "{{.NetworkSettings.Networks.bridge98.IPAddress}}" 98c1
# 2.1 host ping container 99c1
ping docker inspect -f "{{.NetworkSettings.Networks.bridge98.IPAddress}}" 98c1
# 2.2 container ping 外網(wǎng)
docker exec -it 98c1 ping www.baidu.com

3、docker bridge 測試結(jié)果

0、為何看不到 docker 容器的namespace ?

/var/run/netns 目錄下面沒有 namespace 符號鏈接,創(chuàng)建一個(gè)ns 的符號鏈接就可以

ip netns ls
mkdir -p /var/run/netns/
pid=$(docker inspect -f '{{.State.Pid}}' 99c1)
ln -sfT /proc/$pid/ns/net /var/run/netns/99c1
# 可以看到命名空間
ip netns ls
ip netns exec 99c1 ip a

1、bridge99 與 bridge98 網(wǎng)絡(luò)隔離
2、bridge99 與 bridge98 分別可以局部內(nèi)通信,以及與外部通信(NAT)
3、bridge99 與 bridge98 分別可以使用docker 內(nèi)部 DNS 服務(wù)。使用默認(rèn)的docker0 bridge 沒有DSN 服務(wù)
4、路由配置分析

  • 4.1、容器里面的命名空間自動添加了一條默認(rèn)路由,使用ip 命令 需要我們自己添加默認(rèn)路由
  • 4.2、主機(jī)空間里面的bridge由于設(shè)置了ip ,也自動添加了路由,與我們自己創(chuàng)建bridge 設(shè)備一樣

5、iptables 配置分析
NAT 配置,這兒是 docker 容器能夠連通外網(wǎng)的原因

# 查看nat 表
sudo iptables -t nat -v -L

Chain POSTROUTING
out !=bridge98 ,用出口的的接口的ip 修改原數(shù)據(jù)包ip
out !=bridge99 ,用出口的的接口的ip 修改原數(shù)據(jù)包ip

bridge99 與 bridge98 隔離配置

# 查看filter 表
sudo iptables  -v -L

Chain FORWARD
a 表示一個(gè)接口
in=a out=!a 跳轉(zhuǎn)到 Chain DOCKER-ISOLATION-STAGE-1

Chain DOCKER-ISOLATION-STAGE-1
in =bridge98 ,out !=bridge98,跳轉(zhuǎn)到 Chain DOCKER-ISOLATION-STAGE-2
in =bridge99 ,out !=bridge99 跳轉(zhuǎn)到 Chain DOCKER-ISOLATION-STAGE-2

Chain DOCKER-ISOLATION-STAGE-2 ,
out =bridge98,out=bridge99 drop
這條配置是bridge98 與bridge99 隔離原因

清除 DOCKER-ISOLATION-STAGE-2 配置

sudo iptables -F  DOCKER-ISOLATION-STAGE-2

# bridge98 與bridge99 可以連通
docker exec -it 99c1 ping `docker inspect -f "{{.[NetworkSettings.Networks.bridge98.IPAddress](http://NetworkSettings.Networks.bridge98.IPAddress)}}" 98c1`

總結(jié)

1、docker 的網(wǎng)絡(luò)模型,簡化了網(wǎng)絡(luò)的設(shè)置。屏蔽了不同操作系統(tǒng)的實(shí)現(xiàn)。為上層提供統(tǒng)一接口支持還提供了內(nèi)建DNS服務(wù),負(fù)載均衡服務(wù)等。

2、bridge 優(yōu)缺點(diǎn)以及適用的業(yè)務(wù)場景能夠滿足大部分業(yè)務(wù)場景,性能沒有host 模式高,但是能夠支持各種自定義網(wǎng)絡(luò), 以及實(shí)現(xiàn)網(wǎng)絡(luò)隔離,能夠滿足容器網(wǎng)絡(luò)隔離的要求。

相關(guān)內(nèi)容

docker 網(wǎng)絡(luò)-準(zhǔn)備
docker 網(wǎng)絡(luò)-host
docker 網(wǎng)絡(luò)-bridge
docker 網(wǎng)絡(luò)-overlay
docker 網(wǎng)絡(luò)-macvlan

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

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