使用Docker网络相关的命令管理容器

Docker常用的网络相关的命令有如下几种:

docker network create

docker network connect

docker network ls

docker network rm

docker network disconnect

docker network inspect

创建网络:

Docker引擎会在用户安装docker的时候自动的创建一个bridge类型的网络,这个网络是基于docker0网桥。除此之外,用户可以创建自己的bridge网络和overlay网络。

bridge网络一般处在单台安装了docker引擎的宿主中,而overlay网络则是运转在多台宿主中,如果在创建网络的时候,只提供了,网络的名称

e.g:

docker network create simple-network

该网络即为bridge网络

Overlay网络需要一下几个前置条件:

集群有一个key-value存储器

集群内每个宿主都可以连接到存储器

集群内每个宿主都正确的配置了swarm

不管需不需要,使用Docker Swarm来管理集群都是一个好办法,Swarm可以帮助用户简化服务器管理,Swarm拥有成熟的服务发现系统。

在我们创建网络的同时,Docker引擎默认会为每个网络创建一个绝对无重叠的子网,用户可以沿用这种方法创建网络,也可以直接使用--subnet属性创建特定Cidr的子网。bridge网络下,用户只能指定一个子网,一个overlay网络下, 可以支持多个子网。

###Docker建议我们创建的网络的时候,尽量使用--subnet参数,如果该参数没有指定,Docker守护会自动选择一个子网,该子网,可能会与目前创建的子网重复。

除了--subnet参数,还有--gateway,--ip-range 以及--aux-adress

e.g.:

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-adress="my-switch=192.168.1.16" \

--aux-address="my-router=192.170.1.5" --aux-adress="my-switch=192.170.1.16" \

my-mutihost-network

确保每个子网的Cidr不重叠。

在创建自定义网路哦的时候,默认的网络驱动是bridge,当然,其他的驱动也可以传入,以下的参数也相当于使用docker0网桥:

Option Equivalent Description
com.docker.network.bridge.name - bridge name to be used when creating the Linux bridge
com.docker.network.bridge.enable_ip_masquerade --ip-masq Enable IP masquerading
com.docker.network.bridge.enable_icc --icc Enable or Disable Inter Container Connectivity
com.docker.network.bridge.host_binding_ipv4 --ip Default IP when binding container ports
com.docker.network.driver.mtu --mtu Set the containers network MTU

com.docker.network.driver.mtu在overlay驱动下,也是支持。

e.g:

docker network create -o "com.docker.network.bridge.host_binding_ipv4"="172.23.0.1" my-network

docker network inspect my-network

[{"Name":"my-network","Id":"b1a086897963e6a2e7fc6868962e55e746bee8ad0c97b54a5831054b5f62672a","Scope":"local","Driver":"bridge","IPAM":{"Driver":"default","Options":{},"Config":[{"Subnet":"172.23.0.0/16","Gateway":"172.23.0.1/16"}]},"Containers":{},"Options":{"com.docker.network.bridge.host_binding_ipv4":"172.23.0.1"}}]

docker -run -d -P --name reds --network my-network

连接容器

用户可以将自己的容器连接到一个,或者多个网络,所连接的网络,可以是不同种类的网络(使用不同的网络驱动),一旦连接,容器可以通过,容器的name,以及容器的IP进行交互。

对于支持多宿主的overlay网络以及其他自定义的网络插件,容器即使不是处于同台宿主,但是,他们之间的交互,仍然可以使用IP,或者name交互。

docker run -itd --name=container1 busybox

docker run -itd --name=container2 busybox

docker network create -d bridge --subnet 172.25.0.0/16 isolated_nw

docker network connect isolated_nw container2

docker network inspect isolated_nw

