prometheusの設定ファイルに環境変数を埋め込みたい
About
最近prometheus導入を頑張っていたときの気付きです。もっとよい方法がありそうなのでご存知のかたいたら教えてほしいです。。結構雑目に書いています。
課題
prometheusやalertmanagerは私が知る限り設定ファイルベースとなっていて、一部の設定値を除きコマンドラインで設定を埋め込むということができません。
コンテナ環境で動かそうと思っていて、例えば下記の点が不便だなと思っています。
- alertmanagerのreceiverの設定ファイルに秘匿情報(slackのWebhookとか)を入れないといけない。
- regionが違う場合にregionごとにimageを作成する必要がある
imageを作成した時点で設定を固めないといけないため柔軟に設定を変えるのが難しいなーと感じていました。何かいい方法ないかなといろいろ考えていたときにenvsubstというものを見つけました。
envsubstとは
軽量なテンプレートエンジンのようです。gettext utilitiesに含まれています。環境変数を展開してくれるようです。
使ってみる
既存のprometheusのimageでpackageを入れる方法がわからなかったので、alpineベースでimageを作り直しenvsubstを導入します。
# 参考にしたDockerfileへのリンクが見つからない…
FROM alpine:latest
ARG ARCH=amd64
ARG VERSION=1.8.1
RUN apk --no-cache add gettext
RUN apk --no-cache add --virtual build-dependencies wget ca-certificates \
&& mkdir -p /tmp/install /tmp/dist \
&& wget -O /tmp/install/prometheus.tar.gz https://github.com/prometheus/prometheus/releases/download/v$VERSION/prometheus-$VERSION.linux-$ARCH.tar.gz \
&& apk del build-dependencies \
&& cd /tmp/install \
&& tar --strip-components=1 -xzf prometheus.tar.gz \
&& mkdir -p /etc/prometheus /usr/share/prometheus \
&& mv prometheus promtool /bin/ \
&& mv prometheus.yml /etc/prometheus/prometheus.yml \
&& mv consoles console_libraries NOTICE LICENSE /usr/share/prometheus/ \
&& ln -s /usr/share/prometheus/console_libraries /usr/share/prometheus/consoles/ /etc/prometheus/ \
&& rm -rf /tmp/install
EXPOSE 9090
VOLUME [ "/prometheus" ]
WORKDIR /prometheus
COPY prometheus.yml.template /etc/prometheus/prometheus.yml.template
prometheus本体のimageだとcommandやEntrypointがありますがわかりにくくなりそうだったので一旦削除しました。最後にCOPYでtemplateをimageに入れています。
template自体はサンプルなので、下記のようにしました。
$ cat prometheus.yml.template
# my global config
global:
scrape_interval: 15s # By default, scrape targets every 15 seconds.
evaluation_interval: 15s # By default, scrape targets every 15 seconds.
# scrape_timeout is set to the global default (10s).
# Attach these labels to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
monitor: ${PROJECT_NAME}
...
${PROJECT_NAME} という部分が環境変数で置き換える部分ですね。
docker-compose.ymlは下記のようにします。
version: '3'
services:
prometheus:
build: .
command:
- /bin/sh
- -c
- |
envsubst '$$PROJECT_NAME'< /etc/prometheus/prometheus.yml.template> /etc/prometheus/prometheus.yml
/bin/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--storage.local.path=/prometheus \
--alertmanager.url=http://alertmanager:9093/alertmanager \
--web.console.libraries=/usr/share/prometheus/console_libraries \
--web.console.templates=/usr/share/prometheus/consoles
ports:
- 9090:9090
environment:
PROJECT_NAME: 'test'
commandの部分でenvsubstで設定ファイルを置き換えたのちにprometheusを起動させています。
commandを複数実行する際の参考 Running multiple commands in entrypoint · Issue #52 · docker-library/redmine · GitHub
起動後にコンテナに入ってみると
# cat /etc/prometheus/prometheus.yml
# my global config
global:
scrape_interval: 15s # By default, scrape targets every 15 seconds.
evaluation_interval: 15s # By default, scrape targets every 15 seconds.
# scrape_timeout is set to the global default (10s).
# Attach these labels to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
monitor: test
...
というように起動時に環境変数を挿入できるようになりました。