DockerのFluentd Logging Driverを試してみる
ども、大瀧です。 Dockerバージョン1.6でLogging Driverというプラガブルなログ機構が追加され、DockerコンテナのログをSyslogに送信するなど柔軟なログ構成ができるようになりました。 ログアグリゲータとして著名なFluentdのLogging Driverが最近Dockerのmasterブランチにマージされたので、試してみた様子をご紹介します。
検証環境
- OS : Ubuntu 15.04 Vivid Vervet(AMI : ubuntu-vivid-15.04-amd64-server-20150616.1 (ami-0473a904) 東京リージョン)
- Docker : Master Binaries 1.8.0-dev/Git commit: 90024b9
まだリリースされていない段階なので、最新リリースのDockerパッケージをインストールした状態でGitHubのmasterブランチのデイリービルドから入手した/usr/bin/dockerをすげ替える形でやってみました。
$ wget -qO- https://get.docker.com/ | sh $ sudo usermod -aG docker ubuntu $ docker version Client version: 1.7.0 Client API version: 1.19 Go version (client): go1.4.2 Git commit (client): 0baf609 OS/Arch (client): linux/amd64 Server version: 1.7.0 Server API version: 1.19 Go version (server): go1.4.2 Git commit (server): 0baf609 OS/Arch (server): linux/amd64 $ sudo service docker stop $ wget https://master.dockerproject.org/linux/amd64/docker $ chmod 755 ./docker $ sudo mv /usr/bin/docker /usr/bin/docker17 $ sudo mv ./docker /usr/bin/ $ sudo service docker start $ docker version Client: Version: 1.8.0-dev API version: 1.20 Go version: go1.4.2 Git commit: 90024b9 Built: Tue Jun 30 13:02:19 UTC 2015 OS/Arch: linux/amd64 Server: Version: 1.8.0-dev API version: 1.20 Go version: go1.4.2 Git commit: 90024b9 Built: Tue Jun 30 13:02:19 UTC 2015 OS/Arch: linux/amd64 $
Fluentdサーバーとしてtd-agentをセットアップしておきます。
$ curl -L https://td-toolbelt.herokuapp.com/sh/install-ubuntu-trusty-td-agent2.sh | sh
デバッグ用に、td-agent.confファイルの末尾にDockerログを標準出力(td-agentのログファイル)に出力する以下を追加しました。
: <match docker.**> type stdout </match>
td-agent.confファイルの再読込をしておきます。
$ sudo service td-agent restart
これで準備OKです。
動作確認
Dockerコンテナの実行オプション--log-driverにfluentdとセットすると、コンテナのログがローカルのFluentdサーバー(localhost:24224)に送信されます。
$ docker run --log-driver=fluentd hello-world $ tail -n 20 /var/log/td-agent/td-agent.log </ROOT> 2015-06-30 13:39:44 +0000 [info]: listening fluent socket on 0.0.0.0:24224 2015-06-30 13:39:44 +0000 [info]: listening dRuby uri="druby://127.0.0.1:24230" object="Engine" 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7","container_name":"/angry_mestorf","source":"stdout","log":"Hello from Docker."} 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"source":"stdout","log":"This message shows that your installation appears to be working correctly.","container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7","container_name":"/angry_mestorf"} 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"source":"stdout","log":"","container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7","container_name":"/angry_mestorf"} 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"container_name":"/angry_mestorf","source":"stdout","log":"To generate this message, Docker took the following steps:","container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7"} 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7","container_name":"/angry_mestorf","source":"stdout","log":" 1. The Docker client contacted the Docker daemon."} 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7","container_name":"/angry_mestorf","source":"stdout","log":" 2. The Docker daemon pulled the \"hello-world\" image from the Docker Hub."} 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7","container_name":"/angry_mestorf","source":"stdout","log":" (Assuming it was not already locally available.)"} 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7","container_name":"/angry_mestorf","source":"stdout","log":" 3. The Docker daemon created a new container from that image which runs the"} 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"source":"stdout","log":" executable that produces the output you are currently reading.","container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7","container_name":"/angry_mestorf"} 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"container_name":"/angry_mestorf","source":"stdout","log":" 4. The Docker daemon streamed that output to the Docker client, which sent it","container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7"} 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7","container_name":"/angry_mestorf","source":"stdout","log":" to your terminal."} 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7","container_name":"/angry_mestorf","source":"stdout","log":""} 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"log":"To try something more ambitious, you can run an Ubuntu container with:","container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7","container_name":"/angry_mestorf","source":"stdout"} 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"container_name":"/angry_mestorf","source":"stdout","log":" $ docker run -it ubuntu bash","container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7"} 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"container_name":"/angry_mestorf","source":"stdout","log":"","container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7"} 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"source":"stdout","log":"For more examples and ideas, visit:","container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7","container_name":"/angry_mestorf"} 2015-06-30 13:39:52 +0000 docker.49cdcf66ce0c: {"log":" http://docs.docker.com/userguide/","container_id":"49cdcf66ce0c882f9788cbdeeea0e354bf7331eb3a1fd8ccd4746834def84ef7","container_name":"/angry_mestorf","source":"stdout"} $
49cdcf66ce0cがコンテナIDに対応しており、DockerのコンテナログがFluentdに渡っているのがわかりますね!
まとめ
最小限の動作確認でしたが、確かにDockerコンテナのログをFluentdに送信できている様子が確認できました。
Fluentdサーバーを今回のようにホストでデーモンとして実行するのか、これはこれでFluentdのDockerコンテナとして実行するのかを次に検討しつつ、FluentdからはひとまずS3にログを格納する感じになるのではないでしょうか。リリースに入るのを心待ちにしつつ、Dockerのログアーキテクチャの構想を練っておきましょう。