在Docker构建过程中如何连接到宿主机

38次阅读
没有评论

问题描述

在多阶段构建的过程中,用户想要在Dockerfile中运行一些测试。这些测试试图在Dockerfile的RUN命令中连接到localhost上的特定端口(该端口在宿主机上是可用的)。然而,似乎它们无法在Dockerfile的RUN命令中连接成功。用户想知道是否有可能在构建过程中实现这样的连接,如果可以,应该如何实现?在构建时可以进行外部连接(用于下载依赖等),但在运行时可以进行回环连接。

以下是用户的Dockerfile示例:

FROM python:3.7-alpine as tester
COPY . .
RUN python -m unittest discover

下面是用于检查连接的Python代码示例:

def setUp():
    timeout = 120.0
    port = 15903
    host = 'localhost'
    start_time = time.perf_counter()
    while True:
        try:
            with socket.create_connection((host, port), timeout=timeout):
                break
        except OSError as ex:
            time.sleep(1.0)
            if time.perf_counter() - start_time >= timeout:
                raise TimeoutError('Waited too long for the port {} on host {} to start accepting connections.'.format(port, host)) from ex

解决方案

以下解决方案考虑了Docker版本和操作系统的不同情况。

使用宿主机IP地址进行通信

从容器的角度来看,localhost 是容器本身。如果你想要与宿主机通信,你需要知道宿主机的IP地址。根据操作系统和Docker配置的不同,这个IP地址可能会有所不同。

  • 对于Mac用户,从18.03版本开始,推荐使用host.docker.internal
    以下是一个在Mac上从容器与Docker主机通信的示例:
# Dockerfile
FROM python:3.7-alpine
RUN ping host.docker.internal -c 4

运行上述Dockerfile后的输出示例:

sending build context to Docker daemon  562.7kB
Step 1/2 : FROM python:3.7-alpine
---> a93594ce93e7
Step 2/2 : RUN ping host.docker.internal -c 4
---> Running in 54ce465f7386
PING host.docker.internal (192.168.65.2): 56 data bytes
64 bytes from 192.168.65.2: seq=0 ttl=37 time=0.735 ms
64 bytes from 192.168.65.2: seq=1 ttl=37 time=1.898 ms
64 bytes from 192.168.65.2: seq=2 ttl=37 time=0.720 ms
64 bytes from 192.168.65.2: seq=3 ttl=37 time=0.643 ms
--- host.docker.internal ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.643/0.999/1.898 ms
Removing intermediate container 54ce465f7386
---> b2f32c26a135
Successfully built b2f32c26a135

注意事项

  • 使用宿主机IP地址进行通信是一个可行的方法,但在不同的操作系统和Docker版本中,使用的方式可能会有所不同。因此,在使用这种方法时需要进行相关的测试和验证,以确保其在你的环境中正常工作。

总结

在Docker构建过程中连接到宿主机是可能的,但需要注意在不同操作系统和Docker版本中使用的方法可能会有所不同。你可以通过获取宿主机的IP地址来实现这一目标,但需要注意它在不同环境中的适用性。

正文完