Overlay 网络驱动

overlay 网络驱动在多个 Docker 守护进程主机之间创建分布式网络。它叠加在各主机自身的网络之上,启用加密后,连接到该网络的容器可以安全通信。Docker 透明地处理每个数据包的路由,将其发送到正确的 Docker 守护进程主机和目标容器,或从这些位置接收数据包。

你可以使用 docker network create 创建用户自定义的 overlay 网络,方式与创建用户自定义的 bridge 网络相同。服务或容器可以同时连接多个网络。服务或容器只能通过双方都连接的网络通信。

Overlay 网络常用于连接 Swarm 服务,也可以连接运行在不同主机上的独立容器。使用独立容器时,仍然必须启用 Swarm 模式来建立主机间的连接。

本页介绍 overlay 网络的一般概念及其与独立容器配合使用的方式。有关 Swarm 服务的 overlay 网络,请参阅“管理 Swarm 服务网络”。 [1]

要求 [2]

要使用 overlay 网络,Docker 主机必须加入同一个 swarm,即使连接的是独立容器也一样。参与通信的主机之间必须开放下列端口:

端口 说明
2377/tcp 默认的 Swarm 控制平面端口,可通过 docker swarm join –listen-addr 配置。 [3]
4789/udp 默认的 overlay 流量端口,可通过 docker swarm init –data-path-port 配置。 [4]
7946/tcp、7946/udp 用于节点间通信,不能配置。

创建 overlay 网络 [5]

要创建一个允许其他 Docker 主机上的容器连接的 overlay 网络,请运行以下命令:

$ docker network create -d overlay --attachable my-attachable-overlay

–attachable 选项允许独立容器和 Swarm 服务连接 overlay 网络。不使用 –attachable 时,只有 Swarm 服务可以连接该网络。

你可以指定 IP 地址范围、子网、网关等选项。详情请参阅 docker network create –help。

加密 overlay 网络中的流量 [6]

使用 –opt encrypted 标志来加密通过 overlay 网络传输的应用数据:

$ docker network create \
  --opt encrypted \
  --driver overlay \
  --attachable \
  my-attachable-multi-host-network

这会在虚拟可扩展局域网(VXLAN)层启用 IPsec 加密。加密带来的性能开销不可忽略,因此应先测试这一选项,再用于生产环境。


警告

不要将 Windows 容器连接到加密的 overlay 网络。

Windows 不支持 overlay 网络加密。Windows 主机尝试连接加密的 overlay 网络时,Swarm 不会报告错误,但 Windows 容器的网络会受到以下影响:

  • Windows 容器无法与该网络中的 Linux 容器通信。
  • 该网络中 Windows 容器之间的数据流量不会被加密。

将容器连接到 overlay 网络 [7]

把容器加入 overlay 网络后,它们可以与其他容器通信,而不必在每台 Docker 守护进程主机上单独配置路由。前提是这些主机已经加入同一个 Swarm。

要使用 busybox 容器加入名为 multi-host-network 的 overlay 网络:

$ docker run --network multi-host-network busybox sh

说明

这只适用于可附加的 overlay 网络,即创建时使用了 –attachable 标志的网络。

容器发现 [8]

发布 overlay 网络中容器的端口,会向同一网络中的其他容器开放这些端口。通过使用容器名称进行 DNS 查询,可以发现容器。

标志值 说明
-p 8080:80 将容器中的 TCP 端口 80 映射到 overlay 网络中的端口 8080。
-p 8080:80/udp 将容器中的 UDP 端口 80 映射到 overlay 网络中的端口 8080。
-p 8080:80/sctp 将容器中的 SCTP 端口 80 映射到 overlay 网络中的端口 8080。
-p 8080:80/tcp -p 8080:80/udp 将容器中的 TCP 端口 80 映射到 overlay 网络中的 TCP 端口 8080,并将容器中的 UDP 端口 80 映射到 overlay 网络中的 UDP 端口 8080。

Overlay 网络的连接数量限制 [9]

受 Linux 内核的限制,当 1000 个容器集中运行在同一主机上时,overlay 网络会变得不稳定,容器间通信可能中断。

有关这一限制的更多信息,请参阅 moby/moby#44973。 [10]

使用示例 [11]

本节提供使用 overlay 网络的实践示例,涵盖多个 Docker 主机上的 swarm 服务和独立容器。

前提条件 [12]

所有示例至少需要一个单节点 swarm。在主机上运行 docker swarm init 即可初始化。也可以在多节点 swarm 中运行这些示例。

