dockerコンテナのログをfluentdに集める方法

# TL;DR

* Docker logdriverの機能を利用して，ひとつのfluentdコンテナにdockerコンテナのログを集積する方法をまとめます
    * fluentdコンテナで集まったログをローカル・ファイルに書き出します
    * fluent.confの設定を書き換えて，他のログ収集サーバに転送することもできます
* 設定例をgithub.comで公開しています

# コンテナ構成例

* ホスト（コンテナを稼働させる物理マシン）で，複数のサービスが，docker-compose-{A,B}として稼働している
* これらのログを，fluentdコンテナに送る設定を行う

![docker-fluentd2.jpg](https://qiita-image-store.s3.amazonaws.com/0/309617/d8737b0c-4f94-667a-bf7d-ffc17ad0387a.jpeg)

# 設定

* ログ収集用のfluentdコンテナを立ち上げおき，その後，サービスを立ち上げます

## fluentdコンテナの立ち上げ

### Dockerコマンド版

* いくつかのオプションを付けて，fluentdコンテナを立ち上げます
    * 実行時のローカルディレクトリに，fluent.confを置きます
        * 内容は [fluentd-docker-logging](https://github.com/myoshimi/fluentd-docker-logging) を確認してください
        * [dockerhub提供のfluent.conf](https://hub.docker.com/r/fluent/fluentd/)と同じものです
    * 不揮発領域は，fluentdのlogディレクトリです
    * ```/fluentd/etc```に設定ファイル ```fluent.conf``` をマウントします

```bash
docker run -d -p 127.0.0.1:24224:24224 -p 127.0.0.1:24224:24224/udp \
  -v ${PWD}log:/fluentd/log \
  -v ${PWD}/fluent.conf:/fluentd/etc/fluent.conf:ro \
fluent/fluentd:latest \
  /usr/bin/fluentd -c /fluentd/etc/fluent.conf -v
```

* 2019年4月9日時点ではv1.4.1がリリースされていますが， ```fluent/fluentd:latest``` は安定版と書かれているv1.3系です

dockerコマンドの詳細は以下の通り

| オプション | 説明 |
|:---|:---|
| -d | バックグラウンド実行 |
| -p | ローカルホスト(127.0.0.1)へポート開放, 24224/{TCP,UDP} |
| -v ${PWD}/fluentd/log:/fluentd/log | 不揮発化するfluentdログディレクトリ |
| -v ${PWD}/fluentd/etc:/fluentd/etc | 設定ファイルのためのボリュームマウント |
| fluent/fluentd:latest | [fluentdのDockerイメージ](https://hub.docker.com/r/fluent/fluentd/) |
| /usr/bin/fluentd -c /fluentd/etc/fluent.conf -v | fluentd実行コマンド．指定の設定ファイルを読み込み， verboseなログ出力 |

### docker-compose.yml

* 前項のdockerコマンドをdocker-compose.ymlにまとめたものです
* [fluentd-docker-logging](https://github.com/myoshimi/fluentd-docker-logging) を ```git clone``` して，```docker-compose up -d```で立ち上げます
* ディレクトリ内のfluent.confを読み込む
* ローカルディレクトリに ```log``` ディレクトリを作成し，不揮発ボリュームとして使用します

## fluentdコンテナを使用する側の設定

* 例として，nginxコンテナを立ち上げ，ログをfluentdコンテナに送る構造を作り，動作確認します

### Docker run

* 以下は， ```nginx:latest``` を稼働させた場合のコマンド例

```bash
docker run -d \
  --log-driver=fluentd \
  --log-opt fluentd-address=localhost:24224 \
  --log-opt tag=docker.{{.Name}} \
  nginx:latest
```

dockerコマンドの詳細は以下の通り

| オプション | 説明 |
|:---|:---|
| -d | バックグラウンド実行 |
| --log-driver=fluentd | ログをfluentdに出力するログドライバの指定 |
| --log-opt fluentd-address | fluentdサーバの宛先（本記事の場合はローカルホストのfluentdコンテナ） |
| --log-opt tag=docker.{{.Name}} | ログに付与するタグ（ ```{{.ID}}``` も使える） |

### docker-compose.yml

* 前項のnginxを，docker-compose.ymlにまとめると，以下のようになります．
    * ```docker-compose up -d```で立ち上がります
    * デフォルト設定のみなので，特段の機能は提供しません

```docker
version: '3.7'
services:
  rev:
    image: nginx:1.15.8
    ports:
      - "80:80"
    logging:
      driver: "fluentd"
      options:
        fluentd-address: "localhost:24224"
        tag: "docker.{{.Name}}"
```

## 動作確認

* fluentdコンテナを立ち上げた後，nginxコンテナを立ち上げます
* fluent.confを編集して，別のログサーバ(elasticsearchなど)への転送することができます
* 立ち上げ後の状況は以下のようになります

```bash
$ docker ps -a

CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS                                                              NAMES
xxxxxxxxxxxx        nginx:1.15.8            "nginx -g 'daemon of…"   3 minutes ago       Up 3 minutes        0.0.0.0:80->80/tcp                                                 nginx_rev_1
yyyyyyyyyyyy        fluent/fluentd:v1.3.2   "/bin/entrypoint.sh …"   About an hour ago   Up About an hour    5140/tcp, 127.0.0.1:24224->24224/tcp, 127.0.0.1:24224->24224/udp   fluentd-docker-logging_fluentd_1
```

* nginxのログはfluentdに転送されていて，コマンドでは確認できません

```bash
$ docker logs nginx_rev_1
Error response from daemon: configured logging driver does not support reading
```

* fluentdのログディレクトリ内にログファイルが作成されており，nginxから転送されたログ内容を確認できます

```bash
$ tail -1 ~/fluentd-docker-logging/log/docker.zzzzzzzzzzzzzzzzzzzzzzzzzzzz.log

2019-04-09T03:44:41+00:00	docker.xxxxxxxxxxxx 	{"source":"stdout","log":"AAA.BBB.CCC.DDD - - [09/Apr/2019:03:44:41 +0000] \"GET / HTTP/1.1\" 200 612 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1 Safari/605.1.15\" \"-\"","container_id":"xxxxxxxxxxxx","container_name":"/nginx_rev_1"}
```

## 注意点

* log-driverで指定したfluentdサーバが疎通しない場合，コンテナの立ち上げが失敗しますので，起動順が重要です

# 参考

* [Fluentd logging driver](https://docs.docker.com/config/containers/logging/fluentd/)
* [ロギング・ドライバの設定](http://docs.docker.jp/engine/admin/logging/overview.html)