前言
本文主要是说明docker容器内容交互的network子命令。这些命令可通过Docker ENGINE CLI获得。
docker network create
docker network connect
docker network ls
docker network rm
docker network disconnect
docker network inspect
创建网络
上篇基本已经说明docker在安装时会自动创建bridge网络,除了该网络外我们还可以创建自定义的bridge或者overlay网络。
bridge 网络驻留在运行Docker Engine实例的单个主机上。 overlay 网络可跨越运行Docker Engine的多个主机。
使用docker network create simple-network就可以创建一个bridge网络。
如果要创建overlay网络需要满足一定的条件才可以创建,比如:
访问key-value存储。 引擎支持Consul,Etcd和ZooKeeper(分布式存储)key-value存储。
与key-value存储连接的主机集群。
在swarm中的每个主机上正确配置的Docker daemon
另外支持overlay 网络的dockerd 选项有:
--cluster-store
--cluster-store-opt
--cluster-advertise
一般在创建网络时,docker引擎会自动创建一个不重叠的子网,当然也可使用subset指定子网。对于bridge只能指定一个子网,而overlay可以指定多个子网。
一般在创建网络如果未指定--subset选项,则docker会自动分配子网,产生的弊端就是可能会出现重叠导致出现网络连接故障,所以一般最好指定此选项
除--subnet 选项以外,您还可以指定--gateway , --ip-range --gateway --ip-range和--aux-address选项
docker network create -d overlay --subnet=192.168.0.0/16 --subnet=192.170.0.0/16 --gateway=192.168.0.100 --gateway=192.170.0.100 --ip-range=192.168.1.0/24 --aux-address="my-router=192.168.1.5" --aux-address="my-switch=192.168.1.6" --aux-address="my-printer=192.170.1.5" --aux-address="my-nas=192.170.1.6" my-multihost-network
一般创建bridge网络时可以接受如下选项。
--创建Linux网桥时要使用的网桥名称
com.docker.network.bridge.name
--启用ip伪装
com.docker.network.bridge.enable_ip_masquerade
--启用或禁用跨容器连接
com.docker.network.bridge.enable_icc
--绑定容器端口时的默认IP
com.docker.network.bridge.host_binding_ipv4
--设置容器网络MTU
com.docker.network.driver.mtu
在创建网络时使用-o参数进行指定ip地址。
docker network create -o "com.docker.network.bridge.host_binding_ipv4"="172.23.0.1" my-network
连接容器
可以将容器连接到创建的一个或者多个子网络,容器连接到使用不同网络驱动的网络,一旦连接,则容器之间就可以使用ip进行通信。对于支持多主机连接的overlay 网络或自定义插件,不同主机上的容器,只要连接到同一multi-host network多主机网络,也可以这种方式进行通信
如果我这里创建两个容器container1和container2
然后创建一个bridge网络进行测试。
docker network create -d bridge --subnet 172.19.0.0/16 isolated_nw
将container2连接到isolated_nw并检测
docker network connect isolated_nw container2
docker network inspect [ { "Name": "isolated_nw", "Id": "dfa845b0a5034f7563e54f64a62bbbbba44bafdbd35dcc1bc65d8cce29d6d31a", "Created": "2020-07-30T15:35:33.490618979+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.19.0.0/16", "Gateway": "172.19.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "ebec93c4cf1e314f8a84389e09df7c77471c445c723718c5130bc8bdcd375100": { "Name": "container2", "EndpointID": "caf3349e8b18eeff203e871b9f30c8590406e4b443326c58a93ba5b62c8db3d5", "MacAddress": "02:42:ac:13:00:02", "IPv4Address": "172.19.0.2/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} }]
此处的container2会自动分配一个ip,在指定的subset中选择。而此处的container1只是连接到了默认的bridge网络
使用docker -run的方式启动container3容器并且指定刚才--network=isolated_nw的网络并且分配一个指定的ip
docker run --network=isolated_nw --ip=172.19.0.3 -itd --name=container3 busybox
注意:仅当连接到具有用户配置子网的网络时,才支持用户指定的IP地址
docker run --network=isolated_nw --ip=172.19.0.3 -itd --name=container3 busybox64bfe8f7e1c85690c53f8605968c26525c2f47395e789c2f1da8fe30b1bfc590
此处的container3在启动时候就连接到了isolated_nw网络,所以它并没有连接到默认的bridge网络。
container2 连接到默认bridge网络和isolated_nw 网络,因此,container2 可与container1 以及container3进行通信。 但是,container3 和container1 没有任何共同的网络,所以它们不能通信。
一般连接到了默认的bridge网络就无法使用ping -w 4 container3 这种命令了,但可以使用
ping -w 4 172.17.0.2这种方式。
连接容器而不使用自定义网络
在上述过程中创建的isolated_nw网络,container2、container3连接后可以通过解析容器名称的方式进行通信,而container1就无法通过这种方式进行通信,如果要实现通信,就得使用之前的--link的方式了。
- 将容器名称解析为IP地址的能力
- 使用--link=CONTAINER-NAME:ALIAS 定义一个网络别名去连接容器的能力
- 安全的容器连接(通过--icc=false 隔离)
- 环境变量注入
此处再创建一个容器container4然后使用link的方式连接到container5别名c5
docker run --network=isolated_nw -itd --name=container4 --link container5:c5 busybox
注意 :使用遗留的link功能创建的容器之间的任何链接本质上都是静态的,并且通过别名强制绑定容器。 它无法容忍连接的容器重新启动。 用户自定义网络中的新链接功能支持容器之间的动态链接,并且允许链接容器中的重新启动和IP地址更改。
网络范围内的容器别名
一般在连接容器时,无论是自己创建的网络还是link方法等,别名只对特定的容器有意义,并且不能在默认的bridge上运行。别名不适用不在同一网络的容器。另外,如果容器属于多个网络,则给定的连接别名与给定的网络范围一致
docker network 限制
环境变量注入
环境变量都是静态的,一般在你的容器启动将无法更改。--link标志将所有的环境变量共享到连接容器,而docker network没有此等效的选项。故而当你使用docker network将容器连接到网络时无法在容器之间共享环境变量。
网络范围内的别名
别名定义只在定义它的网络上生效,也就是只有连接了定义有别名的网络的容器之间才能通过别名的方式通信。
将多个容器解析为一个别名
此处的别名为网络别名,不是容器别名
多个容器可在同一网络范围内容共享相同网络范围内的别名,顾名思义就是多个容器在连接到一个网络时给予相同的别名。此时docker提供了一种DNS轮询高可用的特性。
当多个容器共享相同的别名时,其中一个容器将解析为别名。 如果该容器不可用,则另一个具有别名的容器将被解析。 这提供了群集中的高可用性
断开连接
还可以使用docker network disconnect 命令断开容器与网络的连接。
docker network disconnect isolated_nw container2 将容器container2从isolated_nw网络断开
当容器断开网络时,它将不能在与它之前统一网络中的容器进行通信,除非有其他共享网络的存在
但当断开自定义网络时,仍然具有默认的bridge网络。
处理过时的网络端点
在某些场景中可能会出现多主机网络中以非正常的方式重启docker daemon,那么此时将无法清理过时的连接端点,如果新的容器连接到具有相同名称的过期网络端点,可能会出现错误。
要清理这些过时的端点,可移除容器并强制将其与网络断开( docker network disconnect -f )。 这样,您就可将容器成功连接到网络。
删除网络
一般情况下当创建的网络过多或者某些没用的网络时,就可以删除了,但前提是要保证此网络没有被任何一个容器所连接,如果是这样,可以先断开。再删除
docker network rm isolated_nw
列出所有网络docker network ls可见isolated_nw已经不存在
docker network lsNETWORK ID NAME DRIVER SCOPEe484a98b6ae2 bridge bridge locale951a3ec116f docekrcomposetest_default bridge local8fb642440eb6 docker_gwbridge bridge local0de223c56186 host host localtdibtp0jpjk8 ingress overlay swarm63c6a034415d none null local