如何从主机访问 Docker 容器的内部 IP 地址?
How to access Docker container's internal IP address from host?
我的 Mac 主机上有 2 docker 个容器 运行 - 容器 1 是 Jenkins from Docker Hub and container 2 is SonarQube from Docker Hub。我有两个容器 运行 成功。我可以通过转到 http://localhost:8080/
从我的主机访问 Jenkins,我可以通过转到 http://localhost:9000/
访问我的 SonarQube。
Jenkins 容器是这样启动的:
docker run -d -p 8080:8080 -p 50000:50000 jenkins/jenkins:latest
SonarQube容器是这样启动的:
docker run -d -p 9000:9000 sonarqube
现在我想让每个容器相互通信,所以我需要向每个容器提供另一个容器的 IP 地址。
我通过执行以下命令获得了 IP address of each container:
docker inspect --format '{{ .NetworkSettings.IPAddress }}' container_name_or_id
Jenkins 容器的 returns IP 地址为 172.17.0.2
,SonarQube 容器的 IP 地址为 172.17.0.3
。但是当我尝试通过转到 http://172.17.0.2:8080
从我的主机访问 Jenkins 容器时,我收到请求超时。当我尝试通过转到 http://172.17.0.3:9000
从我的主机访问 SonarQube 容器时,也会发生同样的事情
这是正常行为吗?
难道我不能通过主机的内部 IP 地址访问每个容器吗?
我如何测试一个容器(例如 Jenkins)可以通过 IP 地址访问另一个容器(例如 SonarQube)?
看起来您正在使用默认的 bridge
网络模型。内部 IP 用于每个容器在 bridge
网络下相互通信。您无法从主机访问它们。
您有多种选择。
- 您可以在 Jenkins 中将
http://172.17.0.3:9000
配置为声纳端点。
- 您可以在声纳中将
http://172.17.0.2:8000
配置为您的 jenkins 端点。
- 如果您不想在 Ips 之上进行硬编码,那么您的两个容器都可以使用 Docker 默认 GatewayIp(
172.17.0.1
) 及其 internal
端口相互通信。所以基本上你也可以配置 http://172.17.0.1
。
注意 - 如果您定义 user defined bridge network.
,则默认网关 IP 更改更改
https://docs.docker.com/v17.09/engine/userguide/networking/#the-default-bridge-network
https://docs.docker.com/network/network-tutorial-standalone/
如果您想使用 docker-compose 启动两个容器,那么您可以 link 使用服务名称来启动两个容器。关注 Networking in Compose.
Is this normal behavior? Shouldn't I be able to access each container from my host by their internal IP address?
您所描述的是正常行为:您无法从 MacOS 主机直接访问 Docker-内部 IP 地址。参见 "Per-container IP addressing is not possible" in the Docker for Mac docs。
How can I test that one container (e.g. Jenkins) can access the other container (e.g. SonarQube) by IP address?
这不是我通常 "test" 本身 的东西。启动两个进程并让它们建立正常的(HTTP)连接;如果有效,您将看到相应的日志消息,如果无效,您将看到投诉。 (在容器中获取根 shell 以将 ICMP 数据包从一个容器发送到另一个容器似乎是一种流行的选择,但并没有证明太多。)
另外:不要通过明确的 IP 地址建立此连接。正如您已经注意到的,Docker-内部 IP 地址在某些情况下不可用,并且只要您重新启动容器,它们就会更改。相反,Docker 提供了一个内部 DNS 服务,可以在容器之间通信时解析主机名,但你需要显式设置一个 non-default bridge network。该设置如下所示:
docker network create jenkinsnet
docker run --name sonarqube -d --net jenkinsnet \
-p 9000:9000 \
sonarqube
docker run --name jenkins -d --net jenkinsnet \
-p 8080:8080 -p 50000:50000 \
-e SONARQUBE_URL=http://sonarqube:9000 \
jenkins/jenkins:latest
所以我明确地创建了一个网络;启动连接到它的两个容器;并告诉客户端容器(通过环境变量)服务器容器的位置。您不必通过 docker run -p
发布端口即可通过这种方式访问它们;无论您是否这样做,都使用服务器进程正在侦听的端口(docker run -p
选项中的 second 端口号)。
从主机到达容器的唯一(便携、可靠)路径是通过其发布的端口。
接受的答案 () 已经提供了有效的选项,我个人通常更喜欢使用 docker 撰写。
但是因为你是 运行 Docker 在 Mac 你也可以使用 host.docker.internal 结合定义的转发主机端口。所以 Docker 会注意将 host.docker.internal 解析为相应的 IP,即使您的主机 IP 发生变化也是如此。
参见https://docs.docker.com/desktop/mac/networking/。
请注意,这仅适用于开发模式,并且在您使用 Docker 桌面时有效。
我的 Mac 主机上有 2 docker 个容器 运行 - 容器 1 是 Jenkins from Docker Hub and container 2 is SonarQube from Docker Hub。我有两个容器 运行 成功。我可以通过转到 http://localhost:8080/
从我的主机访问 Jenkins,我可以通过转到 http://localhost:9000/
访问我的 SonarQube。
Jenkins 容器是这样启动的:
docker run -d -p 8080:8080 -p 50000:50000 jenkins/jenkins:latest
SonarQube容器是这样启动的:
docker run -d -p 9000:9000 sonarqube
现在我想让每个容器相互通信,所以我需要向每个容器提供另一个容器的 IP 地址。
我通过执行以下命令获得了 IP address of each container:
docker inspect --format '{{ .NetworkSettings.IPAddress }}' container_name_or_id
Jenkins 容器的 returns IP 地址为 172.17.0.2
,SonarQube 容器的 IP 地址为 172.17.0.3
。但是当我尝试通过转到 http://172.17.0.2:8080
从我的主机访问 Jenkins 容器时,我收到请求超时。当我尝试通过转到 http://172.17.0.3:9000
这是正常行为吗?
难道我不能通过主机的内部 IP 地址访问每个容器吗?
我如何测试一个容器(例如 Jenkins)可以通过 IP 地址访问另一个容器(例如 SonarQube)?
看起来您正在使用默认的 bridge
网络模型。内部 IP 用于每个容器在 bridge
网络下相互通信。您无法从主机访问它们。
您有多种选择。
- 您可以在 Jenkins 中将
http://172.17.0.3:9000
配置为声纳端点。 - 您可以在声纳中将
http://172.17.0.2:8000
配置为您的 jenkins 端点。 - 如果您不想在 Ips 之上进行硬编码,那么您的两个容器都可以使用 Docker 默认 GatewayIp(
172.17.0.1
) 及其internal
端口相互通信。所以基本上你也可以配置http://172.17.0.1
。
注意 - 如果您定义 user defined bridge network.
,则默认网关 IP 更改更改https://docs.docker.com/v17.09/engine/userguide/networking/#the-default-bridge-network
https://docs.docker.com/network/network-tutorial-standalone/
如果您想使用 docker-compose 启动两个容器,那么您可以 link 使用服务名称来启动两个容器。关注 Networking in Compose.
Is this normal behavior? Shouldn't I be able to access each container from my host by their internal IP address?
您所描述的是正常行为:您无法从 MacOS 主机直接访问 Docker-内部 IP 地址。参见 "Per-container IP addressing is not possible" in the Docker for Mac docs。
How can I test that one container (e.g. Jenkins) can access the other container (e.g. SonarQube) by IP address?
这不是我通常 "test" 本身 的东西。启动两个进程并让它们建立正常的(HTTP)连接;如果有效,您将看到相应的日志消息,如果无效,您将看到投诉。 (在容器中获取根 shell 以将 ICMP 数据包从一个容器发送到另一个容器似乎是一种流行的选择,但并没有证明太多。)
另外:不要通过明确的 IP 地址建立此连接。正如您已经注意到的,Docker-内部 IP 地址在某些情况下不可用,并且只要您重新启动容器,它们就会更改。相反,Docker 提供了一个内部 DNS 服务,可以在容器之间通信时解析主机名,但你需要显式设置一个 non-default bridge network。该设置如下所示:
docker network create jenkinsnet
docker run --name sonarqube -d --net jenkinsnet \
-p 9000:9000 \
sonarqube
docker run --name jenkins -d --net jenkinsnet \
-p 8080:8080 -p 50000:50000 \
-e SONARQUBE_URL=http://sonarqube:9000 \
jenkins/jenkins:latest
所以我明确地创建了一个网络;启动连接到它的两个容器;并告诉客户端容器(通过环境变量)服务器容器的位置。您不必通过 docker run -p
发布端口即可通过这种方式访问它们;无论您是否这样做,都使用服务器进程正在侦听的端口(docker run -p
选项中的 second 端口号)。
从主机到达容器的唯一(便携、可靠)路径是通过其发布的端口。
接受的答案 (
但是因为你是 运行 Docker 在 Mac 你也可以使用 host.docker.internal 结合定义的转发主机端口。所以 Docker 会注意将 host.docker.internal 解析为相应的 IP,即使您的主机 IP 发生变化也是如此。
参见https://docs.docker.com/desktop/mac/networking/。 请注意,这仅适用于开发模式,并且在您使用 Docker 桌面时有效。