Docker
Docker/Apache起動イメージ

Fluentd とは

Docker/Apache起動イメージのログ集約を行うのに Fluentd を使ってみます。

Fluentd は Ruby ベースのログ集約ツールです。
http://www.fluentd.org/

ログをすべて JSON として扱い、
プラグイン構造で様々な種類のログを読み込み、
ファイルに書き出したり DB に書き込んだり SaaS(Software as a Service) に forwardしたりできます。

全てのログを Fluentd で方向整理して管理できるので、
docker で複数のコンテナを起動してサービスを行い必要がなくなったらコンテナを終了する、
といった場合に全コンテナ上の Apache のログを一カ所に集めて集中管理するようなことができます。

想定状況

コンテナを起動すると Apahce が立ち上がる docker イメージ内の Apache ログを
Fluentd で収集し mongodb に保存します。

この想定状況で可能な方法は以下のようなものが考えられます。

1. Fluentd もコンテナ内で動作させ、コンテナ内で Fluentd が読み込んだ Apache ログを
ネットワーク経由で別サーバ上の Fluentd に送信、
受け取った別サーバ上の Fluentd が mongodb に保存する。

2. コンテナ内の Apache のログが書き込まれる PATH をホストOS上にマウントし、
ホストOS上の Fluentd でログファイルを読み込んで mongodb に保存する。


1. の方法では送信側と受信側の二つの Fluentd をそれぞれサーバ上で動作させます。
2. の方法では一つの Fluentd がファイルを読んで nosql に書き込みます。


なお、コンテナ内の Fluentd から送信したログを
コンテナを動かしているホストOS上の Fluentd で受信することはできませんでした。
受信側 Fluentd と送信側 Fluentd は使用 port が一致していないと送受信できませんが、
ホストOS上で Fluentd を起動し通信用 port を使用していると
docker コンテナ起動時に同じ port と通信できるよう forward をしようとしても

$ sudo docker run -d -p 80:80 -p 24224:24224 -p 24224:24224/udp centos:apache+fluentd
Error: Cannot start container 2094c72e6685bd9f54e7f3f8de797845d6d8a43db37fd2f4f8231444e4bf377e: port has already been allocated

といったエラーが出てコンテナ自体を起動することができないためです。

install

今回は docker のコンテナ内もホストOSも CentOS6 を使用しているので、
公式サイトの
rpmパッケージからFluentdをインストールする
に従ってインストールします。

上記ドキュメント内にあるように、Fluentd 開発元の treasure data が提供する安定板 Fluentd は
td-agent という名前でインストールされます。

docker コンテナ内へのインストールは Dockerfile を使わず、
Docker/Apache起動イメージ を detach 状態にしないで起動し bash 上で行っています。

$ sudo docker run -i -p -p 192.168.161:8080:80 centos:apache
bash-4.1# curl -L http://toolbelt.treasuredata.com/sh/install-redhat.sh | sh

インストール完了後動作するか確認を行います。

bash-4.1# /etc/init.d/td-agent start 
Starting td-agent: [  OK  ]

設定はまだ行っていませんが正常に起動することを確認できたので停止しておきます。

bash-4.1# /etc/init.d/td-agent stop
Stopping td-agent: [ OK ]

この後設定ファイルを編集し bash を抜けてコンテナを終了させてから
docker commit で Fluentd をインストールした状態をイメージにして保存します。

ホストOS上へのインストールは、 docker コンテナ操作の部分を除き上記と全く同じです。

設定ファイル

Fluentd の設定ファイルは

/etc/td-agent/td-agent.conf

です。

ログの入力元は Sourceディレクティブ

<source>
 .....
</source>

ログの出力先は Matchディレクティブ

<match>
...
</match>

として記述します。

1. コンテナ内とリモートサーバ上の Fluentd によるログ記録

コンテナ内の送信側 Fluentd の設定は以下のようになります。

<source>
  type tail
  path /var/log/httpd/access_log
  tag apache.access
  pos_file /var/log/td-agent/httpd-access_log.pos
  format apache2
</source>

<match apache.access>
  type forward
  send_timeout 60s
  recover_wait 30s
  heartbeat_interval 1s
  <server>
    name fluentd-receiver
    host 192.168.0.204
    port 24224
  </server>
</match>

Apache のアクセスログを読み込んでリモートサーバの Fluentd に送出します。
この設定で

$ sudo docker run -d -p 80:80 -p 24224:24224 -p 24224:24224/udp centos:apache+fluentd

