前から気になってたツールを試すシリーズその2。
今回は、複数のDockerコンテナを管理する fig がどんなものなのか試すために、これまた気になってた fluentd 、 Elasticsearch 、 Kibana を試すための環境を fig を使って構築してみた。が、環境構築で満足して fluentd や Kibana の使用感はまだ確認できてない。ちょっと欲張りすぎたかな。。。
なお、環境は Mac OS X Mavericks + boot2docker。
fig のインストール
手っ取り早く Homebrew でインストール。
% brew install fig
% fig --version
fig 1.0.1
ちなみに Docker の環境は以下の通り。
% docker version
Client version: 1.3.0
Client API version: 1.15
Go version (client): go1.3.3
Git commit (client): c78088f
OS/Arch (client): darwin/amd64
Server version: 1.3.0
Server API version: 1.15
Go version (server): go1.3.3
Git commit (server): c78088f
構成
今回は fig を使って以下の3つのコンテナを作成して連携させる。
- コンテナ名: web
- Apache
- fluentd
- コンテナ名: elasticsearch
- Elasticsearch
- コンテナ名: kibana
- Apache
- Kibana
webコンテナがフロントエンドのサーバという想定。このサーバのアクセスログを fluentd を使って Elasticsearch へ送り Kibana で可視化する。
実際にプロダクトで使用する際はいきなり Elasticsearch へ転送するのではなく、間に集約する fluentd を入れる構成にするのがいいらしい。
Dockerfile
それぞれのコンテナを作るための Dockerfile を以下のように作成した。
いずれも CentOS 6 をベースにしている。
web コンテナ
fluentd は公式の ドキュメント の通りにインストールする。
が、yum で Apache をインストールすると /var/log/httpd
が root:root
で作られるのだが、パーミッションを変えてもなぜか td-agent ユーザーから参照することができなかった。色々試してもよくわからなかったので、 こちら を参考に root で起動するように起動スクリプトを書き換えた。
fluentd には Elasticsearch 用のプラグインもインストール。依存する libcurl-devel
と gcc
は yum で入れておく。
FROM centos:centos6
# Install core modules
RUN yum update -y &&\
yum install -y sudo tar &&\
yum clean -y all
# Edit sudoers file
RUN sed -i -e "s/Defaults requiretty.*/ #Defaults requiretty/g" /etc/sudoers
# Install fluentd
RUN curl -L http://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh
RUN sed -i -e "s/--user td-agent/--user root/g" /etc/init.d/td-agent &&\
sed -i -e "s/--group td-agent/--user root --group td-agent/g" /etc/init.d/td-agent
RUN ulimit -n 65536
COPY td-agent.conf /etc/td-agent/td-agent.conf
# Install Fluent::Plugin::Elasticsearch
RUN yum install -y libcurl-devel gcc &&\
yum clean -y all
RUN /opt/td-agent/embedded/bin/gem install fluent-plugin-elasticsearch
# Install httpd
RUN yum install -y httpd &&\
yum clean -y all
COPY run.sh /tmp/
EXPOSE 80
ENTRYPOINT ["/bin/bash", "/tmp/run.sh"]
Apache と fluentd の両方のサービスを起動させるため、以下のようなシェルスクリプトを作成してプロセスがフォアグラウンドで動き続けるようにしている。
#!/bin/bash
service httpd start
service td-agent start
tail -f /var/log/td-agent/td-agent.log
fluentd の設定ファイルである td-agent.conf
は、とりあえず以下のように作ってみた。
<source>
type tail
path /var/log/httpd/access_log
tag apache.web
pos_file /var/log/td-agent/httpd-access.log.pos
format apache2
</source>
<match apache.**>
type copy
<store>
type stdout
</store>
<store>
type elasticsearch
host elasticsearch
port 9200
</store>
</match>
elasticsearch コンテナ
java
と which
が必要なので、事前に yum で入れておく。また環境変数 JAVA_HOME
を設定し、 PATH
も通しておく。
Elasticsearch も ドキュメント の通りにインストールする。インストール先は /opt/elasticsearch
とした。
クロスドメイン対策のため、 elasticsearch.yml
に設定を追加している。
FROM centos:centos6
# Install core modules
RUN yum update -y &&\
yum install -y java-1.7.0-openjdk sudo tar which &&\
yum clean -y all
# Edit sudoers file
RUN sed -i -e "s/Defaults requiretty.*/ #Defaults requiretty/g" /etc/sudoers
# Set JAVA_HOME
ENV JAVA_HOME /usr/lib/jvm/java-1.7.0-openjdk.x86_64
ENV PATH $JAVA_HOME/bin:$PATH
# Install elasticsearch
ENV ES_PKG_NAME elasticsearch-1.4.0
ADD https://download.elasticsearch.org/elasticsearch/elasticsearch/$ES_PKG_NAME.tar.gz /tmp/$ES_PKG_NAME.tar.gz
RUN cd /tmp &&\
tar xzvf $ES_PKG_NAME.tar.gz &&\
mv $ES_PKG_NAME /opt/elasticsearch &&\
rm -f $ES_PKG_NAME.tar.gz
RUN echo 'http.cors.enabled: true' >> /opt/elasticsearch/config/elasticsearch.yml &&\
echo 'http.cors.allow-origin: "/.*/"' >> /opt/elasticsearch/config/elasticsearch.yml
EXPOSE 9200
EXPOSE 9300
ENTRYPOINT ["/opt/elasticsearch/bin/elasticsearch"]
kibana コンテナ
Kibana 3 はダウンロードして Apache のドキュメントルート以下に突っ込むだけで使えるようになる( Kibana 4 からはちょっと構成が変わるらしい)。簡単。今回は /var/www/html/kibana
へ配置した。
FROM centos:centos6
# Install core modules
RUN yum update -y &&\
yum install -y sudo tar &&\
yum clean -y all
# Edit sudoers file
RUN sed -i -e "s/Defaults requiretty.*/ #Defaults requiretty/g" /etc/sudoers
# Install httpd
RUN yum install -y httpd &&\
yum clean -y all
# Install kibana
ENV KIBANA_PKG_NAME kibana-3.1.2
ADD https://download.elasticsearch.org/kibana/kibana/$KIBANA_PKG_NAME.tar.gz /tmp/$KIBANA_PKG_NAME.tar.gz
RUN cd /var/www/html &&\
tar xzvf /tmp/$KIBANA_PKG_NAME.tar.gz &&\
mv $KIBANA_PKG_NAME kibana
COPY run.sh /tmp/run.sh
EXPOSE 80
ENTRYPOINT ["/bin/bash", "/tmp/run.sh"]
一応 web コンテナと同様にシェルスクリプトを用意したが、動かすサービスは1つだけなので直接 Apache を起動しても構わない。
#!/bin/bash
service httpd start
tail -f /var/log/httpd/access_log
fig.yml
Dockerfile ができたので、次に fig の設定ファイルを作成する。設定は YAML で書く。 リファレンス を参考にして以下のような fig.yml
を作成した。
---
elasticsearch:
build: elasticsearch
ports:
- "9200:9200"
- "9300:9300"
kibana:
build: kibana
ports:
- "50080:80"
links:
- elasticsearch
web:
build: web
ports:
- "10080:80"
- "18888:8888"
links:
- elasticsearch
build
で Dockerfile のあるディレクトリを指定する。エクスポートするポートは ports
で、リンクしたいコンテナは links
でそれぞれ指定できる。 fig を使わないで起動しようとすると、 docker run
のオプションに自分で指定する必要があるが、 fig なら簡単に設定できてGood。
コンテナの起動
Dockerfile をビルドしてイメージを作る。
% fig build
Building elasticsearch...
---> 70441cac1ed5
Step 1 : RUN yum update -y && yum install -y java-1.7.0-openjdk sudo tar which && yum clean -y all
(...snip...)
Successfully built c9747896561b
これだけですべての Dockerfile がビルドされる。便利。
そして起動。こちらも簡単一発。
% fig up
Recreating fluentdsample_elasticsearch_1...
Recreating fluentdsample_web_1...
Recreating fluentdsample_kibana_1...
Attaching to fluentdsample_elasticsearch_1, fluentdsample_web_1, fluentdsample_kibana_1
elasticsearch_1 | [2014-11-22 17:43:57,222][INFO ][node ] [Eros] version[1.4.0], pid[1], build[bc94bd8/2014-11-05T14:26:12Z]
elasticsearch_1 | [2014-11-22 17:43:57,223][INFO ][node ] [Eros] initializing ...
elasticsearch_1 | [2014-11-22 17:43:57,228][INFO ][plugins ] [Eros] loaded [], sites []
web_1 | httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.198 for ServerName
kibana_1 | httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.200 for ServerName
web_1 | Starting httpd: [ OK ]
kibana_1 | Starting httpd: [ OK ]
web_1 | Starting td-agent: [ OK ]
(...snip...)
それぞれのコンテナの出力が標準出力に吐かれる。
動作確認
boot2docker を使用しているので、VMのIPアドレスを確認しておく。
% boot2docker ip
The VM's Host only interface IP address is: 192.168.XX.YYY
それぞれのコンテナへアクセスしてみる。
Elasticsearch コンテナ:
% curl -s "http://192.168.XX.YYY:9200/"
{
"status" : 200,
"name" : "Eros",
"cluster_name" : "elasticsearch",
"version" : {
"number" : "1.4.0",
"build_hash" : "bc94bd81298f81c656893ab1ddddd30a99356066",
"build_timestamp" : "2014-11-05T14:26:12Z",
"build_snapshot" : false,
"lucene_version" : "4.10.2"
},
"tagline" : "You Know, for Search"
}
web コンテナ:
% curl -s -I "http://192.168.XX.YYY:10080/"
HTTP/1.1 403 Forbidden
Date: Sat, 22 Nov 2014 17:52:14 GMT
Server: Apache/2.2.15 (CentOS)
Accept-Ranges: bytes
Content-Length: 4954
Connection: close
Content-Type: text/html; charset=UTF-8
kibana コンテナ:
% curl -s -I "http://192.168.XX.YYY:50080/kibana/"
HTTP/1.1 200 OK
Date: Sat, 22 Nov 2014 17:53:52 GMT
Server: Apache/2.2.15 (CentOS)
Last-Modified: Fri, 07 Nov 2014 15:15:25 GMT
ETag: "cb-819-507464842dd40"
Accept-Ranges: bytes
Content-Length: 2073
Connection: close
Content-Type: text/html; charset=UTF-8
それぞれ動作しているようだ。
またwebブラウザから http://192.168.XX.YYY:50080/kibana/
へアクセスすると、 Kibana の画面がきちんと表示された。 Elasticsearch との連携がうまくいっていないと、エラー画面が表示される。
まとめ
複数の Dockerfile を組み合わせて使う場合に fig はとても便利。コンテナの連携がしやすくなるので、できるだけコンテナの役割を分けて1つ1つのコンテナの役割を明確にしていきたい。