ChefからDockerコンテナにSensu Serverをインストールする
前回、ChefからDockerコンテナ内の起動プロセスを追加することが確認できました。そこで、今回はChefを使ってDockerコンテナに監視ツールのSensu Serverをインストールしてみました。
Dockerコンテナ
Dockerfileの構成は以下の通りです。
sshd ├──Dockerfile ├──sources.list ... ミラーサイト一覧 ├──id_rsa.pub ... Chef workstationの公開鍵 └──supervisord.conf ... supervisorの定義ファイル
Dockerfileを以下のように作成します。
supervisorの定義ファイルは、/etc/supervisor/conf.d/配下にも置くことができるので、「RUN mkdir -p /etc/supervisor/conf.d/」でディレクトリを作成しています。
$ vi Dockerfile FROM ubuntu:12.04 MAINTAINER hidemium # Ubuntu update ADD sources.list /etc/apt/sources.list RUN apt-get -y update # Hack for initctl not being available in Ubuntu RUN dpkg-divert --local --rename --add /sbin/initctl RUN ln -sf /bin/true /sbin/initctl # ssh install RUN apt-get -y install openssh-server RUN apt-get -y install python-setuptools RUN apt-get clean RUN easy_install supervisor RUN mkdir /var/run/sshd RUN echo 'root:root' | chpasswd # sshd config ADD id_rsa.pub /root/id_rsa.pub RUN mkdir /root/.ssh/ RUN mv /root/id_rsa.pub /root/.ssh/authorized_keys RUN chmod 700 /root/.ssh RUN chmod 600 /root/.ssh/authorized_keys RUN sed -i -e '/^UsePAM\s\+yes/d' /etc/ssh/sshd_config # supervisor config RUN mkdir -p /var/log/supervisor RUN mkdir -p /etc/supervisor/conf.d/ ADD supervisord.conf /etc/supervisord.conf # Expose ports. EXPOSE 22 # Define default command. CMD ["supervisord", "-n"]
supervisorの定義ファイルは、デフォルトの定義にsshdの起動を追加したものにしています。
$ vi supervisord.conf [unix_http_server] file=/tmp/supervisor.sock ; (the path to the socket file) [supervisord] logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log) logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB) logfile_backups=10 ; (num of main logfile rotation backups;default 10) loglevel=info ; (log level;default info; others: debug,warn,trace) pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid) nodaemon=false ; (start in foreground if true;default false) minfds=1024 ; (min. avail startup file descriptors;default 1024) minprocs=200 ; (min. avail process descriptors;default 200) [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket [include] files = /etc/supervisor/conf.d/*.conf [program:sshd] command=/usr/sbin/sshd -D autostart=true autorestart=true
docker buildコマンドにより、イメージを作成します。
実行後、ubuntu-supervisorというイメージが作成されていることを確認します。
$ sudo docker build -t ubuntu-supervisor:12.04 . $ sudo docker images
Sensu ServerのChefレシピ
それでは、Sensu Serverをインストーするレシピについて見ていきます。
cookbookの構成
cookbookの構成は以下の通りです。
site-cookbook
└──sensu-server
└──recipes
│ └──default.rb
└──templates
└──default
├──checks_proc.json.erb ... 監視動作定義ファイル
├──client.json.erb ... Sensu Clientの監視定義ファイル
├──config.json.erb ... Sensu Serverの定義ファイル
├──sensu.list.erb ... リポジトリの定義ファイル
└──sensu-server.conf.erb ... supervisorの定義ファイル
recipesファイル
recipesファイルは以下の通りです。
$ vi site-cookbooks/sensu-server/recipes/default.rb
%w{wget python-software-properties}.each do | pkg |
package pkg do
action :install
end
end
template "/etc/apt/sources.list.d/sensu.list" do
owner "root"
mode 0644
source "sensu.list.erb"
end
bash "add sensu apt-key" do
code "wget -q http://repos.sensuapp.org/apt/pubkey.gpg -O- | apt-key add -"
action :run
end
bash "add rabbitmq apt-key" do
code "wget -q http://www.rabbitmq.com/rabbitmq-signing-key-public.asc -O- | apt-key add -"
action :run
end
bash "add redis repos" do
code "add-apt-repository -y ppa:rwky/redis"
action :run
end
bash "apt-get update" do
code "apt-get update"
action :run
end
%w{sensu rabbitmq-server redis-server git-core bc rsyslog}.each do | pkg |
package pkg do
action :install
end
end
git "/tmp/sensu_plugins" do
repository "git://github.com/sensu/sensu-community-plugins.git"
reference "master"
action :sync
end
bash "copy sensu plugins" do
code "cp -Rf /tmp/sensu_plugins/plugins /etc/sensu/"
action :run
end
bash "chmod sensu plugins" do
code "find /etc/sensu/plugins/ -name *.rb -exec chmod +x {} \\;"
action :run
end
template "sensu-server.conf" do
path "/etc/supervisor/conf.d/sensu-server.conf"
owner "root"
group "root"
mode "0644"
source "sensu-server.conf.erb"
end
template "config.json" do
path "/etc/sensu/config.json"
owner "root"
group "root"
mode "0644"
source "config.json.erb"
end
template "client.json" do
path "/etc/sensu/conf.d/client.json"
owner "root"
group "root"
mode "0644"
source "client.json.erb"
end
template "checks.json" do
path "/etc/sensu/conf.d/checks.json"
owner "root"
group "root"
mode "0644"
source "checks.json.erb"
end
bash "ln ruby path" do
code "ln -s /opt/sensu/embedded/bin/ruby /usr/bin/ruby"
action :run
end
bash "supervisorctl reload" do
code "supervisorctl reload; sleep 10"
action :run
end
bash "rabbitmqctl add_user" do
code "rabbitmqctl add_user admin admin"
action :run
end
bash "rabbitmqctl set_user_tags" do
code "rabbitmqctl set_user_tags admin administrator"
action :run
end
bash "rabbitmqctl set_permissions" do
code "rabbitmqctl set_permissions -p / admin '.*' '.*' '.*'"
action :run
end
bash "rabbitmq_management" do
code "rabbitmq-plugins enable rabbitmq_management"
action :run
end
bash "rabbitmq restart" do
code "rabbitmqctl stop"
action :run
end
- Sensu Serverをインストールするために、Sensuのリポジトリを指定しています。
- 普通にapt-get install rabbitmq-serverとした場合、RabbitMQ 2.7.1がインストールされるため、RabbitMQのリポジトリを指定し、RabbitMQ 3系がインストールされるようにしています。
- GitHubからSensuのCommunity Pluginを取得しています。
- Sensu ServerやRabbitMQを起動するため、supervisorの定義ファイルであるsensu-server.confを配置しています。
- RabbitMQ 3系では、RabbitMQの管理画面にguestユーザでログインするためには、localhost経由しかできない仕様となったため、adminユーザを追加しています。
- RabbitMQの管理画面を有効にするため、rabbitmq-plugins enable rabbitmq_managementコマンドを実行後、RabbitMQを再起動が必要となります。supervisorでRabbitMQプロセスのautorestartをオンにしているため、rabbitmqctl stopコマンドだけ実行しています。
templateファイル
templateファイルは以下の通りです。
checks.json
checks.jsonは監視の動作を定義しているファイルであり、Sensu Server側に配置します。
command内のcheck-procs.rbはSensuのCommunity Pluginになります。
$ vi site-cookbooks/sensu-server/templates/default/checks_proc.json.erb
{
"checks": {
"sensu-rabbitmq-beam": {
"handlers": [
"default"
],
"command": "/etc/sensu/plugins/processes/check-procs.rb -p beam -C 1 -w 4 -c 5",
"interval": 60,
"occurrences": 2,
"refresh": 300,
"subscribers": [ "sensu" ]
},
"sensu-rabbitmq-epmd": {
"handlers": [
"default"
],
"command": "/etc/sensu/plugins/processes/check-procs.rb -p epmd -C 1 -w 1 -c 1",
"interval": 60,
"occurrences": 2,
"refresh": 300,
"subscribers": [ "sensu" ]
},
"sensu-redis": {
"handlers": [
"default"
],
"command": "/etc/sensu/plugins/processes/check-procs.rb -p redis-server -C 1 -w 4 -c 5",
"interval": 60,
"occurrences": 2,
"refresh": 300,
"subscribers": [ "sensu" ]
},
"sensu-api": {
"handlers": [
"default"
],
"command": "/etc/sensu/plugins/processes/check-procs.rb -p sensu-api -C 1 -w 4 -c 5",
"interval": 60,
"occurrences": 2,
"refresh": 300,
"subscribers": [ "sensu" ]
},
"sensu-dashboard": {
"handlers": [
"default"
],
"command": "/etc/sensu/plugins/processes/check-procs.rb -p sensu-dashboard -C 1 -w 1 -c 1",
"interval": 60,
"occurrences": 2,
"refresh": 300,
"subscribers": [ "sensu" ]
}
}
}
client.json
client.jsonは監視対象の情報や監視定義を設定するファイルであり、Sensu Client側に配置します。
checks.jsonの"subscribers"に定義した名称をsubscriptionsに指定することで、監視定義を設定することができます。
$ vi site-cookbooks/sensu-server/templates/default/client.json.erb
{
"client": {
"name": "sensu-server",
"address": "127.0.0.1",
"subscriptions": [ "default", "sensu" ]
}
}
config.json
config.jsonはSensu Serverの定義ファイルになります。
"rabbitmq"には、追加したユーザ名(guest以外)を指定しています。
$ vi site-cookbooks/sensu-server/templates/default/config.json.erb
{
"rabbitmq": {
"port": 5672,
"host": "localhost",
"user": "admin",
"password": "admin",
"vhost": "/"
},
"redis": {
"host": "localhost",
"port": 6379
},
"api": {
"host": "localhost",
"port": 4567
},
"dashboard": {
"host": "localhost",
"port": 8080,
"user": "admin",
"password": "admin"
},
"handlers": {
"default": {
"type": "pipe",
"command": "true"
}
}
}
sensu.list
sensu.listには、SensuとRabbitMQのリポジトリを指定しています。
$ vi site-cookbooks/sensu-server/templates/default/sensu.list.erb deb http://repos.sensuapp.org/apt sensu main deb http://www.rabbitmq.com/debian/ testing main
sensu-server.conf
sensu-server.confには、supervisorからSensu Serverを起動する設定をしています。
$ vi site-cookbooks/sensu-server/templates/default/sensu-server.conf.erb [program:rabbitmq] priority=10 directory=/tmp command=/usr/sbin/rabbitmq-server user=root autostart=true autorestart=true stopsignal=QUIT [program:redis] priority=10 directory=/tmp command=redis-server user=root autostart=true autorestart=true [program:sensu-server] priority=20 directory=/tmp command=/opt/sensu/bin/sensu-server -c /etc/sensu/config.json -d /etc/sensu -e /etc/sensu/extensions -v -l /var/log/sensu/server.log user=root startsecs=5 autostart=true autorestart=true [program:sensu-api] priority=30 directory=/tmp command=/opt/sensu/bin/sensu-api -c /etc/sensu/config.json -d /etc/sensu -e /etc/sensu/extensions -v -l /var/log/sensu/api.log user=root startsecs=5 autostart=true autorestart=true [program:sensu-client] priority=40 directory=/tmp command=/opt/sensu/bin/sensu-client -c /etc/sensu/config.json -d /etc/sensu -e /etc/sensu/extensions -v -l /var/log/sensu/client.log user=root autostart=true autorestart=true [program:sensu-dashboard] priority=50 directory=/tmp command=/opt/sensu/bin/sensu-dashboard -c /etc/sensu/config.json -d /etc/sensu -e /etc/sensu/extensions -v -l /var/log/sensu/dashboard.log user=root autostart=true autorestart=true
Chefレシピの実行
Dockerコンテナを起動します。
22、8080、4567、5672、15672のポートを外部からアクセスできるようにしておきます。
$ sudo docker run -d -p 22 -p 8080:8080 -p 4567:4567 -p 5672:5672 -p 15672:15672 ubuntu-supervisor:12.04 $ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b245647afb46 ubuntu-supervisor:12.04 supervisord -n 27 minutes ago Up 27 minutes 0.0.0.0:4567->4567/tcp, 0.0.0.0:5672->5672/tcp, 0.0.0.0:15672->15672/tcp, 0.0.0.0:[ポート番号]->22/tcp, 0.0.0.0:8080->8080/tcp drunk_mayer
Sensu ServerのChefレシピを流します。
Chefを実行する時は、22番ポートにフォワードされているポート番号を指定します。
$ vi nodes/<IPアドレス>.json
{
"run_list": [
"recipe[sensu-server]"
]
}
$ knife solo bootstrap root@<IPアドレス> -p [ポート番号]
Sensu Serverの管理画面
Sensu Serverの構築ができたことを確認するため、「http://<サーバのIPアドレス>:8080」にアクセスし、Sensuのダッシュボードに接続します。ログインはadmin/adminでできます。(config.jsonで定義しています。)

また、「http://<サーバのIPアドレス>:15672」にアクセスし、RabbitMQの管理画面に接続します。ログインはadmin/adminでできます。(config.jsonで定義しています。)

おわりに
ChefからDockerコンテナにSensu Serverをインストールすることができました。*1
Sensuの環境ができたので、これから色々試してみたいと思います。
Sensuの特徴として、クライアント(監視対象)の自動登録がありますが、Dockerのようにscrap & buildが多い仮想環境に合っているのではと思っています。
Dockerコンテナをプロビジョニングする際に、Sensu Clientをインストールする仕組みにしておけば、コンテナをいくら起動しても監視設定を自動的にすることができるかもしれません。
参考
*1:Chefを使ったDockerコンテナのプロビジョニングは、慣れてくると意外といい気がしてきました。