Graphite
の勉強のつもりでDockerfile
を作ってみた- 単にコマンドを並べるだけではもちろん上手く動作しなくて試行錯誤しながら周辺の技術とか勉強になったのでメモしておく
- 結局は
Dockerfile
では上手く動かせていない
- ビルドは成功するし起動は成功する
- ログインされるものの肝心のダッシュボードが表示されない
/var/log/httpd/graphite-web-access.log
に以下のようなログが出てる。
bash-4.1# tail -f graphite-web-access.log
10.0.2.2 - - [25/May/2014:18:18:34 -0500] "GET /composer/? HTTP/1.1" 200 1622
10.0.2.2 - - [25/May/2014:18:18:35 -0500] "GET /content/js/browser.js HTTP/1.1" 500 632
10.0.2.2 - - [25/May/2014:18:18:35 -0500] "GET /content/js/composer.js HTTP/1.1" 500 632
10.0.2.2 - - [25/May/2014:18:18:35 -0500] "GET /content/js/completer.js HTTP/1.1" 500 632
10.0.2.2 - - [25/May/2014:18:18:35 -0500] "GET /content/img/carbon-fiber.png HTTP/1.1" 500 632
10.0.2.2 - - [25/May/2014:18:18:35 -0500] "GET /content/js/ext/ext-all.js HTTP/1.1" 500 632
10.0.2.2 - - [25/May/2014:18:18:35 -0500] "GET /content/js/composer_widgets.js HTTP/1.1" 500 632
10.0.2.2 - - [25/May/2014:18:18:35 -0500] "GET /content/js/ext/resources/css/ext-all.css HTTP/1.1" 500 632
10.0.2.2 - - [25/May/2014:18:18:35 -0500] "GET /content/js/ext/adapter/ext/ext-base.js HTTP/1.1" 500 632
10.0.2.2 - - [25/May/2014:18:18:36 -0500] "GET /favicon.ico HTTP/1.1" 200 542
なんで?
/etc/graphite-web/local_settings.py
に設定が不足していた。
# 以下足りてなかった部分
GRAPHITE_ROOT = '/usr/share/graphite'
CONF_DIR = '/etc/graphite-web'
STORAGE_DIR = '/var/lib/graphite-web'
CONTENT_DIR = '/usr/share/graphite/webapp/content'
WHISPER_DIR = '/var/lib/carbon/whisper/'
RRD_DIR = '/var/lib/carbon/rrd'
LOG_DIR = '/var/log/graphite-web/'
# 以下して設定してなかった...
DATABASES = {
'default': {
'NAME': 'graphite',
'ENGINE': 'django.db.backends.mysql',
'USER': 'graphite',
'PASSWORD': 'xxxxxxx',
'HOST': 'localhost',
'PORT': '3306',
}
}
うう、どっか山ごもりしたい...
- django-admin.py という Django を管理する為のコマンドラインユーティリティのラッパ
- 詳細はこちら
graphite-web
も漏れ無く Django
で実装されているの manage.py
のお世話になるのだが、graphite-web
の初期セットアップ時に manage.py syncdb
を実行してデータベースのテーブル作ったり、管理ユーザーを作成しなければならない。
この管理ユーザーを作成する際に普通だと以下のようなインタラクティブな状態になる。
この状態をどのように実現するかで約半日悩んだ...試行錯誤の内容は以下の「manage.py syncdb をどうやって Dockerfile 内で実現するか?(詳細)」に譲るとして manage.py syncdb
に --noinput` というオプションがあるのでそちらを利用した。
--noinput
については以下の通り。
ユーザプロンプトでの "Are you sure?" のような確認メッセージの出力の抑制には --noinput オプションを使います。対話を必要とせずに django-admin.py を実行する自動化されたスクリプトで役に立ちます。
一旦、正常に稼働する環境を構築して以下のようなオプションでデータベースの内容を JSON
形式でダンプして上述の「自動化されたスクリプト」を生成した。
/usr/lib/python2.6/site-packages/graphite/manage.py dumpdata --indent=2 --format=json auth.user
上記を実行すると以下のような JSON
ファイルが出力される。
[
{
"pk": 1,
"model": "auth.user",
"fields": {
"username": "admin",
"first_name": "",
"last_name": "",
"is_active": true,
"is_superuser": true,
"is_staff": true,
"last_login": "2014-05-25T18:57:01",
"groups": [],
"user_permissions": [],
"password": "pbkdf2_sha256$10000$IxdLbQaUHl9O$gjMsDbAijARfk0HEZQuDpTSd9EzUrn3B2hzeqUwa0N4=",
"email": "admin@example.com",
"date_joined": "2014-05-25T18:57:01"
}
}
]
この JSON
ファイルを docker build
時に ADD
しておいて mange.py syncdb --noinput
する。尚、ファイル名は initial_data.json
というファイル名で保存しておくと良さそう(他の名前でイケるかは試していない)。
ADD initial_data.json /path/to/initial_data.json
RUN cd /path/to/ && /usr/lib/python2.6/site-packages/graphite/manage.py syncdb --noinput
また、initial_data.json
ファイルが存在するディレクトリで manage.py syncdb
を実行する必要がある。
上記の JSON
ファイルにも定義されているが password
の文字列としては以下のようなルールが設けられている。
hashtype$salt$hash
ハッシュ方式 (hashtype
)、ハッシュソルト (salt
)、そしてハッシュ値 (hash
) をドル記号 ($
) で分割した文字列となる。
#
FROM centos
#
MAINTAINER YOHEI KAWAHARA inokappa
#
RUN echo "NETWORKING=yes" >/etc/sysconfig/network
#
RUN yum -y update
RUN rpm --import http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/RPM-GPG-KEY-EPEL-6
RUN cd /tmp/ && wget http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
RUN cd /tmp/ && rpm -Uvh epel-release-6-8.noarch.rpm
#
RUN yum -y install graphite-web mysql mysql-server MySQL-python python-carbon monit vim telnet expect
#
ADD graphite/local_settings.py /etc/graphite-web/local_settings.py
ADD graphite/initial_data.json /etc/graphite-web/initial_data.json
#
RUN /etc/init.d/mysqld start && \
mysql -e "CREATE USER 'graphite'@'localhost' IDENTIFIED BY 'passw0rd';" -u root && \
mysql -e "GRANT ALL PRIVILEGES ON graphite.* TO 'graphite'@'localhost';" -u root && \
mysql -e "CREATE DATABASE graphite;" -u root && \
mysql -e 'FLUSH PRIVILEGES;' -u root && \
export LANG="en_US.UTF-8" && \
cd /etc/graphite-web && \
/usr/lib/python2.6/site-packages/graphite/manage.py syncdb --noinput && \
sleep 1
#
ADD monit/monit.conf /etc/monit.conf
RUN chown root:root /etc/monit.conf && chmod 600 /etc/monit.conf
ADD monit/httpd /etc/monit.d/
ADD monit/mysqld /etc/monit.d/
ADD monit/carbon-cache /etc/monit.d/
RUN chown root:root /etc/monit.d/* && chmod 600 /etc/monit.d/*
#
EXPOSE 3306 2003 2004 7002 80 2812
CMD ["/usr/bin/monit", "-I", "-c", "/etc/monit.conf"]
まずは expect
を利用する例。
#!/usr/bin/env expect
set timeout -1
spawn python /usr/lib/python2.6/site-packages/graphite/manage.py syncdb
expect "Would you like to create one now" {
send "yes\r"
}
expect "Username *:" {
send "admin\r"
}
expect "E-mail address:" {
send "admim@example.com\r"
}
expect "Password:" {
send "admin\r"
}
expect "Password *:" {
send "admin\r"
}
interact
expect "Superuser created successfully"
Ubuntu
環境では動作したが boot2docker
な MacOS X
環境だと The system has no more ptys.Ask your system administrator to create more.
というエラーが出てしまい却下。
/usr/lib/python2.6/site-packages/graphite/manage.py dumpdata
でフルダンプしてレストア(syncdb --noinput
)案。
/usr/lib/python2.6/site-packages/graphite/manage.py dumpdata
認証情報以外にもセッション情報等も出力されるのでホストを移行したりする際には使えるような気がするが中身をちゃんと把握出来ておらず、思わぬ挙動でハマるのも面倒だったので却下。
例によって今回も monit
で各種プロセスを監視。
- 色々とハマってしまったが振り返ってみると得られたことって少ないような気がして残念
python
周りの知識が殆ど0
なのでトラブった時にキツイ- ただ、ハマることで内部のことを知るきっかけになって良かった