如何通过名称而不是IP地址访问Docker容器?

93
有没有办法使用名称而不是IP地址访问我的Docker容器?
我听说过pipework,也看到了一些关于Docker的dns和主机名类型选项,但我仍然无法将所有内容组合在一起。
谢谢您的时间。
我不确定这是否有帮助,但这是我迄今为止所做的:
- 使用docker-machine和vmwarevsphere驱动程序安装了Docker容器主机 - 使用docker-compose启动了所有服务 - 我可以使用IP和端口从网络上的任何其他计算机访问所有服务
我已向我的私有网络DNS服务器添加了DNS别名条目,并且与docker-machine使用的机器名称匹配。 但是,机器在启动并连接到网络时总是选择另一个IP地址。
我只是不知道从哪里入手:
- 网络DNS服务器 - docker-machine主机名 - Docker容器主机名 - 可能是所有这些组合
我可能正在寻找类似于此问题的东西:

如何让docker使用我的网络路由器轻松地为容器分配dhcp ip,而不是使用pipework?

任何一般的指导方向都将很棒...再次感谢!


请查看这个答案,您可以使用 DPS 来实现此目的,同时还可以利用一些其他功能。 - deFreitas
我曾经有这个问题。解决方案 - Alex
7个回答

64

Docker 1.10内置了DNS。如果您的容器连接到同一用户定义网络(创建一个网络docker network create my-network并使用--net my-network运行容器),它们可以使用容器名称相互引用。(文档)。

很酷!

但是,如果您正在使用Docker compose,则应该知道它会向您的容器名称添加前缀,即<project name>_<service name>-#。这使得您的容器名称有些难以控制,但对于您的用例来说可能还可以接受。您可以通过在compose模板中手动设置容器名称来覆盖docker compose命名功能,但那样就无法使用compose进行扩展


2
(更正)刚看到您关于扩展的最后一部分,现在我明白您的意思了!(原文)您应该能够使用 docker-compose.yml 并在服务中设置 container_name: anything,它不应该添加任何东西,但如果我错了,请纠正我,因为我经常在自定义网络上这样做。 - JREAM
1
在docker-compose中,默认情况下项目名称是basedir的名称。您可以设置环境变量COMPOSE_PROJECT_NAME。然后像http://<project name><service name>#这样访问服务。 - Mariusz W.

19

创建一个除docker0外的新桥接网络,在其中运行容器,您可以通过容器名称引用该网络中的容器。

Docker守护进程运行嵌入式DNS服务器,为连接到用户定义网络的容器提供自动服务发现。 容器的名称解析请求首先由嵌入式DNS服务器处理。

尝试一下:

docker network create <network name>
docker run --net <network name> --name test busybox nc -l 0.0.0.0:7000
docker run --net <network name> busybox ping test

首先,我们创建一个新的网络。然后,我们运行一个名为test的busybox容器,监听端口7000(只是为了让它保持运行)。最后,我们通过容器名称ping测试容器,应该可以正常工作。


7

编辑于2018-02-17: Docker可能会从docker-compose中删除links键,因此建议使用用户定义的网络,如此处所述=> https://docs.docker.com/compose/compose-file/#links


假设您希望从您的docker-compose.yml文件中的web容器访问mysql容器,如下所示:
web:
  build: .
  links:
    - mysql

mysqlservice:
  image: mysql

你会很高兴知道,Docker Compose 已经添加了一个名为 mysqlservice 的域名(在 web 容器的 /etc/hosts 中),它指向 mysql 容器。
不需要查找 mysql 容器的 IP 地址,只需使用 mysqlservice 域名即可。
如果您想添加自定义域名,则可以使用 extra_hosts 参数。

https://docs.docker.com/compose/compose-file/#labels-2 链接会被删除吗? :-O - Junior Mayhé

4

3
如果您需要一个开箱即用的解决方案,您可以考虑查看例如Kontena。它带有来自Weave的网络覆盖技术,该技术用于创建服务之间的虚拟私有局域网网络。由此,每个服务/容器都可以通过service_name.kontena.local访问。

3
这个能让你使用 service_name.kontena.local 从主机连接到容器暴露的端口吗? - erickson

3

我将--net参数替换为--network参数,它按预期运行:

docker network create <network name>
docker run --network <network name> --name <container name> <other container options>
docker run --network <network name> --name <container name> <other container options>

1
如果您正在使用Docker Compose,并且您的docker-compose.yml文件具有顶级services:块(您没有使用过时的“版本1”文件格式),那么Compose会自动执行所有必需的设置。 services:下面的名称可以直接用作主机名。
version: '3.8'
services:
  database:             # <-- "database" is a usable hostname
    image: postgres
  application:          # <-- "application" is a usable hostname
    build: .
    environment:
      PGHOST: database  # <-- use the "database" hostname

Docker文档中的Compose网络进一步描述了这个设置。

这些主机名只适用于在同一Compose文件中的容器之间的连接。如果您手动声明networks:,则两个容器必须有一些共同的网络,但最简单的设置是根本不声明networks:。这些连接只会使用“标准”端口(例如,对于PostgreSQL,总是连接到端口5432);ports:声明不是必需的,如果存在则会被忽略。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接