0

My problem is specific to k6 and InfluxDB, but i think the root cause is more general.

I'm using the official k6 distribution and its docker-compose.yml to run Grafana and InfluxDB which i start with the docker-compose up -d influxdb grafana command.

Grafana dashboard is accessible from localhost:3000, but running k6 with the recommended command $ docker run -i loadimpact/k6 run --out influxdb=http://localhost:8086/myk6db - <script.js (following this guide) k6 throws the following error (on Linux and MacOS as well):

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"

I tried the command with localhost and 127.0.0.1 as well for InfluxDB as well. Also with IP addresses returned by docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' k6_influxdb_1 It either failed with the above error or didnt work, which means k6 didn't complain, but no data appeared in InfluxDB.

However, if i query the "internal IP" address which the network interface is using (with ifconfig command) and use that IP (192.168.1.66), everything works fine:

docker run -i loadimpact/k6 run --out influxdb=http://192.168.1.66:8086/k6db  - <test.js

So my questions are:

  1. Why does Grafana work fine with localhost:3000 and InfluxDB with localhost:8086 doesn't?
  2. Why does only the "internal IP" work and no other IP?

I know there is a similar question, but that doesn't answer mine.

inspiral
  • 611
  • 1
  • 7
  • 15

1 Answers1

2

Docker containers run in an isolated network space. Docker can maintain internal networks, and there is Compose syntax to create them.

If you're making a call to a Docker container from outside Docker space but on the same host, you can usually connect to it as localhost, and the first port number listed in the Compose ports: section. If you look at the docker-compose.yml file you link to, it lists ports: [3000:3000], so port 3000 on the host forwards to port 3000 in the container; and if you're calling http://localhost:3000 from a browser on the same host, that will reach that forwarded port.

Otherwise, calls from one container to another can generally use the container's name (as in docker run --name) or the Compose service name; but, they must be on the same Docker network. That docker-compose.yml file also lists

services:
  influxdb:
    networks:
      - k6
      - grafana

so you can reach http://influxdb:8086 using the service's normal port number, provided the calling container is on one of those two networks. If the service has ports:, they're not considered for inter-container calls.

In the Docker documentation, Networking in Compose has more details on this setup.

There's one final trick that can help you run the specific command you're trying to run. docker-compose run will run a one-off command, using the setup for some container in the docker-compose.yml, except without its ports: and replacing its command:. The docker-compose.yml file you reference includes a k6 container, on the k6 network, running the loadimpact/k6 image. So you can probably run

docker-compose run k6 \
  run --out influxdb=http://influxdb:8086/myk6db - \
  <script.js

(And probably the K6_OUT environment variable in the docker-compose.yml can supply that --out option for you.)

You shouldn't ever need to look up the container-private IP addresses. They aren't usable in a variety of common scenarios, and in between Docker networking for calls between containers and published ports for calls from outside Docker, there are better ways to make calls to containers.

David Maze
  • 130,717
  • 29
  • 175
  • 215
  • Thanks a lot for the constructive tone and details! I'm not sure if you were going for this, but i just realized that k6 was not running. So Grafana and InfluxDB were up, but not k6. Running k6 with `docker run` was not enough to have k6 on the network InfluxDB was. Using the `docker-compose run` command you suggested last solves this. – inspiral Apr 05 '21 at 22:48