DockerNetWork
Docker 容器和服务如此强大的原因之一是您可以将它们连接在一起,或者将它们连接到非 Docker 工作负载。 Docker 容器和服务甚至不需要知道它们部署在 Docker 上,或者它们的对等点是否也是 Docker 工作负载。无论您的 Docker 主机运行 Linux、Windows 还是两者的混合,您都可以使用 Docker 以与平台无关的方式管理它们。
本主题定义了一些基本的 Docker 网络概念,并让您准备好设计和部署应用程序以充分利用这些功能。
Scope of this topic
本主题不涉及有关 Docker 网络如何工作的特定于操作系统的详细信息,因此您将找不到有关 Docker 如何在 Linux 上操作 iptables 规则或它如何在 Windows 服务器上操作路由规则的信息,您也不会找到有关 Docker 如何操作的详细信息形成和封装数据包或处理加密。请参阅 Docker 和 iptables。
此外,本主题不提供任何有关如何创建、管理和使用 Docker 网络的教程。每个部分都包含相关教程和命令参考的链接。
Network drivers
Docker 的网络子系统是可插拔的,使用驱动程序。默认情况下存在几个驱动程序,并提供核心网络功能:
- **bridge ** 默认网络驱动程序。如果您未指定驱动程序,则这是您正在创建的网络类型。当您的应用程序在需要通信的独立容器中运行时,通常会使用桥接网络。参见桥接网络。
- host 对于独立容器,去掉容器和 Docker 主机之间的网络隔离,直接使用主机的网络。See use the host network
- overlay 覆盖网络将多个 Docker 守护进程连接在一起,并使 swarm 服务能够相互通信。您还可以使用覆盖网络来促进 swarm 服务和独立容器之间的通信,或者不同 Docker 守护程序上的两个独立容器之间的通信。这种策略消除了在这些容器之间进行操作系统级路由的需要。 See overlay networks.
- ipvlan IPvlan 网络使用户可以完全控制 IPv4 和 IPv6 寻址。 VLAN 驱动程序建立在此之上,为对底层网络集成感兴趣的用户提供了对第 2 层 VLAN 标记甚至 IPvlan L3 路由的完全控制权。See IPvlan networks.
- macvlan Macvlan 网络允许您为容器分配 MAC 地址,使其显示为网络上的物理设备。 Docker 守护进程通过它们的 MAC 地址将流量路由到容器。在处理期望直接连接到物理网络而不是通过 Docker 主机的网络堆栈路由的遗留应用程序时,使用 macvlan 驱动程序有时是最佳选择。See Macvlan networks.
- none 对于此容器,禁用所有网络。通常与自定义网络驱动程序一起使用。 none 不适用于 swarm 服务。See disable container networking.
- Network plugins 您可以通过 Docker 安装和使用第三方网络插件。这些插件可从 Docker Hub 或第三方供应商处获得。请参阅供应商的文档以安装和使用给定的网络插件
Networking tutorials
现在您已经了解了有关 Docker 网络的基础知识,请使用以下教程加深您的理解:
- Standalone networking tutorial
- Host networking tutorial
- Overlay networking tutorial
- Macvlan networking tutorial
Networking with overlay networks
本系列教程涉及 swarm 服务的网络。有关使用独立容器联网,see Networking with standalone containers 如果您需要了解有关 Docker 网络的更多信息,请参阅概述
本主题包括四个不同的教程。您可以在 Linux、Windows 或 Mac 上运行它们中的每一个,但对于最后两个,您需要在其他地方运行第二个 Docker 主机。
- 使用默认覆盖网络演示了如何使用 Docker 在您初始化或加入 swarm 时自动为您设置的默认覆盖网络。该网络不是生产系统的最佳选择。
- 使用用户定义的覆盖网络展示了如何创建和使用您自己的自定义覆盖网络来连接服务。这建议用于生产中运行的服务。
- 为独立容器使用覆盖网络展示了如何使用覆盖网络在不同 Docker 守护程序上的独立容器之间进行通信。
- 容器和 swarm 服务之间的通信使用可附加的覆盖网络在独立容器和 swarm 服务之间建立通信
Prerequisites
这些要求您至少有一个单节点 swarm,这意味着您已经启动了 Docker 并在主机上运行了 docker swarm init。您也可以在多节点集群上运行示例。
使用默认的overlay网络
在此示例中,您启动了一个 alpine 服务并从各个服务容器的角度检查网络的特征。本教程不涉及有关如何实现覆盖网络的特定于操作系统的详细信息,而是从服务的角度关注覆盖如何发挥作用。
Prerequisites
本教程需要三个可以相互通信的物理或虚拟 Docker 主机。本教程假设三台主机在同一个网络上运行,不涉及防火墙。
这些主机将被称为 manager、worker-1 和 worker-2。 manager 主机将同时充当 manager 和 worker,这意味着它既可以运行服务任务又可以管理 swarm。 worker-1 和 worker-2 将仅作为工人工作,
演练(Walkthrough)
Create the swarm
在此过程结束时,所有三个 Docker 主机都将加入到 swarm 中,并将使用称为 ingress 的覆盖网络连接在一起。
-
在manager节点上初始化群。如果主机只有一个网络接口,则 --advertise-addr 标志是可选的
docker swarm init --advertise-addr=<IP-ADDRESS-OF-MANAGER> ## 执行命令后会展示如下 docker swarm join --token SWMTKN-1-3xepig1vnyncojgz3dkvr54slxvyy245ccmqrju0xq64vtxn4f-0p3msbwr46g43a8ep08xyjtl2 192.168.142.111:2377 ## 查看节点 docker network ls docker network ls --filter role=worker
-
在worker节点上,可以使用上面的命令加入swarm集群
## 加入 docker swarm join --token SWMTKN-1-3xepig1vnyncojgz3dkvr54slxvyy245ccmqrju0xq64vtxn4f-0p3msbwr46g43a8ep08xyjtl2 192.168.142.111:2377 ## 离开swarm集群可以使用下面命令 docker swarm leave
-
在manager节点上查看网络
[root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 85c838a1ef74 bridge bridge local 95afaf625843 docker_gwbridge bridge local eda8e6f73ffc host host local rfzvaf4snuf2 ingress overlay swarm 902d5b136046 none null local
docker_gwbridge 将入口网络连接到 Docker 主机的网络接口,以便流量可以流入和流出 swarm manager 和 worker。如果您创建 swarm 服务但未指定网络,它们将连接到入口网络。建议您为将协同工作的每个应用程序或应用程序组使用单独的覆盖网络。在下一个过程中,您将创建两个覆盖网络并将服务连接到每个网络。
-
在manager节点创建服务
docker service create \ --name my-nginx \ --publish target=80,published=80 \ --replicas=5 \ --network nginx-net \ nginx ## 更新服务 docker service update \ --network-add nginx-net-2 \ --network-rm nginx-net \ my-nginx
-
查看 manager、worker-1 和 worker-2 上的 nginx-net 网络。请记住,您不需要在 worker-1 和 worker-2 上手动创建它,因为 Docker 为您创建了它。输出会很长,主要注意 Containers 和 Peers 部分。 Containers 列出了从该主机连接到覆盖网络的所有服务任务(或独立容器)。
docker network inspect nginx-net
[ { "Name": "nginx-net", "Id": "yu54hpy0df56a9qa5s33rkhy7", "Containers": { "c676af8fa8d3de13e4051ad105b3b306df1e3933512ac619bccb5360e52912ba": { "Name": "my-nginx.5.so1x1poaohhbaqeygf8w1dg7u", "EndpointID": "cc997f6f013d5be2515e73d597987973ac297722aa79d6e37c2e77799336b429", "MacAddress": "02:42:0a:00:01:06", "IPv4Address": "10.0.1.6/24", "IPv6Address": "" }, "d6e3748aeb3e9b0f1bb1e07fed192fc4fd7ebebb222ffdfcadc7fdda1e298529": { "Name": "my-nginx.2.ek0lpao3uu0w4f05mdxdf30ln", "EndpointID": "66be757cc325d0f573b5dadbbb0cecf05422935a4f5d6b7ceec7db9b346e8b0c", "MacAddress": "02:42:0a:00:01:03", "IPv4Address": "10.0.1.3/24", "IPv6Address": "" }, "lb-nginx-net": { "Name": "nginx-net-endpoint", "EndpointID": "5aadb6c03958ced922341d2beeee9a746d52e562395b1fc5afe0bce980ba0fe9", "MacAddress": "02:42:0a:00:01:09", "IPv4Address": "10.0.1.9/24", "IPv6Address": "" } }, "Peers": [ { "Name": "23244938e112", "IP": "192.168.142.111" }, { "Name": "30cb96547927", "IP": "192.168.142.112" } ] } ]
-
在manager节点上查看service信息,docker service inspect my-nginx, 主要注意 Endpoint和 Ports部分
[ { "ID": "y0cpqz8lt4giiqdg7oq0fv9n7", "Endpoint": { "Ports": [ { "Protocol": "tcp", "TargetPort": 80, "PublishedPort": 80, "PublishMode": "ingress" } ], "VirtualIPs": [ { "NetworkID": "rfzvaf4snuf25jb5k0aht06bb", "Addr": "10.0.0.5/24" }, { "NetworkID": "yu54hpy0df56a9qa5s33rkhy7", "Addr": "10.0.1.2/24" } ] } } ]
独立的容器使用overlay网络
Prerequisites
对于此测试,您需要两个可以相互通信的不同 Docker 主机。每个主机必须在两个 Docker 主机之间打开以下端口
- TCP port 2377
- TCP and UDP port 7946
- UDP port 4789
演练
-
在宿主机A中初始化swarm
docker swarm init Swarm initialized: current node (buaihn02aqy6qxo66rckbjedz) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-1mbu65zkr1a30om1xugzo49qsxm9pac59wi4huhg0qmyxh54f2-7jfohvfnifskwqdmhqfqzeofz 192.168.142.111:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
-
宿主机B加入swarm集群
docker swarm join --token SWMTKN-1-1mbu65zkr1a30om1xugzo49qsxm9pac59wi4huhg0qmyxh54f2-7jfohvfnifskwqdmhqfqzeofz 192.168.142.111:2377 This node joined a swarm as a worker.
-
在宿主机A中创建一个overlay网络
docker network create --driver=overlay --attachable test-net
-
在宿主机A中创建一个容器,并加入这个overlay网络
docker run -it --name alpine1 --network test-net alpine
-
在另一个宿主机上并没有发现这个test-net网络
docker network ls NETWORK ID NAME DRIVER SCOPE 9e85f090b89d bridge bridge local 01d650a482b8 docker_gwbridge bridge local eda8e6f73ffc host host local j5x08b8yuwik ingress overlay swarm 902d5b136046 none null local
-
仍然可以创建容器并加入这个网络
docker run -dit --name alpine2 --network test-net alpine
-
再次确认网络,已经有test-net网络了
docker network ls NETWORK ID NAME DRIVER SCOPE 9e85f090b89d bridge bridge local 01d650a482b8 docker_gwbridge bridge local eda8e6f73ffc host host local j5x08b8yuwik ingress overlay swarm 902d5b136046 none null local 04tq50uodx9y test-net overlay swarm
-
宿主机A中启动的容器中 ping 宿主机A中的容器,可以正常连通
ping -c 2 alpine2 PING alpine2 (10.0.1.4): 56 data bytes 64 bytes from 10.0.1.4: seq=0 ttl=64 time=0.717 ms 64 bytes from 10.0.1.4: seq=1 ttl=64 time=0.504 ms
-
宿主机B查看overlay网络,宿主机B中的容器IP为 10.0.1.4
docker network inspect test-net
[ { "Name": "test-net", "Id": "04tq50uodx9y9vfhchvr2639f", "ConfigOnly": false, "Containers": { "c877a9a43d8028810bfd6b3e474325b9ca8a3ddf87ab1bdd8ea08ee1b1977456": { "Name": "alpine2", "EndpointID": "ec38e443f5788bdf8536540c13b50a44fd14303fbf74708bc511a0c30d8f9470", "MacAddress": "02:42:0a:00:01:04", "IPv4Address": "10.0.1.4/24", "IPv6Address": "" }, "lb-test-net": { "Name": "test-net-endpoint", "EndpointID": "901530897b268bf6760b54797fe2e6cef91a66c26914820dfbe247c84ad7278c", "MacAddress": "02:42:0a:00:01:05", "IPv4Address": "10.0.1.5/24", "IPv6Address": "" } }, "Peers": [ { "Name": "4e5fe51d4fd5", "IP": "192.168.142.111" }, { "Name": "397ded583820", "IP": "192.168.142.112" } ] } ]
lb-test-net 这个没有搞懂什么意思,后续再看