使用默认 overlay 网络 [13]

本示例说明默认 overlay 网络如何与 swarm 服务协作。你将创建一个 nginx 服务,并从服务容器的角度查看网络。

多节点设置的前提条件 [14]

本教程需要三台 Docker 主机,它们位于同一网络且可以互相通信,主机间流量不被防火墙阻挡:

  • manager:同时充当管理节点和工作节点。
  • worker-1:仅充当工作节点。
  • worker-2:仅充当工作节点。

如果没有三台可用主机,可以在云服务商上创建三台虚拟机并安装 Docker。

创建 swarm [15]

  1. 在 manager 上初始化 swarm。如果主机只有一个网络接口,–advertise-addr 标志可以省略:

    $ docker swarm init --advertise-addr=<IP-ADDRESS-OF-MANAGER>
    

    保存显示的加入令牌,以便工作节点使用。

  2. 在 worker-1 上加入 swarm:

    $ docker swarm join --token <TOKEN> \
      --advertise-addr <IP-ADDRESS-OF-WORKER-1> \
      <IP-ADDRESS-OF-MANAGER>:2377
    
  3. 在 worker-2 上加入 swarm:

    $ docker swarm join --token <TOKEN> \
      --advertise-addr <IP-ADDRESS-OF-WORKER-2> \
      <IP-ADDRESS-OF-MANAGER>:2377
    
  4. 在 manager 上列出所有节点:

    $ docker node ls
    
    ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
    d68ace5iraw6whp7llvgjpu48 *   ip-172-31-34-146    Ready               Active              Leader
    nvp5rwavvb8lhdggo8fcf7plg     ip-172-31-35-151    Ready               Active
    ouvx2l7qfcxisoyms8mtkgahw     ip-172-31-36-89     Ready               Active
    

    如有需要,可按角色筛选:

    $ docker node ls --filter role=manager
    $ docker node ls --filter role=worker
    
  5. 在所有主机上列出 Docker 网络。现在每台主机都有一个名为 ingress 的 overlay 网络和一个名为 docker_gwbridge 的 bridge 网络:

    $ docker network ls
    
    NETWORK ID          NAME                DRIVER              SCOPE
    495c570066be        bridge              bridge              local
    961c6cae9945        docker_gwbridge     bridge              local
    ff35ceda3643        host                host                local
    trtnl4tqnc3n        ingress             overlay             swarm
    c8357deec9cb        none                null                local
    

docker_gwbridge 将 ingress 网络连接到 Docker 主机的网络接口。创建服务时如果不指定网络,服务会连接 ingress。建议为每个应用或一组相关应用使用独立的 overlay 网络。

创建服务 [16]

  1. 在 manager 上创建一个新的 overlay 网络:

    $ docker network create -d overlay nginx-net
    

    当工作节点运行需要该网络的服务任务时,overlay 网络会自动在工作节点上创建。

  2. 在 manager 上创建一个具有 5 个副本、连接到 nginx-net 的 Nginx 服务:


    说明

    只能在管理节点上创建服务。

    $ docker service create \
      --name my-nginx \
      --publish target=80,published=80 \
      --replicas=5 \
      --network nginx-net \
      nginx
    

    默认的 ingress 发布模式意味着,你可以访问任意节点的端口 80,并连接到 5 个服务任务中的某一个,即使该节点上没有运行任何任务。

  3. 观察服务创建进度:

    $ docker service ls
    
  4. 在所有主机上检查 nginx-net 网络。Containers 部分列出了该主机上连接到 overlay 网络的所有服务任务。

  5. 在 manager 上检查服务:

    $ docker service inspect my-nginx
    

    留意端口和端点信息。

  6. 创建第二个网络,并更新服务以使用该网络:

    $ docker network create -d overlay nginx-net-2
    $ docker service update \
      --network-add nginx-net-2 \
      --network-rm nginx-net \
      my-nginx
    
  7. 确认更新已完成:

    $ docker service ls
    

    检查两个网络,确认容器已经从 nginx-net 迁移到 nginx-net-2。


    说明

    Overlay 网络会按需在 swarm 工作节点上自动创建,但不会自动删除。

  8. 清理:

    $ docker service rm my-nginx
    $ docker network rm nginx-net nginx-net-2
    

使用用户自定义的 overlay 网络 [17]

本示例展示生产服务使用自定义 overlay 网络的推荐方式。

前提条件 [18]

