Docker
在创建容器的时候,可以使用--net
选项指定容器的的网络模式。
Docker
支持4种网络模式供大家选择:
- -net=host
指定。- -net=container:NAME_or_ID
指定。- -net=none
指定。- -net=bridge
指定,默认设置。众所周知,Docker
使用了Linux
的Namespaces
技术来进行资源隔离,如PID Namespace
隔离进程,Mount Namespace
隔离文件系统,Network Namespace
隔离网络等。一个Network Namespace
提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的Network Namespace
隔离。一个Docker
容器一般会分配一个独立的Network Namespace
。但如果启动容器的时候使用host
模式,那么这个容器将不会获得一个独立的Network Namespace
,而是和宿主机共用一个Network Namespace
。容器将不会虚拟出自己的网卡,配置自己的IP
等,而是使用宿主机的IP
和端口。
例如,我们在10.10.101.105/24
的机器上用host
模式启动一个含有web
应用的Docker
容器,监听tcp80
端口。当我们在容器中执行任何类似ifconfig
命令查看网络环境时,看到的都是宿主机上的信息。而外界访问容器中的应用,则直接使用10.10.101.105:80
即可,不用任何NAT
转换,就如直接跑在宿主机中一样。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
在理解了host
模式后,这个模式也就好理解了。这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace
,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP
,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。
这个模式和前两个不同。在这种模式下,Docker
容器拥有自己的Network Namespace
,但是,并不为Docker
容器进行任何网络配置。也就是说,这个Docker
容器没有网卡、IP、路由等信息。需要我们自己为Docker
容器添加网卡、配置IP
等。
bridge
模式是Docker
默认的网络设置,此模式会为每一个容器分配Network Namespace
、设置IP
等,并将一个主机上的Docker
容器连接到一个虚拟网桥上。
当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
。
安装完Docker
的时候,会自动创建三个网络。使用docker network ls
命令可以查看这些网络:
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
75b73b341642 bridge bridge local
dbef3961eb84 host host local
90741a2555ee none null local
这三个网络都建在Docker
中。运行容器时,可以使用该--network
标志来指定容器应连接到的网络。
Docker
服务启动后默认会创建一个 docker0
网桥(其上有一个 docker0
内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。
Docker
默认指定了 docker0
接口 的 IP
地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了 MTU
(接口允许接收的最大传输单元),通常是 1500 Bytes
,或宿主主机网络路由上支持的默认值。这些值都可以在服务启动的时候进行配置。
bridge
所有Docker
主机上都存在默认网络。如果您不指定其他网络,则新的容器会自动连接到默认bridge
网络。
使用docker network inspect
命令可以查看相关的网络信息:
$ docker network inspect 75b73b341642
[
{
"Name": "bridge",
"Id": "75b73b3416429364a268ba6db607cb6bffbc921241714228d22fd95c15cde76f",
"Created": "2019-01-01T05:13:00.609463Z",
"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,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"1bd6dc5dbb7c6a73801ce682d4fe590cff14ba046837c75de70b7a2f756cdd21": {
"Name": "boring_nash",
"EndpointID": "060084e59605428932e9862193ede495b23459d4d8039b1ef4e0f25099726599",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"3dc606b07fbbbc2e2040104764b81cf6fbccf1594f4da99fcf03264ad2fcb9d6": {
"Name": "rabbitmq",
"EndpointID": "08031fb6659f74caa2940d473f3c5ccbc849a5af485361705e63c3df66927e8c",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"4b8887d1cf1cbe7c8d17990d2c91dce95f7099e9a9f178b6feed525b7879a369": {
"Name": "objective-mysql",
"EndpointID": "9732e3b010e7053cf8e3d0f0985e5e26557d75a4930d100452ac71c5e97ecc15",
"MacAddress": "02:42:ac:11:00:04",
"IPv4Address": "172.17.0.4/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": {}
}
]
分享计划
博客内容将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/
许可协议
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 许可协议,转载请注明出处。