: O. Yuanying

Cloud Foundry を Zabbix で監視する

Cloud Foundry 上で動くアプリの話ではなく、 Cloud Foundry を構成する各仮想マシンの監視の話。 ぶっちゃけ BOSH で監視すれば?って話なんだが、 政治的な理由で Zabbix で監視する必要がある場合もある。 そんな場合は cf-release をいじって Zabbix Agent を実行する Job を追加するのが正道。

cf-release の修正

cf-release の v173 をいじって、zabbix のジョブを追加する。

cf-release の修正のためにはオリジナルの cf-release を clone した後に、 対応する Blob Store を自分が書き込み権限を持つ Blob Store に変更しなければならない。

自分用 cf-release への下準備

cf-release を clone した後に、 blob を自分の Blob Store にアップロードし直し、 完全に cf-release を自分の管理下におさめる。

$ git clone https://github.com/cloudfoundry/cf-release.git
$ cd cf-release/
$ git checkout -b cf-modify refs/tags/v173
$ git submodule foreach --recursive \
      'git submodule sync; git clean -d --force --force'
$ git submodule update --init --recursive --force

とりあえず今回の場合は、 cf-release v173 から fork する。

$ bosh sync blobs
$ mv blobs blobs-old
$ cp -RL blobs-old blobs
$ rm -rf blobs-old

v173 で使用している blobs をダウンロードする。 bosh は blobs ディレクトリ配下にあるファイルが、 シンボリックリンクか実ファイルかであるかで、 Blob Store にアップロードされている blobs かそうでないかを判断しているため、 上記の作業で blobs ディレクトリ下のファイルをすべて実ファイルに変換する。

実ファイルに変換した後に、 自分が利用する Blob Store にファイルを後にアップロードする。

$ rm -rf .blobs
$ rm -f config/blobs.yml
$ rm -rf .final_build
$ rm -rf releases

また、必要ないファイルを削除する。 これにより自分の管理下である Blob Store をまっさらな状態で利用することが可能。

$ vim config/final.yml
# final.yml
---
blobstore:
  provider: dav
  options:
    endpoint: http://localhost/storage
$ vim config/private.yml
# private.yml
---
blobstore:
  dav:
    user: admin
    password: admin

今回は Blob Store として WebDAV を利用する。 localhost の storage というパスに WebDAV を構築している物とする。 アクセスするための認証情報は、 BASIC 認証で admin:admin.

$ yes yes | bosh upload blobs

上記のコマンドで、 blobs ディレクトリにある blobs が WebDAV にアップロードされる。

$ git add .
$ git add -u .
$ git commit -m "Creating modify cf-release base."

これにて cf-release を自分用にカスタマイズする準備は整った。 整ったところで git commit する。

Zabbix Agent を cf-release に追加する

bosh の Release Repository を簡単にいじるツールとして、 bosh-gen があるのでそれをインストールしておく。

$ sudo gem install bosh-gen

Zabbix のアーカイブを blobs に追加

$ mkdir -p blobs/zabbix
$ cd blobs/zabbix/
$ curl -L -O http://downloads.sourceforge.net/project/zabbix/ZABBIX%20Latest%20Stable/2.0.11/zabbix-2.0.11.tar.gz
$ yes yes | bosh upload blobs
$ git add .
$ git diff HEAD
diff --git a/config/blobs.yml b/config/blobs.yml
index 9c86422..cf8f762 100644
--- a/config/blobs.yml
+++ b/config/blobs.yml
@@ -609,3 +609,8 @@ libyaml/yaml-0.1.4.tgz:
   sha: !binary |-
     ZTBlNWUwOTE5MmFiMTBhNjA3ZTNkYTI5NzBkYjQ5MjExOGY1NjBmMg==
   size: 471759
+zabbix/zabbix-2.0.11.tar.gz:
+  object_id: c6711ac2-1e43-4822-bcc9-bb31ce8aec7b
+  sha: !binary |-
+    NjAzNmM3MGU3NGNlYTYzNTc2MzA3OGQ4NmM1ZTUyNWI2ZmRiNjhkNw==
+  size: 13680855

