通过主机名发现Docker容器无效 [英] Docker container discovery by hostnames doesn't work

查看:413
本文介绍了通过主机名发现Docker容器无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用位于 /tmp/compose.yml 的以下docker compose文件进行Docker堆栈部署:

I use the following docker compose file located at /tmp/compose.yml for docker stack deployment :

version: "3.6"

services:
  service-A:
    image: service-A
    networks:
      - net
    hostname: "service-A-{{.Task.Slot}}"
    deploy:
      replicas: 2

  service-B:
    image: service-B
    networks:
      - net
    hostname: "service-B-{{.Task.Slot}}"
    deploy:
      replicas: 2

networks:

  net:

运行命令:

docker network create -d overlay net
docker stack deploy -c /tmp/compose.yml my

我的期望是 service-A 各个容器将能够通过容器预定义的主机名发现 service-B 容器: service-B-1,service-B-2
但是,从任何 service-A 容器中进行 ping service-B-1 失败。

My expectation was that service-A individual containers will be able to discover service-B containers by container pre defined hostnames: service-B-1, service-B-2. However, ping service-B-1 from within any service-A container fails.

文档状态:


主机名设置容器知道其自身的主机名。这是将
写入/ etc / hostname中,作为容器的
面向主机的IP地址的名称写入/ etc / hosts中,并且是
容器中/ bin / bash的名称将显示在其提示内。但是从容器外部很难看到
的主机名。它不会出现在docker ps中,也不会出现在任何其他容器的/ etc / hosts文件中的
中。

hostname Sets the hostname by which the container knows itself. This is written into /etc/hostname, into /etc/hosts as the name of the container's host-facing IP address, and is the name that /bin/bash inside the container will display inside its prompt. But the hostname is not easy to see from outside the container. It will not appear in docker ps nor in the /etc/hosts file of any other container.

如何实现docker swarm service container通过容器预定义的主机名为容器通信提供服务吗?

How to achieve docker swarm service container to service container communication by container pre defined hostnames?

唯一可行的方法是添加条目,例如:

The only way that works is adding entries like:

[service_B_container_1_virtual_ip] service-B-1
[service_B_container_2_virtual_ip] service-B-2

service-A 个容器的 / etc / hosts

有趣的是,如果在 docker-composes hostname $ c>文件,但由docker生成的 ping [container_id] 即使在多主机docker swarm中也成功。

It's interesting also that if hostname is not set in docker-composes file, but generated by docker, ping [container_id] succeeds even across multi host docker swarm.

我期望预定义的主机名具有相同的行为。

I expected the same behavior for pre defined hostnames.

推荐答案

我认为没有任何简单的方法可以做到这一点。而且我对它的思考越多,就应该没有一种通过设计来完成您所要问的事情

I don't think there is any straightforward way to do this. And the more I think about it, the more it makes sense that there should not be a way to do what you are asking, by design.

堆栈服务的基本特性之一是,它应该以Docker可以互换地对待该服务中所有副本的方式进行部署。如果需要连接到各个实例,则建议不要首先将这些容器创建为服务副本,因为有 something 可以区分它们。适当的堆栈服务应该能够将每个副本视为可以随时销毁和重建的临时实体,并且该操作从外部是不可见的。

One of the fundamental properties of a stack service is that it should be deployable in such a way that Docker is able to treat all of the replicas in that service interchangeably. If you need to connect to individual instances, it suggests that those containers should not be created as service replicas in the first place, as there is something that distinguishes them. A proper stack service should be able to treat every replica as an ephemeral entity that can be destroyed and rebuilt at any time, and the operation should be invisible from the outside.

在Docker网络内部可以做的操作是使用服务名称引用服务实体。因此,在您的示例中, ping Service-A 应该可以从堆栈中的任何容器工作, ping Service-B 。

What you can do from inside the Docker network is reference the service entity using the service name. So in your example, ping Service-A should work from any container in the stack, and so will ping Service-B.

服务中各个容器的名称类似于

The names of individual containers in a service are things like

my_stack_redis.1.y1pwzeg8239yb6n6ynefs78br
my_stack_webserver.1.d6cxx8nlg7db9m2poy9wfjdyd

如果您绝对必须获得访问权限这些名称来自容器中,我唯一想到的方法是在启动时通过绑定安装在容器内部公开 /var/run/docker.sock 。然后,将套接字上的 chmod 750 作为 CMD / ENTRYPOINT 脚本的一部分,以便非root用户可以读取它。现在,您应该能够安装Docker CLI并使用 docker network inspect 查找实际服务成员的名称,并使用 jq 解析它们(您可能需要将两个包都添加到映像中)。但是到那时,更好的选择可能是将那些不可替代的容器分成自己的服务组。

If you absolutely must gain access to those names from within a container, the only way I can think of is to expose /var/run/docker.sock inside the container via bind mount when starting. Then, chmod 750 on the socket as part of the CMD / ENTRYPOINT script so a non-root user can read it. Now you should be able to install the Docker CLI and use docker network inspect to discover the names of actual service members, and jq to parse them out (you'll probably need to add both packages to the image). But at that point, the better option would probably be to separate those non-fungible containers into their own service groups.

这篇关于通过主机名发现Docker容器无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