假设 swarm 已经设置完成,且你正在管理节点上操作。

步骤 [19]

  1. 创建用户自定义的 overlay 网络:

    $ docker network create -d overlay my-overlay
    
  2. 启动一个使用该 overlay 网络的服务,将端口 80 发布到端口 8080:

    $ docker service create \
      --name my-nginx \
      --network my-overlay \
      --replicas 1 \
      --publish published=8080,target=80 \
      nginx:latest
    
  3. 确认服务任务已连接该网络:

    $ docker network inspect my-overlay
    

    在 Containers 部分检查 my-nginx 服务任务。

  4. 清理:

    $ docker service rm my-nginx
    $ docker network rm my-overlay
    

为独立容器使用 overlay 网络 [20]

本示例演示不同 Docker 主机上的独立容器如何通过 overlay 网络使用 DNS 发现彼此。

前提条件 [21]

需要两台可以互相通信的 Docker 主机,并在它们之间开放以下端口:

  • TCP 端口 2377。
  • TCP 和 UDP 端口 7946。
  • UDP 端口 4789。

本示例将这两台主机称为 host1 和 host2。

步骤 [22]

  1. 设置 swarm:

    在 host1 上初始化 swarm:

    $ docker swarm init
    Swarm initialized: current node (vz1mm9am11qcmo979tlrlox42) is now a manager.
    
    To add a worker to this swarm, run the following command:
    
        docker swarm join --token SWMTKN-1-5g90q48weqrtqryq4kj6ow0e8xm9wmv9o6vgqc5j320ymybd5c-8ex8j0bc40s6hgvy5ui5gl4gy 172.31.47.252:2377
    

    在 host2 上使用上一步输出中的令牌加入 swarm:

    $ docker swarm join --token <your_token> <your_ip_address>:2377
    This node joined a swarm as a worker.
    

    如果加入失败,在 host2 上运行 docker swarm leave –force,检查网络和防火墙设置后重试。

  2. 在 host1 上创建一个可附加的 overlay 网络:

    $ docker network create --driver=overlay --attachable test-net
    uqsof8phj3ak0rq9k86zta6ht
    

    记下返回的网络 ID。

  3. 在 host1 上启动连接 test-net 的交互式容器:

    $ docker run -it --name alpine1 --network test-net alpine
    / #
    
  4. 在 host2 上列出可用网络。注意,test-net 此时尚不存在:

    $ docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    ec299350b504        bridge              bridge              local
    66e77d0d0e9a        docker_gwbridge     bridge              local
    9f6ae26ccb82        host                host                local
    omvdxqrda80z        ingress             overlay             swarm
    b65c952a4b2b        none                null                local
    
  5. 在 host2 上启动一个在后台运行、连接 test-net 的交互式容器:

    $ docker run -dit --name alpine2 --network test-net alpine
    fb635f5ece59563e7b8b99556f816d24e6949a5f6a5b1fbd92ca244db17a4342
    

    说明

    自动 DNS 容器发现只适用于具有唯一名称的容器。

  6. 在 host2 上确认 test-net 已创建,且其网络 ID 与 host1 上的相同:

    $ docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    ...
    uqsof8phj3ak        test-net            overlay             swarm
    
  7. 在 host1 上,从 alpine1 容器内 ping alpine2:

    / # ping -c 2 alpine2
    PING alpine2 (10.0.0.5): 56 data bytes
    64 bytes from 10.0.0.5: seq=0 ttl=64 time=0.600 ms
    64 bytes from 10.0.0.5: seq=1 ttl=64 time=0.555 ms
    
    --- alpine2 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.555/0.577/0.600 ms
    

    两个容器通过连接两台主机的 overlay 网络通信。你也可以在 host2 上运行另一个容器并 ping alpine1:

    $ docker run -it --rm --name alpine3 --network test-net alpine
    / # ping -c 2 alpine1
    / # exit
    
  8. 在 host1 上退出 alpine1 会话,这会停止容器:

    / # exit
    
  9. 清理。必须在每台主机上分别停止并删除容器:

    在 host2 上:

    $ docker container stop alpine2
    $ docker network ls
    $ docker container rm alpine2
    

    停止 alpine2 时,test-net 会从 host2 上消失。

    在 host1 上:

    $ docker container rm alpine1
    $ docker network rm test-net
    

后续步骤 [23]

  • 了解容器视角下的网络。 [24]
  • 了解独立的 bridge 网络。 [25]
  • 了解 Macvlan 网络。 [26]
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容