Docker使用Linux桥接,在主机构建了一个特殊的、可定制的虚拟网络拓扑结构,Docker网桥接口路由,这个网桥接口被成为docker0。
每一个容器都被赋予一个唯一的私有IP地址,从外部的网络是不能直接连接到该私有IP。主机上的每个容器都会连接到docker0,构成一个网络,同时网桥接口docker0会连接到主机所连接的网络上。
1、查看Docker容器网络
Docker安装后自动提供了三种网络,可以使用docker network ls命令查看:
1
2
3
4
5
|
$~ docker network ls
NETWORK ID NAME DRIVER SCOPE
50d276f46ba7 bridge bridge local
f7d70556f900 host host local
7081fbaf563c none null local
|
2、四种网络容器原型
所有的Docker容器要符合四种原型中的一种,原型定义了一个容器如何和本地容器、主机网络进行通信,每种原型有不同的目的,隔离程度。
- Closed容器,容器中进程只能访问本地回环接口,不允许任何的网络流量,容器内进程不能访问容器外的网络,容器外程序也无法连接到容器网络接口上。
docker run 命令后添加参数–net none,即可创建Closed容器:
1
2
3
4
5
6
7
8
9
|
$ docker run --rm --net none alpine ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN qlen 1000
link/tunnel6 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
|
- Bridged容器 拥有两个接口:私有的本地回环接口和一个通过网桥连接主机的私有接口。Bridged容器是Docker的默认选项,可定制性最高,被认为是最佳实践。
docker run 命令忽略–net选项,或者–net 值设置为bridge,创建一个Brided容器:
1
2
|
$docker run --rm --net bridge alpine:latest ip addr
$docker run --rm alpine:latest ip addr
|
从容器中访问阿里DNS服务器:
1
2
3
4
5
6
7
8
|
$ docker run --rm alpine:latest ping -w 2 223.5.5.5 0 [15:36:26]
PING 223.5.5.5 (223.5.5.5): 56 data bytes
64 bytes from 223.5.5.5: seq=0 ttl=37 time=27.976 ms
64 bytes from 223.5.5.5: seq=1 ttl=37 time=31.903 ms
--- 223.5.5.5 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 27.976/29.939/31.903 ms
|
Joined容器原型隔离程度更低,这些容器共享一个网络栈,容器之间没有任何隔离。
可以使用docker run –network将两个容器进行连接,如下:第一个命令启动一个在本地回环接口监听的服务器,第二个命令连接第一个容器,并列出当前容器所有的开发端口。
1
2
3
4
5
6
7
8
9
|
$ docker run -d --name tudou --net none alpine:latest nc -l 127.0.0.1:4444
a72ecddb0f461720495960331c36ea29594e7986e87e8fa2f1cfff9f41468301
$ docker run -it --rm --network container:tudou alpine netstat -al
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:33957 0.0.0.0:* LISTEN
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node Path
|
当两个容器被连接,每一个接口都被共享,因此会引入端口冲突的问题。
Joined容器的使用场景:
- 想要不同容器上的程序通过本地回环接口进行通信
- 一个容器中的程序将要改变Joined网络栈,而另外一个程序将要使用那个被改变的网络栈
- 想要监控另外一个容器中某个程序的网络流量
Open容器非常危险。它没有网络容器,并对主机网络有完全的访问权。
docker run 命令的–net选项值为host时,就会创建Open容器:
1
|
$ docker run --rm --net host alpine ip addr
|