Add Plugins to the Telegraf Docker Container and keep the Container Size small

How to add external plugins to the Telegraf docker container while keeping container size as small as possible.

Add Plugins to the Telegraf Docker Container and keep the Container Size small
Telegraf Logo from InfluxData Mascots

At gridscale, we currently use InfluxDB for some things. That means we collect our metrics with Telegraf. Telegraf does collect a lot of metrics already by default. But sometimes you just need more.

It does not make sense for the Telegraf team to put everything into the Telegraf core. This would blow up the project and most people would only use a small percentage of those metrics.

On the other side, this means some more work for you. Yes, you the dev, ops, DevOps whatever guy! So here is a quick example how I have manged this.

Keep the Telegraf Docker image small while adding functionality

With a multi-staged docker build you can add more plugins while keeping the container size small and the Dockerfile readable. The docker container will only increase by the size of the artifact you are adding with the COPY directive. The downloaded git repo, possible build artifact, etc. will be discarded.

I highly advise naming your build stages for readability. Here an example of using one stage:

# Get repo for psi plugin

FROM bitnami/git AS git-psi
WORKDIR /app
RUN git clone --depth 1 --branch v0.1.0 https://github.com/gridscale/linux-psi-telegraf-plugin.git linux-psi-telegraf-plugin

# Build psi binary

FROM golang:1.16-alpine AS binary-psi
WORKDIR /go/src/app/
COPY --from=git-psi /app/ ./
WORKDIR /go/src/app/linux-psi-telegraf-plugin
RUN go build -o psi cmd/main.go

# Build the telegraf container with your plugins
FROM telegraf:alpine

COPY --from=binary-psi /go/src/app/linux-psi-telegraf-plugin/psi /usr/local/bin/psi

Now you just have to add some config for your new plugin. That of course depends on the plugin you want to add.

[...]

[[inputs.execd]]
  command = ["/usr/local/bin/psi"]
  signal = "none"

So you did find another plugin from this list? Or you found something useful on GitHub like this plugin to get btrfs file system metrics:

https://github.innominds.com/iwvelando/telegraf-exec-btrfs-status

Just add another block to get the code, build the binary and copy the artifact:

# Get repo for psi plugin

FROM bitnami/git AS git-psi
WORKDIR /app
RUN git clone --depth 1 --branch v0.1.0 https://github.com/gridscale/linux-psi-telegraf-plugin.git linux-psi-telegraf-plugin

# Build psi binary

FROM golang:1.16-alpine AS binary-psi
WORKDIR /go/src/app/
COPY --from=git-psi /app/ ./
WORKDIR /go/src/app/linux-psi-telegraf-plugin
RUN go build -o psi cmd/main.go

# Get repo for telegraf-exec-btrfs-status
FROM bitnami/git AS git-btrfs-stats
WORKDIR /app
RUN git clone --single-branch --depth 1 https://github.com/iwvelando/telegraf-exec-btrfs-status.git telegraf-exec-btrfs-status

# Build telegraf-exec-btrfs-status binary
FROM golang:1.16-alpine AS binary-btrfs-stats
WORKDIR /go/src/app/
COPY --from=git-btrfs-stats /app/ ./
WORKDIR /go/src/app/telegraf-exec-btrfs-status
RUN go build -o telegraf-exec-btrfs-status .


# Build the telegraf container with your plugins
FROM telegraf:alpine


COPY --from=binary-psi /go/src/app/linux-psi-telegraf-plugin/psi /usr/local/bin/psi

# Copy binary for btrfs-stats
COPY --from=binary-btrfs-stats /go/src/app/telegraf-exec-btrfs-status/telegraf-exec-btrfs-status /usr/local/bin/telegraf-exec-btrfs-status

# Copy config for btrfs-stats
COPY --from=git-btrfs-stats /app/telegraf-exec-btrfs-status/btrfs_device_stats_template.txt /etc/telegraf/
COPY --from=git-btrfs-stats /app/telegraf-exec-btrfs-status/btrfs_filesystem_usage_template.txt /etc/telegraf/
COPY --from=git-btrfs-stats /app/telegraf-exec-btrfs-status/btrfs_scrub_status_template.txt /etc/telegraf/

It still is relatively easy to understand what is going on.

You could put the git pull for both repositories in one stage. You would have to switch paths or working directories. This makes the code more complex and less obvious in my opinion. Imagine you just want to delete 1 plugin later on. You need more brainpower to distinguish what is where and what.

?
If the maintainer of your desired plugin is offering a binary you could also use that and save some build time. I did however not find many pre-build binaries for Telegraf plugins in general.
Also, you could get some trouble starting a binary that was built on Ubuntu and using it on the alpine-based container. I had some problems with that and was forced to build the binary on alpine in order to get it working on alpine as well.

Anyway, I hope this helps some fellow out there and if so let me know down in the comment section ?

Have a great day!