如何在 docker-compose 中访问链接服务?

How to reach a linked service in docker-compose?

根据 https://docs.docker.com/compose/compose-file/#links,如果我在 docker-compose 中的 links 下指定另一个服务的名称,我应该能够通过与服务名称相同的主机名访问该服务.

为了对此进行测试,我尝试了以下 docker-compose.yml

version: '3'

services:
  tor:
    build: ./tor

  use_tor:
    build: ./use_tor
    links:
      - tor

其中 toruse_tor 目录包含 Dockerfiles:

.
├── docker-compose.yml
├── tor
│   └── Dockerfile
└── use_tor
    └── Dockerfile

对于 tor:

FROM alpine:latest
EXPOSE 9050
RUN apk --update add tor
CMD ["tor"]

use_tor:

FROM alpine:latest
CMD ["nc", "-z", "tor", "9050"]

但是,如果我执行 docker-compose build 后跟 docker-compose up,我从日志中看到 use_tor 服务以状态代码 1 退出:

Starting scrapercompose_tor_1
Recreating scrapercompose_use_tor_1
Attaching to scrapercompose_tor_1, scrapercompose_use_tor_1
tor_1      | May 02 15:36:34.123 [notice] Tor v0.2.8.12 running on Linux with Libevent 2.0.22-stable, OpenSSL LibreSSL 2.4.4 and Zlib 1.2.8.
tor_1      | May 02 15:36:34.123 [notice] Tor can't help you if you use it wrong! Learn how to be safe at https://www.torproject.org/download/download#warning
tor_1      | May 02 15:36:34.123 [notice] Configuration file "/etc/tor/torrc" not present, using reasonable defaults.
tor_1      | May 02 15:36:34.129 [notice] Opening Socks listener on 127.0.0.1:9050
tor_1      | May 02 15:36:34.000 [notice] Parsing GEOIP IPv4 file /usr/share/tor/geoip.
tor_1      | May 02 15:36:34.000 [notice] Parsing GEOIP IPv6 file /usr/share/tor/geoip6.
tor_1      | May 02 15:36:34.000 [warn] You are running Tor as root. You don't need to, and you probably shouldn't.
tor_1      | May 02 15:36:34.000 [notice] We were built to run on a 64-bit CPU, with OpenSSL 1.0.1 or later, but with a version of OpenSSL that apparently lacks accelerated support for the NIST P-224 and P-256 groups. Building openssl with such support (using the enable-ec_nistp_64_gcc_128 option when configuring it) would make ECDH much faster.
tor_1      | May 02 15:36:34.000 [notice] Bootstrapped 0%: Starting
scrapercompose_use_tor_1 exited with code 1
tor_1      | May 02 15:36:35.000 [notice] Bootstrapped 80%: Connecting to the Tor network
tor_1      | May 02 15:36:36.000 [notice] Bootstrapped 85%: Finishing handshake with first hop
tor_1      | May 02 15:36:36.000 [notice] Bootstrapped 90%: Establishing a Tor circuit
tor_1      | May 02 15:36:36.000 [notice] Tor has successfully opened a circuit. Looks like client functionality is working.
tor_1      | May 02 15:36:36.000 [notice] Bootstrapped 100%: Done

显然命令 nc -z tor 9050 没有 return use_tor 容器上的预期状态代码 0。但是,在我看来,这应该可行。比如我修改tor服务,将容器上的9050端口映射到宿主机,如下,

services:
  tor:
    build: ./tor
    ports:
      - "9050:9050"

然后在我的普通终端中,我确实看到 nc -z localhost 9050 产生了退出代码 0:

kurt@kurt-ThinkPad:~$ nc -z localhost 9050
kurt@kurt-ThinkPad:~$ echo $?
0

简而言之,我希望主机名 tor 在端口映射后在我的主机上表现得像 localhost,但事实并非如此。为什么这不起作用?

这个问题让我愣了一次。虽然我克隆了这个例子,但无法得到解决方案。根据dockerdocs

The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. EXPOSE does not make the ports of the container accessible to the host. To do that, you must use either the -p flag to publish a range of ports or the -P flag to publish all of the exposed ports. You can expose one port number and publish it externally under another number.

所以我认为这可能是因为 tor 服务在 127.0.0.1 而不是 0.0.0.0 上 运行(对于它们之间的区别,您可以查看 here

tor_1 | May 02 15:36:34.129 [notice] Opening Socks listener on 127.0.0.1:9050

它可以通过终端访问是因为 docker-compose.yml 中的 ports 参数与 -p 参数的作用相同。

总而言之,如果 tor 服务在 0.0.0.0 上侦听,那么它应该会按预期工作。