docker容器的网络

准备工作

  • 安装docker

使用默认的网络启动一个容器

Docker通过 network drivers支持容器的网络环境。默认情况下,Docker支持bridgeoverlay两种网络驱动。也可以支持自定义的网络驱动。

每一个Docker Engine都会自动支持三种默认的网络,可以使用docker network ls列出所有的网络驱动:

1
2
3
4
5
6
$ docker network ls
NETWORK ID NAME DRIVER
18a2866682b8 none null
c288470c46f6 host host
7b369448dccb bridge bridge

bridge是一个特殊的网络驱动,如果不做特别指定,所有的容器都会在bridge下启动。尝试一下如下的命令:

1
2
$ docker run -itd --name=networktest ubuntu
74695c9cea6d9810718fddadc01a727a5dd3ce6a69d09752239736c030599741

通过docker network 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
$ docker network inspect bridge
[
{
"Name": "bridge",
"Id": "f7ab26d71dbd6f557852c7156ae0574bbf62c42f539b50c8ebde0f728a253b6f",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.1/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Containers": {
"3386a527aa08b37ea9232cbcace2d2458d49f44bb05a6b775fba7ddd40d8f92c": {
"Name": "networktest",
"EndpointID": "647c12443e91faf0fd508b6edfe59c30b642abb60dfab890b4bdccee38750bc1",
"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": "9001"
},
"Labels": {}
}
]

从一个网络中移除一个容器,如下

1
$ docker network disconnect bridge networktest

以上的命令将networktest容器从bridge网络中移除。使用网络可以方便的将容器隔离。

创建自定义网桥

Docker Engine支持bridgeoverlay模式的网络,bridge模式只能在单机上使用,overlay支持多机使用。接下来,使用bridge创建自定义的网络,

1
$ docker network create -d bridge my_bridge

-d参数指定网络的模式,如果不加-d参数,默认也使用bridge模式。检查一下是否创建成功,

1
2
3
4
5
6
7
$ docker network ls
NETWORK ID NAME DRIVER
7b369448dccb bridge bridge
615d565d498c my_bridge bridge
18a2866682b8 none null
c288470c46f6 host host

使用inspect命令检查新建网络的信息,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ docker network inspect my_bridge
[
{
"Name": "my_bridge",
"Id": "5a8afc6364bccb199540e133e63adb76a557906dd9ff82b94183fc48c40857ac",
"Scope": "local",
"Driver": "bridge",
"IPAM": {
"Driver": "default",
"Config": [
{
"Subnet": "10.0.0.0/24",
"Gateway": "10.0.0.1"
}
]
},
"Containers": {},
"Options": {},
"Labels": {}
}
]

隔离的网络让应用更加安全

接下来,用一个简单的web应用展示如何安全的使用容器的网络。

第一步,在自定义的网络上创建数据库容器,

1
$ docker run -d --net=my_bridge --name db training/postgres

--net参数指定使用的网络,检查是否创建成功,

1
2
3
4
5
$ docker inspect --format='{{json .NetworkSettings.Networks}}' db
{"my_bridge":{"NetworkID":"7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99",
"EndpointID":"508b170d56b2ac9e4ef86694b0a76a22dd3df1983404f7321da5649645bf7043","Gateway":"10.0.0.1","IPAddress":"10.0.0.254","IPPrefixLen":24,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:02"}}

第二步,在默认的网络下创建web应用,

1
$ docker run -d --name web training/webapp python app.py

检查网络信息,

1
2
3
4
5
$ docker inspect --format='{{json .NetworkSettings.Networks}}' web
{"bridge":{"NetworkID":"7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812",
"EndpointID":"508b170d56b2ac9e4ef86694b0a76a22dd3df1983404f7321da5649645bf7043","Gateway":"172.17.0.1","IPAddress":"10.0.0.2","IPPrefixLen":24,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:02"}}

查看web的地址,

1
2
3
4
$ docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web
172.17.0.2

当前的网络拓扑图如下,

第三步,查看网络的连通性,

1
2
3
4
5
6
7
8
$ docker exec -it db bash
root@a205f0dd33b2:/# ping 172.17.0.2
ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
^C
--- 172.17.0.2 ping statistics ---
44 packets transmitted, 0 received, 100% packet loss, time 43185ms

会发现在db上,无法连通到web上。

第四步,将web连接到my_bridge上,

1
$ docker network connect my_bridge web

当前的网络拓扑,

第五步,再一次验证网络的连通性,

1
2
3
4
5
6
7
8
9
10
11
$ docker exec -it db bash
root@a205f0dd33b2:/# ping web
PING web (10.0.0.2) 56(84) bytes of data.
64 bytes from web (10.0.0.2): icmp_seq=1 ttl=64 time=0.095 ms
64 bytes from web (10.0.0.2): icmp_seq=2 ttl=64 time=0.060 ms
64 bytes from web (10.0.0.2): icmp_seq=3 ttl=64 time=0.066 ms
^C
--- web ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.060/0.073/0.095/0.018 ms

会发现db和web已经能够正常的连通。其它不在my_bridge上的容器不能连接到该网络环境中

总结

通过自定义网络环境,可以将安全性要求较高的服务,放入单独的自定义的网络环境中,以此保证服务的安全行。

Comentarios