• Docker网络


    1. docker网络介绍

      大量的互联网应用服务需要多个服务组件,这往往需要多个容器之间通过网络通信进行相互配合。

      docker 网络从覆盖范围可分为单个 host 上的容器网络和跨多个 host 的网络。

      docker 目前提供了映射容器端口到宿主主机和容器互联机制(映射)来为容器提供网络服务,在启动容器的时候,如果不指定参数,在容器外部是没有办法通过网络来访问容器内部的网络应用和服务的。

    docker 安装时会自动在host上创建三个网络,查看一下docker网络:

    [root@alph ~]# docker network ls
    NETWORK ID       NAME            DRIVER            SCOPE
    59cb3737df3c        bridge              bridge              local
    8b9081147227        host                host                local
    ea6732b465e8        none                null                local
    [root@alph ~]#

    2. docker none网络

           none 网络就是什么都没有的网络。挂在这个网络下的容器除了 lo(本地回环地址),没有其他任何网卡。容器创建时,可以通过 --network=none 指定使用 none 网络

    启动容器:
    [root@alph ~]# docker run -itd --network=none --name box reg.yunwei.edu/learn/httpd:latest
    18f6521f1ae21775203a3d0efe40b62082a4edb637e074292ab6f6e665cee361
    
    查看:
    18f6521f1ae21775203a3d0efe40b62082a4edb637e074292ab6f6e665cee361
    [root@alph ~]# docker ps -a
    CONTAINER ID        IMAGE                               COMMAND              CREATED             STATUS              PORTS               NAMES
    18f6521f1ae2        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   7 seconds ago       Up 7 seconds                            box
     
    进入容器:
    [root@alph ~]# docker exec -it 18f6521f1ae2 /bin/bash
    
    查看ip
    root@18f6521f1ae2:/usr/local/apache2# ip a            #仅有lo
    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
    root@18f6521f1ae2:/usr/local/apache2# ^C
    root@18f6521f1ae2:/usr/local/apache2#

    none 网络的应用

      封闭的网络意味着隔离,一些对安全性要求高并且不需要联网的应用可以使用 none 网络。

      比如某个容器的唯一用途是生成随机密码,就可以放到 none 网络中避免密码被窃取。

    3. host网络

           连接到 host 网络的容器,共享 docker host 的网络栈,容器的网络配置与 host 完全一样。可以通过 --network=host 指定使用 host 网络。

    [root@alph ~]# docker run -itd --network=host --name box2  reg.yunwei.edu/learn/httpd:latest
    [root@alph ~]# docker ps -a
    CONTAINER ID        IMAGE                               COMMAND              CREATED             STATUS              PORTS               NAMES
    d478bbdb1ef8        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   23 seconds ago      Up 22 seconds                           box2
    18f6521f1ae2        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   About an hour ago   Up About an hour                        box
    
    [root@alph ~]# docker exec -it d478bbdb1ef8 /bin/sh 
    # 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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 00:50:56:37:0c:29 brd ff:ff:ff:ff:ff:ff
        inet 192.168.16.88/24 brd 192.168.16.255 scope global noprefixroute ens33
           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:25:8a:98:c6 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:25ff:fe8a:98c6/64 scope link
           valid_lft forever preferred_lft forever
    # hostname 
    alph

           在容器中可以看到 host 的所有网卡,并且连 hostname 也是 host 的。

      直接使用 Docker host 的网络最大的好处就是性能,如果容器对网络传输效率有较高要求,就可以选择 host 网络。

      当然不便之处就是牺牲一些灵活性,比如要考虑端口冲突问题,Docker host 上已经使用的端口就不能再用了。

      Docker host 的另一个用途是让容器可以直接配置 host 网路。比如某些跨 host 的网络解决方案,其本身也是以容器方式运行的,这些方案需要对网络进行配置,比如管理 iptables。

    4. docker bridge 网络

           docker 安装时会创建一个 命名为 docker0 的 linux bridge。如果不指定--network,创建的容器默认都会挂到 docker0 上。

    [root@alph ~]# brctl show
    bridge name     bridge id       STP enabled     interfaces
    docker0         8000.0242258a98c6       no

           当前docker0 上没有其他网络设备,创建一个容器查看变化。

    [root@alph ~]# docker run -itd  --name box3  reg.yunwei.edu/learn/httpd:latest  5ddc5295e266aaf49c897710ccbb1e02273f49b15afd1bdfb8f4dfffc1de9dfe
    [root@alph ~]# docker ps -a
    CONTAINER ID        IMAGE                               COMMAND              CREATED             STATUS              PORTS               NAMES
    5ddc5295e266        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   17 seconds ago      Up 17 seconds       80/tcp              box3
    d478bbdb1ef8        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   9 minutes ago       Up 9 minutes                            box2
    18f6521f1ae2        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   About an hour ago   Up About an hour                        box
    [root@alph ~]# docker exec -it 5ddc5295e266 /bin/bash
    root@5ddc5295e266:/usr/local/apache2# 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
    6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
        link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
        inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
           valid_lft forever preferred_lft forever
    [root@alph ~]# brctl show
    bridge name     bridge id       STP enabled     interfaces
    docker0         8000.0242258a98c6       no          vethaecb9c8

      一个新的网络接口 vethaecb9c8 被挂到了 docker0 上,vethaecb9c8就是新创建容器的虚拟网卡。eth0@if7和vethaecb9c8是一对 veth pair。veth pair 是一种成对出现的特殊网络设备,可以把它们想象成由一根虚拟网线连接起来的一对网卡,网卡的一头(eth0@if7)在容器中,另一头(vethaecb9c8)挂在网桥 docker0 上,其效果就是将 eth0@if7 也挂在了 docker0 上。

           eth0@if7已经配置了ip 172.17.0.2/16,这个网段有配置信息network inspect bridge 决定。

    [root@alph ~]# docker network inspect bridge
    [
        {
            "Name": "bridge",
            "Id": "59cb3737df3cea7308084fb5c112836f55520e8546cd7e7603949ab4db36a0e4",
            "Created": "2019-07-15T22:10:23.832317973+08:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": null,
                "Config": [
                    {
                        "Subnet": "172.17.0.0/16",
                        "Gateway": "172.17.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {
                "5ddc5295e266aaf49c897710ccbb1e02273f49b15afd1bdfb8f4dfffc1de9dfe": {
                    "Name": "box3",
                    "EndpointID": "cb51e0323762eed6e4ea588cf64f9b0f06ffc79642c71e98008e54b3a3923341",
                    "MacAddress": "02:42:ac:11:00:02",
                    "IPv4Address": "172.17.0.2/16",
                    "IPv6Address": ""
                }
            },
            "Options": {
                "com.docker.network.bridge.default_bridge": "true",
                "com.docker.network.bridge.enable_icc": "true",
                "com.docker.network.bridge.enable_ip_masquerade": "true",
                "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
                "com.docker.network.bridge.name": "docker0",
                "com.docker.network.driver.mtu": "1500"
            },
            "Labels": {}
        }
    ]

    5. 自定义创建网络

      可通过 bridge 驱动创建类似前面默认的 bridge 网络

     

    (1)利用bridge驱动创建名为my-net2网桥(docker会自动分配网段):

    [root@alph ~]# docker network create --driver bridge my-net2
    966e69c70ce3eb189be4d993f97e6c572b470f7c74f8104059e27bd04cf9c95a

    (2)查看一下当前 host 的网络结构变化:

    [root@alph ~]# docker network list
    NETWORK ID          NAME                DRIVER              SCOPE
    59cb3737df3c        bridge              bridge              local
    8b9081147227        host                host                local
    966e69c70ce3        my-net2             bridge              local
    ea6732b465e8        none                null                local

    (3)查看容器bridge网桥配置(bridge就是容器和网桥形成一对veth pair)

    [root@alph ~]# docker network inspect bridge   my-net2
        {
            "Name": "my-net2",
            "Id": "966e69c70ce3eb189be4d993f97e6c572b470f7c74f8104059e27bd04cf9c95a",
            "Created": "2019-07-16T02:25:29.664999007+08:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": {},
                "Config": [
                    {
                        "Subnet": "172.18.0.0/16",  #16为掩码。提供更多的服务
                        "Gateway": "172.18.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {},
            "Options": {},
            "Labels": {}
        }
    ]

           删除网络用命令 rm

    [root@alph ~]# docker network create --driver bridge my-net3
    596fc585538f6862425300dcdc35b62a759f8b11feb249d142492c5519a6a0c2
    [root@alph ~]# docker network list
    NETWORK ID          NAME                DRIVER              SCOPE
    59cb3737df3c        bridge              bridge              local
    8b9081147227        host                host                local
    966e69c70ce3        my-net2             bridge              local
    596fc585538f        my-net3             bridge              local
    ea6732b465e8        none                null                local
    [root@alph ~]# docker rm my-net3
    Error: No such container: my-net3
    [root@alph ~]# docker network  rm my-net3 
    my-net3
    [root@alph ~]# docker network list
    NETWORK ID          NAME                DRIVER              SCOPE
    59cb3737df3c        bridge              bridge              local
    8b9081147227        host                host                local
    966e69c70ce3        my-net2             bridge              local
    ea6732b465e8        none                null                local

    (4)利用bridge驱动创建名为my-net3网桥(用户自定义网段及网关)

    [root@alph ~]# docker run -itd --network=my-net3 --name box4 reg.yunwei.edu/learn/httpd:latest
    1fd7e0d3e08345da6e7259fbf6dcb0bf95861ec457236e81125737840032c539
    [root@alph ~]# docker ps -a
    CONTAINER ID        IMAGE                               COMMAND              CREATED             STATUS              PORTS               NAMES
    1fd7e0d3e083        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   18 seconds ago      Up 17 seconds       80/tcp              box4
    5ddc5295e266        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   About an hour ago   Up About an hour    80/tcp              box3
    d478bbdb1ef8        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   About an hour ago   Up About an hour                        box2
    18f6521f1ae2        reg.yunwei.edu/learn/httpd:latest   "httpd-foreground"   2 hours ago         Up 2 hours                              box

    (5)启动容器使用新建的my-net3网络

    [root@alph ~]# docker exec -it box4
    "docker exec" requires at least 2 arguments.
    See 'docker exec --help'.
    Usage:  docker exec [OPTIONS] CONTAINER COMMAND [ARG...] [flags]
    Run a command in a running container
    [root@alph ~]# docker exec -it box4 /bin/sh
    # 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
    19: eth0@if20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
        link/ether 02:42:ac:16:01:02 brd ff:ff:ff:ff:ff:ff
        inet 172.22.1.2/24 brd 172.22.1.255 scope global eth0     #自定义的网段
           valid_lft forever preferred_lft forever

    (6)启动容器使用my-net3网络并指定ip(只有使用 --subnet 创建的网络才能指定静态 IP,如果是docker自动分配的网段不可以指定ip)

    [root@alph ~]# docker run -it --network=my-net3 --ip 172.22.1.10 reg.yunwei.edu/learn/httpd:latest /bin/sh
    # 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
    21: eth0@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
        link/ether 02:42:ac:16:01:0a brd ff:ff:ff:ff:ff:ff
        inet 172.22.1.10/24 brd 172.22.1.255 scope global eth0
           valid_lft forever preferred_lft forever

    (7)让已启动不同vlan的box容器,可以连接到my-net2(其实在box中新建了my-net2的网卡)

    [root@alph ~]# docker network connect my-net2 box4
    [root@alph ~]# docker exec -it box4 /bin/sh
    # 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
    19: eth0@if20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
        link/ether 02:42:ac:16:01:02 brd ff:ff:ff:ff:ff:ff
        inet 172.22.1.2/24 brd 172.22.1.255 scope global eth0
           valid_lft forever preferred_lft forever
    23: eth1@if24: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default                     #连接到box2的网卡
        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 eth1
           valid_lft forever preferred_lft forever
    #

    (8)使用--name指定启动容器名字,可以使用docker自带DNS通信,但只能工作在user-defined 网络,默认的 bridge 网络是无法使用 DNS 的。

    docker run -it --network=my_net2 --name=bbox1 busybox
    docker run -it --network=my_net2 --name=bbox2 busybox

     (9)容器之间的网络互联

      a). 首先创建一个 db 容器

    [root@alph ~]#  docker run -dti --name db reg.yunwei.edu/learn/centos:7
    2b9cdc455352f8a5e2da50db61fef706089f4abe7ba7c4b91033cc2a55a55bf8

     b). 创建一个 web 容器,并使其连接到 db  

    [root@alph ~]# docker run -dti --name web --link db:dblink  reg.yunwei.edu/learn/centos:7 /bin/bash
    40bba17b3dfe2ad01d6b80d78230c975e127340170d15a49e8f7c905bbd075fe

    -link db:dblink 实际是连接对端的名字和这个链接的名字,也就是和 db 容器建立一个叫做 dblink 的链接

      c). 查看链接的情况

    [root@alph ~]# docker ps -a
    CONTAINER ID        IMAGE                               COMMAND              CREATED              STATUS                      PORTS               NAMES
    40bba17b3dfe        reg.yunwei.edu/learn/centos:7       "/bin/bash"          About a minute ago   Up About a minute                               web
    2b9cdc455352        reg.yunwei.edu/learn/centos:7       "/bin/bash"          About a minute ago   Up About a minute                               db

     d). 使用 ping 命令来测试网络链接的情况

    [root@alph ~]# docker exec -it 40bba17b3dfe /bin/bash
    [root@40bba17b3dfe /]# ping db
    PING dblink (172.17.0.3) 56(84) bytes of data.
    64 bytes from dblink (172.17.0.3): icmp_seq=1 ttl=64 time=48.5 ms
    64 bytes from dblink (172.17.0.3): icmp_seq=2 ttl=64 time=0.058 ms

    再换到db容器来ping web容器,因为连接是单向的,因此是ping不同的

    [root@alph ~]# docker exec -it db /bin/sh
    sh-4.2# ping web

    (10)容器端口映射

      在启动容器的时候,如果不指定参数,在容器外部是没有办法通过网络来访问容器内部的网络应用和服务的。

      当容器需要通信时,我们可以使用 -P (大)和 -p (小)来指定端口映射。

      -P(大) : Docker 会随机映射一个 49000 ~ 49900 的端口到容器内部开放的网络端口

      -p (小):则可以指定要映射的端口,并且在一个指定的端口上只可以绑定一个容器。

     

    支持的格式有

      IP : HostPort : ContainerPort     (将Host端口映射给Container)

      IP : : ContainerPort      (随机生成一个端口号映射为Container)

      IP : HostPort :           (类似的,让容器随机生成一个端口)      

    a)映射所有接口地址,此时绑定本地所有接口上的 5000 到容器的 5000 接口,访问任何一个本地接口的 5000 ,都会直接访问到容器内部

    [root@alph ~]# docker run -itd -p 8081 --name http reg.yunwei.edu/learn/httpd 
    c69494d7692d9cd5aa0ce24c286ad607adb9879f35cb8ce214a1002d8c24c336

    通过访问宿主机的端口号来访问容器

    尝试在容器http更改html文件,再刷新查看

    [root@alph ~]# docker ps -a
    CONTAINER ID        IMAGE                               COMMAND              CREATED              STATUS                         PORTS                  NAMES
    2d7cc376dd27        reg.yunwei.edu/learn/httpd          "httpd-foreground"   About a minute ago   Up About a minute              0.0.0.0:8081->80/tcp   http
    [root@alph ~]# docker exec -it http /bin/bash
    root@2d7cc376dd27:/usr/local/apache2# ls                #工作目录
    bin  build  cgi-bin  conf  error  htdocs  icons  include  logs  modules
    root@2d7cc376dd27:/usr/local/apache2# cd htdocs/        #容器文件目录
    root@2d7cc376dd27:/usr/local/apache2/htdocs# ls
    index.html
    root@2d7cc376dd27:/usr/local/apache2/htdocs#  echo " It is so beautiful!" >> inde.html

    b)多次使用可以实现多个接口的映射

    docker run -dti -p 5000:5000 -p 5022:22 centos:7.0 /bin/bash

    c)映射到指定地址的指定接口

      此时会绑定本地 192.168.4.169 接口上的 5000 到容器的 5000 接口

    docker run -dti -p 192.168.4.169:5000:5000 centos:7.0 /bin/bash

    d) 映射到指定地址的任意接口

    此时会绑定本地 192.168.4.169 接口上的任意一个接口到容器的 5000 接口

    docker run -dti -p 192.168.4.169::5000 centos:7.0 /bin/bash

    e) 使用接口标记来指定接口的类型

    docker run -dti -p 192.168.4.169::5000/UDP centos:7.0 /bin/bash

    11) 通过端口映射实现访问本地的 IP:PORT 可以访问到容器内的 web

    [root@alph ~]# for id in `docker ps -a | awk '{print $1}' | grep -v CONTAINER`;do docker rm -f $id;done
    [root@alph ~]# docker run -itd --name http reg.yunwei.edu/learn/httpd:latest
    34099c67cf07685fa830c1feb143d2f948a5231a48d5d542a285d3cd62a074d4
    [root@alph ~]# docker exec -it http /bin/bash
    root@34099c67cf07:/usr/local/apache2# ls
    bin  build  cgi-bin  conf  error  htdocs  icons  include  logs  modules
    root@34099c67cf07:/usr/local/apache2#
     
    
    将容器http的/usr/local/apache2导出以免丢失目录下内容
    [root@alph ~]# docker cp http:/usr/local/apache2 ./
    [root@alph ~]# ls
    anaconda-ks.cfg  apache2  doc_file  docker  test
    [root@alph ~]#  cd apache2/
    [root@alph apache2]# ls
    bin  build  cgi-bin  conf  error  htdocs  icons  include  logs  modules
    
    将现在在root下的目录apache2映射给容器下的/usr/local/apache2
    [root@alph ~]# docker run -itd -v /root/apache2/:/usr/local/apache2 -p 8081:80 --name http2  reg.yunwei.edu/learn/httpd
    31ca9cce1b2c61043bfa385a1572bf9d1bf76fa19a45c8f7b2a63c983f9073a8
     
    
    映射完成后相当于共享文件夹,在容器创建的文件在宿主机相应目录下能够查到,同样在宿主机相关文件进行的修改对容器有效
    [root@alph ~]# docker exec -it http2 /bin/bash
    root@31ca9cce1b2c:/usr/local/apache2# ls
    bin  build  cgi-bin  conf  error  htdocs  icons  include  logs  modules
    root@31ca9cce1b2c:/usr/local/apache2# touch aaaaa
    root@31ca9cce1b2c:/usr/local/apache2# exit
    exit
    [root@alph apache2]# ls
    aaaaa  bin  build  cgi-bin  conf  error  htdocs  icons  include  logs  modules
    [root@alph apache2]# cd htdocs/
    [root@alph htdocs]# ls
    index.html
    [root@alph htdocs]# vim index.html
    <html><body><h1>It works!</h1></body></html>
    <html><body><h1>It so beautiful!</h1></body></html>
    将该容器删除后其文件将不受影响,再次激活该容器该文件可以继续使用,这是一种动态的更改。
  • 相关阅读:
    JavaScript调试
    HTML5 Content Editable实践
    微信中a链接无法进行跳转
    javascript数据类型理解整理
    做个实用的选择器,从此远离满世界找插件
    Ajax中get和post使用问题
    JSON.stringify()、JSON.parse()和eval(string)
    PHP插入header('content-type:text/html;charset="utf-8')和error_reporting()
    Ajax关于readyState(状态值)和status(状态码)的研究
    堆排序中的上滤和下滤
  • 原文地址:https://www.cnblogs.com/ajunyu/p/11213362.html
Copyright © 2020-2023  润新知