Zabbix のバージョン 2.0.11 のソースコードを入手し、 blobs フォルダに追加した後に Blob Store にアップロードする。

$ git commit -m "Added zabbix-2.0.11 blob."

config/blobs.yml を確認し、 Blob Store にちゃんとアップロードされていたら git commit する。

zabbix パッケージの追加

仮想マシンにzabbix をコンパイル、 インストールするための zabbix パッケージを作成する。

$ cd ${RELEASE_DIR}
$ bosh-gen package zabbix
      create  packages/zabbix/packaging
      create  packages/zabbix/spec

bosh-gen package により、 Release Repository に zabbix package のスケルトンが追加される。

packages/zabbix/packaging および packages/zabbix/spec を修正する。

$ vim packages/zabbix/packaging
$ vim packages/zabbix/spec
$ git add .
$ git diff HEAD
diff --git a/packages/zabbix/packaging b/packages/zabbix/packaging
new file mode 100644
index 0000000..53534ed
--- /dev/null
+++ b/packages/zabbix/packaging
@@ -0,0 +1,15 @@
+set -e # exit immediately if a simple command exits with a non-zero status
+set -u # report the usage of uninitialized variables
+
+# Detect # of CPUs so make jobs can be parallelized
+CPUS=$(grep -c ^processor /proc/cpuinfo)
+ # Available variables
+# $BOSH_COMPILE_TARGET - where this package & spec'd source files are available
+# $BOSH_INSTALL_TARGET - where you copy/install files to be included in package
+export HOME=/var/vcap
+
+tar xfv zabbix/zabbix-2.0.11.tar.gz
+cd zabbix-2.0.11
+./configure --prefix=${BOSH_INSTALL_TARGET} --enable-agent
+make
+make install
diff --git a/packages/zabbix/spec b/packages/zabbix/spec
new file mode 100644
index 0000000..19fa224
--- /dev/null
+++ b/packages/zabbix/spec
@@ -0,0 +1,5 @@
+---
+name: zabbix
+dependencies: []
+files:
+- zabbix/zabbix-2.0.11.tar.gz

packaging ファイルには zabbix をコンパイルおよびインストールするスクリプトを記述、 spec ファイルには packaging じに必要とされるファイルのリストを記述する。

$ git commit -m "Added zabbix package."

ここまでの修正を commit しておく。

zabbix-agent Job の追加

bosh-gen job コマンドを使って、 zabbix-agent Job のスケルトンを作成する。 -d オプションには依存する Package を指定する。

$ bosh-gen job zabbix-agent -d zabbix
      create  jobs/zabbix-agent
      create  jobs/zabbix-agent/monit
      create  jobs/zabbix-agent/templates/bin/zabbix-agent_ctl
      create  jobs/zabbix-agent/templates/bin/monit_debugger
      create  jobs/zabbix-agent/templates/config/.gitkeep
      create  jobs/zabbix-agent/templates/data/properties.sh.erb
      create  jobs/zabbix-agent/templates/helpers/ctl_setup.sh
      create  jobs/zabbix-agent/templates/helpers/ctl_utils.sh
      create  jobs/zabbix-agent/spec
$ git add .
$ git commit -m "Added zabbix-agent job base."

zabbix-2.0.11 のソースコードを解凍すると、 zabbix-agentd のデフォルトの設定ファイルが入手できるので、 それを Job のテンプレートとして templates フォルダに追加する。

$ cp ${SOMEWHERE}/zabbix-2.0.11/conf/zabbix_agentd.conf \
     jobs/zabbix-agent/templates/zabbix_agentd.conf.erb
$ git add . && git commit -m "Added original zabbix agentd config."

すべての準備は整ったので、

  • zabbix_agentd.conf.erb
  • zabbix-agent_ctl
  • spec

を修正する。