のように Apache と Fluentd で使用する port を forward してコンテナを起動します。

受信側サーバ(上記例では 192.168.0.204) の Fluentd 設定は以下のようになっています。

<source>
  type forward
  port 24224
</source>

<match apache.access>
  type mongo
  host localhost
  port 27017
  database fluentd
  collection apache
  flush_interval 10s
</match>

forward されてきたログを mongodb に保存します。
保存されたログを確認すると以下のように Apache のログが JSON 化されて保存されているのがわかります。

$ mongo
> show dbs
fluentd	0.203125GB
local	0.078125GB
proj_20140314	0.203125GB
> use fluentd
switched to db fluentd
> show collections
apache
system.indexes
> db.apache.find()
{ "_id" : ObjectId("53a8e94314cbd22e4e000012"), "host" : "192.168.0.128", "user" : null, "method" : "GET", "path" : "/", "code" : 403, "size" : 5039, "referer" : null, "agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36", "time" : ISODate("2014-06-24T02:57:58Z") }
{ "_id" : ObjectId("53a8e94314cbd22e4e000013"), "host" : "192.168.0.128", "user" : null, "method" : "GET", "path" : "/icons/apache_pb.gif", "code" : 304, "size" : null, "referer" : "http://192.168.0.161", "agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36", "time" : ISODate("2014-06-24T02:57:58Z") }
{ "_id" : ObjectId("53a8e94314cbd22e4e000014"), "host" : "192.168.0.128", "user" : null, "method" : "GET", "path" : "/icons/poweredby.png", "code" : 304, "size" : null, "referer" : "http://192.168.0.161", "agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36", "time" : ISODate("2014-06-24T02:57:58Z") }
{ "_id" : ObjectId("53a8e98514cbd22e4e000015"), "host" : "192.168.0.138", "user" : null, "method" : "GET", "path" : "/", "code" : 403, "size" : 5039, "referer" : null, "agent" : "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0", "time" : ISODate("2014-06-24T02:58:28Z") }
{ "_id" : ObjectId("53a8e98514cbd22e4e000016"), "host" : "192.168.0.138", "user" : null, "method" : "GET", "path" : "/icons/apache_pb.gif", "code" : 200, "size" : 2326, "referer" : "http://192.168.0.161", "agent" : "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0", "time" : ISODate("2014-06-24T02:58:28Z") }
{ "_id" : ObjectId("53a8e98514cbd22e4e000017"), "host" : "192.168.0.138", "user" : null, "method" : "GET", "path" : "/icons/poweredby.png", "code" : 200, "size" : 3956, "referer" : "http://192.168.0.161", "agent" : "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0", "time" : ISODate("2014-06-24T02:58:28Z") }
{ "_id" : ObjectId("53a8e98514cbd22e4e000018"), "host" : "192.168.0.138", "user" : null, "method" : "GET", "path" : "/favicon.ico", "code" : 404, "size" : 290, "referer" : null, "agent" : "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0", "time" : ISODate("2014-06-24T02:58:28Z") }
>

2. ホストOS上の Fluentd によるログ記録

docker コンテナ内では Fluentd を動作させず、
コンテナを動かしているホストOS上の Fluentd でコンテナ内の Apache のログを読み込むためには
コンテナ内で Apache のログが書かれるディレクトリを以下のようなオプションで
ホストOS上にマウントしてコンテナを起動します。

$ sudo docker run -d -p 80:80 -v /var/log/httpd/:/var/log/td-agent/httpd/ 

この状態でコンテナを起動しホストOS上の /var/log/td-agent/httpd/access_log へアクセスすれば
コンテナ内の Apache のログを読むことができます。

この Apache ログを読み込んで mongodb へ保存する Fluentd 設定ファイルは以下のようになります。

<source>
  type tail
  path /var/log/td-agent/httpd/access_log
  tag apache.access
  pos_file /var/log/td-agent/httpd-access_log.pos
  format apache2
</source>

<match apache.access>
  type mongo
  host localhost
  port 27017
  database fluentd
  collection apache
  flush_interval 10s
</match>

match ディレクティブの設定内容を変更すれば、
ファイルに書き出すこともリモートサーバー上の Fluentd へ送ることも出来ます。

更新履歴

2014/06/24 初稿公開

Satoshi OTSUKA

BC::labsへの質問は、bc9-dev @ googlegroups.com までお願い致します。
トップ   新規 一覧 単語検索 最終更新   最終更新のRSS