• Docker-Bridge Network 03 自定义网络


    本节介绍自定义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系列文章目录

     

     作者原创,转载请声明出处!


    本人微信公众号同步更新云计算、容器、网络、编程等文章,欢迎参观!

  • 相关阅读:
    Java的类演进过程
    P112、面试题16:反转链表
    P107、面试题15:链表中倒数第K个结点
    Java对象相关元素的初始化过程
    P102、面试题14:调整数组顺序使奇数位于偶数前面
    P99、面试题13:在o(1)时间删除链表结点
    面试常考的数据结构Java实现
    Linux命令面试常考的简单汇总
    操作系统与进程基础知识
    python--process
  • 原文地址:https://www.cnblogs.com/sunqingliang/p/12741387.html
Copyright © 2020-2023  润新知