【问题标题】:Why do I need a default docker network to start a common docker network for two docker-compose projects?为什么我需要一个默认的 docker 网络来为两个 docker-compose 项目启动一个公共的 docker 网络?
【发布时间】:2020-02-19 20:15:23
【问题描述】:

我有两个项目(a 和 b),它们都有一个 docker-compose.yml 文件。我现在希望其中一个项目能够调用另一个项目的服务,据我所知,我需要为此创建一个通用的 docker 网络。因此,为了创建一个最小的示例,我创建了两个文件夹(a/b/),它们都包含一个 docker-compose.yml 文件。

这是文件夹a/中的那个:

version: '3'

services:
  common_server:
    image: ubuntu
    ports:
      - 4444:4444
    command: >
      bash -c '
      apt update && apt install netcat -y && 
      while true; do echo -e "HTTP/1.1 200 OK\n\npong" | nc -k -l -p 4444 -q 1; done'
#    networks:
#      - my_network

  project_a:
    image: ubuntu
    depends_on: 
      - common_server
#    networks:
#      - my_network
    command: >
      bash -c '
      apt update && apt install curl -y && 
      while true; do echo "Calling the container";  echo "AAAAAAAA"; curl common_server:4444; sleep 10; done'

#networks:
#  my_network:
#    driver: bridge

这设置了两件事:

  • common_server: 一个简单的 ping/pong 服务器,它会响应它收到的每个请求“pong”
  • project_a:一个简单的客户端,每 10 秒调用一次common_server

这样很好用。我使用以下方法快速检查了 docker 网络:

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
5ac503033848        a_default           bridge              local  <== THIS NETWORK WAS CREATED
1f65f9c91441        bridge              bridge              local
72fcb38f2060        host                host                local
b76cd7ef1ac9        none                null                local

我在文件夹 b/ 中有第二个 docker-compose.yml 文件,我还想从中调用上面文件中定义的 common_server。所以我取消了上面文件中带有网络的行的注释以启用my_network。跑步也很有效。

当我再次查看docker network ls 时,我还看到了它创建的第二个网络:

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
5ac503033848        a_default           bridge              local  <== CREATED BY THE FIRST RUN
f0a42e17007b        a_my_network        bridge              local  <== CREATED BY THE SECOND RUN
1f65f9c91441        bridge              bridge              local
72fcb38f2060        host                host                local
b76cd7ef1ac9        none                null                local

然后我启动了第二个 docker-compose 文件:

version: '3'

services:
  project_b:
    image: ubuntu
    command: >
      bash -c '
      apt update && apt install curl -y && 
      while true; do echo "Calling the container";  echo "BBBBBBB"; curl common_server:4444; sleep 10; done'
    networks:
     - a_my_network
networks:
  a_my_network:
    external: true

这也有效。它可以从第一个 docker-compose 文件中调用common_server

我的第一个问题:虽然我在第一个文件中将网络定义为my_network,但被docker称为a_my_network。有没有办法定义网络,以便我可以在两个 docker-compose 文件中调用它?

然后我决定使用docker network prune 删除这两个网络,然后重新开始。不幸的是,当我现在再次运行第一个文件时,我现在收到以下错误:

$ docker-compose up
Creating network "a_my_network" with driver "bridge"
Starting a_common_server_1 ... error

ERROR: for a_common_server_1  Cannot start service common_server: network f0a42e17007bc0f352042f5394aef65be18bb12c7836e8864ecb734f83a421d7 not found

ERROR: for common_server  Cannot start service common_server: network f0a42e17007bc0f352042f5394aef65be18bb12c7836e8864ecb734f83a421d7 not found
ERROR: Encountered errors while bringing up the project.

所以我的第二个问题:如果我首先创建a_default 网络而不明确定义网络,为什么我只能启动第一个 docker-compose 文件?

【问题讨论】:

    标签: docker networking docker-compose docker-networking docker-network


    【解决方案1】:

    当您在第二个文件中声明网络时,您可以明确指定其name:

    version: '3.7'  # minimum of 3.5
    networks:
      my_network:
        external: true
        name: a_my_network
    

    正如您在开头提到的那样,Compose creates a default network for you,如果您没有为容器显式声明networks:,它将附加到default。你可以reconfigure the default network 随便你。

    所以我可能在这里做的不是在第一个docker-compose.yml 文件中声明networks:。在第二个中,我将在第一个文件的 default 网络上创建 default 网络点,并且也不为容器配置 networks:

    networks:
      default:
        external: true
        name: a_default
    

    Compose 主要通过在对象上使用标签来跟踪正在发生的事情。这些通常对您隐藏,但它们是非常详细的docker inspect 输出中包含的内容之一。在您的最后一个示例中,如果您从 Compose 下手动 docker network prune 一个网络,它就会开始感到困惑。另一方面,如果您只是注释掉您手动创建的网络并重新运行docker-compose up,Compose 应该会注意到它创建了一个不再需要的网络并为您清理它。

    【讨论】:

    • 好的,我花了一些时间才让它工作,因为我忽略了你对最低版本需要 3.5 的建议,但现在它可以工作了,非常感谢!不过我想知道;因为我无法控制其他人将项目克隆到的文件夹,我想知道我是否可以使这项工作独立于 docker 标签,这样我就不需要在自述文件中添加一个大胖子NOTE项目文件夹名称默认?有什么想法吗?或者这根本不可能?
    • 您也可以在第一个docker-compose.yml中手动指定默认网络的name:。这将限制您多次并行运行这组 Compose 文件的能力,但除此之外没有特定的缺点。
    【解决方案2】:

    您可以使用 -p 或 --project-name 标志或 COMPOSE_PROJECT_NAME 环境变量来更改网络名称。

    也许可以看这里:https://docs.docker.com/compose/networking/#use-a-pre-existing-network

    【讨论】:

    • 感谢您的建议。不幸的是,这只改变了项目名称,它只改变了前缀,而不是完整的网络名称本身。所以-p my_project 将使网络名称为my_project_my_network。这样我仍然不能在两个 docker 文件中使用相同的网络名称。
    猜你喜欢
    • 1970-01-01
    • 2020-08-09
    • 2017-11-17
    • 1970-01-01
    • 2020-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多