一、Bridge桥接模式
bridge网络模式是Docker容器的默认网络模式,它可以使用一个Linux bridge设备,默认为docker0;利用veth0,一头连接在容器的网络namespace中,另一头在docker0上,互相连接来进行通信,在该模式下Docker Container不具有一个公有IP,因为宿主机的IP地址与veth pair的ip地址不在同一网段内;Docker采用NAT转换的方式,将容器内部的服务监听的端口与宿主机的某一个端口进行"绑定",使得宿主机以外的世界可以主动将网络报文发送至容器内部,外界访问容器内的服务时,需要访问宿主机的IP以及宿主机的端口。
# 查看网络模式信息
[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
2448303ed0fc bridge bridge local
583184b1f8e0 harbor_harbor bridge local
ff35fa4400e4 host host local
1af23f0e55b5 none null local
# 查看bridge桥接模式的网络信息
[root@docker ~]# docker inspect network bridge
[
{
"Name": "bridge",
"Id": "2448303ed0fc762762aa15214cbf802d0d3032521f88e3cc46054093fcb18249",
"Created": "2019-09-28T14:51:41.530125413+08:00",
"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": {},
"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": {}
}
]
自定义桥设备:
# 创建一个名为mybr0的桥接设备
[root@docker ~]# docker network create -d bridge --subnet "172.27.0.0/16" --gateway "172.27.0.1" mybr0
3342336ee16ac5c8dda3263370b334ac97c7d5a7d7a2ac258fc0a920389372b4
[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
2448303ed0fc bridge bridge local
583184b1f8e0 harbor_harbor bridge local
ff35fa4400e4 host host local
3342336ee16a mybr0 bridge local
1af23f0e55b5 none null local
# 查看mybr0设备的详细信息
[root@docker ~]# docker network inspect mybr0
[
{
"Name": "mybr0",
"Id": "3342336ee16ac5c8dda3263370b334ac97c7d5a7d7a2ac258fc0a920389372b4",
"Created": "2019-09-28T15:16:16.939025763+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.27.0.0/16",
"Gateway": "172.27.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
启用一个此模式的容器:
# 创建一个名为myweb01的nginx容器;--network可指明使用的桥设备
[root@docker ~]# docker run --name myweb01 -d --network mybr0 -p 8080:80 nginx
597f307f2559c887b3f37cfe8e233a5f81554e00fa0afbf7cdea2af9b83e162e
# 查看myweb01的详细信息
[root@docker ~]# docker inspect myweb01
"mybr0": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"597f307f2559"
],
"NetworkID": "3342336ee16ac5c8dda3263370b334ac97c7d5a7d7a2ac258fc0a920389372b4",
"EndpointID": "bc760320a388d1a65d876b4461a02ca8f2eb42a900ef69a6328b5724f80bbcc4",
"Gateway": "172.27.0.1",
"IPAddress": "172.27.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:1b:00:02",
"DriverOpts": null
}
# 查看端口映射信息
[root@docker ~]# docker port myweb01
80/tcp -> 0.0.0.0:8080
[root@docker ~]# curl localhost:8080 -I
HTTP/1.1 200 OK
Server: nginx/1.17.3
Date: Sat, 28 Sep 2019 07:29:43 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 13 Aug 2019 08:50:00 GMT
Connection: keep-alive
ETag: "5d5279b8-264"
Accept-Ranges: bytes
# 查看路由转换信息
[root@docker ~]# iptables -t nat -L -n -v | grep "172.27.0.*"
0 0 MASQUERADE all -- * !br-3342336ee16a 172.27.0.0/16 0.0.0.0/0
0 0 MASQUERADE tcp -- * * 172.27.0.2 172.27.0.2 tcp dpt:80
2 104 DNAT tcp -- !br-3342336ee16a * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.27.0.2:80
二、Host网络模式
Host网络模式并没有为容器创建一个隔离的网络环境。而之所以称之为host模式,是因为该模式下的Docker容器会和本地宿主机共享一个同一个网络名称空间,故Docker Container可以和宿主机一样,使用宿主机的eth0等网卡设备,实现和外界的通信。换言之,Docker Container的IP地址即为宿主机的eth0网卡设备的IP地址;这种模式下的容器没有隔离的Network Namespace,容器的IP地址同宿主机的IP地址,需要注意的是容器中服务的端口号不能与宿主机上已经使用了的端口号相冲突;Host网络模式可以和其他模式相共存。
# 创建myweb02容器,并指明它使用的网络模式为host
[root@docker ~]# docker run --name myweb02 -d --network host nginx:latest
WARNING: Published ports are discarded when using host network mode
945a4959f74a0c14498cc7d901a1091460f108baa9329add3c15d082b29304b7
[root@docker ~]# docker inspect myweb02
"Networks": {
"host": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "ff35fa4400e43347564b0eda09c9c13d35ac71d89888adb02b1d3a9caf170394",
"EndpointID": "",
"Gateway": "",
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "",
"DriverOpts": null
}
}
三、Container模式
Container网络模式是Docker中一种比较特殊的网络的模式,处于这个模式下的Docker容器会共享其他容器的网络环境,因此,至少这两个容器之间不存在网络隔离,而这两个容器又与宿主机以及除此之外其他的容器存在网络隔离。
也就是说,虽然我们启动的是不同的容器,但是他们彼此之间是可以使用localhost进行通讯的。
# 创建myweb03容器,使其共享myuweb01容器的网络名称空间
[root@docker ~]# docker run --name myweb03 -d --network container:myweb01 nginx:latest
9bd76830a1dc0e03a77b77a3ed7d37076e7286d0a1744afaa54a44d3c1303455
[root@docker ~]# docker inspect myweb03
"NetworkSettings": {
"Bridge": "",
"SandboxID": "",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"MacAddress": "",
"Networks": {}
}
四、None网络模式
None网络模式即不为Docker容器构造任何的网络环境。一旦Docker容器采用了None网络模式,那么容器内部就只能使用loopback网络设备,不会再有其他的网络资源。Docker Container的None网络模式意味着不给该容器创建任何的网络环境,容器只能使用127.0.0.1的本机网络栈。
[root@docker ~]# docker run --name myweb04 -d --network none nginx:latest
629c73b9a7cc795bd97bfccb22cb4f8f6fc1b96587046f7ce27a97496b026532
"Networks": {
"none": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "1af23f0e55b5ceabcaf4c1aaa405e964deaf27760ac38bc497e75456f997d570",
"EndpointID": "9daba49d1574300af3017817ff4f905f933c5a4465180dee673c719e563a229a",
"Gateway": "",
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "",
"DriverOpts": null
}