Docker 网络详细解释
Docker 附带了一个网络管理系统。该系统有助于管理容器、托管 Docker 的机器和外部网络之间的通信。它还支持多种网络类型,每种类型适用于不同的典型情况。
在本文中,我将尝试解释 Docker 的网络系统如何工作,并提供有关在容器中使用这些网络的基本指导。
Docker 网络设置容器之间以及与外部服务的通信方式。为了能够访问网络,容器需要成为 Docker 网络的一部分。容器通信的方式取决于其网络连接。
Docker 为核心网络功能提供了五个标准网络驱动程序:
Bridge(桥接)
Host(主机)
Overlay
IPvLAN
Macvlan
Bridge Network(桥接网络)
Bridge networks在主机和容器之间形成虚拟桥梁。该网络上的容器可以相互通信,但与不在网络上的容器之间会被切断。
每个容器都有一个唯一的 IP 地址。由于与主机的桥接连接,这些容器还可以与您的本地网络 (LAN) 和互联网进行交互。但是,它们不会在您的 LAN 上显示为物理设备。
Host Network(主机网络)
使用Host Network模式的容器使用与主机相同的网络设置,而不是隔离的。他们没有单独的 IP 地址。相反,它们使用的任何端口都直接链接到您主机的网络。例如,如果容器进程使用端口 8080(在本例中它将是我们的app
容器),则可以通过 192.168.1.101:8080 访问它,这是您主机的 IP 地址和端口号。
由于我们的app容器使用端口 8080,因此不需要端口映射,因为本例中的容器使用主机端口。我们的数据库使用端口5432,因此可以通过主机IP地址和5432端口访问它。
注意:在主机网络模式下,容器没有单独的IP地址。它们直接使用主机的IP地址和端口。这意味着来自这些容器的任何网络活动看起来都好像来自主机本身
Overlay Network
Overlay networks是分布在多个 Docker 主机上的网络。它们允许任何主机上的容器相互通信,而不需要操作系统来管理路由。
这些网络在 Docker Swarm 集群中用于联网。但如果您有两个单独运行的 Docker 引擎,并且容器需要直接连接,您也可以使用它们。这样,您就可以自己创建类似于 Docker Swarm 的环境。
上图让事情变得简单。因为在实际场景中,就像容器一样,主机也从覆盖网络获取虚拟IP地址,并且这些地址在同一范围内。
IPvLAN网络
IPvLAN 是一种高级驱动程序,可让您对容器的 IPv4 和 IPv6 地址进行详细控制。它还处理第 2 层和第 3 层 VLAN 标记和路由。
如果您需要将容器服务与已有的物理网络连接,此驱动程序会很方便。IPvLAN 网络有自己的接口,其性能优于基于桥接网络的网络。
该图像简化了概念,但它确实表明,包括容器在内的所有内容都在 IPvLAN 设置中获得自己的 IP 地址,并且都是网络的一部分。
Macvlan网络
Macvlan 是一种更高级的选择,可让容器像网络上的物理设备一样运行。它通过为每个容器提供自己的 MAC 地址来实现此目的。
对于这种网络类型,您需要将主机的物理网络接口之一分配给虚拟网络。此外,还应该设置更广泛的网络来处理可能来自具有大量容器的 Docker 主机的许多 MAC 地址。
使用哪种网络类型
桥接网络适合大多数情况。这些网络上的容器可以使用 IP 地址和 DNS 名称相互通信。他们还可以连接到互联网和您的本地网络。
当您需要直接使用主机的网络接口并且不需要分离容器的网络时,主机网络是很好的选择。此设置允许容器化应用程序像主机网络的一部分一样工作。
不同 Docker 主机上的容器之间的直接通信需要覆盖网络。它们非常适合创建分布式设置以提高可靠性。
当您的容器需要看起来像网络上的物理设备(例如用于监控网络流量)时,Macvlan 网络非常有用。IPvLAN 网络用于满足高级需求,例如对容器 IP 地址、标签和路由的特定控制。
创建网络
要创建新网络,请使用docker network create
命令。您可以通过设置标志来指定要使用的驱动程序,例如bridge
或。如果省略该标志,将会创建一个网络。host-dbridge
在第一个终端窗口中运行以下命令:
$ docker network create test-network -d bridge
50ed05634f6a3312e56700ef683ca39df44bfc826e2e4da9179c2593c79910f9
创建的网络的 ID 将发送到您的终端。新网络目前没有用,因为还没有连接容器。
--network
但是您可以通过使用命令设置标志来将新容器附加到网络docker run
。在第二个终端窗口中运行此命令:
$ docker run -it --rm --name container1 --network test-network busybox:latest
接下来,打开第三个终端窗口并启动另一个 Ubuntu 容器,这次没有标志--network
:
$ docker run -it --rm --name container2 busybox:latest
现在尝试使用两个容器的名称在它们之间进行通信:
# in container1
/ # ping container2
ping: bad address 'container2'
容器尚未处于同一网络中,因此它们无法直接相互通信。
使用您的第一个终端窗口加入container2
网络:
$ docker network connect test-network container2
容器现在共享一个网络,这使它们能够互相发现:
# in container1
/ # ping container2
PING container2 (172.22.0.7): 56 data bytes
64 bytes from 172.22.0.7: seq=0 ttl=64 time=2.205 ms
Docker 可让您自由管理网络连接,而无需重新启动容器。在上一节中,您了解了如何在创建容器后连接容器,也可以从它们不再需要参与的网络中删除容器:
$ docker network disconnect test-network container2
您所做的任何更改都将立即应用。
如果要删除网络,请断开或停止使用该网络的所有 Docker 容器,然后将网络的 ID 或名称传递给network rm
:
$ docker network rm test-network
因此,最终,docker 的网络系统提供了不同的方法来管理容器之间、容器之间以及邻近容器和 Docker 主机之间的通信方式。同一网络中的容器可以使用其名称或 IP 地址进行连接。
网络依赖于不同的驱动程序,这些驱动程序可以根据需要进行更改,涵盖最典型的情况。这些网络使用主机的网络设置,但使用称为命名空间的东西将事物分开。这种分离并不像您在虚拟机 (VM) 中看到的那样强烈,但如果您使用 macvlan 网络,容器仍然看起来像网络上的物理设备。