这篇主要是学习了docker网络相关的知识,主要参考以下三篇文章:容器默认网络bridge,使用 Docker 容器网,Docker网络详解及pipework源码解读与实践
,最后一篇原理更清楚一些。
要构建具有安全的一致行为的 Web 应用程序,可以使用 Docker 网络特性,网络为容器实现了完全隔离,所以,控制您的应用程序所在的网络很重要。
安装 Docker 时,它会自动创建 3 个网络。可以使用 docker network ls命令列出这些网络。
1 2 3 4 5 6
| 1$ docker network ls
2NETWORK ID NAME DRIVER
37fca4eb8c647 bridge bridge
49f904ee27bf5 none null
5cf03ee007fb4 host host
6 |
- bridge 网络表示所有 Docker 安装中都存在的 docker0 网络。除非使用 docker run –net=<NETWORK>选项另行指定,否则 Docker 守护进程默认情况下会将容器连接到此网络。在主机上使用 ifconfig命令,可以看到此网桥是主机的网络堆栈的一部分。
- none 网络在一个特定于容器的网络堆栈上添加了一个容器。该容器缺少网络接口。
- host 网络在主机网络堆栈上添加一个容器。您可以发现,容器中的网络配置与主机相同。
当Docker server启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。接下来就要为容器分配IP了,Docker会从RFC1918所定义的私有IP网段中,选择一个和宿主机不同的IP地址和子网分配给docker0,连接到docker0的容器就从这个子网中选择一个未占用的IP使用。如一般Docker会使用172.17.0.0/16这个网段,并将172.17.42.1/16分配给docker0网桥(在主机上使用ifconfig命令是可以看到docker0的,可以认为它是网桥的管理接口,在宿主机上作为一块虚拟网卡使用)。单机环境下的网络拓扑如下,主机地址为10.10.101.105/24。
在bridge模式下,连在同一网桥上的容器可以相互通信,容器也可以与外部通信,通过inspect命令查看各个网络中的容器,下边是查看网络bridge中的容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| 1[root@iZwz9cps5bpzjurg8m4ax0Z ~]# docker network inspect bridge
2[
3 {
4 "Name": "bridge",
5 "Id": "ac1d92e5a5686ec83a9f5c1081214515729248af992dd063107dcbe37aaaac49",
6 "Scope": "local",
7 "Driver": "bridge",
8 "IPAM": {
9 "Driver": "default",
10 "Config": [
11 {
12 "Subnet": "172.17.42.1/16",
13 "Gateway": "172.17.42.1"
14 }
15 ]
16 },
17 "Containers": {
18 "33225198ecc3be768993ba548394f94c062c7ab2b5acf47362b812b409a9d059": {
19 "EndpointID": "2266dae6f2c5821b72914df9a2779cc48e0dde530321d1b54fd88d452e33ea04",
20 "MacAddress": "02:42:ac:11:00:04",
21 "IPv4Address": "172.17.0.4/16",
22 "IPv6Address": ""
23 },
24 "812b841b54229210f8c261ee6c976327caf1e6d823936557b8e68ccdac43bb34": {
25 "EndpointID": "8c1f8fe852443f631d3737a0747605ee76bc2ef55562429026512ff5fa6bb21c",
26 "MacAddress": "02:42:ac:11:00:05",
27 "IPv4Address": "172.17.0.5/16",
28 "IPv6Address": ""
29 },
30 "c0a44b2116c88c6c0e708814d4cfcd323fb20867f71180fcfbf59a934e4a7add": {
31 "EndpointID": "b269af7709921df6ad07863d5a9d638c73f3eb92b07e469cf454b2b3cadc5430",
32 "MacAddress": "02:42:ac:11:00:03",
33 "IPv4Address": "172.17.0.3/16",
34 "IPv6Address": ""
35 },
36 "d01019ff4818378f5d8cebd87ed606c3f02443fa05fdbc74e1cd04bbc2531cdd": {
37 "EndpointID": "f74b74f2d66162fb5e7772e808b7e28035a22ded00571966fa4ecb9d85363c95",
38 "MacAddress": "02:42:ac:11:00:01",
39 "IPv4Address": "172.17.0.1/16",
40 "IPv6Address": ""
41 },
42 "eb7b3e268ff248d41b0d421852d1491c862279eacc971664bc28ddd3eac396c9": {
43 "EndpointID": "779a2530227b7f3e30539fd6f807d0c4824ce8660a4b2e99cc5155e84ed5416d",
44 "MacAddress": "02:42:ac:11:00:02",
45 "IPv4Address": "172.17.0.2/16",
46 "IPv6Address": ""
47 }
48 },
49 "Options": {
50 "com.docker.network.bridge.default_bridge": "true",
51 "com.docker.network.bridge.enable_icc": "true",
52 "com.docker.network.bridge.enable_ip_masquerade": "true",
53 "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
54 "com.docker.network.bridge.name": "docker0",
55 "com.docker.network.driver.mtu": "1500"
56 }
57 }
58]
59
60 |
1 2
| 1 在containers中看到的是5个,表示目前有5个容器加入到这个网络中
2 |
1 2 3 4 5 6 7 8
| 1[root@iZwz9cps5bpzjurg8m4ax0Z ~]# docker ps
2CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3812b841b5422 daocloud.io/mysql "docker-entrypoint.sh" 8 days ago Up 8 days 0.0.0.0:3308->3306/tcp mysql-slave
433225198ecc3 daocloud.io/mysql "docker-entrypoint.sh" 8 days ago Up 8 days 0.0.0.0:3307->3306/tcp mysql-master
5c0a44b2116c8 txxs/springbootdocker:1.0 "java -jar /app.jar" 2 weeks ago Up 8 days 0.0.0.0:8083->8080/tcp insane_noyce
6eb7b3e268ff2 txxs/springbootdocker:1.0 "java -jar /app.jar" 2 weeks ago Up 8 days 0.0.0.0:8082->8080/tcp stoic_mayer
7d01019ff4818 txxs/springbootdocker:1.0 "java -jar /app.jar" 2 weeks ago Up 8 days 0.0.0.0:8081->8080/tcp stoic_morse
8 |
1 2
| 1可以通过container的ID,找到其在bridge中的映射的配置,比如d01019ff4818这个ID对应的网络配置就是:
2 |
1 2 3 4 5 6 7
| 1 "d01019ff4818378f5d8cebd87ed606c3f02443fa05fdbc74e1cd04bbc2531cdd": {
2 "EndpointID": "f74b74f2d66162fb5e7772e808b7e28035a22ded00571966fa4ecb9d85363c95",
3 "MacAddress": "02:42:ac:11:00:01",
4 "IPv4Address": "172.17.0.1/16",
5 "IPv6Address": ""
6 },
7 |
1 2
| 1docker run启动容器的时候会默认使用bridge这个网络,进入mysql-slave这个容器中可以查看对应的对应的IP
2 |
1 2
| 1docker exec -it mysql-slave /bin/bash
2 |
1 2 3 4 5 6 7 8 9 10
| 1root@812b841b5422:/# more /etc/hosts
2172.17.0.5 812b841b5422
3127.0.0.1 localhost
4::1 localhost ip6-localhost ip6-loopback
5fe00::0 ip6-localnet
6ff00::0 ip6-mcastprefix
7ff02::1 ip6-allnodes
8ff02::2 ip6-allrouters
9
10 |
1 2 3 4 5 6 7
| 1 "812b841b54229210f8c261ee6c976327caf1e6d823936557b8e68ccdac43bb34": {
2 "EndpointID": "8c1f8fe852443f631d3737a0747605ee76bc2ef55562429026512ff5fa6bb21c",
3 "MacAddress": "02:42:ac:11:00:05",
4 "IPv4Address": "172.17.0.5/16",
5 "IPv6Address": ""
6 },
7 |
1 2
| 1进入到mysql-master这个容器后可以ping 172.17.0.5可以获取相关的数据,原因就是在同一个bridge网络内,在同一个网络下的容器是可以相互ping通的
2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 1[root@iZwz9cps5bpzjurg8m4ax0Z ~]# docker exec -it mysql-master /bin/bash
2root@33225198ecc3:/# more /etc/hosts
3172.17.0.4 33225198ecc3
4127.0.0.1 localhost
5::1 localhost ip6-localhost ip6-loopback
6fe00::0 ip6-localnet
7ff00::0 ip6-mcastprefix
8ff02::1 ip6-allnodes
9ff02::2 ip6-allrouters
10root@33225198ecc3:/# ping 172.17.0.5
11PING 172.17.0.5 (172.17.0.5): 56 data bytes
1264 bytes from 172.17.0.5: icmp_seq=0 ttl=64 time=0.204 ms
1364 bytes from 172.17.0.5: icmp_seq=1 ttl=64 time=0.070 ms
1464 bytes from 172.17.0.5: icmp_seq=2 ttl=64 time=0.066 ms
15 |
1 2
| 1了解完默认的bridge网络后,可以创建一个自己的网络,使用create命令,默认的驱动方式也是bridge,除此之外还可以创建overlay类型的网络。bridge网络适用于单台宿主机运行的单Docker引擎环境,而overlay网络允许我们跨多台宿主机进行通讯。使用默认的创建结果如下:
2 |
1 2
| 1docker network create springboot-app-net
2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 1[root@iZwz9cps5bpzjurg8m4ax0Z springboot-docker-test]# docker network inspect springboot-app-net
2[
3 {
4 "Name": "springboot-app-net",
5 "Id": "cf4ca23bcb27914148c822d6f675469a5e8bd87dbf6066890e6aba1593eec9f5",
6 "Scope": "local",
7 "Driver": "bridge",
8 "IPAM": {
9 "Driver": "default",
10 "Config": [
11 {}
12 ]
13 },
14 "Containers": {},
15 "Options": {}
16 }
17]
18 |
1 2
| 1docker Version: 1.9.1的情况下使用docker run --net=<NETWORK>将新创建的容器加入到自定义的网络中,运行结果如下
2 |
1 2
| 1docker run --net=springboot-app-net -d -p 8084:8080 -it --name syway txxs/springbootdocker:1.0
2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 1[root@iZwz9cps5bpzjurg8m4ax0Z springboot-docker-test]# docker network inspect springboot-app-net
2[
3 {
4 "Name": "springboot-app-net",
5 "Id": "cf4ca23bcb27914148c822d6f675469a5e8bd87dbf6066890e6aba1593eec9f5",
6 "Scope": "local",
7 "Driver": "bridge",
8 "IPAM": {
9 "Driver": "default",
10 "Config": [
11 {}
12 ]
13 },
14 "Containers": {
15 "9313ea5d190e6675cfa36a0327e81f480e8d0d8e530e21037d2948b7772b8c6f": {
16 "EndpointID": "d1054b8bb430e68a504df200f6d81efb3b7cd62e45534f272659cc40c1bb936c",
17 "MacAddress": "02:42:ac:13:00:02",
18 "IPv4Address": "172.19.0.2/16",
19 "IPv6Address": ""
20 }
21 },
22 "Options": {}
23 }
24]
25 |
1 2
| 1将在bridge网络中的stoic_mayer重新调整网络加入到springboot-app-net中,在原有的网络bridge中的映射关系没有发生改变
2 |
1 2
| 1docker network connect springboot-app-net stoic_mayer
2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| 1root@iZwz9cps5bpzjurg8m4ax0Z /]# docker network inspect springboot-app-net
2[
3 {
4 "Name": "springboot-app-net",
5 "Id": "cf4ca23bcb27914148c822d6f675469a5e8bd87dbf6066890e6aba1593eec9f5",
6 "Scope": "local",
7 "Driver": "bridge",
8 "IPAM": {
9 "Driver": "default",
10 "Config": [
11 {}
12 ]
13 },
14 "Containers": {
15 "9313ea5d190e6675cfa36a0327e81f480e8d0d8e530e21037d2948b7772b8c6f": {
16 "EndpointID": "d1054b8bb430e68a504df200f6d81efb3b7cd62e45534f272659cc40c1bb936c",
17 "MacAddress": "02:42:ac:13:00:02",
18 "IPv4Address": "172.19.0.2/16",
19 "IPv6Address": ""
20 },
21 "eb7b3e268ff248d41b0d421852d1491c862279eacc971664bc28ddd3eac396c9": {
22 "EndpointID": "6a6d9bb12e66a9994e4ffd79f50d1a3fbfdf44ff8a355d7fb2eac28a074fc38d",
23 "MacAddress": "02:42:ac:13:00:03",
24 "IPv4Address": "172.19.0.3/16",
25 "IPv6Address": ""
26 }
27 },
28 "Options": {}
29 }
30]
31
32 |
1 2
| 1容器仅能在网络内通信,不能跨网络进行通信。一个连接到两个网络的容器可与每个网络中的成员容器进行通信。当一个容器连接到多个网络时,外部连接通过第一个(按词典顺序)非内部网络提供。还可以使用--link命令将两个容器连接起来,通过--link选项创建的容器可以对链接的容器名(container-name)作为hostname进行直接访问
2 |
当解除网络关系的时候使用命令:
1 2
| 1docker network disconnet springboot-app-net stoic_mayer
2 |
删除网络:
1 2
| 1docker network rm springboot-app-net
2 |
1 2
| 1docker网络这部分不懂的还有很多,需要花时间继续学习,如果有不正确的请多指正!
2 |