【问题标题】:How to avoid the "Docker cannot link to a non running container" error when the external-linked container is actually running using docker-compose当外部链接的容器使用 docker-compose 实际运行时,如何避免“Docker 无法链接到非运行的容器”错误
【发布时间】:2017-10-20 20:47:01
【问题描述】:

我们想做的事:

我们想使用 docker-compose 将一个已经运行的容器 (A) 链接到另一个容器 (B) 按容器名称。我们使用“external-link”,因为两个容器都是从不同的 docker-compose.yml 文件启动的。

问题:

尽管同名容器正在运行,但容器 B 无法启动并出现错误。

ERROR: for container_b  Cannot start service container_b: Cannot link to a non running container: /PREVIOUSLY_LINKED_ID_container_a_1 AS /container_b_1/container_a_1

“docker ps”的输出

CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                         NAMES
RUNNING_ID        container_a       "/docker-entrypoint.s"   15 minutes ago      Up 15 minutes       5432/tcp                      container_a_1

示例代码:

容器B的docker-compose.yml

container_b:
  external_links:
  - container_a_1

这个问题与其他“如何解决”问题有什么不同:

  • 我们不能使用“sudo service docker restart”(有效),因为这是生产环境
  • 我们不想每次都手动解决这个问题,但要找到原因,以便我们可以
    • 了解我们做错了什么
    • 了解如何避免这种情况

假设:

  • 似乎存在两个 container_a 实例(RUNNING_ID 和 PREVIOUSLY_LINKED_ID)
  • 这可能是因为我们
    • 通过 docker-compose build 重建容器并
    • 更改了容器的转发外部端口(80801:8080)

评论

  • 不要按照 cmets 的建议使用 docker-compose down,这会删除卷!

【问题讨论】:

  • 您是否在 compose 中重新启动容器?还是您又在使用docker-compose downdocker-compose up
  • 感谢您的回复。老实说,我不知道“down”这个命令。现在我正在使用 Ctrl+C(当它们在前台时)或当它们在后台时使用“docker stop container_name”。你觉得这应该有什么不同吗?为什么?如果没有其他建议,我将开始尝试 docker-compose down 并在一段时间后报告。
  • 它对你有用吗?
  • 我还没有机会在日常使用中测试它,因为我在前台模式下生成 docker 容器以始终查看每个容器的日志输出。我可以尝试使用该命令而不是 Ctrl+C 来关闭它们,但我仍然不明白为什么这个命令会有所作为?你有提示吗?
  • @Tarun Lalwani:测试docker-compose down 是一次非常不愉快的经历:(我的 --help 输出错误,它只是在停止它后删除了我们的卷 ...不酷。不要使用这个docker-compose down只是为了停止一个容器!

标签: docker docker-compose docker-container docker-link


【解决方案1】:

Docker links are deprecated 因此,除非您需要他们提供的某些功能或使用非常旧版本的 docker,否则我建议您切换到 docker 网络。

由于您要连接的容器似乎是在单独的撰写文件中启动的,因此您可以在外部创建该网络:

docker network create app_net

然后在 docker-compose.yml 文件中,将容器连接到该网络:

version: '3'

networks:
  app_net:
    external:
      name: app_net

services:
  container_a:
    # ...
    networks:
    - app_net

然后在您的 container_b 中,您将连接到 container_a 作为“container_a”,而不是“container_a_1”。

顺便说一句,除非您传递 -v 标志,否则不会记录 docker-compose down 来删除卷。也许您正在使用匿名卷,在这种情况下,我不确定docker-compose up 是否知道在哪里可以找到您的数据。命名卷是首选。很可能,您的数据没有存储在卷中,这很危险,并且您无法更新容器:

$ docker-compose down --help

By default, the only things removed are:

- Containers for services defined in the Compose file
- Networks defined in the `networks` section of the Compose file
- The default network, if one is used

Networks and volumes defined as `external` are never removed.

Usage: down [options]

Options:
    --rmi type          Remove images. Type must be one of:
                        'all': Remove all images used by any service.
                        'local': Remove only images that don't have a custom tag
                        set by the `image` field.
    -v, --volumes       Remove named volumes declared in the `volumes` section
                        of the Compose file and anonymous volumes
                        attached to containers.
    --remove-orphans    Remove containers for services not defined in the
                        Compose file

【讨论】:

  • 首先:非常感谢您的回复!一旦我有时间测试它,我将检查网络并接受您的回复。 @docker-compose-down:我将数据库数据存储在一个单独的存储“busybox”卷容器中,只要我们不使用 -v 标志,它通常会保持数据不变。容器使用volumes_from: - storage 访问卷。因此,当 storage-volumn-container 也被删除时,我真的很震惊 - 但我猜该卷仍然存在,只是因为 storage-container 已经消失而取消链接。
  • volumes_from 也即将退出,如果您转换到 swarm 模式,则无法使用。首选使用命名卷。 github.com/moby/moby/issues/17798#issuecomment-154815207。数据容器最大的问题是它们混合了数据和容器,所以你删除一个容器,你就删除了你的数据。
  • 这是个好建议,我终于找到时间使用网络升级到 compose 文件版本 v3 并删除 volumne_from。谢谢!
猜你喜欢
  • 2018-12-25
  • 2016-07-29
  • 1970-01-01
  • 2018-02-11
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 2019-05-16
相关资源
最近更新 更多