概要
最近急にクラウドネイティブ界隈で話題になっているらしいロギングツールのLokiをDockerで試してみた。
コンテナのロギングと言えば今のところEFKスタック(Elasticsearch + Fluentd + Kibana)が一般的だが、個人的な開発環境や遊び環境だとElasticsearchが重いせいでEFKを使うことに抵抗があった。しかし、Lokiはちょっと使ってみた感じだと全然リソース消費が気にならず、シンプルでお手軽に導入できることからDockerの開発環境にはとりあえず入れておいた方がいいレベルのものになるかもしれない。
まだバージョン1.0ではなく、今後はPrometheusとも連携できるようになるようだが、個人的に使う分には現状でも十分役立ちそう。
構築
- DockerにLokiのプラグインをインストールする
- 各コンテナがログをLokiへ転送するように設定する
- ログ収集用のLokiコンテナと可視化用のGrafanaコンテナを起動する
- GrafanaからLokiに接続する設定をする
事前準備
コンテナが一つもあがっていないことを確認
あがっていたら消しておく。
docker container ls -a
DockerにLokiのプラグインをインストールする
コマンド1つ実行するだけ。
docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions
インストール確認はdocker plugin ls
でできる。
$ docker plugin ls
ID NAME DESCRIPTION ENABLED
bb97061da4a3 loki:latest Loki Logging Driver true
各コンテナがログをLokiへ転送するように設定する
Logging Driverの設定を変更することでLokiへログを転送させるようにする。
基本的には公式のdocker-driverのREADMEに書かれている通りに設定を行えばよい。log-optsに記載できるオプションがたくさんあるようなので詳しく知りたい場合も同ページを参照。
同一ホスト上でデフォルトのポート番号でLokiを起動すればlocalhost:3100
でアクセスできるようになるため、daemon.json
を変更する場合は以下のように記載すればよい。
コンテナごとに指定したい場合は、各コンテナを起動するdocker-compose.yaml
の各サービスごとにloggingのオプションを記載する必要があるので結構手間
{
"debug" : true,
"log-driver": "loki",
"log-opts": {
"loki-url": "http://localhost:3100/api/prom/push",
"loki-batch-size": "400"
}
}
daemon.json
の変更を反映させるためにDockerを再起動する。
systemctl restart docker.service
まだLokiを起動していないが、とりあえずこれで今後起動したコンテナのログがLokiに転送されるようになる。
次に肝心のLokiとGrafanaを起動する。
ログ収集用のLokiコンテナと可視化用のGrafanaコンテナを起動する
コード取得
公式のGitHubからコードを取得する。
https://github.com/grafana/loki/blob/master/production/docker-compose.yaml のみあれば十分なので、git clone
せずに直接docker-compose.yaml
を作成してしまっても全然問題無い。
git clone https://github.com/grafana/loki.git
cd loki/production/
docker-compose.yamlの編集
デフォルトではpromtailを使ってホストの/var/log/*log
も収集するようになっているが、Dockerコンテナのログのみ収集したい場合は不要なのでpromtail部分をコメントアウトor削除する。
ホストのログも収集したい場合はそのままでよい。
Lokiのホスト側のポート番号を変更する場合はdaemon.json
の方も合わせるのを忘れずに。
Grafanaの方のポートは外部からブラウザアクセスで使うだけなので好きな番号にしておそらく問題無い。
いきなりpromtailというものが出てきたが、イメージ的にはおそらく以下のように思っていいと思う。
Loki = Elasticsearch みたいなやつ(ログが集まる場所)
promtail = Fluentd みたいなやつ(ログ集めるやつ)
Grafana = Kibana みたいなやつ(集まったログを見やすくするやつ)
直接Lokiにログを送れてしまうのでpromtailの存在意義がわかりにくいが、おそらく標準出力に出てくるタイプの一般的なコンテナのログはLokiに直接送って、ファイルに書き出されていくタイプのログ(主にサーバのログ)はpromtail経由でLokiに送る感じなのではないかと思う。
version: "3"
networks:
loki:
services:
loki:
image: grafana/loki:latest
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
networks:
- loki
# promtail:
# image: grafana/promtail:latest
# volumes:
# - /var/log:/var/log
# command: -config.file=/etc/promtail/docker-config.yaml
# networks:
# - loki
grafana:
image: grafana/grafana:master
ports:
- "3000:3000"
networks:
- loki
編集が終わったらLokiとGrafanaのコンテナを起動
ちゃんと使うならLokiのログが溜め込まれていくディレクトリを永続化しておくべきだと思う。
Grafanaはどちらでも。
docker-compose up -d
GrafanaでLokiに接続する設定をする
※ここの設定は画面上で手動で行わなくても、事前に設定ファイル作っておいてコンテナ起動時に送る方法があると思う。
- ブラウザでGrafana(デフォルトでは「http://<サーバアドレス>:3000」)にアクセスし、admin/adminでログインする。
- adminユーザのパスワード変更を求められるので適当に変更
- 「Add data source」をクリックし、Lokiをクリック
- URLに「http://loki:3100」と入力し、「Save & Test」をクリック
Data source connected and labels found.
と表示されたら成功
なお、接続に成功してもLoki起動後に追加されたログが1つも無い場合はData source connected, but no labels received. Verify that Loki and Promtail is configured properly.
というエラーが出る。とりあえず何かしらのログを発生させればこのエラーは表示されなくなる。
daemon.json
を変更した場合は既にLokiとGrafanaのログが入っているはずなのでエラーになることはないと思うが、docker-compose.yaml
等で個別に変更するつもりの場合は注意
使う
あとは適当にコンテナを起動した後に、サイドバーからExploreをクリックし、左上のLog labelsで適当に見たいコンテナ名などをクリックすればそのコンテナのログが表示される。ホスト単位で見たり複数のコンテナを指定して見たりもできる。
デフォルトでは自動で更新されないため、右上のRefleshボタンで適当に更新間隔を変更しておくと便利
最初の画面にサンプルで記載されているが、{app="cassandra"} (duration|latency)\s*(=|is|of)\s*[\d\.]+
のように正規表現でフィルタリングして表示も可能なのでdockerコマンドで頑張ってログを見るよりもだいぶ楽ができる。
ただダッシュボードがLokiに未対応のようで、画面を開くたびにQueryの入力が必要になるところが面倒
その他
ダメだったこと
そもそもコンテナのログは/var/lib/docker/containers/<コンテナID>/<コンテナID>-json.log
に書き込まれているわけで、最初はpromtailに/var/lib/docker/containers/
をマウントさせてjsonファイルのみ取り込む方式でいけるのではないかと思った。
この方法だとdaemon.json
などを変更する必要もなく、既に起動中のコンテナのログを後から収集対象にできるから便利に使える。
が、同じことをしようとしていた人がいて、過去のバージョンでは強引にやれないこともなかったが今はやれなくなってしまっている様子。https://github.com/grafana/loki/issues/333
サーバ上でもログを見たい場合
Lokiへログを転送する設定にしてもホストの/var/lib/docker/containers/<コンテナID>/<コンテナID>-json.log
には通常通りログが書き込まれているらしく、docker container logs
コマンドで普通にログを見ることができる。
ただし、なぜかdocker-compose logs
コマンドではWARNING: no logs are available with the 'loki' log driver
と表示されてしまってログが見れない。
サーバ上でログを見たい場合は注意