ZabbixからTomcatコンテナを監視する
EatSmartではサーバ、サービスの監視にZabbixを利用しています。 利用するテンプレートは、サーバの監視には"Template OS Linux"を、Tomcatの監視には"Template App Generic Java JMX"と独自に拡張したものを利用しています。 これらの構成はデータセンターを利用していた頃から基本的に変わらないのですが、Zabbix Java GatewayでTomcatを監視するのに工夫が必要でした。
Tomcatコンテナの設定
以前は一つのサーバに複数のTomcatをインストールしていたので、JMXが利用するポートが重複しないよう分けていました。 Dockerコンテナで可動するTomcatも同様にコンテナごとに重複しないようにポートは分けるようにしました。 当初、setenv.shと起動時のコマンドは以下のようにしました。
setenv.sh
CATALINA_OPTS="${CATALINA_OPTS} \ -Dcom.sun.management.jmxremote=true \ -Dcom.sun.management.jmxremote.port=12345 \ -Dcom.sun.management.jmxremote.rmi.port=12345\ -Dcom.sun.management.jmxremote.local.only=false \ -Dcom.sun.management.jmxremote.authenticate=false \ -Dcom.sun.management.jmxremote.ssl=false" export CATALINA_OPTS
run.sh
docker run -d \ --name tomcat-mog \ -p 38080:8080 \ -p 32345:12345 \ esma/tomcat
このTomcatコンテナは各サービスで共通で利用することを想定しています。 そのため、コンテナ自体は8080/12345という固定のポートを利用し、必要に応じて実行時にポートフォワードさせます。 "tomcat-mog"という名前のこのコンテナは、外部に38080/32345の2つのポートを開放しています。 ZabbixからはZabbix Java Gatewayを経由して32345ポートを利用すれば良いと考えていました。
しかし、この設定では監視ができませんでした。 調査した結果、Zabbixが指定したIPアドレス/ポート(Dockerホストのもの)と自身のIPアドレス/ポート(Dockerコンテナのもの)が異なるため、Zabbix Agentはメトリクスを返していませんでした。
設定の変更
原因がわかったので解消するための設定を行います。
setenv.sh
CATALINA_OPTS="${CATALINA_OPTS} \ -Dcom.sun.management.jmxremote=true \ -Dcom.sun.management.jmxremote.port=${JMX_PORT} \ -Dcom.sun.management.jmxremote.rmi.port=${JMX_PORT} \ -Dcom.sun.management.jmxremote.local.only=false \ -Dcom.sun.management.jmxremote.authenticate=false \ -Dcom.sun.management.jmxremote.ssl=false \ -Djava.rmi.server.hostname=${HOST_IP_ADDRESS}" export CATALINA_OPTS
run.sh
HOST_IP_ADDRESS=`hostname -I` docker run -d \ --name tomcat-mog \ -p 38080:8080 \ -p 32345:32345 \ --env="JMX_PORT=32345" \ --env="HOST_IP_ADDRESS=${HOST_IP_ADDRESS}" \ esma/tomcat
Dockerホストとコンテナ間のIP/ポートを同一にすることは出来ないので、ホストの設定をコンテナ起動時に渡すようにしました。 コンテナではその値を参照して、JMXの値を設定しています。 以上の変更で、無事ZabbixからTomcatコンテナを監視することができるようになりました。