主要內(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、三個命名空間 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)卡命名@符號,vethsl@if9 表示一對 舵盈,if 9 表示 9號接口陋率,所有命名空間的接口ID 值唯一可以通過@符號找到對應(yīng)的設(shè)備對。
2秽晚、測試命名以及步驟
1瓦糟、創(chuàng)建三個命名空間
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 命令后,如果長時間沒有返回哀九,一般情況下只有單邊的路由剿配。或者是arp 中找不對對應(yīng)的mac 地址
3阅束、ping 命名需要來回兩條路都有正確的路由才能ping 通呼胚。
.
#查看server ns 路由,發(fā)現(xiàn)只有到gw一個接口 的路由
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ò)在一個局網(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 膜眠,里面有一個ip 為192.168.100.3岩臣, host-B(172.10.1.3) 有自己的ns ,里面有一個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)于兩個主機(jī)通信。主機(jī)收到消息后在分發(fā)給自己ns
修改了原地址捎琐,怎么知道回來的消息改發(fā)給哪個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 這個網(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 時顯式地允許 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、每一個容器使用自己的網(wǎng)絡(luò)命名空間
2撤嫩、每個容器的網(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丈牢、各個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
pingdocker 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
pingdocker 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)建一個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 表示一個接口
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