本節介紹自定義bridge network的自定義網絡。
1.前言2.創建自定義網絡2.1 創建網絡2.2 指定網段創建網絡3.創建容器3.1 指定網絡創建容器3.2 指定IP創建容器4.通信4.1 不同bridge之間是網絡隔離的4.2 不同bridge上的容器如何通信4.3 原理5.小結
1.前言
前兩節,我們創建的容器默認使用了bridge network,網橋docker0,網段是172.17.0.0/16。那能不能自己定義網絡、網段呢?
2.創建自定義網絡
Docker提供三種user-defined網絡驅動:bridge、overlay和macvlan。本章只介紹bridge方式。
創建之前,查看當前網絡,可以發現docker安裝時創建了bridge、host、none三個網絡。
[root@docker1 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
c1bb643c9c5a bridge bridge local
59364623cee2 host host local
fb704391fb47 none null local
2.1 創建網絡
執行docker network create --driver=bridge mynet1
- docker網絡 多了mynet1,驅動為bridge
[root@docker1 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
c1bb643c9c5a bridge bridge local
59364623cee2 host host local
50ffccecba76 mynet1 bridge local
fb704391fb47 none null local
- 網橋 新增了一個網橋
[root@docker1 ~]# brctl show
bridge name bridge id STP enabled interfaces
br-50ffccecba76 8000.0242c34e7ef4 no
docker0 8000.0242a8646c32 no veth535a8bb
veth895fec0
- 路由表 新增了目的地址為172.18.0.0/16的路由表
[root@docker1 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.0.1 0.0.0.0 UG 100 0 0 enp0s3
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 br-50ffccecba76
192.168.0.0 0.0.0.0 255.255.255.0 U 100 0 0 enp0s3
- 用
docker network inspect
命令查看網絡詳情
可以發現其網段是由docker指定的,為172.18.0.0/16
[root@docker1 ~]# docker network inspect mynet1
[
{
"Name": "mynet1",
"Id": "50ffccecba76af9de29d457743e6859d34b6a70b61f364a66ec15813425b1454",
"Created": "2020-04-19T21:57:34.490552328+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
......
2.2 指定網段創建網絡
執行命令docker network create --driver=bridge --subnet=172.21.21.0/24 --gateway=172.21.21.1 mynet2
創建完,路由表、網橋等發生類似的變化,且該網絡的網段和網關是我們自己指定的。
3.創建容器
分別用上面兩個網絡創建容器。
3.1 指定網絡創建容器
執行docker run -it -d --network=mynet1 --name=bbox_mynet1 busybox
,進入容器,查看其IP
[root@docker1 ~]# docker exec -it bbox_mynet1 sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
3.2 指定IP創建容器
執行docker run -it -d --network=mynet2 --ip=172.21.21.65 --name=bbox_mynet2 busybox
,進入容器,查看IP
[root@docker1 ~]# docker exec -it bbox_mynet2 sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:15:15:41 brd ff:ff:ff:ff:ff:ff
inet 172.21.21.65/24 brd 172.21.21.255 scope global eth0
valid_lft forever preferred_lft forever
注意:只有自己定義網段的網絡,才允許指定容器IP。
4.通信
當前網絡拓撲
4.1 不同bridge之間是網絡隔離的
同一個bridge上容器自然可以通信,我們不再測試。那不同bridge上呢?看樣子應該不通,畢竟網段都不一樣。但是等等,我們前面說過linux系統開啟了ip_forward,它本身就是一個路由器,我們查看一下主機的路由表:
[root@docker1 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.0.1 0.0.0.0 UG 100 0 0 enp0s3
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 br-50ffccecba76
172.21.21.0 0.0.0.0 255.255.255.0 U 0 0 0 br-757bb8fb1878
192.168.0.0 0.0.0.0 255.255.255.0 U 100 0 0 enp0s3
從路由表來看,不同bridge的容器是可以通信的。測試一下,從bbox_mynet1 ping bbox1,發現不通。
為什么呢?查看iptables,執行iptables -t filter -vnL
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
pkts bytes target prot opt in out source destination
0 0 DOCKER-ISOLATION-STAGE-2 all -- br-757bb8fb1878 !br-757bb8fb1878 0.0.0.0/0 0.0.0.0/0
0 0 DOCKER-ISOLATION-STAGE-2 all -- br-50ffccecba76 !br-50ffccecba76 0.0.0.0/0 0.0.0.0/0
33 6167 DOCKER-ISOLATION-STAGE-2 all -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0
76 9290 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
Chain DOCKER-ISOLATION-STAGE-2 (3 references)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * br-757bb8fb1878 0.0.0.0/0 0.0.0.0/0
0 0 DROP all -- * br-50ffccecba76 0.0.0.0/0 0.0.0.0/0
0 0 DROP all -- * docker0 0.0.0.0/0 0.0.0.0/0
33 6167 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
這幾條規則決定了不同bridge之間的流量被DROP了。
可見Docker設計之初就規定了不同bridge之間不能通信。
4.2 不同bridge上的容器如何通信
那如何讓兩個bridge上的容器通信呢?
現在想讓bbox_mynet1能訪問bbox1,我在bbox_mynet1里加上一塊連接docker0的網卡,如下圖:
執行命令將容器bbox_mynet1連接到網絡bridge上docker network connect bridge bbox_mynet1
(注意docker network connect docker0 bbox_mynet1是不行的,網絡名稱必須是docker network ls
查出的NAME)
查看容器bbox_mynet1的網卡,可以發現多了網卡eth1:
[root@docker1 ~]# docker exec -it bbox_mynet1 sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
16: eth1@if17: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.5/16 brd 172.17.255.255 scope global eth1
valid_lft forever preferred_lft forever
此時可以ping通bbox1
/ # ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.202 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.101 ms
4.3 原理
為什么通了呢?根據拓撲圖,很好理解,查看bbox_mynet1的路由表,里面多了一條指向172.17.0.0/16的路由,並且出口為eth1,而eth1與docker0的接口是veth pair,流量自然走到了docker0上。
/ # route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.17.0.1 0.0.0.0 UG 0 0 0 eth1
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth1
172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
5.小結
- Docker支持用戶自己創建網絡,支持指定CIDR及網關
- 在自定義CIDR的網絡上創建容器,可以指定容器IP
- 不同bridge的容器是隔離的,通過iptables Filter table實現
- 想讓不同bridge上的容器A訪問容器B,需要給容器A添加一個網卡,該網卡連接到容器B所在的bridge上
下一節,我們介紹None & Host網絡。點擊此處回到docker系列文章目錄。
作者原創,轉載請聲明出處!
本人微信公眾號同步更新雲計算、容器、網絡、編程等文章,歡迎參觀!