问题描述
我的问题特定于 k6 和 InfluxDB,但我认为根本原因更普遍。
我使用官方 k6 发行版及其 docker-compose.yml 来运行 Grafana 和 InfluxDB,我从 docker-compose up -d influxdb grafana
命令开始。
Grafana 仪表板可从 localhost:3000 访问,但使用推荐的命令 $ docker run -i loadimpact/k6 run --out influxdb=http://localhost:8086/myk6db - <script.js
运行 k6(遵循 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"
我也为 InfluxDB 尝试了 localhost 和 127.0.0.1 的命令。还有 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 可以正常工作,而使用 localhost:8086 的 InfluxDB 不行?
- 为什么只有“内部 IP”有效而其他 IP 无效?
我知道有一个类似的问题,但这并不能回答我的问题。
解决方法
Docker 容器在隔离的网络空间中运行。 Docker 可以维护内部网络,并且有 Compose 语法来创建它们。
如果您从 Docker 空间外部但在同一主机上调用 Docker 容器,您通常可以连接到它作为 localhost
,以及 Compose 中列出的第一个端口号 {{1} } 部分。如果您查看链接到的 ports:
文件,它会列出 docker-compose.yml
,因此主机上的端口 3000 转发到容器中的端口 3000;如果您从同一主机上的浏览器调用 ports: [3000:3000]
,它将到达该转发端口。
否则,从一个容器到另一个容器的调用通常可以使用容器的名称(如 http://localhost:3000
)或 Compose 服务名称;但是,它们必须在同一个 Docker 网络上。该 docker run --name
文件还列出了
docker-compose.yml
因此您可以使用服务的正常端口号访问 services:
influxdb:
networks:
- k6
- grafana
,前提是调用容器位于这两个网络之一上。如果服务具有 http://influxdb:8086
,则它们不会被考虑用于容器间调用。
在 Docker 文档中,Networking in Compose 提供了有关此设置的更多详细信息。
最后一个技巧可以帮助您运行您尝试运行的特定命令。 docker-compose run
将运行一次性命令,使用 ports:
中某个容器的设置,除了没有它的 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
中的 K6_OUT
环境变量可以为您提供该 docker-compose.yml
选项。)
您永远不需要查找容器专用 IP 地址。它们不适用于各种常见场景,并且在用于容器之间调用的 Docker 网络和用于从 Docker 外部调用的已发布端口之间,有更好的方法来调用容器。