在docker实例中你可以使用现有的容器连接到一个或多个网络,容器也可以使用不通网络驱动的网络。一旦连击了容器就可以使用另外一个容器的ip和主机名进行对外通信。
对于支持多主机的覆盖型或自定义的网络,连接到同一个主机网络但是不同启动主机的容积也可以使用这种方式。
下面会创建6个容器,通过这个过程讲解网络使用:
1.创建两个容器container1,container2
[root@salt-node1 ~]# docker run -itd --name=container1 busybox cafef076b2d4fe587e2441cf801d3c411badd816effe2f0936da6c755e521f27 [root@salt-node1 ~]# docker run -itd --name=container2 busybox ed27144379918206669013f13afd5617a87f32778ca1df26daff8ee0edd70e7f
2.创建一个隔离的桥接网络test_bridge
[root@salt-node1 ~]# docker network create -d bridge --subnet 10.6.0.0/16 test_bridge 5ed752ce05ef33d4e326385693eaa0c9cc325b18045fab7727901893dd233c6e
3.container2连接到test_bridge,查看网络信息:
通过下面操作可以看到container2获取到了test_bridge指定网段ip地址“10.6.0.2”,现在container1依然连接的默认的网络
[root@salt-node1 ~]# docker network connect test_bridge container2 [root@salt-node1 ~]# docker network inspect test_bridge [ { "Name": "test_bridge", "Id": "5ed752ce05ef33d4e326385693eaa0c9cc325b18045fab7727901893dd233c6e", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "10.6.0.0/16" } ] }, "Internal": false, "Containers": { "ed27144379918206669013f13afd5617a87f32778ca1df26daff8ee0edd70e7f": { "Name": "container2", "EndpointID": "5cfa7576b9fdb66080f81533ade3b8511c6106d3dd12c90a839a6ec8df7f73fd", "MacAddress": "02:42:0a:06:00:02", "IPv4Address": "10.6.0.2/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
通过下面的信息可以知道,容器2依然在默认的网络里面,所以这里说明docker只是给容器2新建了一个网络到指定的网络里面
[root@salt-node1 ~]# docker network inspect bridge [ { "Name": "bridge", "Id": "13b6e04d86a5ec237d3a33946b75ad197f569ae28e793bb4ea967e81cbfe126b", "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, "Containers": { "cafef076b2d4fe587e2441cf801d3c411badd816effe2f0936da6c755e521f27": { "Name": "container1", "EndpointID": "8fac97e5cacc4909d0ddf0d341b130acab38341db58c3bf14902dfc097ef8084", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" }, "ed27144379918206669013f13afd5617a87f32778ca1df26daff8ee0edd70e7f": { "Name": "container2", "EndpointID": "411271ca18bc64d471cdf2fbe43b3c08f4cd487cf380dc7046aeb4403dcb8163", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/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": {} } ]
4.创建第三个容器,并指定ip“10.6.9.3”
只要你的ip在指定网段就可以,你可以使用--ip和--ip6来完成ip的指定,这个操作尽量在用户自定义网络用。
因为docker默认生成网络的网络并不固定,一旦docker重启网段很可能发生变化。
[root@salt-node1 ~]# docker run --network=test_bridge --ip=10.6.9.3 -itd --name=container3 busybox
44f5c4429946b81b71ad6e905d486c1a1760401216edbb717fe2f024caecca7b
5.查看容器3的网络
因为container3 使用的test_bridge所以看不到默认的桥接网络
[root@salt-node1 ~]# docker inspect --format='' container3 ……………………… "NetworkSettings": { "Bridge": "", "SandboxID": "ae1da0ceaa8ac1c62104769eb62ffe2c60b001cc21423fc71af573bee27ed11b", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": {}, "SandboxKey": "/var/run/docker/netns/ae1da0ceaa8a", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "", "Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "", "IPPrefixLen": 0, "IPv6Gateway": "", "MacAddress": "", "Networks": { "test_bridge": { "IPAMConfig": { "IPv4Address": "10.6.9.3" }, "Links": null, "Aliases": [ "44f5c4429946" ], "NetworkID": "5ed752ce05ef33d4e326385693eaa0c9cc325b18045fab7727901893dd233c6e", "EndpointID": "24a4655ee32fbe84902a06adba431ab8455c42f4949cc4705cec5b50a75089eb", "Gateway": "10.6.0.1", "IPAddress": "10.6.9.3", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:0a:06:09:03" } …………………
6.查看容器2的网络
你可以看到两个网络分配的不同ip
[root@salt-node1 ~]# docker inspect --format='' container2 | python -m json.tool ………………. "Networks": { "bridge": { "Aliases": null, "EndpointID": "411271ca18bc64d471cdf2fbe43b3c08f4cd487cf380dc7046aeb4403dcb8163", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAMConfig": null, "IPAddress": "172.17.0.3", "IPPrefixLen": 16, "IPv6Gateway": "", "Links": null, "MacAddress": "02:42:ac:11:00:03", "NetworkID": "13b6e04d86a5ec237d3a33946b75ad197f569ae28e793bb4ea967e81cbfe126b" }, "test_bridge": { "Aliases": [ "ed2714437991" ], "EndpointID": "5cfa7576b9fdb66080f81533ade3b8511c6106d3dd12c90a839a6ec8df7f73fd", "Gateway": "10.6.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAMConfig": {}, "IPAddress": "10.6.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "Links": null, "MacAddress": "02:42:0a:06:00:02", "NetworkID": "5ed752ce05ef33d4e326385693eaa0c9cc325b18045fab7727901893dd233c6e" } }, "Ports": {}, "SandboxID": "2100a213c8e716e91d540157066ada99f9cabf3556bea8aaf343a8a99434b5ce", "SandboxKey": "/var/run/docker/netns/2100a213c8e7", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null },
………………….
此图是现在三个节点网络状态
7.进入到容器2内部查看网络状况明显是2块网卡,每块网卡在不同网络分配不同的IP
[root@salt-node1 ~]# 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:1500 Metric:1 RX packets:9 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:718 (718.0 B) TX bytes:648 (648.0 B) eth1 Link encap:Ethernet HWaddr 02:42:0A:06:00:02 inet addr:10.6.0.2 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:aff:fe06:2/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:32 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:3306 (3.2 KiB) 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:1 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
8.现在测试一下docker自带的dns
如果dns正常我们可以使用容器的名称ping,就可以获取容器ip,但是默认网络bridge它不能dns解析,但是
/ # ping -w 4 container3 PING container3 (10.6.9.3): 56 data bytes 64 bytes from 10.6.9.3: seq=0 ttl=64 time=0.151 ms 64 bytes from 10.6.9.3: seq=1 ttl=64 time=0.144 ms 64 bytes from 10.6.9.3: seq=2 ttl=64 time=0.116 ms 64 bytes from 10.6.9.3: seq=3 ttl=64 time=0.102 ms ^C --- container3 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.102/0.128/0.151 ms
容器container1和container2都有默认网络bridge的ip可以ping通但是不能dns解析
/ # ping -w 4 container1 ping: bad address 'container1' / # 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.114 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.119 ms 64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.087 ms ^C --- 172.17.0.2 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.087/0.106/0.119 ms
通过Ctrl+D退出,这时容器自动终止
/ # [root@salt-node1 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 44f5c4429946 busybox "sh" 38 minutes ago Up 38 minutes container3 cafef076b2d4 busybox "sh" 56 minutes ago Up 56 minutes container1
使用非用户定义网络link
因为默认bridge网络无法解析主机名,所以这也是link唯一值得用到的地方,但是我们更建议你使用自定义网络。
使用传统的link你的容器会获取下面变化
1.能解析容器的name和ip地址
2.能定义网络别名是替换网络的另一种方式,实用参数:--link=CONTAINER-NAME:ALIAS实现
3.保证容器的连接安全,独立通道--icc=false
4.环境变量的注入
要重申,当您使用用户自定义的网络时,默认提供所有这些功能,不需要其他配置。 此外您可以动态附加到多个网络和从多个网络分离。
1.使用dns自动解析name
2.支持--link选项为链接的容器提供名称别名
3.为容器在网络中会自动创建隔离的网络
4.环境变量的注入
1.下面稍微描述下link用户
[root@salt-node1 ~]# docker run --network=test_bridge -itd --name=container4 --link container5:c5 busybox
e738b850f3c12d03f5fecf27e8bfa051f8e5d2c4cdd77f4aaae53cdbb1291453
上面操作你可能不确认有没有创建c5容器可以测试下,发现并没有这个容器
[root@salt-node1 ~]# docker attach container4 / # ping container5 ping: bad address 'container5' / # ping c5 ping: bad address 'c5' / #
现在启动container5 容器
[root@salt-node1 ~]# docker run --network=test_bridge -itd --name=container5 --link container4:c4 busybox 64dd012cf0df4072562d6ff770c6273e8f0142c6aacbf8268af6b2d8d55b3f09
连接到container4里面,才发现之前的link只是给container5 进行了别名的定义
[root@salt-node1 ~]# docker attach container4 You cannot attach to a stopped container, start it first [root@salt-node1 ~]# docker start container4 container4 [root@salt-node1 ~]# docker attach container4 / # ping -w 4 c5 PING c5 (10.6.0.3): 56 data bytes 64 bytes from 10.6.0.3: seq=0 ttl=64 time=0.253 ms 64 bytes from 10.6.0.3: seq=1 ttl=64 time=0.146 ms 64 bytes from 10.6.0.3: seq=2 ttl=64 time=0.143 ms 64 bytes from 10.6.0.3: seq=3 ttl=64 time=0.148 ms --- c5 ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.143/0.172/0.253 ms / # ping -w 2 container5 PING container5 (10.6.0.3): 56 data bytes 64 bytes from 10.6.0.3: seq=0 ttl=64 time=0.212 ms 64 bytes from 10.6.0.3: seq=1 ttl=64 time=0.150 ms --- container5 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.150/0.181/0.212 ms
网络变量作用域
当你link容器,无论是传统link网络还是用户自定义网络,你指定的任何变量意味着只能在指定区域使用,不能再其它传统网络容器内使用。此外,一个容器属于多个网络,那么你在变量只工作在指定的网络。因此,一个容器可以连接不同变量道不同网络,所有的alias不能工作在同一个网络。
下面举例:
1.创建一个桥接网络local_alias
[root@salt-node1 ~]# docker network create -d bridge --subnet 172.26.0.0/24 local_alias 8e836ae84547ad5b4bb26df276ef3e5de52ea50d6c5a0109d7c9c921a001e493
2.container4在local_alias网络创建container5的变量名foo,container5在local_alias网络创建container4的变量名bar
[root@salt-node1 ~]# docker network connect --link container5:foo local_alias container4 [root@salt-node1 ~]# docker network connect --link container4:bar local_alias container5
容器4可以使用foo解析到容器5,容器3却不可以
[root@salt-node1 ~]# docker attach container4 / # ping -w 2 foo PING foo (172.26.0.3): 56 data bytes 64 bytes from 172.26.0.3: seq=0 ttl=64 time=0.155 ms 64 bytes from 172.26.0.3: seq=1 ttl=64 time=0.151 ms [root@salt-node1 ~]# docker attach container3 / # ping -w 2 foo ping: bad address 'foo
现在容器5断开test_bridge则不可以连接
[root@salt-node1 ~]# docker network disconnect test_bridge container5 [root@salt-node1 ~]# docker attach container4 / # ping -w 2 c5 ping: bad address 'c5' / # ping -w 2 foo PING foo (172.26.0.3): 56 data bytes 64 bytes from 172.26.0.3: seq=2 ttl=64 time=0.147 ms 64 bytes from 172.26.0.3: seq=3 ttl=64 time=0.189 ms --- foo ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 0.135/0.162/0.189 ms