logspoutでDockerコンテナのログの集約・ルーティング
logspoutは,ホスト内で動かした全てのDockerコンテナの出力を集約して,好きなところに飛ばす(ルーティングする)ためのツール.開発者はDokkのJeff Lindsay.
以下の2つの特徴がある
- コンテナとして起動(ステートレス)
- HTTP APIによるルーティングの設定
ログを貯めて管理したり,検索するといったことはできない.コンテナのログをリアルタイムで好きなところに飛ばすだけ.
これだけだが,Dockerのログの問題をいい感じに解決してくれそう.
Dockerのログのしくみ
まず,簡単にDockerのログのしくみを説明する.
現時点(2014年5月)でDockerはコンテナ内で吐き出されたstdout/stderrを取得することができる.コンテナのプロセスがstdout
とstderr
にログを吐き出し,Dockerはそれをホストにjson
として保存する.docker log
コマンドを使うとそれを取得することができる.
これはシンプルだけど欠点でもある.いずれディスクが圧迫されるし,毎回docker log
を叩くわけにもいかない.そのため,Dockerのログをどうするかってのはいろいろ試みられている.
Dockerのログ収集の試み
Dockerコンテナのログ収集の試みは,大きく分けて3つある.
- コンテナの内部で収集する:コンテナ内でログ収集のプロセスを同時に走らせる(“dockerなら5分で動く! nginxのログをfluentdで集めてnorikraでストリーム分析”)
- コンテナの外部で収集する:ホスト側でログ収集のエージェントを走らせて,コンテナのログの書き出し先をホストからマウントする,もしくは
json
を直接読む(“Docker Log Management Using Fluentd”) - 収集および配信用のコンテナを立てる:logstash-forwarderのようなログの収集および配信を担うエージェントをコンテナ内に立てる.そして各コンテナが起動の際に
--volumes-from
でそのコンテナを指定する(“Docker And Logstash: Smarter Log management For Your Containers”)
やりようはいろいろあるが,少なくともDocker的に良いのは,
- コンテナに複数プロセスを立てない
- ホストに多くを設定しない
これを満たすのは,3番目の専用のコンテナを立てる方式.logspoutはこれをシンプルに実現することができる(例えば,上のように--volume-from
とか必要ない)
logsoutを使う
まず,インストール.素晴らしい.
1
|
|
例として,”hello world”を出力し続ける単純なコンテナを立てておく.
1 2 |
|
これらに対してログを収集するには以下を実行する.
1
|
|
HTTP APIのアクセスを可能にするため8000
ポートを解放し,ホストの/var/run/docker.sock
をマウントする.
ログを見てみる.
1 2 3 4 5 6 7 |
|
リアルタイムの出力が確認できる.出力は色づけもされている.
ルーティング
一番単純な方法は,rsyslogに投げること.以下のように起動コマンドにURIを指定するだけ.
1
|
|
以下のようにPOSTを使って,ルーティングの設定をすることもできる.
1 2 |
|
上の例では,名前がdb
であるコンテナのstderr
への出力をlogs.papertrailapp.com:55555
に飛ばすように設定している.addr
はDNSで名前解決さえできればいいので,Consulなどのサービスディスカバリを使えば,さらなる道を開けそう.
ルーティングは以下のようにGETでデバッグしつつ設定できる.
1 2 3 4 |
|
まとめ
考慮する問題はいくつかある.
- 若干の遅れが生じる
- stdout/stderrだけしか取得できない(これはDockerの仕様)
まだ出たばかりなので,1つ目はすぐに解決しそう.2つ目の問題に関しては,volume
やマウントを駆使してなんとかするしかない.
それでも素晴らしい.得に良いなと思うのが,docker run
ですぐ使えるところ.Dockerの良さが溢れ出ている.