• docker 5种网络管理


    一、有哪五种模式网络:

    docker的网络模式大致可以分成五种类型:

    • 默认是bridge模式网络 使用–net =bridge指定,默认网络驱动程序。当你的应用程序在需要通信的独立容器中运行时,通常会使用桥接网络。

    • host模式网络 使用–net =host指定,对于独立容器,删除容器和Docker主机之间的网络隔离,并直接使用主机的网络

    • none模式网络 使用–net =none指定,对于此容器,禁用所有网络
      另外两种:

    • container模式网络 使用–net =container:指定容器名,可以多个容器共用一个网络

    • user-defined模式网络:

      • overlay模式网络 使用--net=overlay,覆盖网络将多个Docker守护程序连接在一起,并使群集服务能够相互通信。还可以使用覆盖网络来促进群集服务和独立容器之间的通信,或者在不同Docker守护程序上的两个独立容器之间进行通信
      • macvlan:Macvlan网络允许您为容器分配MAC地址,使其显示为网络上的物理设备。Docker守护程序通过其MAC地址将流量路由到容器。macvlan 在处理期望直接连接到物理网络的传统应用程序时,使用驱动程序有时是最佳选择,而不是通过Docker主机的网络堆叠进行路由

    在安装完docker之后,宿主机上会创建三个网络:
    默认docker主机会存在三种类型的网络,可以使用docker network ls命令查看

    [root@VM_0_6_centos ~]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    f88b1c490d20        bridge              bridge              local
    0954ad9627bc        host                host                local
    7dbe186a84e8        none                null                local
    
    

    1.bridge模式网络

    容器的默认网络模式,docker在安装时会创建一个名为docker0的Linux bridge,在不指定--network的情况下,创建的容器都会默认挂到docker0上面
    
    在该模式(见下图)中,Docker守护进程创建了一个虚拟以太网桥`docker0`,附加在其上的任何网卡之间都能自动转发数据包。默认情况下,守护进程会创建一对对等接口,将其中一个接口设置为容器的eth0接口,另一个接口放置在宿主机的命名空间中,从而将宿主机上的所有容器都连接到这个内部网络上。同时,守护进程还会从网桥的私有地址空间中分配一个IP地址和子网给该容器
    

    1.1 如,docker主机会有一个默认使用的桥接网卡bridge0,它是在运行docker容器时,如果不指定网络,默认使用的网络:docker0

    [root@VM_0_6_centos ~]# ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 52:54:00:69:06:60 brd ff:ff:ff:ff:ff:ff
        inet 172.16.0.6/20 brd 172.16.15.255 scope global eth0
           valid_lft forever preferred_lft forever
        inet6 fe80::5054:ff:fe69:660/64 scope link 
           valid_lft forever preferred_lft forever
    3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
        link/ether 02:42:74:13:f5:ff brd ff:ff:ff:ff:ff:ff
        inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
           valid_lft forever preferred_lft forever
        inet6 fe80::42:74ff:fe13:f5ff/64 scope link 
           valid_lft forever preferred_lft forever
    

    1.2 当运行一个容器时,我们可以看到在docker主机上多了一个网卡(vethd579570@if38),而且master指向docker0

    [root@VM_0_6_centos ~]# docker run -d -P --net=bridge nginx:1.9.1
    59abbf7dbeedf974349fd971970300e311d4ff56aef7e17f8071ec84e8b8e795
    [root@VM_0_6_centos ~]# ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 52:54:00:69:06:60 brd ff:ff:ff:ff:ff:ff
        inet 172.16.0.6/20 brd 172.16.15.255 scope global eth0
           valid_lft forever preferred_lft forever
        inet6 fe80::5054:ff:fe69:660/64 scope link 
           valid_lft forever preferred_lft forever
    3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
        link/ether 02:42:74:13:f5:ff brd ff:ff:ff:ff:ff:ff
        inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
           valid_lft forever preferred_lft forever
        inet6 fe80::42:74ff:fe13:f5ff/64 scope link 
           valid_lft forever preferred_lft forever
    39: vethd579570@if38: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
        link/ether 7e:79:90:55:97:1d brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet6 fe80::7c79:90ff:fe55:971d/64 scope link 
           valid_lft forever preferred_lft forever
    
    因为bridge模式是Docker的默认设置,所以你也可以使用`docker run -d -P nginx:1.9.1`。如果你没有使用-P(发布该容器暴露的所有端口)或者-p
    host_port:container_port(发布某个特定端口),IP数据包就不能从宿主机之外路由到容器中。
    

    1.3 这时候我们在查看该容器的网络信息(ip地址和网关)。发现它的ip地址和docker0一个网段,网关则是docker0的地址

    [root@VM_0_6_centos ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                           NAMES
    59abbf7dbeed        nginx:1.9.1         "nginx -g 'daemon of…"   About a minute ago   Up About a minute   0.0.0.0:32771->80/tcp, 0.0.0.0:32770->443/tcp   competent_cori
    [root@VM_0_6_centos ~]# docker inspect -f {{".NetworkSettings.Networks.bridge.IPAddress"}} 59abbf7dbeed
    172.17.0.2
    [root@VM_0_6_centos ~]# docker inspect -f {{".NetworkSettings.Networks.bridge.Gateway"}} 59abbf7dbeed
    172.17.0.1
    

    1.4 bridge网络的特点

    使用一个 linux bridge,默认为 docker0
    使用veth 对,一头在容器的网络 namespace中,一头在docker0上
    该模式下Docker Container不具有一个公有IP,因为宿主机的IP地址与veth pair的IP地址不在同一个网段内
    Docker采用NAT方式,将容器内部的服务监听的端口与宿主机的某一个端口进行“绑定”,使得宿主机以外的世界可以主动将网络报文发送至容器内部
    外界访问容器内的服务时,需要访问宿主机的 IP 以及宿主机的端口 port
    NAT 模式由于是在三层网络上的实现手段,故肯定会影响网络的传输效率。
    容器拥有独立、隔离的网络栈;让容器和宿主机以外的世界通过NAT建立通信
    

    我们查看iptables的nat表,可以看到,在POSTROUTING链上做了一个MASQUERADE,源是172.17.0.0/1

    2.host模式网络

    该模式将禁用Docker容器的网络隔离。因为容器共享了宿主机的网络命名空间,直接暴露在公共网络中。因此,你需要通过端口映射(port mapping)来进行协调。

    通过命令--network=host指定,使用host模式的容器可以直接使用docker host的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好

    2.1 Host模式并没有为容器创建一个隔离的网络环境。该模式下的Docker容器会和host宿主机共享同一个网络namespace,所以容器可以和宿 主机一样,使用宿主机的eth0,实现和外界的通信。

    特点:

    这种模式下的容器没有隔离的network namespace
    容器的IP地址同 Docker主机的IP地址
    需要注意容器中服务的端口号不能与Docker主机上已经使用的端口号相冲突
    host模式能够和其它模式共存
    

    2.2 首先我通过ss查看一下,我的docker主机80端口并没有使用。当我启动一个提供nginx应用的容器时,在查看发现我的主机使用了80端口

    [root@VM_0_6_centos ~]# ss -lnt |grep 80
    [root@VM_0_6_centos ~]# docker run -itd --privileged --name nginx001 --network host nginx:latest
    Unable to find image 'nginx:latest' locally
    latest: Pulling from library/nginx
    f5d23c7fed46: Already exists 
    918b255d86e5: Pull complete 
    8c0120a6f561: Pull complete 
    Digest: sha256:eb3320e2f9ca409b7c0aa71aea3cf7ce7d018f03a372564dbdb023646958770b
    Status: Downloaded newer image for nginx:latest
    c7ea10aa92dd09b312f844aa70a359861c8da8d4eea2bbae2353505008beea27
    [root@VM_0_6_centos ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                           NAMES
    c7ea10aa92dd        nginx:latest        "nginx -g 'daemon of…"   About a minute ago   Up About a minute                                                   nginx001
    [root@VM_0_6_centos ~]# ss -lnt |grep 80
    LISTEN     0      128          *:80                       *:*                  
    

    2.3 我们还可以通过docker inspect nginx001查看它的网络信息。发现IP地址和网关处根本没有值。因为使用了host网络,它是共用了docker主机的网络

    [rootVM_0_6_centos ~]# docker inspect -f {{".NetworkSettings.Networks.bridge.IPAddress"}} nginx001
    <no value>
    [root@VM_0_6_centos ~]# docker inspect -f {{".NetworkSettings.Networks.bridge.Gateway"}} nginx001
    <no value>
    

    2.4 再例如:

    [root@VM_0_6_centos ~]# docker run -d --net=host ubuntu:14.04 tail -f /dev/null
    Unable to find image 'ubuntu:14.04' locally
    14.04: Pulling from library/ubuntu
    a7344f52cb74: Pull complete 
    515c9bb51536: Pull complete 
    e1eabe0537eb: Pull complete 
    4701f1215c13: Pull complete 
    Digest: sha256:2f7c79927b346e436cc14c92bd4e5bd778c3bd7037f35bc639ac1589a7acfa90
    Status: Downloaded newer image for ubuntu:14.04
    cb5860bbcf61d006c9654cb4678fe3a2b9cb93c2f09cc84da142113d245b6e83
    [root@VM_0_6_centos ~]#  ip addr | grep -A 2 eth0:
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 52:54:00:69:06:60 brd ff:ff:ff:ff:ff:ff
        inet 172.16.0.6/20 brd 172.16.15.255 scope global eth0
    
    [root@VM_0_6_centos ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                           NAMES
    cb5860bbcf61        ubuntu:14.04        "tail -f /dev/null"      About a minute ago   Up 59 seconds                                                       hungry_payne
    [root@VM_0_6_centos ~]# docker exec -it cb5860bbcf61 ip addr
    inet 172.16.0.6/20 brd 172.16.15.255 scope global eth0
    
    

    我们可以从上例中看到:容器和宿主机具有相同的IP地址172.16.0.6

    在下图中,我们可以看到:当使用host模式网络时,容器实际上继承了宿主机的IP地址。该模式比bridge模式更快(因为没有路由开销),但是它将容器直接暴露在公共网络中,是有安全隐患的

    3.none模式网络

    这种网络模式下容器只有lo回环网络,没有其他网卡。none网络可以在容器创建时通过--network=none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。一旦 Docker Container 采用了none网络模式,那么容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。在没有网络配置的情况下,作为 Docker 开发者,才能在这基础做其他无限多可能的网络定制开发。

    3.1 在 none 网络模式下分配固定 ip:
    netns 是在 linux 中提供网络虚拟化的一个项目,使用 netns 网络空间虚拟化可以在本地虚拟化出多个网络环境,目前 netns 在 lxc 容器中被用来为容器提供网络。使用 netns 创建的网络空间独立于当前系统的网络空间,其中的网络设备以及 iptables 规则等都是独立的,就好像进入了另外一个网络一样

    [root@VM_0_6_centos ~]# docker run -it --name vm5 --net none ubuntu
    
    

    3.2 这种方式创建没有网络,可以自己指定设置网络

    [root@VM_0_6_centos ~]# ip addr
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    

    4.container模式网络 共享模式

    用于容器和容器直接频繁交流的情况。

    这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。

    创建容器时使用--network=container:NAME_or_ID这个模式在创建新的容器的时候指定容器的网络和一个已经存在的容器共享一个Network Namespace,但是并不为docker容器进行任何网络配置,这个docker容器没有网卡、IP、路由等信息,需要手动的去为docker容器添加网卡、配置IP等

    (1) 查找 other container(即需要被共享网络环境的容器)的网络 namespace;
    (2) 将新创建的 Docker Container(也是需要共享其他网络的容器)的 namespace,使用
    other container 的 namespace。
    Docker Container 的 other container 网络模式,可以用来更好的服务于容器间的通信。
    在这种模式下的 Docker Container 可以通过 localhost 来访问 namespace 下的其他容器,传输
    效率较高。虽然多个容器共享网络环境,但是多个容器形成的整体依然与宿主机以及其他
    容器形成网络隔离。另外,这种模式还节约了一定数量的网络资源。但是需要注意的是,

    它并没有改善容器与宿主机以外世界通信的情况

    4.1 创建一个nat模式,看一下这个容器ip:

    [root@VM_0_6_centos ~]# docker run -it --name busyboxl busybox sh
    / # ip addr
    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
    34: eth0@if35: <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 eth0
           valid_lft forever preferred_lft forever
    / # hostname
    d9e5c9ad1193
    / # 
    

    4.2 创建一个container网络模式的ip,创建完成后,可以看到这两个ip地址是一模一样的,并且是可以直接通信的

    [root@VM_0_6_centos ~]# docker run -it --name busybox2 --net=container:busybox1 busybox sh
    docker: Error response from daemon: cannot join network of a non running container: 4d33b98101f85aa77e576967c64d8b83b535f99d22d82a89bdd62b15f3f96070.
    [root@VM_0_6_centos ~]# ip addr
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 52:54:00:69:06:60 brd ff:ff:ff:ff:ff:ff
        inet 172.16.0.6/20 brd 172.16.15.255 scope global eth0
           valid_lft forever preferred_lft forever
        inet6 fe80::5054:ff:fe69:660/64 scope link 
           valid_lft forever preferred_lft forever
    3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
        link/ether 02:42:74:13:f5:ff brd ff:ff:ff:ff:ff:ff
        inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
           valid_lft forever preferred_lft forever
        inet6 fe80::42:74ff:fe13:f5ff/64 scope link 
           valid_lft forever preferred_lft forever
    

    4.3 确认是两个容器:

    [root@VM_0_6_centos ~]# docker ps -a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                          PORTS               NAMES
    1af412b5e1d7        busybox             "sh"                58 seconds ago      Created                                             busybox2
    4d33b98101f8        busybox             "sh"                2 minutes ago       Exited (0) About a minute ago                       busybox1
    

    4.4 None,不会创建网络,里面就不会有ip,最常用的是nat模式和container网络模式,container网络模式用于容器和容器直接频繁交流的情况。

    [root@VM_0_6_centos ~]# docker run -it --name none --net=none busybox sh
    / # ip addr
    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
    / # 
    

    5.user-defined模式

    用户自定义模式主要可选的有三种网络驱动:bridge、overlay、macvlan。bridge驱动用于创建类似于前面提到的bridge网络;overlay和macvlan驱动用于创建跨主机的网络。

    二、外部网络访问容器内应用

    1.-P随机指定一个docker主机端口给容器中的端口做映射

    [root@VM_0_6_centos ~]# docker run -itd -P --name nginx001 nginx:latest
    b718bc214f766d154b0608819edac97da066e1edbf1617125d4b707ac4b5c6e4
    [root@VM_0_6_centos ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
    b718bc214f76        nginx:latest        "nginx -g 'daemon of…"   8 seconds ago       Up 7 seconds        0.0.0.0:32772->80/tcp   nginx001
    [root@VM_0_6_centos ~]# 
    

    2.-p将docker主机的一个端口映射容器的一个端口

    [root@VM_0_6_centos ~]# docker run -itd -p 8000:80 --name nginx002 nginx:latest
    bb4cce60ff9da6c7e57d24f0a4d63921925e8990a3172c613d25865eb8b8ab50
    
    [root@VM_0_6_centos ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
    bb4cce60ff9d        nginx:latest        "nginx -g 'daemon of…"   13 seconds ago      Up 13 seconds       0.0.0.0:8000->80/tcp    nginx002
    b718bc214f76        nginx:latest        "nginx -g 'daemon of…"   2 minutes ago       Up 2 minutes        0.0.0.0:32772->80/tcp   nginx001
    [root@VM_0_6_centos ~]# 
    

    访问网站测试(我的docker主机的地址为129.204.207.***,记住要在docker主机上放行32772和8000端口)

    首先访问32768端口:129.204.207.***:32772
    访问8000端口。(都可以正常提供服务)

    三、用户自定义网络

    通过docker network create --driver network_type network_name命令即可创建自定义网络。其中--driver后面支持的类型有三种:bridge、macvlan、overlay

    [root@VM_0_6_centos ~]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    f88b1c490d20        bridge              bridge              local
    0954ad9627bc        host                host                local
    7dbe186a84e8        none                null                local
    
    [root@VM_0_6_centos ~]# ip a
    
    [root@VM_0_6_centos ~]# docker network create --driver bridge my_bridge
    326493de5458416e3a1ccbceea5e03760268ae3412c9fe78fe551dadbfc53c95
    
    [root@VM_0_6_centos ~]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    f88b1c490d20        bridge              bridge              local
    0954ad9627bc        host                host                local
    326493de5458        my_bridge           bridge              local
    7dbe186a84e8        none                null                local
    [root@VM_0_6_centos ~]# ip a
    
    

    通过docker network inspect network_name可以查看该网络的信息

    [root@VM_0_6_centos ~]# docker network inspect my_bridge
    [
        {
            "Name": "my_bridge",
            "Id": "326493de5458416e3a1ccbceea5e03760268ae3412c9fe78fe551dadbfc53c95",
            "Created": "2019-08-06T15:16:08.50367479+08:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": {},
                "Config": [
                    {
                        "Subnet": "172.18.0.0/16",
                        "Gateway": "172.18.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {},
            "Options": {},
            "Labels": {}
        }
    ]
    

    而且通过ip addr可以看到自动在docker主机上创建了一个网卡

    [root@VM_0_6_centos ~]# ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 52:54:00:69:06:60 brd ff:ff:ff:ff:ff:ff
        inet 172.16.0.6/20 brd 172.16.15.255 scope global eth0
           valid_lft forever preferred_lft forever
        inet6 fe80::5054:ff:fe69:660/64 scope link 
           valid_lft forever preferred_lft forever
    3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
        link/ether 02:42:74:13:f5:ff brd ff:ff:ff:ff:ff:ff
        inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
           valid_lft forever preferred_lft forever
        inet6 fe80::42:74ff:fe13:f5ff/64 scope link 
           valid_lft forever preferred_lft forever
    41: vethd9e30c6@if40: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
        link/ether ca:e9:0a:6d:c6:09 brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet6 fe80::c8e9:aff:fe6d:c609/64 scope link 
           valid_lft forever preferred_lft forever
    43: veth2946b2c@if42: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
        link/ether 02:65:c5:d4:31:e6 brd ff:ff:ff:ff:ff:ff link-netnsid 1
        inet6 fe80::65:c5ff:fed4:31e6/64 scope link 
           valid_lft forever preferred_lft forever
    44: br-326493de5458: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
        link/ether 02:42:00:7c:2f:07 brd ff:ff:ff:ff:ff:ff
        inet 172.18.0.1/16 brd 172.18.255.255 scope global br-326493de5458
           valid_lft forever preferred_lft forever
    
    

    查看主机的 NAT 规则:
    再次查看我们nat表,也可以看到在POSTROUTING上做的MASQUERADE

    [root@VM_0_6_centos ~]#  iptables -t nat -vnL
    Chain POSTROUTING (policy ACCEPT 198 packets, 12868 bytes)
     pkts bytes target     prot opt in     out     source               destination         
        0     0 MASQUERADE  all  --  *      !br-326493de5458  172.18.0.0/16        0.0.0.0/0 
    

    这样我们就可以运行容器使用该网络了

    [root@VM_0_6_centos ~]# docker run -itd --name=nginx001 --network my_bridge nginx
    0200f80a916ad188be333232d8eed64c87f19b4c9229c948bc6de1376bd76125
    [root@VM_0_6_centos ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
    0200f80a916a        nginx               "nginx -g 'daemon of…"   6 seconds ago       Up 5 seconds        80/tcp              nginx001
    [root@VM_0_6_centos ~]# docker inspect -f {{".NetworkSettings.Networks.bridge.Gateway"}} nginx001
    172.18.0.1
    [root@VM_0_6_centos ~]# docker inspect -f {{".NetworkSettings.Networks.bridge.IPAddress"}} nginx001
    172.18.0.2
    

    四、docker network管理命令的使用

    1.基本使用:

    # 创建一个网络
    [root@VM_0_6_centos ~]# docker network create --driver bridge bridge_1
    b3a6a2b1063dcca0e6dd26d92c60fbb0dc7ba8bf5b55dff9fb10849343d28b0d
    
    # 查看所有网络
    [root@VM_0_6_centos ~]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    f88b1c490d20        bridge              bridge              local
    b3a6a2b1063d        bridge_1            bridge              local
    0954ad9627bc        host                host                local
    326493de5458        my_bridge           bridge              local
    7dbe186a84e8        none                null                local
    
    # 断开一个网路的连接
    [root@VM_0_6_centos ~]# docker network disconnect bridge_1
    "docker network disconnect" requires exactly 2 arguments.
    See 'docker network disconnect --help'.
    
    Usage:  docker network disconnect [OPTIONS] NETWORK CONTAINER
    
    Disconnect a container from a network
    
    #连接一个网络
    [root@VM_0_6_centos ~]# docker network connect bridge_1
    "docker network connect" requires exactly 2 arguments.
    See 'docker network connect --help'.
    
    Usage:  docker network connect [OPTIONS] NETWORK CONTAINER
    
    Connect a container to a network
    
    # 删除一个网络
    [root@VM_0_6_centos ~]# docker network rm bridge_1
    bridge_1
    
    # 查看所有网络
    [root@VM_0_6_centos ~]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    f88b1c490d20        bridge              bridge              local
    0954ad9627bc        host                host                local
    326493de5458        my_bridge           bridge              local
    7dbe186a84e8        none                null                local
    [root@VM_0_6_centos ~]# 
    

    2.显示一个网络的信息:

    [root@VM_0_6_centos ~]# docker inspect host
    [
        {
            "Name": "host",
            "Id": "0954ad9627bc02e971eb92c9f625dced9c86d994d09217d5fbc609aa4efc608d",
            "Created": "2019-07-30T18:03:34.674156886+08:00",
            "Scope": "local",
            "Driver": "host",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": null,
                "Config": []
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {},
            "Options": {},
            "Labels": {}
        }
    ]
    
    

    五、跨主机docker容器通信方案介绍

    1.基于实现方式的分类

    隧道方案(Overlay Networking):
    Weave:UDP广播,本机建立新的BR,通过PCAP互通。
    Open vSwitch(OVS):基于VxLAN和GRE协议,但是性能方面损失比较严重。
    Flannel:UDP广播,VxLan。
    
    路由方案:
    Calico:基于BGP协议的路由方案,支持很细致的ACL控制,对混合云亲和度比较
    高。
    Macvlan:从逻辑和Kernel层来看隔离性和性能最优的方案,基于二层隔离,所以
    需要二层路由器支持,大多数云服务商不支持,所以混合云上比较难以实现。
    

    2.基于网络模型分类

    Docker Libnetwork Container Network Model(CNM):
    Docker Swarm overlay
    Macvlan & IP network drivers
    Calico
    Contiv(from Cisco)
    ##Docker Libnetwork的优势就是原生,而且和Docker容器生命周期结合紧密;缺点也可以理解为是原生,被Docker“绑架”。
    
    Container Network Interface(CNI):
    Kubernetes
    Weave
    Macvlan
    Flannel
    Calico
    Contiv
    Mesos CNI
    ##CNI的优势是兼容其他容器技术(e.g. rkt)及上层编排系统(Kuberneres & Mesos),而且社区活
    跃势头迅猛,Kubernetes加上CoreOS主推;缺点是非Docker原生。
    

    3.以Flannel方案为例

    Flannel之前的名字是Rudder,它是由CoreOS团队针对Kubernetes设计的一个重载网络工具,它的主要思路是:预先留出一个网段,每个主机使用其中一部分,然后每个容器被分配不同的ip;让所有的容器认为大家在同一个直连的网络,底层通过UDP/VxLAN等进行报文的封装和转发。
    下面这张是Flannel网络的经典架构图(从网上找的)


     
    Flannel网络1.png
    1. 容器直接使用目标容器的ip访问,默认通过容器内部的eth0发送出去。 
    2. 报文通过veth pair被发送到vethXXX。 
    3. vethXXX是直接连接到虚拟交换机docker0的,报文通过虚拟bridge docker0发送出去。 
    4. 查找路由表,外部容器ip的报文都会转发到flannel0虚拟网卡,这是一个P2P的虚拟网卡,然后报文就被转发到监听在另一端的flanneld。 
    5. flanneld通过etcd维护了各个节点之间的路由表,把原来的报文UDP封装一层,通过配置的iface发送出去。 
    6. 报文通过主机之间的网络找到目标主机。 
    7. 报文继续往上,到传输层,交给监听在8285端口的flanneld程序处理。 
    8. 数据被解包,然后发送给flannel0虚拟网卡。 
    9. 查找路由表,发现对应容器的报文要交给docker0。 
    10. docker0找到连到自己的容器,把报文发送过去


    作者:宇宙小神特别萌
    链接:https://www.jianshu.com/p/f592fef67f04
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    es组合多个条件进行查询
    Sidecar模式:下一代微服务架构的关键
    排查python内存泄露中几个工具的使用
    Consul的反熵
    我的Linux操作系统的发行版是什么?版本号是什么?
    如何确定一台linux主机是Linux (i386/i686)还是Linux (x86_64)
    如何确定Isilon cluster的网卡类型是40GbE的还是10GbE的
    如何确定Isilon里的磁盘是多大的?
    用SSH登录远程的机器,在远程机器上执行本地机器上的脚本
    关于EOF的使用的好文章
  • 原文地址:https://www.cnblogs.com/ip99/p/13280002.html
Copyright © 2020-2023  润新知