$ vim jobs/zabbix-agent/templates/zabbix_agentd.conf.erb
$ vim jobs/zabbix-agent/templates/bin/zabbix-agent_ctl
$ vim jobs/zabbix-agent/spec
$ git add . && git commit -m "Fixed zabbix agent job."

zabbix_agentd.conf.erb は、bosh およびそのシステム特有の設定を変数として埋め込む。 zabbix-agent_ctl では zabbix agent を起動するスクリプトを記述する。 spec ファイルではテンプレートファイルをどこに配置するかを記述する。

$ git diff HEAD^ HEAD
diff --git a/jobs/zabbix-agent/spec b/jobs/zabbix-agent/spec
index cbc500c..513f225 100644
--- a/jobs/zabbix-agent/spec
+++ b/jobs/zabbix-agent/spec
@@ -8,3 +8,8 @@ templates:
   data/properties.sh.erb: data/properties.sh
   helpers/ctl_setup.sh: helpers/ctl_setup.sh
   helpers/ctl_utils.sh: helpers/ctl_utils.sh
+  zabbix_agentd.conf.erb: config/zabbix_agentd.conf
+
+properties:
+  zabbix.server.address:
+    description: "IP address of Zabbix server"
diff --git a/jobs/zabbix-agent/templates/bin/zabbix-agent_ctl b/jobs/zabbix-agent/templates/bin/zabbix-agent_ctl
index fd08097..b5c1e5b 100644
--- a/jobs/zabbix-agent/templates/bin/zabbix-agent_ctl
+++ b/jobs/zabbix-agent/templates/bin/zabbix-agent_ctl
@@ -14,8 +14,8 @@ case $1 in
   start)
     pid_guard $PIDFILE $JOB_NAME

-    # TODO: Run some process
-    exec chpst -u vcap:vcap TODO \
+    exec chpst -u vcap:vcap /var/vcap/packages/zabbix/sbin/zabbix_agentd \
+         -c /var/vcap/jobs/zabbix-agent/config/zabbix_agentd.conf \
          >>$LOG_DIR/$JOB_NAME.stdout.log \
          2>>$LOG_DIR/$JOB_NAME.stderr.log

@@ -33,4 +33,4 @@ case $1 in
     ;;

 esac
-exit 0
\ No newline at end of file
+exit 0
diff --git a/jobs/zabbix-agent/templates/zabbix_agentd.conf.erb b/jobs/zabbix-agent/templates/zabbix_agentd.conf.erb
index 345523e..8686a42 100644
--- a/jobs/zabbix-agent/templates/zabbix_agentd.conf
+++ b/jobs/zabbix-agent/templates/zabbix_agentd.conf
@@ -18,7 +18,7 @@
 # Default:
 # LogFile=

-LogFile=/tmp/zabbix_agentd.log
+LogFile=/var/vcap/sys/log/zabbix-agent/zabbix_agentd.log

 ### Option: LogFileSize
 #      Maximum size of log file in MB.
@@ -79,7 +79,7 @@ LogFile=/tmp/zabbix_agentd.log
 # Default:
 # Server=

-Server=127.0.0.1
+Server=<%= p("zabbix.server.address") %>

 ### Option: ListenPort
 #      Agent will listen on this port for connections from the server.
@@ -120,7 +120,7 @@ Server=127.0.0.1
 # Default:
 # ServerActive=

-ServerActive=127.0.0.1
+ServerActive=<%= p("zabbix.server.address") %>

 ### Option: Hostname
 #      Unique, case sensitive hostname.
@@ -131,7 +131,7 @@ ServerActive=127.0.0.1
 # Default:
 # Hostname=

-Hostname=Zabbix server
+Hostname=<%= spec.job.name %>-<%= spec.index %>

 ### Option: HostnameItem
 #      Item used for generating Hostname if it is undefined. Ignored if Hostname is defined.

具体的な修正箇所は以上。

$ bosh create release

bosh create release コマンドにより Dev Release を作成し、 実装した zabbix-agent Job をテストする。