Zabbix-java-gatewayでTomcat7をファイアウォール越しに監視する

以下はVirtualBox上で構築。ホストとはNATでつないで、ゲスト同士は内部ネットワークで接続。

f:id:shrkw:20130702181239p:plain

  • Zabbixサーバー: 192.168.56.2
  • Java Appサーバー: 192.168.56.3

Zabbix関連はyumでzabbix.comのリポジトリから追加。

rpm -ivh http://repo.zabbix.com/zabbix/2.0/rhel/6/x86_64/zabbix-release-2.0-1.el6.noarch.rpm

openJDKはyumで、Tomcatapache.orgからダウンロード。

Tomcat

RMIでサーバーのIPアドレスを解決できるようにする

http://netbuffalo.doorblog.jp/archives/4446395.html がとてもわかりやすくて助かる。 これはjconsoleだけの問題ではないので、すべからく解決する必要がある。 上記のサイトの通り、選択肢は3つ。

  • 起動オプションで -Djava.rmi.server.hostname=172.16.0.100 を指定
  • 起動オプションで -Djava.rmi.server.useLocalHostName=true を指定して、DNSで解決させる
  • /etc/hosts にホスト名とIPアドレスの紐付けをする

アプリケーションの起動時にRMIのサーバーのIPアドレスが解決されるので、反映には再起動が必要。

setenv.shにjmxremoteまわりの設定を追加

server.xmlのほうでRMIポートを指定するので、ここではポートの指定 [com.sun.management.jmxremote.port] は不要。 [java.rmi.server.hostname], [java.rmi.server.useLocalHostName] については、上記の通り、どこでRMIサーバーのIPアドレスの解決をさせるかによる。hostsで解決させていないのであれば、指定すること。

CATALINA_OPTS="\
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
";
export CATALINA_OPTS;

今回はauthenticateとかなしでやってるけど、本番では認証もSSLも設定する。その場合は以下のようになる。

CATALINA_OPTS="\
-Dcom.sun.management.jmxremote.authenticate=true \
-Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password \
-Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access \
-Dcom.sun.management.jmxremote.ssl=true \
";
export CATALINA_OPTS;

この例では、confの下に jmxremote.password, jmxremote.access のふたつのファイルがあるという設定になっている。passwordファイルについては

でなければならない。 ちなみにそれぞれの内容は以下のような感じ。

$CATALINA_BASE/conf/jmxremote.access

monitorRole readonly

$CATALINA_BASE/conf/jmxremote.password

monitorRole tomcat

http://tomcat.apache.org/tomcat-7.0-doc/monitoring.html

JMXのポートを固定する

JMXが利用しているRMI(?)では2つのポートを使用するが、実行時オプションで [com.sun.management.jmxremote.port] で指定した場合、もうひとつのポートはランダムに使用される。そのため、ファイアウォールで制限された環境ではポートをフルで開くなどしない限り、RMIの疎通ができない。そのため、Tomcatには使用するポートを固定するための措置が存在する。

catalina-jmx-remote.jar を $TOMCAT_HOME/lib に配置

追加のjarが必要。

curl -O http://ftp.yz.yamagata-u.ac.jp/pub/network/apache/tomcat/tomcat-7/v7.0.41/bin/extras/catalina-jmx-remote.jar

server.xmlにListenerを追加

<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" />

useLocalPorts="true" にすると、リモートから繋ごうとすると java.net.ConnectException connection refused になるので注意。

サービススタート

あとは適当にスタートすればOK。

参考

Zabbix-java-gateway

Zabbixサーバーに同居。/etc/zabbix/zabbix_server.conf みても、複数gatewayが設定できなそうだったし。

JMXで繋がるか試す

コマンドラインJMXクライアントで、とりあえず疎通できるか試す。

curl -O http://crawler.archive.org/cmdline-jmxclient/cmdline-jmxclient-0.10.3.jar
curl -O http://ftp.yz.yamagata-u.ac.jp/pub/network/apache/tomcat/tomcat-7/v7.0.41/bin/extras/catalina-jmx-remote.jar

RMIの対向側なんで、catalina-jmx-remote.jarが必要。 こんな感じでclasspathにjarを追加して実行する。
指定するポートはrmiRegistryPortPlatformとして指定した10001だけでよい。rmiServerPortPlatformの10002ポートのほうは、とくに指定しなくても勝手にパケットが通るので、ファイアウォールで10001も10002も許可すること。

java -classpath /usr/sbin/zabbix_java/lib/catalina-jmx-remote.jar:cmdline-jmxclient-0.10.3.jar org.archive.jmx.Client - 192.168.56.3:10001

結果で、MBeanのリストが返ってくればOK.

 Catalina:J2EEApplication=none,J2EEServer=none,WebModule=//localhost/manager,j2eeType=Servlet,name=HTMLManager
Catalina:J2EEApplication=none,J2EEServer=none,WebModule=//localhost/manager,j2eeType=Servlet,name=Manager
java.lang:type=Memory
Catalina:J2EEApplication=none,J2EEServer=none,WebModule=//localhost/examples,j2eeType=Servlet,name=stock
JMImplementation:type=MBeanServerDelegate
Catalina:context=/host-manager,host=localhost,name=StandardContextValve,type=Valve
(snip)

catalina-jmx-remote.jar を $zabbix_java/lib に配置

さっきダウンロードしたのを、java-gatewayのlibに置く。initスクリプト見たら、ここに置いたら実行時にクラスパスに追加してくれてた。

mv catalina-jmx-remote.jar /usr/sbin/zabbix_java/lib/

zabbix_java_gateway.confは編集しない

/etc/zabbix/zabbix_java_gateway.conf はそのままのでよいようだ。

サービススタート

あとは適当にスタートすればOK。

Zabbixサーバー側

Java Gatewayを設定

/etc/zabbix/zabbix_server.conf に設定を追加。

JavaGateway=127.0.0.1
JavaGatewayPort=10052
StartJavaPollers=5

JMXインターフェースの追加

これで終わり。ホストの追加のときにJMXインターフェースで

192.168.56.3:10001

を追加してやればOK. ここで指定するのも、rmiRegistryPortPlatformとして指定した10001だけ。10001だけなんだけど、上記の通り、rmiServerPortPlatformの10002ポートのほうもパケットが通るので、ファイアウォールで開けておく必要がある。

https://www.zabbix.com/forum/showthread.php?t=27111

JMXの設定の際にクレデンシャルを指定している場合はユーザー名とパスワードを設定する必要がある。でもホストのインタフェース設定では見つからない。では、どこで設定するかというと個別のアイテムで設定する。 https://www.zabbix.com/documentation/doku.php?id=2.0/manual/config/items/itemtypes/jmx_monitoring

マクロを使えるとはいえ、クレデンシャルはホストで指定するほうが素直というのはすでにフォーラムで話題に上がってた。ぼくもそう思う。

https://www.zabbix.com/forum/showthread.php?t=31764

あとは Template JMX Generic とか Template JMX Tomcat 7 のテンプレート[ https://gist.github.com/hgomez/3209196 ]を適用させていいんじゃないかと。

f:id:shrkw:20130702202612p:plain

アイコンが緑になると気持ちいい。

参考