介绍
在本实验中,我们将基于 Docker 网络的基础知识,深入探讨高级 Docker 网络概念。我们将深入研究三种主要的网络模式:Bridge(桥接)、Host(主机)和 None(无网络)。我们还将学习如何创建自定义网络、跨不同网络连接容器,并理解每种网络模式对容器通信和隔离的影响。通过动手实践,你将获得扎实的 Docker 网络实践基础。
在本实验中,我们将基于 Docker 网络的基础知识,深入探讨高级 Docker 网络概念。我们将深入研究三种主要的网络模式:Bridge(桥接)、Host(主机)和 None(无网络)。我们还将学习如何创建自定义网络、跨不同网络连接容器,并理解每种网络模式对容器通信和隔离的影响。通过动手实践,你将获得扎实的 Docker 网络实践基础。
虽然 Docker 提供了默认的桥接网络,但创建自定义桥接网络可以更好地隔离和控制容器之间的通信。
docker network ls
你应该会看到类似以下的输出:
NETWORK ID NAME DRIVER SCOPE
296d1b460b17 bridge bridge local
91199fc6ad2e host host local
1078d2c781b6 none null local
docker network create my-custom-bridge
docker network ls
你现在应该会在输出中看到 my-custom-bridge
:
NETWORK ID NAME DRIVER SCOPE
296d1b460b17 bridge bridge local
91199fc6ad2e host host local
7215f99d0080 my-custom-bridge bridge local
1078d2c781b6 none null local
docker run --network=my-custom-bridge --name container1 -d nginx
docker run --network=my-custom-bridge --name container2 -d nginx
现在,让我们在这两个容器中安装 ping 工具。我们需要这样做,因为默认的 Nginx 镜像不包含 ping:
docker exec container1 apt-get update && docker exec container1 apt-get install -y iputils-ping
docker exec container2 apt-get update && docker exec container2 apt-get install -y iputils-ping
docker exec container1 ping -c 4 container2
你应该会看到成功的 ping 响应,这表明在同一自定义桥接网络上的容器可以使用容器名称进行通信。这是因为 Docker 内置的 DNS 会在同一网络中将容器名称解析为其 IP 地址。
如果你没有看到成功的 ping 响应,请确保两个容器都在运行(docker ps
),并且你已经正确安装了 ping 工具。
Docker 允许容器连接到多个网络,从而实现不同网络上的容器之间的通信。这在你想隔离某些容器但仍允许它们之间进行特定通信时特别有用。
docker network create my-second-bridge
docker network ls
你现在应该会看到两个自定义网络:
NETWORK ID NAME DRIVER SCOPE
296d1b460b17 bridge bridge local
91199fc6ad2e host host local
7215f99d0080 my-custom-bridge bridge local
8a15f99d0081 my-second-bridge bridge local
1078d2c781b6 none null local
container2
连接到新网络:docker network connect my-second-bridge container2
此命令将 container2
添加到 my-second-bridge
网络,同时保持其与 my-custom-bridge
的连接。
docker run --network=my-second-bridge --name container3 -d nginx
docker exec container3 apt-get update && docker exec container3 apt-get install -y iputils-ping
docker exec container1 ping -c 2 container2
docker exec container1 ping -c 2 container3
docker exec container2 ping -c 2 container3
注意结果:
container1
可以与 container2
通信(它们在同一个网络上)container1
无法与 container3
通信(它们在不同的网络上)container2
可以与 container1
和 container3
通信(它连接到了两个网络)如果 container1
能够 ping 通 container3
,说明你的网络隔离可能存在问题。
主机网络模式移除了容器与 Docker 主机之间的网络隔离,允许容器直接使用主机的网络。这对于最大化性能非常有用,但由于减少了隔离性,会带来一定的安全隐患。
docker run --network host --name host-container -d nginx
docker network ls
你不会看到这个容器的新网络,因为它直接使用了主机的网络。
docker inspect --format '{{.HostConfig.NetworkMode}}' host-container
这应该会输出 host
。
curl localhost:80
你应该会看到 Nginx 的欢迎页面。这是因为容器使用了主机的网络,而 Nginx 正在监听主机网络接口的 80 端口。
注意:如果你的主机上已经有服务运行在 80 端口,这一步可能会失败。在这种情况下,你需要先停止现有的服务。
'none' 网络模式创建的容器没有任何网络接口,完全将其与网络隔离。这对于最大程度的安全隔离非常有用,但也意味着容器无法通过网络进行任何通信。
docker run --network none --name isolated-container -d alpine sleep infinity
docker network ls
你不会看到这个容器的新网络,因为它没有连接到任何网络。
docker exec isolated-container ip addr
你应该只会看到回环接口(lo)。不会有任何 eth0 或其他网络接口。
docker exec isolated-container ping -c 2 google.com
这应该会失败,并显示“Network is unreachable”(网络不可达)错误,因为容器没有网络访问权限。
Docker 网络支持使用网络别名进行服务发现,这对于创建弹性、可扩展的应用程序非常有用。此功能允许多个容器响应相同的 DNS 名称,从而实现基本的负载均衡。
docker network create service-network
docker network ls
你应该会在列表中看到 service-network
。
docker run -d --network service-network --network-alias myservice --name service1 nginx
docker run -d --network service-network --network-alias myservice --name service2 nginx
nslookup
解析服务:docker run --rm --network service-network appropriate/curl nslookup myservice
你应该会看到返回的两个容器 IP,这表明 Docker 的内置 DNS 服务器正在两个容器之间进行负载均衡。
for i in {1..4}; do docker run --rm --network service-network appropriate/curl ping -c 1 myservice; done
你应该会看到来自两个容器的响应,这展示了基本的负载均衡。Docker DNS 服务器在解析 myservice
时会在两个 IP 地址之间交替选择。
PING myservice (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.106 ms
--- myservice ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.106/0.106/0.106 ms
PING myservice (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.119 ms
--- myservice ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.119/0.119/0.119 ms
PING myservice (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.097 ms
--- myservice ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.097/0.097/0.097 ms
PING myservice (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.140 ms
--- myservice ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.140/0.140/0.140 ms
在这个高级 Docker 网络实验中,我们探索了几个关键概念:
Docker 中的这些高级网络功能为设计复杂的多容器应用程序提供了强大的工具,能够精确控制容器之间的通信和隔离。理解这些概念对于设计高效、安全和可扩展的容器化应用程序至关重要。
请记住,虽然 Docker 网络提供了极大的灵活性,但在设计容器网络架构时,考虑安全影响非常重要。始终遵循最小权限原则,仅暴露必要的端口和服务。
随着你继续使用 Docker,你会发现这些网络概念在编排复杂应用程序和微服务架构时非常宝贵。定期练习这些概念,以便熟练掌握 Docker 网络的有效管理。