Docker-Bridge Network 03 自定義網絡

本節介紹自定義bridge network的自定義網絡。html

1.前言2.建立自定義網絡2.1 建立網絡2.2 指定網段建立網絡3.建立容器3.1 指定網絡建立容器3.2 指定IP建立容器4.通訊4.1 不一樣bridge之間是網絡隔離的4.2 不一樣bridge上的容器如何通訊4.3 原理5.小結linux

1.前言

  前兩節,咱們建立的容器默認使用了bridge network,網橋docker0,網段是172.17.0.0/16。那能不能本身定義網絡、網段呢?web

2.建立自定義網絡

  Docker提供三種user-defined網絡驅動:bridge、overlay和macvlan。本章只介紹bridge方式。
  建立以前,查看當前網絡,能夠發現docker安裝時建立了bridge、host、none三個網絡。docker

[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 mynet1shell

  • 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,進入容器,查看IPapp

[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。oop

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系列文章目錄

 

 做者原創,轉載請聲明出處!


本人微信公衆號同步更新雲計算、容器、網絡、編程等文章,歡迎參觀!

相關文章
相關標籤/搜索