I am playing around with telegraf and influxdb v2. I want to get both running in Docker, using docker-compose. This post explains how to do it, but it lets telegraf use the admin token, which I do not like.
I want to create a special user with only write access to a specific bucket.
There are a lot of OS solutions for this out there using InfluxDB 1, but in InfluxDB 2 this has gotten difficult: The telegraf plugin now requires a token. The influx CLI does not let me choose a token. Hence, there is this temporal dependency where I first have to run InfluxDB, then create the user and the token, and then set the token in telegraf (e.g. as an environment variable). This is not possible with a single docker-compose file. Curiously enough, the influx setup script actually would let me specify the token myself, but I can only run this once for an org. Am I missing something?
So my current solution uses two docker-compose files and the following script to up both:
#!/bin/bash
...
docker-compose -f docker-compose.influxdb.yaml up -d
wait_for_influxdb
token=$(telegraf/extract-token.sh)
INFLUXDB_TELEGRAF_TOKEN=$token docker-compose -f docker-compose.telegraf.yaml up -d
This is the script I currently use to setup the metrics bucket:
My influxdb docker-compose file sets the admin account using the DOCKER_INFLUXDB_INIT_* variables, and mounts the above script to /docker-entrypoint-initdb.d.
Are there any better ideas for this? Or is my aversion of using the admin user misguided?
You could use a start script in influxdb like you are to create the user and then do a volume share between the containers but I don’t think it is exactly worth the effort. You can always just start one container at a time with docker-compose on first start.
Your answer contains two bits of information which I did not think/know about:
I only need to create and extract the token on first start, after that the token will persist in the mounted volume
It is possible to start a specific container of a docker-compose file
So what I will try to do is: for the first start extract the token with the script, but then, instead of providing it as an environment variable to the docker-compose command, I persist it in a local .env file. All successive starts are a simple docker-compose up.
Sure.
I made it work, the next challenge was that telegraf inside docker has to observe the host.
here is the relevant part of my docker-compose:
version: '3'
services:
influxdb:
image: influxdb:2.0.4
container_name: influxdb
ports:
- 8086:8086
volumes:
- ./influxdb/scripts:/docker-entrypoint-initdb.d # setup.sh, see my previous post
- influxdb-storage:/var/lib/influxdb2
- influxdb-config:/etc/influxdb2 # Stores credentials, so docker exec does not need them
environment:
- INFLUXD_REPORTING_DISABLED=true
- DOCKER_INFLUXDB_INIT_MODE=setup
- DOCKER_INFLUXDB_INIT_USERNAME=admin
- DOCKER_INFLUXDB_INIT_PASSWORD=${INFLUXDB_ADMIN_PASSWORD} # set in .env
- DOCKER_INFLUXDB_INIT_ORG=myorg
- DOCKER_INFLUXDB_INIT_BUCKET=game
telegraf:
image: telegraf:1.18.1
container_name: telegraf
volumes:
- ./telegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro
- /:/hostfs:ro # to enable collecting metrics from the host
environment:
- INFLUXDB_TELEGRAF_TOKEN=${INFLUXDB_TELEGRAF_TOKEN}
- HOST_ETC=/hostfs/etc # to enable collecting metrics from the host
- HOST_PROC=/hostfs/proc
- HOST_SYS=/hostfs/sys
- HOST_MOUNT_PREFIX=/hostfs
depends_on:
- influxdb
privileged: true
volumes:
influxdb-config:
influxdb-storage:
the script I run for first startup:
#!/bin/bash
# This script has to be run on first startup of the TI-Stack.
# Every startup after that can simply be done by docker-compose up
# The reason for this script is that the influxdb token for telegraf
# has to be set as an environment variable to the telegraf container,
# but the token is only created after the first startup of influxdb.
wait_for_influxdb() {
echo -n "Waiting for InfluxDB "
i=0
until $(curl --output /dev/null --silent --head --fail http://localhost:8086); do
echo -n "."
sleep 1
i=$((i + 1))
if [[ $i -gt 15 ]] ; then
echo " Timeout. InfluxDB container is not reachable."
return 1
fi
done
echo " Success."
return 0
}
docker-compose up -d influxdb
wait_for_influxdb
token=$(docker exec -it influxdb influx auth list | grep telegraf_token | awk '{print $3}')
sed -i '/INFLUXDB_TELEGRAF_TOKEN/d' .env
echo INFLUXDB_TELEGRAF_TOKEN=$token >> .env
docker-compose up -d telegraf
Please consider that the security of this solution relies on the attacker not having access to the server: the credentials are stored plain-text in the .env file, and docker-exec does not even require the token.