面向开发人员的 Docker 网络概念
在这篇博文中,我们将学习 Docker 网络概念。例如覆盖网络、Docker Swarm、嵌入式 DNS 服务器、路由网格等。
三种类型的 Docker 网络..
首先我们来了解一下docker中可用的三种网络类型:“bridge”,“none”和“host”。

网桥是容器默认连接到的网络。如果要将容器关联到其他网络,则需要使用 network 命令行参数指定网络信息,如下所示:
docker run --network=ubuntu
用法:docker run [选项] IMAGE [命令] [参数…]
桥接网络是 Docker 在主机上创建的私有内部网络。所有容器默认连接到此网络,并获得一个内部 IP 地址。通常在 170.17.xx 范围内。
如果需要,容器可以使用此内部 IP 相互访问。为了从外部访问这些容器,docker 桥接架构将这些容器的端口映射到 docker 主机上的端口。
另一种类型的网络是主机网络。它消除了 Docker 主机和 Docker 容器之间的任何网络隔离。
例如,如果您要在连接到主机网络的 web-app 容器中的端口 5000 上运行 web 服务器,则可以自动在同一端口上从外部访问它,而无需使用 -p 选项发布端口。
docker run --network=host ubuntu
用法:docker run --network=[bridge | none | host] [IMAGE]
作为使用主机网络的 Web 容器,这意味着与以前不同,您现在将无法在同一主机和端口上运行多个 Web 容器,因为这些现在对于主机网络中的所有容器都是通用的。

第三种是 None 网络。容器不连接到任何网络,也无法访问外部网络或其他容器。它与所有其他网络隔离。

docker run --network=none ubuntu
多节点集群中的桥接网络
让我们更详细地了解一下桥接网络。
例如,假设我们有多个 Docker 主机运行容器。每个 Docker 主机都有自己的内部私有网络,地址范围是 172.17.xx 系列,允许每个主机上运行的容器相互通信。但是,除非您发布这些容器上的端口并自行设置某种路由,否则跨主机的容器无法相互通信。

Docker Swarm 中的覆盖网络
这正是 Docker Swarm 中覆盖网络发挥作用的地方。
您可以创建一个新的覆盖网络类型,它将创建一个覆盖所有参与 Swarm 集群节点的内部私有网络。
docker network create driver -d overlay subnet --10.0.9.0/24 my-overlay-network
用法:docker network create [OPTIONS] NETWORK
然后,我们可以在创建服务时使用--network选项将容器或服务附加到该网络,这样我们就可以让它们通过覆盖网络相互通信。
docker service create --replicas --network my-overlay-network nginx
用法:docker service create [选项] 图像 [命令] [参数...]

多个容器如何在同一个端口上发布?
之前我们学习了端口发布或端口映射。假设我们在 5000 端口上运行一个 Web 服务。为了让外部用户访问该 Web 服务,我们必须映射 Docker 主机上的端口。在本例中,我们将容器上的 5000 端口映射到 Docker 主机上的 80 端口。
完成此操作后,用户将能够使用 80 端口的 URL 访问 Web 服务器。这在运行单个容器时有效,并且易于理解,但在使用如图所示的 Swarm 集群时则不然。
例如,假设此主机是一个单节点 Swarm 集群。假设我们要创建一个包含两个副本的 Web 服务器服务,并将端口 80 映射到 5000。由于这是一个单节点集群,因此两个实例都部署在同一个节点上。这将导致两个 Web 服务容器都尝试将其 5000 端口映射到 Docker 主机上的公共端口 80,但我们不能将两个映射映射到同一个端口。

入口网络
这时,Ingress 网络就派上用场了。创建 Docker Swarm 集群时,它会自动创建一个 Ingress 网络。Ingress 网络内置负载均衡器,可以重定向来自已发布端口(在本例中为 80 端口)的流量。所有映射的端口均为每个容器上的 5000 端口。由于 Ingress 网络是自动创建的,因此您无需进行任何配置。
您只需运行 service create 命令创建所需的服务,并使用 -p 参数发布您想要发布的端口即可。和之前一样,ingress 网络和内部负载均衡开箱即用,但了解其实际工作原理至关重要。
docker service create — replicas=2 -p 80:5000 my-web-server
用法:docker service create [选项] IMAGE [命令] [参数…]
现在让我们看看当 Docker Swarm 集群中有多个节点时它是如何工作的。在本例中,我们有一个三节点的 Docker Swarm 集群,运行着两个 Web 服务器实例。由于我们只请求了两个副本,所以第三个 Docker 主机是空闲的,并且没有实例。我们先不讨论 Ingress 网络,看看在没有 Ingress 网络的情况下这种安排是如何工作的。
如果没有 Ingress 网络,我们该如何期望用户在多节点的 Swarm 集群中访问我们的服务?
由于这是一个集群,我们希望用户能够从集群中的任何节点访问服务,这意味着任何用户都应该能够使用任意容器的 IP 地址访问 Web 服务器,因为它们都属于同一个集群。
如果没有 Ingress 集群网络,用户可以访问节点 1 和 2 上的 Web 服务器,但无法访问节点 3 上的 Web 服务器,因为节点 3 上没有运行 Web 服务实例。
现在让我们回顾一下 Ingress 网络。Ingress
网络实际上是一种覆盖集群中所有节点的覆盖网络。该负载均衡器的工作方式是,它接收来自集群中任何节点的请求,并将其转发到任何其他节点上的相应实例,从而实质上创建了一个路由网格。

由入口网络创建的路由网格
路由网格有助于将未运行 Web 服务实例的节点上接收到的用户流量路由到实际运行实例的其他节点。同样,所有这些都是 docker swarm 的默认行为,您无需进行任何其他配置。只需创建您的服务、指定副本数量并发布端口即可。Docker swarm 将确保实例在集群中均匀分布。端口在所有节点上发布,用户可以使用任意节点的 IP 访问服务。当他们这样做时,流量会在内部路由到正确的服务。
容器如何相互发现?
我们一直在讨论容器之间的通信。那么它究竟是如何工作的呢?
例如,在这种情况下,我有一个 Web 服务和一个 MySQL 数据库服务在同一个节点或工作器上运行。
如何让用户或服务访问数据库容器上的数据库?您可以使用 MySQL 容器的内部 IP 地址,在本例中为 172.12.0.3。
mysql.连接(172.17.0.3)
但是,这并非理想情况,因为无法保证容器在系统重启时获得相同的 IP。正确的做法是使用容器名称。Docker 主机中的所有容器都可以通过容器名称相互解析。Docker 内置 DNS 服务器,可帮助容器使用容器名称相互解析。请注意,内置 DNS 服务器始终运行在 127.0.0.11 地址上。
好了,以上就是 Docker Swarm 网络的快速介绍。
如果您喜欢这篇文章并想了解更多,请务必点赞 50 次并关注我的博客。
想要了解更多关于 Docker 的实践操作,请访问 kodekloud.com。KodeKloud 提供在线、自定进度、互动式的实践课程,涵盖 Docker、Kubernetes、OpenShift 等各种技术,以及 Ansible、Puppet 和 Chef 等自动化工具。
观看下面的视频,
本文最初发表于codeburst,发布在这里是为了获得更多有价值的信息并帮助社区。
文章来源:https://dev.to/kodekloud/docker-networking-concepts-for-developers-58la