在 Linux 主机上的 docker 容器中访问 PROPER IP 运行 上的服务
Accessing a service on the PROPER IP running in docker container on a Linux host
我的问题特定于 k6 和 InfluxDB,但我认为根本原因更为普遍。
我正在使用官方 k6 发行版及其 docker-compose.yml 到 运行 Grafana 和 InfluxDB,我从 docker-compose up -d influxdb grafana
命令开始。
Grafana 仪表板可从 localhost:3000 访问,但 运行ning k6 使用推荐的命令 $ docker run -i loadimpact/k6 run --out influxdb=http://localhost:8086/myk6db - <script.js
(遵循 this 指南)k6 抛出以下错误(在 Linux 和 MacOS):
level=error msg="InfluxDB: Couldn't write stats" error="Post \"http://localhost:8086/write?consistency=&db=myk6db&precision=ns&rp=\": dial tcp 127.0.0.1:8086: connect: connection refused"
我也尝试使用 localhost 和 127.0.0.1 以及 InfluxDB 的命令。还有 docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' k6_influxdb_1
返回的 IP 地址,它要么因上述错误而失败,要么没有工作,这意味着 k6 没有抱怨,但没有数据出现在 InfluxDB 中。
但是,如果我查询网络接口正在使用的“内部 IP”地址(使用 ifconfig
命令)并使用该 IP (192.168.1.66) ,一切正常:
docker run -i loadimpact/k6 run --out influxdb=http://192.168.1.66:8086/k6db - <test.js
所以我的问题是:
- 为什么 Grafana 可以与 localhost:3000 一起正常工作而 InfluxDB 与 localhost:8086 不能正常工作?
- 为什么只有“内部 IP”有效而其他 IP 无效?
我知道有一个类似的问题,但没有回答我的问题。
Docker 个容器 运行 在隔离网络 space 中。 Docker 可以维护内部网络,并且有 Compose 语法来创建它们。
如果您从外部 Docker space 调用 Docker 容器但在同一主机上,您通常可以连接到它 localhost
, 以及 Compose ports:
部分中列出的第一个端口号。如果查看 link 的 docker-compose.yml
文件,它会列出 ports: [3000:3000]
,因此主机上的端口 3000 转发到容器中的端口 3000;如果您从同一主机上的浏览器调用 http://localhost:3000
,它将到达转发的端口。
否则,从一个容器到另一个容器的调用通常可以使用容器的名称(如 docker run --name
)或 Compose 服务名称;但是,它们必须在同一个 Docker 网络上。该 docker-compose.yml
文件还列出了
services:
influxdb:
networks:
- k6
- grafana
因此您可以使用服务的正常端口号访问 http://influxdb:8086
,前提是调用容器位于这两个网络之一上。如果服务有 ports:
,则不考虑容器间调用。
在 Docker 文档中,Networking in Compose 提供了有关此设置的更多详细信息。
最后一个技巧可以帮助您 运行 您尝试执行的特定命令 运行。 docker-compose run
将 运行 一个一次性命令,使用 docker-compose.yml
中某个容器的设置,除了不使用其 ports:
并替换其 command:
。您引用的 docker-compose.yml
文件包含一个 k6
容器,在 k6
网络上,运行 连接 loadimpact/k6
图像。所以你大概可以 运行
docker-compose run k6 \
run --out influxdb=http://influxdb:8086/myk6db - \
<script.js
(可能 docker-compose.yml
中的 K6_OUT
环境变量可以为您提供 --out
选项。)
您永远不需要查找容器私有 IP 地址。它们在各种常见场景中不可用,并且在 Docker 用于容器之间调用的网络和用于来自外部的调用的已发布端口 Docker 之间,有更好的方法来调用容器。
我的问题特定于 k6 和 InfluxDB,但我认为根本原因更为普遍。
我正在使用官方 k6 发行版及其 docker-compose.yml 到 运行 Grafana 和 InfluxDB,我从 docker-compose up -d influxdb grafana
命令开始。
Grafana 仪表板可从 localhost:3000 访问,但 运行ning k6 使用推荐的命令 $ docker run -i loadimpact/k6 run --out influxdb=http://localhost:8086/myk6db - <script.js
(遵循 this 指南)k6 抛出以下错误(在 Linux 和 MacOS):
level=error msg="InfluxDB: Couldn't write stats" error="Post \"http://localhost:8086/write?consistency=&db=myk6db&precision=ns&rp=\": dial tcp 127.0.0.1:8086: connect: connection refused"
我也尝试使用 localhost 和 127.0.0.1 以及 InfluxDB 的命令。还有 docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' k6_influxdb_1
返回的 IP 地址,它要么因上述错误而失败,要么没有工作,这意味着 k6 没有抱怨,但没有数据出现在 InfluxDB 中。
但是,如果我查询网络接口正在使用的“内部 IP”地址(使用 ifconfig
命令)并使用该 IP (192.168.1.66) ,一切正常:
docker run -i loadimpact/k6 run --out influxdb=http://192.168.1.66:8086/k6db - <test.js
所以我的问题是:
- 为什么 Grafana 可以与 localhost:3000 一起正常工作而 InfluxDB 与 localhost:8086 不能正常工作?
- 为什么只有“内部 IP”有效而其他 IP 无效?
我知道有一个类似的问题,但没有回答我的问题。
Docker 个容器 运行 在隔离网络 space 中。 Docker 可以维护内部网络,并且有 Compose 语法来创建它们。
如果您从外部 Docker space 调用 Docker 容器但在同一主机上,您通常可以连接到它 localhost
, 以及 Compose ports:
部分中列出的第一个端口号。如果查看 link 的 docker-compose.yml
文件,它会列出 ports: [3000:3000]
,因此主机上的端口 3000 转发到容器中的端口 3000;如果您从同一主机上的浏览器调用 http://localhost:3000
,它将到达转发的端口。
否则,从一个容器到另一个容器的调用通常可以使用容器的名称(如 docker run --name
)或 Compose 服务名称;但是,它们必须在同一个 Docker 网络上。该 docker-compose.yml
文件还列出了
services:
influxdb:
networks:
- k6
- grafana
因此您可以使用服务的正常端口号访问 http://influxdb:8086
,前提是调用容器位于这两个网络之一上。如果服务有 ports:
,则不考虑容器间调用。
在 Docker 文档中,Networking in Compose 提供了有关此设置的更多详细信息。
最后一个技巧可以帮助您 运行 您尝试执行的特定命令 运行。 docker-compose run
将 运行 一个一次性命令,使用 docker-compose.yml
中某个容器的设置,除了不使用其 ports:
并替换其 command:
。您引用的 docker-compose.yml
文件包含一个 k6
容器,在 k6
网络上,运行 连接 loadimpact/k6
图像。所以你大概可以 运行
docker-compose run k6 \
run --out influxdb=http://influxdb:8086/myk6db - \
<script.js
(可能 docker-compose.yml
中的 K6_OUT
环境变量可以为您提供 --out
选项。)
您永远不需要查找容器私有 IP 地址。它们在各种常见场景中不可用,并且在 Docker 用于容器之间调用的网络和用于来自外部的调用的已发布端口 Docker 之间,有更好的方法来调用容器。