[ { "Name": "isolated_nw", "Id": "06a62f1c73c4e3107c0f555b7a5f163309827bfbbf999840166065a8f35455a8", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Config": [ { "Subnet": "172.25.0.0/16", "Gateway": "172.25.0.1/16" } ] }, "Containers": { "90e1f3ec71caf82ae776a827e0712a68a110a3f175954e5bd4222fd142ac9428": { "Name": "container2", "EndpointID": "11cedac1810e864d6b1589d92da12af66203879ab89f4ccd8c8fdaa9b1c48b1d", "MacAddress": "02:42:ac:19:00:02", "IPv4Address": "172.25.0.2/16", "IPv6Address": "" } }, "Options": {} }]

可以看到Docker引擎自动为container2在isolated_nw的cidr中分配了一个IP,

docker run --network=isolated_nw --ip=172.25.3.3 -itd --name=container3 busybox

使用--ip参数指定容器的IP,选中的IP address,属于容器网络设置的一部分并且这部分信息将会在容器中重新加载,这种特性只在用户自定义的网络时可用,因为这种网络的Cidr在docker daemon重新加载的时候不会发生变化。

现在观察一下container3的网络资源

docker inspect --format=‘’ container3

{"isolated_nw":{"IPAMConfig":{"IPv4Address":"172.25.3.3"},"NetworkID":"1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b","EndpointID":"dffc7ec2915af58cc827d995e6ebdc897342be0420123277103c40ae35579103","Gateway":"172.25.0.1","IPAddress":"172.25.3.3","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:19:03:03"}}


观察container2的网络资源

$ docker inspect --format='' container2 | python -m json.tool{ "bridge": { "NetworkID":"7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812", "EndpointID": "0099f9efb5a3727f6a554f176b1e96fca34cae773da68b3b6a26d046c12cb365", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAMConfig": null, "IPAddress": "172.17.0.3", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:11:00:03" }, "isolated_nw": { "NetworkID":"1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b", "EndpointID": "11cedac1810e864d6b1589d92da12af66203879ab89f4ccd8c8fdaa9b1c48b1d", "Gateway": "172.25.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAMConfig": null, "IPAddress": "172.25.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:19:00:02" }}


container2接入了两个不同的网络,一个是默认的bridge网络,另外一个是自定义的isolated_nw。

docker attach container2

ifconfig

eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03 inet addr:172.17.0.3 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:acff:fe11:3/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:9001 Metric:1 RX packets:8 errors:0 dropped:0 overruns:0 frame:0 TX packets:8 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:648 (648.0 B) TX bytes:648 (648.0 B)eth1 Link encap:Ethernet HWaddr 02:42:AC:15:00:02 inet addr:172.25.0.2 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:acff:fe19:2/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:8 errors:0 dropped:0 overruns:0 frame:0 TX packets:8 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:648 (648.0 B) TX bytes:648 (648.0 B)lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

在isolated_nw,Docker将DNS server嵌入到该网络下作为域名解析,所以在container2下,可以直接ping container3.

但是在默认的bridge网络下,不能使用,Docker目前不支持自服务发现在bridge下,所以,在container2下ping container1,还是需要依赖于/etc/hosts文件


如果,用户需要container1与container2的连接,需要使用docker run --link 命令来启动容器间通过name连接。


用户可以通过docker network connect将容器接入到某个网络,无论该容器是否处于运行状态都是可以的。但是,docker network inspect 只会显示正在运行的容器的信息。


在用户定义的网络下连接容器

在上述的例子中,在isolated_nw中container2可以通过container——name连接到container3,但是,这种名称解析的方案,在默认的bridge下是不可用的。但是在默认bridge中拥有link方法。

link方法有4个主要的功能点,

1.container_name的解析

2.name别名,连接容器使用 --link=CONTAINER-NAME:ALIAS

3.通信的安全性(via --icc=false)

4.环境变量的注入

比起默认的docker网络(bridge),自定义网络(isolated_nw)在这个四个功能点上的提供以下内容:

1.自动的名称解析通过DNS。

2.安全的,隔离的划分网络下的容器。

3.可以动态的将容器接入或者断开与其他网络的连接

4.--link选项,为每个linked的容器提供名称别名

创建container4,并且使用--link来提供别名的域名解析。

docker run --network=isolated_nw -itd --name=container4 --link container5:c5 busybox

由于使用了--link container5:c5,我们将会使用别名c5连接到container5。

注意: 在创建container4的时候,我们所连接的container5还仍未创建,这就是一个bridge与自定义网络的不同点,要注意,bridge使用的是老版本的link,这种link,容器与这个别名是强绑定的,不会允许连接着的容器重启。在自定义的网络环境下,新版的link的功能点,在本质上是动态的,并且支持,连接着的容器重启,甚至允许连接着的容器的Ip发生变化。

docker run --network=isolated_nw -itd --name=container5 --link container4:c4 busybox

正如用户希望的,用户现在可以通过使用ip,container_name,以及container的别名,都可以访问到指定的容器。

与老版本的link功能相似的是,新版的别名是具有局限性的,并且容器的别名在容器外部将会丧失其意义

在横跨多个网络的容器中,容器的别名仅仅在给定的网络中,有效。


docker network -d bridge --subnet 172.26.0.0/24 local_alias

docker network connect --link container5:foo local_alias container4

docker network connect --link container4:bar local_alias container5


接入到container4下,发现,foo,以及c5都能正常解析

docker network disconnect isolated_nw container5

此时接入到container4下,只有foo可以解析。

结论:alias只是在互相连接的彼此下有效,他的作用域就是彼此之间。


Network-scoped 别名

link提供了本地容器私有的名称解析方案,网络范围的别名提供了在相同网络下一种额外的名称发现方案,不像 link alias,这种Network-scoped Alias定义的是一种在当前网络下Container提供的服务。

docker run --network=isolated_nw -itd --name=container6 --network-alias app busybox

进入container4 直接就可以通过app就可以访问到container6

docker network connect --alias scoped-app local_alias container6

container6在该例子中的isolated_nw被命名为app, 在local_alias网络中,被命名为scoped-app。

现在app只有在isolated_nw中有效,而scoped-app只在local_alias中有效

docker run --network=isolated_nw -itd --name=container7 --network-alias app busybox

当前在该网络下,拥有两个容器拥有别名app,这个时候,Docker通常会将app这个别名解析为第一个启动的container,如果该容器挂掉,将会解析到另外一个容器,这个解决方案特别适合做主备。


docker disconnect isolated_nw container2 

将会断开container与该网络的连接,并且丧失与该网络下所有容器的通信能力。

⚠️:  在docker daemon在不正常的重启之后,就会发生 container already connected to network 此时应该逐步排错,并且断开相关的container

docker rm isolated_nw 删除isolated_nw























你可能感兴趣的:(Docker)