超今更感が有りますが、fluentdを使ってログを柔軟に扱えるシステムを組んでみようかなあって思ってしまいました。
せっかくだから、dockerを使って、ローカルでAWSチックな分散システムにでもしてみようかなと思います。
ロードマップ
というほどだいそれたものではないですが、こんなことやりたいよっていうのを示します。
- PHPログを同じサーバ上のFluentdに流す
- Fluentdから別の集約用のFluentdにログを流す
- 集約用のFluentdからMongoDBにログを流す
これらの機能をdockerのコンテナ上で実現しようと考えました。
で、題名から見ても分かる通り、妙に分量が多くなってしまったので、今回はロードマップの1番までの内容を報告しようと思います。
結果
経緯とかは後で書きますが、まずはどうなったかの結果だけ書きますと、
https://github.com/niisan-tokyo/log_experioment/tree/singleContainer
で、一応実現できました。
こいつをローカルに落として、
$ vagrant up
$ vagrant ssh
$ sudo su
# docker build -t niisan-tokyo/php56 niisan-tokyo/
# docker run -d -p 8080:8080 niisan-tokyo/php56
ここまでやったら
http://192.168.33.40:8080/
にアクセスすると、
こんな画面が出ます
かくスコアに数値を入れてやり、送信ボタンを押すと、裏でログに吐き出されます
ログの確認はこんなふうにすればよいです
# docker exec -it <コンテナID or コンテナ名> /bin/bash
# cd /var/log/td-agent
# ls
# tail -f app.<ハッシュ文字列>
コンテナ名やコンテナIDはdocker ps
コマンドを打てばわかります
ハッシュ文字はls
で出てきたappで始まるログを確認すればよいです
ログはこんな感じです
2015-12-16T09:18:02+00:00 app.scores {"score1":33,"score2":23,"score3":232}
2015-12-16T09:19:18+00:00 app.scores {"score1":41,"score2":56,"score3":84}
とりあえず今回の目的は果たせました
ここから先は、ここに至るまでの過程をダラダラと書いています。
詳細経緯
環境の構築
CentOS環境を別途用意する
dockerのコンテナ上での開発はかなり面倒というか、ちょっとわかりにくかったので、一旦別のCentOS環境を用意しました。
環境にはPHP5.6とComposerを突っ込んでありました。
BEAR.Sundayを導入する
Phalconはエクステンション入れないといけないし、Laravelの今のバージョンよくわからんし、CakePHPでもDBなしの場合どうなるかわからんかったので、わかりやすいBEAR.Sundayを導入することにしました。
BEAR.Sundayの導入は、公式サイトにあるので、それに従って作ります。
$ composer create-project bear/skeleton niisan-tokyo/Logexp
これでプロジェクトのスケルトンを構築できます。途中にベンダー名とプロジェクト名を聞いてくるので、それぞれ入力します。(例:NiisanTokyo
/ Logexp
)
必要なパッケージを突っ込む
チュートリアルの方法以外でのHTMLの表示方法がわからなかったので、とりあえず、テンプレート用のパッケージを入れます。
composer require madapaja/twig-module ~1.0
これでHTML出力できるようになりました。
あとは、fluentdにログを投げるためのパッケージも入れちゃいましょう
composer require fluent/logger v1.0.0
本当はこいつをPSR4のLoggerInterfaceに合うようにラッピングしておくべきなんでしょうが、面倒なのでやってません。。。
フォームを作る
簡単なスコアを入力するだけのフォームを作成します。
コードの内容は先のURLにあるリポジトリに全部あげているので、詳細には書きません。
ただ、チュートリアルに従うと少々動作しない部分があるので、その点だけ書きます
-
var/www/index.php
の$context
にprod-html-app
と入れると、必ずapc_fetch
関数の呼び出しが発生し落ちるので、html-app
と書くと良いです。 - FluentLoggerはPSR4のLoggerInterfaceの実装になっていないため、チュートリアルのmonologと同じようにAppModuleに設定すると、コンパチエラーが発生します。
フォームができて、POSTでデータを送信できるようになれば、一旦PHPの作業は終わりです
Fluentd入れる
フォームができてもFluentdがないとログを処理できないので、導入します。
Fluentdはコマンド一発で入れられるので、「現在作業している環境」上では簡単です。
curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh
これでFluentdのインストールが終わるので、設定ファイル/etc/td-agent/td-agent.conf
に書き込んでやりましょう
<source>
type forward
</source>
<match app.**>
type file
path /var/log/td-agent/app
</match>
とりあえずこの項目があれば大丈夫だと思います。
詳細は上に上げたリポジトリの niisan-tokyo/etc/td-agent.conf を見てください
あとは sudo service td-agent start
してあげれば、fluentdによるログ収集が始まります。
Dockerに移す
と、ローカルのcentos環境でゴリゴリやるのは慣れているのでいいのですが、問題はこれらをDockerコンテナ上で実現するということです。
手順
作業は以下の様な手順で行われました
- dockerのホストマシンを用意する
- コンテナのイメージを作る
- 起動する
実際には2->3の手順を何度も繰り返すはめになりました
ホストマシンの容易
ホストマシンはdockerに特化したディストリビューションである、Atomic Hostを使用しました
Vagrantのイメージもあるので、これを利用すると楽ちんです
https://atlas.hashicorp.com/centos/boxes/atomic-host
コンテナのイメージを作る
Dockerfileを作る
とても変な場所にDockerfileおいてありますが(niisan-tokyo/Dockerfile)、これには理由があって(言い訳)、コンテナイメージの中にソースコードを入れてしまい、一種のimmutableなアプリケーションサーバを作ろうと考えたためです。
で、Dockerfileがホストにあるファイルやディレクトリをイメージに送るためには、自分と同じ階層か低い階層にターゲットがなければならないという制約があるのです。
ADD ../../niisan-tokyo/Logexp
とか書いたら、エラーが出ました。
というわけで、あの位置にDockerfileをおいています。
https://github.com/niisan-tokyo/log_experioment/blob/singleContainer/niisan-tokyo/Dockerfile
PHPの導入
これはremiリポジトリを普通に導入しています。
#install remi
RUN yum -y install epel-release
RUN yum -y install wget
RUN wget -P /etc/yum.repos.d http://rpms.famillecollet.com/enterprise/remi.repo
#install php
RUN yum -y --enablerepo=remi,remi-php56 install php php-common
#install composer
RUN curl -sS https://getcomposer.org/installer | php; mv composer.phar /usr/local/bin/composer
あとで使うのでcomposerもこの時点で導入しています。
Fluentdの導入
なぜかDockerfile上でFluentdを導入しようとすると、先に行った、ワンライナーでの導入ができません(sudo
がないとか言われる)
なので、件のコマンドをバラしてDockerfileに入れています。
#install fluentd
ADD etc/td.repo /etc/yum.repos.d/td.repo
RUN rpm --import https://packages.treasuredata.com/GPG-KEY-td-agent; yum check-update; yes|yum install -y td-agent
RUN service td-agent start; chkconfig td-agent on
ADD etc/td-agent.conf /etc/td-agent/td-agent.conf
td-agent.confは設定ファイルで、現在はログをファイルに出力するように設定してあります
次回ではここを集約用のfluentdに投げるように修正します
アプリケーションのデプロイ
Logexpディレクトリ配下のファイルを全て/var/www 配下にコピーし、しかるのちにcomposerを使って、パッケージを入れます
#build application
WORKDIR /var/www
ADD Logexp ./
RUN composer install --no-dev
EXPOSE 8080
アプリケーションの起動コマンドを設置
Dockerは1コンテナ1アプリが原則らしいので、複数アプリケーションの起動はちょい面倒くさいです。
やり方としては、起動スクリプトをファイルに吐き出して、イメージ上に設置し、コンテナ起動時にこの起動スクリプトを作動させればよいです。
まとめ
ということで、とりあえずPHPのログをFluentdに突っ込んで内容を確認できるところまでやりました。
次は集約用のFluentd用のコンテナを用意して、さらにデータ格納用のMongoDBコンテナを用意し、ログを流すところまで作りたいです。
少々ダラダラ書きすぎましたが、今回はこの辺で失礼します。
Fluentdによる柔軟なPHPのアプリケーションログ管理をDockerでシミュレートしたい(2)
追記
koriymさんより指摘いただきましたので、BEAR.Sundayの導入部分が修正されました
composer create-project bear/skeleton MyVendor.Weekday
入力後、対話型でベンダー名とプロジェクト名を聞いてくるので、そこで入力した内容が名前空間に反映されるようで、実際に検証した結果、そのとおりになりました。
-n対話スキップオプションをつけると、名前空間がMyVendor\MyProjectになるとのことです。
私の場合はエンター連打でもしたのかもしれません。。。