由于容器的隔离性,它们不共享主机网络,但 Docker 为它们提供了网络 。
当 Docker 运行时启动时,它会创建 3 个默认网络:
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
5c65c2b3031b bridge bridge local
cf446ef29441 host host local
50fd86384bb9 none null local
桥接网络
首先,我们可以通过检查网络来检查配置:
$ docker network inspect bridge
[
{
"Name": "bridge",
"Id": "5c65c2b3031b6d10f357f74f6cb5bf04af13819fca28b5458e00bb6b1d1718ec",
"Created": "2022-06-27T23:49:43.227773167Z",
"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": {}
}
]
我们可以看到网络通过Gateway 172.17.0.1进行响应,此时没有添加容器。
桥接网络提供桥接驱动程序,以便在此网络中创建的容器接收IP 地址。
为了确认这一点,我们创建一个 NGINX 容器:
$ docker run --name nginx --network bridge -d nginx
它只是一个在容器端口上运行的 NGINX Web 应用程序80,并提供传统的 HTML 页面“欢迎来到 NGINX”。
容器是否已添加到网络中?
$ docker network inspect bridge
...
"Containers": {
"bb283ee626dbc631281fc0c27a1f02f075ab1908800965008a315cedd7f9d438": {
"Name": "nginx",
"EndpointID": "f12f67c1d7488f708027c2e948b204ce09743721095d4514c9c24bedf8167191",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
我们可以看到最近创建的容器已添加到bridge网络中并获得了 IP 地址172.17.0.2。
我们如何使用它的 IP 与这样的容器进行通信,换句话说,我们可以点击http://172.17.0.2并看到“Welcome to NGINX”HTML 结果吗?
$ wget http://172.17.0.2 -O -
Connecting to 172.17.0.2:80...
容器不共享主机网络
同样,容器不共享“主机”网络。这意味着只有同一网络(网桥)中的其他容器才能相互通信。
好的,我们可以运行另一个容器并访问 NGINX 吗?
$ docker run \
--network bridge \
alpine \
sh -c "wget http://172.17.0.2 -O -"
Connecting to 172.17.0.2 (172.17.0.2:80)
writing to stdout
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
- 100% |********************************| 615 0:00:00 ETA
written to stdout
Bridge 已经是默认网络
只是为了节省时间,每当我们创建容器时,它们都会自动添加到网络中bridge。
主机网络
当我们需要将容器暴露给主机网络时,这个网络非常有用。 host模式主要用于对网络性能要求高、追求传输效率的服务,但是需要注意的是会占用主机的端口,多个容器工作可能需要处理冲突。
$ docker --name nginx --network host -d nginx
$ docker network inspect host
[
{
"Name": "host",
"Id": "cf446ef29441aeaaee2a40cfcf9ad120aedb7c51cf2dbc20cc23e567101d217c",
"Created": "2022-01-13T21:57:00.2326735Z",
"Scope": "local",
"Driver": "host",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": []
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"668c12bbabb8cd28e8cc8666d074fc929214f7b9ddfddfa3d76c8476652c4091": {
"Name": "nginx",
"EndpointID": "738ea09ee3d450e9f655440a303a52f219d9ca22fe011eb62dffe7d0351f31de",
"MacAddress": "",
"IPv4Address": "",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
我们可以看到容器添加到网络中,但它没有 IP 地址,这意味着其他容器无法与它通信,只能与主机通信。
# Linux only
$ wget http://localhost -O -
注意:该网络仅适用于 Linux。在 Mac 或 Windows 的 Docker Desktop 中,我们必须使用另一种方式将容器暴露给主机。
-p 选项
将容器暴露给主机的另一种方法是使用 flag ,它本身-p不是主机网络,但它将 [container port] 发布到 [host port] 。
$ docker run --name nginx -p 80:80 -d nginx
$ wget http://localhost -O -
无网络
任何时候我们需要创建一个完全隔离的容器,不与任何其他容器通信,我们都可以将其添加到none使用驱动程序的网络中null。
$ docker run --name nginx --network none -d nginx
$ docker network inspect none
[
{
"Name": "none",
"Id": "50fd86384bb9cc90d953a624a5ab70b869357027d3cdc7ebc9b4043798dd4f6a",
"Created": "2022-01-13T21:57:00.224557375Z",
"Scope": "local",
"Driver": "null",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": []
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"90a6691b818e164bd2e1f67e8f3a62ce71eaddbe9ac215c370a8a6766204a2b0": {
"Name": "nginx",
"EndpointID": "0ed9e33f051f2df2c37b96fc2fdf7df074b73359117a12a81ae4c28ef0ec6877",
"MacAddress": "",
"IPv4Address": "",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
该网络没有网关 IP,因此不要将IP 地址与容器关联。