力技で動かす
CentOS6 で Zabbix 3.0 を動かす実験の記録です。MySQL 用を使って実験しました。
検証は CentOS 6.7 で行いました。
rpm パッケージと、対応する glibc や libmysqlclient、libcurl をほどいて配置して動かす方法です。ソースからのビルドは不要ですが、必要となる glibc のバージョンが合わないため、かなり強引な方法で実現しています。
[CentOS6 で Zabbix 3.0 を動かす (自力ビルド編)] (http://qiita.com/items/b6b7adc914a3ca8ad0cb) も参照してください。
パッケージを入手する
リポジトリから直接パッケージをダウンロードしました。
zabbix-agent-3.0.1-1.el7.x86_64.rpm
zabbix-get-3.0.1-1.el7.x86_64.rpm
zabbix-java-gateway-3.0.1-1.el7.x86_64.rpm
zabbix-proxy-mysql-3.0.1-1.el7.x86_64.rpm
zabbix-sender-3.0.1-1.el7.x86_64.rpm
zabbix-server-mysql-3.0.1-1.el7.x86_64.rpm
zabbix-web-3.0.1-1.el7.noarch.rpm
zabbix-web-japanese-3.0.1-1.el7.noarch.rpm
zabbix-web-mysql-3.0.1-1.el7.noarch.rpm
今回は実験のために一通りダウンロードしましたが、zabbix-server-mysql と zabbix-web の一連のパッケージ以外は RHEL6/CentOS6 用のものが提供されています。
MySQL
remi リポジトリのパッケージを導入しました。
インストールしたパッケージは以下の通りです。
- mysql-libs-5.5.48-1.el6.remi.x86_64
- compat-mysql51-5.1.54-1.el6.remi.x86_64
- mysql-5.5.48-1.el6.remi.x86_64
- perl-DBD-MySQL-4.013-3.el6.x86_64
- mysql-server-5.5.48-1.el6.remi.x86_64
パッケージをほどいて配置
rpm パッケージと、対応する glibc や libmysqlclient、libcurl を解いて配置します。
配置先を /opt/zabbix とします。
# mkdir /opt/zabbix
# rpm2cpio zabbix-server-mysql-3.0.1-1.el7.x86_64.rpm | (cd /opt/zabbix && cpio -idmvu)
# rpm2cpio zabbix-agent-3.0.1-1.el7.x86_64.rpm | (cd /opt/zabbix && cpio -idmvu)
# rpm2cpio zabbix-get-3.0.1-1.el7.x86_64.rpm | (cd /opt/zabbix && cpio -idmvu)
# rpm2cpio zabbix-sender-3.0.1-1.el7.x86_64.rpm | (cd /opt/zabbix && cpio -idmvu)
データベースの作成
データベースと接続ユーザを作成します。以下は、ユーザ名 zabbix パスワード zabbix での例です。
$ mysql -uroot -p
Enter password:
mysql> create database zabbix character set utf8 collate utf8_bin;
mysql> grant all privileges on zabbix.* to zabbix@localhost identified by 'zabbix';
mysql> quit;
$ gzip -dc /opt/zabbix/usr/share/doc/zabbix-server-mysql-3.0.1/create.sql.gz |
mysql -uzabbix -pzabbix zabbix
設定ファイル
ディレクトリのシンボリックリンクを張っておきます。
# ln -s /opt/zabbix/etc/zabbix /etc/zabbix
# ln -s /opt/usr/lib/zabbix/alertscripts /usr/lib/zabbix/alertscripts
# ln -s /opt/usr/lib/zabbix/externalscripts /usr/lib/zabbix/externalscripts
設定ファイルを修正します。
diff -u zabbix_server.conf zabbix_server.conf
--- zabbix_server.conf- 2016-02-28 16:23:55.000000000 +0900
+++ zabbix_server.conf 2016-03-02 15:50:50.000000000 +0900
@@ -114,6 +114,8 @@
# Default:
# DBPassword=
+DBPassword=zabbix
+
### Option: DBSocket
# Path to MySQL socket.
#
@@ -121,6 +123,8 @@
# Default:
# DBSocket=/tmp/mysql.sock
+DBSocket=/var/lib/mysql/mysql.sock
+
### Option: DBPort
# Database port when not using local socket. Ignored for SQLite.
#
# chown zabbix /etc/zabbix/zabbix_server.conf
# chmod 640 /etc/zabbix/zabbix_server.conf
共有ライブラリ
共有ライブラリが足りているかどうかチェックします。
$ ldd /opt/zabbix/usr/sbin/zabbix_server_mysql
/opt/zabbix/usr/sbin/zabbix_server_mysql: /lib64/libc.so.6: version `GLIBC_2.15' not found (required by /opt/zabbix/usr/sbin/zabbix_server_mysql)
/opt/zabbix/usr/sbin/zabbix_server_mysql: /lib64/libc.so.6: version `GLIBC_2.17' not found (required by /opt/zabbix/usr/sbin/zabbix_server_mysql)
/opt/zabbix/usr/sbin/zabbix_server_mysql: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /opt/zabbix/usr/sbin/zabbix_server_mysql)
linux-vdso.so.1 => (0x00007ffc81169000)
libmysqlclient.so.18 => /usr/lib64/mysql/libmysqlclient.so.18 (0x00007fb896437000)
libiksemel.so.3 => /usr/lib64/libiksemel.so.3 (0x00007fb896229000)
libxml2.so.2 => /usr/lib64/libxml2.so.2 (0x00007fb895ed6000)
libodbc.so.2 => /usr/lib64/libodbc.so.2 (0x00007fb895c6f000)
libnetsnmp.so.31 => not found
libssh2.so.1 => /usr/lib64/libssh2.so.1 (0x00007fb895a46000)
libOpenIPMI.so.0 => /usr/lib64/libOpenIPMI.so.0 (0x00007fb89573e000)
libOpenIPMIposix.so.0 => /usr/lib64/libOpenIPMIposix.so.0 (0x00007fb895539000)
libssl.so.10 => /usr/lib64/libssl.so.10 (0x00007fb8952cc000)
libcrypto.so.10 => /usr/lib64/libcrypto.so.10 (0x00007fb894ee8000)
libldap-2.4.so.2 => /lib64/libldap-2.4.so.2 (0x00007fb894c98000)
liblber-2.4.so.2 => /lib64/liblber-2.4.so.2 (0x00007fb894a88000)
libcurl.so.4 => /usr/lib64/libcurl.so.4 (0x00007fb894822000)
libm.so.6 => /lib64/libm.so.6 (0x00007fb89459e000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fb894399000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x00007fb89417f000)
libc.so.6 => /lib64/libc.so.6 (0x00007fb893deb000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fb893bcd000)
libz.so.1 => /lib64/libz.so.1 (0x00007fb8939b7000)
librt.so.1 => /lib64/librt.so.1 (0x00007fb8937af000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fb8934a8000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fb893292000)
libgnutls.so.26 => /usr/lib64/libgnutls.so.26 (0x00007fb892fef000)
libgcrypt.so.11 => /lib64/libgcrypt.so.11 (0x00007fb892d79000)
libgpg-error.so.0 => /lib64/libgpg-error.so.0 (0x00007fb892b75000)
libltdl.so.7 => /usr/lib64/libltdl.so.7 (0x00007fb89296c000)
libOpenIPMIutils.so.0 => /usr/lib64/libOpenIPMIutils.so.0 (0x00007fb892763000)
libncurses.so.5 => /lib64/libncurses.so.5 (0x00007fb892541000)
libgdbm.so.2 => /usr/lib64/libgdbm.so.2 (0x00007fb89233b000)
libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007fb8920f6000)
libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007fb891e0f000)
libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007fb891c0b000)
libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007fb8919de000)
libsasl2.so.2 => /usr/lib64/libsasl2.so.2 (0x00007fb8917c4000)
libssl3.so => /usr/lib64/libssl3.so (0x00007fb891584000)
libsmime3.so => /usr/lib64/libsmime3.so (0x00007fb891357000)
libnss3.so => /usr/lib64/libnss3.so (0x00007fb891018000)
libnssutil3.so => /usr/lib64/libnssutil3.so (0x00007fb890dec000)
libplds4.so => /lib64/libplds4.so (0x00007fb890be7000)
libplc4.so => /lib64/libplc4.so (0x00007fb8909e2000)
libnspr4.so => /lib64/libnspr4.so (0x00007fb8907a4000)
libidn.so.11 => /lib64/libidn.so.11 (0x00007fb890571000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb89691f000)
libtasn1.so.3 => /usr/lib64/libtasn1.so.3 (0x00007fb890361000)
libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007fb89013f000)
libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007fb88ff34000)
libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007fb88fd31000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007fb88faf9000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fb88f8da000)
libfreebl3.so => /lib64/libfreebl3.so (0x00007fb88f6d6000)
RHEL7/CentOS7 用にビルドされた Zabbix 3.0 は glibc 2.17 を要求します。
また libnetsnmp.so.31 が not found になっています。
CentOS7 のリポジトリからパッケージをダウンロードしてきます。
また、curl も CentOS6 ものは、バージョンが古く SMTP AUTH が使えないためこちらもダウンロードしてきます。
先ほどと同様に展開します。
# rpm2cpio glibc-2.17-105.el7.x86_64.rpm | (cd /opt/zabbix && cpio -idmvu)
# net-snmp-libs-5.7.2-24.el7.x86_64.rpm | (cd /opt/zabbix && cpio -idmvu)
# rpm2cpio libcurl-7.29.0-25.el7.centos.x86_64.rpm | (cd /opt/zabbix && cpio -idmvu)
ひとまず実行してみる
起動できるかどうか試してみます。
$ LD_LIBRARY_PATH=/opt/zabbix/lib64:/opt/zabbix/usr/lib64 /opt/zabbix/usr/sbin/zabbix_server_mysql -h
/opt/zabbix/usr/sbin/zabbix_server_mysql: relocation error: /opt/zabbix/lib64/libc.so.6: symbol _dl_starting_up, version GLIBC_PRIVATE not defined in file ld-linux-x86-64.so.2 with link time reference
起動時に使用するダイナミックリンカー ld-linux-x86-64.so.2 が合っていないようです。
CentOS6 と CentOS7 では、glibc のバージョンが異なります。
CentOS6 の glibc は 2.12 CentOS7 の glibc は 2.17 となっています。
このため、rpm パッケージと、対応する glibc や libmysqlclient、libcurl を解いて配置して、環境変数 LD_LIBRARY_PATH を設定しただけではうまく起動できません。
glibc の場合、libc-2.XX.so とダイナミックリンカー ld-2.XX.so とが対応している必要があるのですが、起動時に使用されるダイナミックリンカーは、ロード-モジュールを作成するときに、libc.so に記載されているものがプログラムヘッダの INTERP に埋め込まれます。
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib64/ld-linux-x86-64.so.2 ) )
$ readelf -l -S /opt/zabbix/usr/sbin/zabbix_server_mysql | sed -n '/Program Headers:/,/program interpreter/p'
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x00000000000001f8 0x00000000000001f8 R E 8
INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
0x000000000000001c 0x000000000000001c R 1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
/lib64/ld-linux-x86-64.so.2 は CentOS6 では、2.12 用のものなのでうまく起動できません。
ダイナミックリンカーには、プログラムが起動されたときに、必要な共有ライブラリを読み込むヘルパープログラムの機能のほかに、ロードモジュールを起動する機能があります。
NAME
ld.so, ld-linux.so* - dynamic linker/loader
SYNOPSIS
The dynamic linker can be run either indirectly by running some dynami‐
cally linked program or library (in which case no command-line options
to the dynamic linker can be passed and, in the ELF case, the dynamic
linker which is stored in the .interp section of the program is exe‐
cuted) or directly by running:
/lib/ld-linux.so.* [OPTIONS] [PROGRAM [ARGUMENTS]]
OPTIONS
--library-path PATH
Use PATH instead of LD_LIBRARY_PATH environment variable setting
(see below).
ダイナミックリンカ ld-linux-x86-64.so.2 に、共有ライブラリの検索パスを指定して起動し、ロードモジュールを呼び出すようにすれば問題なく動作します。
やってみます。
$ /opt/zabbix/lib64/ld-linux-x86-64.so.2 --library-path /opt/zabbix/lib64:/opt/zabbix/usr/lib64 /opt/zabbix/usr/sbin/zabbix_server_mysql -h
usage:
zabbix_server_mysql [-c config-file]
zabbix_server_mysql [-c config-file] -R runtime-option
zabbix_server_mysql -h
zabbix_server_mysql -V
The core daemon of Zabbix software.
Options:
-c --config config-file Absolute path to the configuration file
(default: "/etc/zabbix/zabbix_server.conf")
-f --foreground Run Zabbix server in foreground
-R --runtime-control runtime-option Perform administrative functions
Runtime control options:
config_cache_reload Reload configuration cache
housekeeper_execute Execute the housekeeper
log_level_increase=target Increase log level, affects all processes if
target is not specified
log_level_decrease=target Decrease log level, affects all processes if
target is not specified
Log level control targets:
pid Process identifier
process-type All processes of specified type (e.g., poller)
process-type,N Process type and number (e.g., poller,3)
-h --help Display this help message
-V --version Display version number
Report bugs to: <https://support.zabbix.com>
Zabbix home page: <http://www.zabbix.com>
Documentation: <https://www.zabbix.com/documentation>
だいじょうぶなようです。
註) この実行結果だけではわかりませんが、じつは libmysqlclient.so.18 は CentOS7 のリポジトリにあるMariaDB のものを使用しないと実行時に未定義シンボルエラーが出ます。このことについては後ほど触れます。
スタートアップスクリプト
CentOS7 では systemd を使用する形になっているため、旧来のスタートアップスクリプトはパッケージに含まれていません。
そこで Zabbix 2.4 のパッケージ含まれるものを使用するため、アーカイブから展開します。
# rpm2cpio zabbix-server-2.4.7-1.el6.x86_64.rpm | (cd /opt/zabbix && cpio -idmvu ./etc/init.d/zabbix-server)
# rpm2cpio zabbix-agent-2.4.7-1.el6.x86_64.rpm | (cd /opt/zabbix && cpio -idmvu
./etc/init.d/zabbix-agent)
ld-linux-x86-64.so.2 経由で起動するように修正します。
--- /opt/zabbix/etc/init.d/zabbix-server 2015-11-13 19:14:20.000000000 +0900
+++ /opt/zabbix/etc/init.d/zabbix-server 2016-03-03 23:57:02.975726383 +0900
@@ -18,11 +18,19 @@
# Source function library.
. /etc/rc.d/init.d/functions
-if [ -x /usr/sbin/zabbix_server ]; then
- exec=zabbix_server
+zroot=/opt/zabbix
+if [ -x $zroot/usr/sbin/zabbix_server ]; then
+ #exec=$zroot/usr/sbin/zabbix_server
+ exec=$zroot/usr/sbin/zabbix_server_mysql
else
exit 5
fi
+if [ -x $zroot/lib64/ld-linux-x86-64.so.2 ]; then
+ ld_so=$zroot/lib64/ld-linux-x86-64.so.2
+else
+ exit 5
+fi
+library_path=$zroot/lib64:$zroot/usr/lib64
prog=${exec##*/}
conf=/etc/zabbix/zabbix_server.conf
@@ -38,7 +46,7 @@
start()
{
echo -n $"Starting Zabbix server: "
- daemon $exec -c $conf
+ LD_LIBRARY_PATH=$library_path $ld_so $exec -c $conf
rv=$?
echo
[ $rv -eq 0 ] && touch $lockfile
実行ユーザ zabbix と実行グループ zabbix を作成しておきます。
# groupadd -g 119 zabbix
# useradd -u 119 -g 119 -d /var/run/zabbix/ -s /bin/false zabbix
ログディレクトリを作成しておきます。
install -o zabbix -g zabbix -d /var/log/zabbix
起動してみます。
# sh -x /opt/zabbix/etc/init.d/zabbix-server start
実行してみると一見エラーは出ないものの、起動したプロセスがありません。zabbix_server.log を見ると未解決シンボルのエラーが出ていました。
/opt/zabbix/usr/sbin/zabbix_server_mysql: relocation error: /opt/zabbix/usr/sbin/zabbix_server_mysql: symbol mysql_init, version libmysqlclient_18 not defined in file libmysqlclient.so.18 with link time reference
CentOS7 では MariaDB を使用するようになっているため、libmysqlclient.so.18 は CentOS7 のリポジトリにある MariaDB のものを使用しないとダメなようです。CentOS7 のリポジトリからパッケージをダウンロードしてきて展開します。
# rpm2cpio mariadb-libs-5.5.44-2.el7.centos.x86_64.rpm | (cd /opt/zabbix && cpio -idmvu)
スタートアップスクリプトの library_path に追加します。
--- zabbix-server 2016-03-04 02:28:56.955721309 +0900
+++ zabbix-server 2016-03-03 23:57:02.975726383 +0900
@@ -30,7 +30,7 @@
else
exit 5
fi
-library_path=$zroot/lib64:$zroot/usr/lib64
+library_path=$zroot/lib64:$zroot/usr/lib64:$zroot/usr/lib64/mysql
if [ ! -d /var/log/zabbix ]; then
install -o zabbix -g zabbix -d /var/log/zabbix
再度起動してみると問題なく立ち上がるようになりました。
ps で見ると、ld-linux ばかり並んで何がなんだかわかりません。
$ ps axg | grep zabbix
366 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2 /opt/zabbix/usr/sbin/zabbix_server_mysql -c /etc/zabbix/zabbix_server.conf
371 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
372 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
373 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
374 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
375 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
376 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
377 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
378 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
379 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
380 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
381 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
382 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
383 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
384 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
385 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
389 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
390 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
391 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
392 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
393 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
394 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
395 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
406 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
407 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
408 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
409 ? S 0:00 /opt/zabbix/lib64/ld-linux-x86-64.so.2
argv[0] がロードモジュール名になるようにして exec するラッパーを作りました。
#!/usr/bin/python
import sys
import os
LD_SO = "/opt/zabbix/lib64/ld-linux-x86-64.so.2"
ZROOT = "/opt/zabbix"
LIBRARY_PATH = [ "/lib64", "/usr/lib64", "/usr/lib64/mysql" ]
if (len(sys.argv) < 1):
sys.exit(1)
#os.environ["LD_LIBRARY_PATH"] = ':'.join([ ZROOT + x for x in LIBRARY_PATH ])
args = [ sys.argv[0] ]
args.append("--library-path")
args.append(':'.join([ ZROOT + x for x in LIBRARY_PATH ]))
if (sys.argv[0][0] == '/'):
path = "%s%s" % (ZROOT, sys.argv[0])
args.append(path)
else:
path = "%s/usr/bin/%s" % (ZROOT, sys.argv[0])
if (os.access(path, os.X_OK)):
args.append(path)
else:
path = "%s/usr/sbin/%s" % (ZROOT, sys.argv[0])
if (os.access(path, os.X_OK)):
printf >>stderr, "%s: not found\n" % sys.argv[0]
sys.exit(1)
args.append(path)
args.extend(sys.argv[1:])
os.execv(LD_SO, args)
このラッパーは /usr/sbin/zabbix_server_mysql として配置して、こちらを起動すると、/opt/zabbix/usr/sbin/zabbix_server_mysql_ を起動して、プロセス名が /usr/sbin/zabbix_server_mysql として見えるようになります。
註)通常プロセス名は Zabbix 側で役割を表すように書き換えられるのですが、ld-linux 経由でロードモジュールを起動したときは、書き換えができていないようです。
$ ps axg | grep zabbix
3840 ? S 0:00 /usr/sbin/zabbix_server_mysql --library-path /opt/zabbix/lib64:/opt/zabbix/usr/lib64:/opt/zabbix/usr/lib64/mysql /opt/zabbix/usr/sbin/zabbix_server_mysql
3845 ? S 0:00 /usr/sbin/zabbix_server_mysql
3846 ? S 0:00 /usr/sbin/zabbix_server_mysql
3847 ? S 0:00 /usr/sbin/zabbix_server_mysql
3848 ? S 0:00 /usr/sbin/zabbix_server_mysql
3849 ? S 0:00 /usr/sbin/zabbix_server_mysql
3850 ? S 0:00 /usr/sbin/zabbix_server_mysql
3851 ? S 0:00 /usr/sbin/zabbix_server_mysql
3852 ? S 0:00 /usr/sbin/zabbix_server_mysql
3853 ? S 0:00 /usr/sbin/zabbix_server_mysql
3854 ? S 0:00 /usr/sbin/zabbix_server_mysql
3855 ? S 0:00 /usr/sbin/zabbix_server_mysql
3856 ? S 0:00 /usr/sbin/zabbix_server_mysql
3857 ? S 0:00 /usr/sbin/zabbix_server_mysql
3858 ? S 0:00 /usr/sbin/zabbix_server_mysql
3859 ? S 0:00 /usr/sbin/zabbix_server_mysql
3860 ? S 0:00 /usr/sbin/zabbix_server_mysql
3861 ? S 0:00 /usr/sbin/zabbix_server_mysql
3862 ? S 0:00 /usr/sbin/zabbix_server_mysql
3863 ? S 0:00 /usr/sbin/zabbix_server_mysql
3870 ? S 0:00 /usr/sbin/zabbix_server_mysql
3871 ? S 0:00 /usr/sbin/zabbix_server_mysql
3872 ? S 0:00 /usr/sbin/zabbix_server_mysql
3873 ? S 0:00 /usr/sbin/zabbix_server_mysql
3874 ? S 0:00 /usr/sbin/zabbix_server_mysql
3875 ? S 0:00 /usr/sbin/zabbix_server_mysql
3876 ? S 0:00 /usr/sbin/zabbix_server_mysql
3894 pts/1 S+ 0:00 grep zabbix
ノート
LD_LIBRARY_PATH を指定して、ld-linux-x86-64.so.2 を起動すると、zabbix_server から起動される子プロセスにもこの環境変数が渡ってしまい、子プロセスの起動に失敗します。
たとえば、zabbix_agentd を LD_LIBRARY_PATH を指定する方法で起動すると、zabbix_agentd そのものは動くのですが、UserParameter で指定した外部プログラムの起動に失敗します。
$ zabbix_get -s 127.0.0.1 -k mysql.version
sh: relocation error: /opt/zabbix/lib64/libc.so.6: symbol _dl_starting_up, version GLIBC_PRIVATE not defined in file ld-linux-x86-64.so.2 with link time reference
~~~
この例の relocation error は、 zabbix_agentd が `execl("/bin/sh", "sh", "-c", command, NULL);` で子プロセスを起動しようとして /bin/sh がエラーを出したものです。
最初スタートアップスクリプトでは、`LD_LIBRARY_PATH` を指定するようにしていましたが、ラッパープログラムでは `--library-path` 引数で指定するように変更しています。
## ラッパーの配置とシンボリックリンクの作成
今回は rpm2cpio でパッケージを展開していますが、本来であればインストール時に
~~~
/usr/sbin/update-alternatives --install /usr/sbin/zabbix_server \
zabbix-server /usr/sbin/zabbix_server_mysql 10
~~~
が実行されて、`/usr/sbin/zabbix_server` は `/usr/sbin/zabbix_server_mysql` を指すようにシンボリックリンクが張られます。
ラッパープログラムでは、起動された名前をもとに実行するロードモジュールを決定しているため、つぎのようにシンボリックリンクを作成します。
~~~
cp zwrapper.py /usr/sbin/zwrapper
ln -s zwrapper /usr/sbin/zabbix_server_mysql
ln -s zwrapper /usr/sbin/zabbix_server
ln -s zabbix_server_mysql /opt/zabbix/usr/sbin/zabbix_server
ln -s zwrapper /usr/sbin/zabbix_agentd
~~~
~~~
ln /usr/sbin/zwrapper /usr/bin/zwrapper
ln -s zwrapper /usr/bin/zabbix_get
ln -s zwrapper /usr/bin/zabbix_sender
~~~
~~~
$ ls -l /usr/sbin/zabbix_server /usr/sbin/zabbix_server_mysql /opt/zabbix/usr/sbin/zabbix_server /opt/zabbix/usr/sbin/zabbix_server_mysql
lrwxrwxrwx 1 root root 19 Mar 4 02:55 /opt/zabbix/usr/sbin/zabbix_server -> zabbix_server_mysql
-rwxr-xr-x 1 root root 1594952 Feb 28 16:24 /opt/zabbix/usr/sbin/zabbix_server_mysql
lrwxrwxrwx 1 root root 8 Mar 4 03:08 /usr/sbin/zabbix_server -> zwrapper
lrwxrwxrwx 1 root root 8 Mar 2 18:41 /usr/sbin/zabbix_server_mysql -> zwrapper
$ ls -l /usr/sbin/zabbix_agentd
lrwxrwxrwx 1 root root 8 Mar 2 18:41 /usr/sbin/zabbix_agentd -> zwrapper
$ ls -l /usr/bin/zabbix_get /usr/bin/zabbix_sender /usr/bin/zwrapper
lrwxrwxrwx 1 root root 8 Mar 2 18:38 /usr/bin/zabbix_get -> zwrapper
lrwxrwxrwx 1 root root 8 Mar 2 18:41 /usr/bin/zabbix_sender -> zwrapper
-rwxr-xr-x 2 root root 881 Mar 4 05:42 /usr/bin/zwrapper
~~~
このようにすると、スタートアッププログラムは変更なしで使えるようになります。
アーカイブから /etc/init.d に展開します。
~~~
# rpm2cpio zabbix-server-2.4.7-1.el6.x86_64.rpm | (cd / && cpio -imv ./etc/init.d/zabbix-server)
# rpm2cpio zabbix-agent-2.4.7-1.el6.x86_64.rpm | (cd / && cpio -imv ./etc/init.d/zabbix-agent)
~~~
## web
PHP 5.4 以上が必要となります。remi リポジトリのパッケージを導入しました。
インストールしたパッケージは以下の通りです。
* php-common-5.4.45-4.el6.remi.x86_64
* php-5.4.45-4.el6.remi.x86_64
* php-mysql-5.4.45-4.el6.remi.x86_64
* php-bcmath-5.4.45-4.el6.remi.x86_64
* php-xml-5.4.45-4.el6.remi.x86_64
* httpd-tools-2.2.15-47.el6.centos.3.x86_64
* httpd-2.2.15-47.el6.centos.3.x86_64
* php-cli-5.4.45-4.el6.remi.x86_64
* php-pdo-5.4.45-4.el6.remi.x86_64
* php-mbstring-5.4.45-4.el6.remi.x86_64
* php-gd-5.4.45-4.el6.remi.x86_64
* php-ldap-5.4.45-4.el6.remi.x86_64
ディレクトリのシンボリックリンクを張っておきます。
~~~
# ln -s /opt/zabbix/usr/share/zabbix /usr/share/zabbix
~~~
GUI からの初期設定で作成されるファイルが書き込めるようにディレクトリのアクセス権を設定します。
~~~
# chgrp apache /etc/zabbix/web
# chmod g+w /etc/zabbix/web
~~~
~~~
# ls -ld /etc/zabbix/web
drwxrwx--- 2 root apache 4096 Mar 2 19:43 /etc/zabbix/web
~~~
`/opt/zabbix/etc/httpd/conf.d/zabbix.conf` にあるファイルは apache 2.4 用のものであるため、以下のように修正して `/etc/httpd/conf.d/zabbix.conf` に配置します。
```/etc/httpd/conf.d/zabbix.conf.patch
diff -u zabbix.conf zabbix.conf
--- zabbix.conf 2016-02-28 16:05:33.000000000 +0900
+++ zabbix.conf 2016-03-04 14:49:45.345699170 +0900
@@ -7,7 +7,8 @@
<Directory "/usr/share/zabbix">
Options FollowSymLinks
AllowOverride None
- Require all granted
+ Order allow,deny
+ Allow from all
<IfModule mod_php5.c>
php_value max_execution_time 300
@@ -16,22 +17,42 @@
php_value upload_max_filesize 2M
php_value max_input_time 300
php_value always_populate_raw_post_data -1
- # php_value date.timezone Europe/Riga
+ php_value date.timezone Asia/Tokyo
</IfModule>
</Directory>
<Directory "/usr/share/zabbix/conf">
- Require all denied
+ Order deny,allow
+ Deny from all
+ <files *.php>
+ Order deny,allow
+ Deny from all
+ </files>
</Directory>
<Directory "/usr/share/zabbix/app">
- Require all denied
+ Order deny,allow
+ Deny from all
+ <files *.php>
+ Order deny,allow
+ Deny from all
+ </files>
</Directory>
<Directory "/usr/share/zabbix/include">
- Require all denied
+ Order deny,allow
+ Deny from all
+ <files *.php>
+ Order deny,allow
+ Deny from all
+ </files>
</Directory>
<Directory "/usr/share/zabbix/local">
- Require all denied
+ Order deny,allow
+ Deny from all
+ <files *.php>
+ Order deny,allow
+ Deny from all
+ </files>
</Directory>
```
~~~
# apachectl graceful
~~~
## GUI からの初期設定
デフォルトでは iptable によるパケットフィルターがかかっています。
必要に応じて修正します。
```iptables.patch
diff -u /etc/sysconfig/iptables /etc/sysconfig/iptables
--- /etc/sysconfig/iptables.old 2016-03-02 05:23:33.296000000 +0900
+++ /etc/sysconfig/iptables 2016-03-03 03:21:08.606717140 +0900
@@ -8,6 +8,10 @@
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
+-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
+-A INPUT -m state --state NEW -m tcp -p tcp --dport 10050 -j ACCEPT
+-A INPUT -m state --state NEW -m tcp -p tcp --dport 10051 -j ACCEPT
+-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
```
ブラウザから http://zabbix-server/zabbix/ にアクセスします。
2.2 や 2.4 とはずいぶん雰囲気が変わりましたが、設定の流れはかわりません。
#### ノート
SElinux が有効になっていると、Zabbix サーバへのヘルスチェックを SElinux が阻止するために、Zabbix server is not running (サーバが停止している) という警告が出たままになります。
このとき audit.log を確認するとメッセージが出ています。
```/var/log/audit/audit.log
type=AVC msg=audit(1456943266.076:612): avc: denied { name_connect } for pid=15592 comm="httpd" dest=10051 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:zabbix_port_t:s0 tclass=tcp_socket
type=SYSCALL msg=audit(1456943266.076:612): arch=c000003e syscall=42 success=no exit=-13 a0=c a1=7fa7401687e8 a2=10 a3=7fa73bf6814c items=0 ppid=15529 pid=15592 auid=1003 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=1 comm="httpd" exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
```
httpd(php)からの通信を許可するようセキュリティーポリシーを変更するか、SELinux を無効(Permissive あるいは Disable) にすると解消します。
```
# setsebool -P httpd_can_network_connect 1
```
## まとめ
rpm パッケージと、対応する glibc や libmysqlclient、libcurl を解いて配置して、ダイナミックリンカに、必要なライブラリパスを指定してロードモジュールを呼び出すようにすれば、問題なく動作することがわかりました。
展開が必要な CentOS 7 のパッケージは以下の通りです。
* glibc-2.17-105.el7.x86_64.rpm
* libcurl-7.29.0-25.el7.centos.x86_64.rpm
* mariadb-libs-5.5.44-2.el7.centos.x86_64.rpm
* net-snmp-libs-5.7.2-24.el7.x86_64.rpm
Web GUI は、2.2 や 2.4 の時と同様の設定で対応可能です。
今回は、実行できる環境を、力業でつくりましたが、SRPM からも、spec ファイルを少し修正すればビルドできました。このことは、[CentOS6 で Zabbix 3.0 を動かす (自力ビルド編)] (http://qiita.com/items/b6b7adc914a3ca8ad0cb) で取り上げます。
# 補足
[PatchELF] (http://nixos.org/patchelf.html) を使用すると INTERP セクションを変更できるのでやってみました。
~~~
$ wget http://nixos.org/releases/patchelf/patchelf-0.8/patchelf-0.8.tar.bz2
$ tar xvfa patchelf-0.8.tar.bz2
~~~
~~~
$ ./configure --prefix=/usr/local
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking dependency style of gcc... gcc3
checking whether gcc and cc understand -c and -o together... yes
checking for g++... no
checking for c++... no
checking for gpp... no
checking for aCC... no
checking for CC... no
checking for cxx... no
checking for cc++... no
checking for cl.exe... no
checking for FCC... no
checking for KCC... no
checking for RCC... no
checking for xlC_r... no
checking for xlC... no
checking whether we are using the GNU C++ compiler... no
checking whether g++ accepts -g... no
checking dependency style of g++... none
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating tests/Makefile
config.status: creating patchelf.spec
config.status: executing depfiles commands
~~~
~~~
$ make
Making all in src
make[1]: Entering directory `/src/patchelf-0.8/src'
source='patchelf.cc' object='patchelf.o' libtool=no \
DEPDIR=.deps depmode=none /bin/sh ../build-aux/depcomp \
g++ -DPACKAGE_NAME=\"patchelf\" -DPACKAGE_TARNAME=\"patchelf\" -DPACKAGE_VERSION=\"0.8\" -DPACKAGE_STRING=\"patchelf\ 0.8\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"patchelf\" -DVERSION=\"0.8\" -I. -c -o patchelf.o patchelf.cc
../build-aux/depcomp: line 761: exec: g++: not found
make[1]: *** [patchelf.o] Error 127
make[1]: Leaving directory `/src/patchelf-0.8/src'
make: *** [all-recursive] Error 1
~~~
ビルドに g++ が必要でした。configure でエラーを出してよ。
~~~
$ sudo yum install gcc-c++
~~~
~~~
$ ./configure --prefix=/usr/local
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking dependency style of gcc... gcc3
checking whether gcc and cc understand -c and -o together... yes
checking for g++... g++
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking dependency style of g++... gcc3
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating tests/Makefile
config.status: creating patchelf.spec
config.status: executing depfiles commands
~~~
~~~
$ make
Making all in src
make[1]: Entering directory `/src/patchelf-0.8/src'
g++ -DPACKAGE_NAME=\"patchelf\" -DPACKAGE_TARNAME=\"patchelf\" -DPACKAGE_VERSION=\"0.8\" -DPACKAGE_STRING=\"patchelf\ 0.8\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"patchelf\" -DVERSION=\"0.8\" -I. -g -O2 -MT patchelf.o -MD -MP -MF .deps/patchelf.Tpo -c -o patchelf.o patchelf.cc
mv -f .deps/patchelf.Tpo .deps/patchelf.Po
g++ -g -O2 -o patchelf patchelf.o
make[1]: Leaving directory `/src/patchelf-0.8/src'
Making all in tests
make[1]: Entering directory `/src/patchelf-0.8/tests'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/src/patchelf-0.8/tests'
make[1]: Entering directory `/src/patchelf-0.8'
make[1]: Nothing to be done for `all-am'.
make[1]: Leaving directory `/src/patchelf-0.8'
~~~
~~~
$ sudo make install
Making install in src
make[1]: Entering directory `/src/patchelf-0.8/src'
make[2]: Entering directory `/src/patchelf-0.8/src'
/bin/mkdir -p '/usr/local/bin'
/usr/bin/install -c patchelf '/usr/local/bin'
make[2]: Nothing to be done for `install-data-am'.
make[2]: Leaving directory `/src/patchelf-0.8/src'
make[1]: Leaving directory `/src/patchelf-0.8/src'
Making install in tests
make[1]: Entering directory `/src/patchelf-0.8/tests'
make[2]: Entering directory `/src/patchelf-0.8/tests'
make[2]: Nothing to be done for `install-exec-am'.
make[2]: Nothing to be done for `install-data-am'.
make[2]: Leaving directory `/src/patchelf-0.8/tests'
make[1]: Leaving directory `/src/patchelf-0.8/tests'
make[1]: Entering directory `/src/patchelf-0.8'
make[2]: Entering directory `/src/patchelf-0.8'
make[2]: Nothing to be done for `install-exec-am'.
/bin/mkdir -p '/usr/local/share/doc/patchelf'
/usr/bin/install -c -m 644 README '/usr/local/share/doc/patchelf'
/bin/mkdir -p '/usr/local/share/man/man1'
/usr/bin/install -c -m 644 patchelf.1 '/usr/local/share/man/man1'
make[2]: Leaving directory `/src/patchelf-0.8'
make[1]: Leaving directory `/src/patchelf-0.8'
~~~
できた
~~~
$ /usr/local/bin/patchelf
syntax: /usr/local/bin/patchelf
[--set-interpreter FILENAME]
[--print-interpreter]
[--set-rpath RPATH]
[--shrink-rpath]
[--print-rpath]
[--force-rpath]
[--remove-needed LIBRARY]
[--debug]
[--version]
FILENAME
~~~
よし。
~~~
$ sudo /usr/local/bin/patchelf --set-interpreter /opt/zabbix/lib64/ld-linux-x86-64.so.2 --set-rpath /opt/zabbix/lib64:/opt/zabbix/usr/lib64:/opt/zabbix/usr/lib64/mysql /opt/zabbix/usr/bin/zabbix_get
~~~
~~~
$ /opt/zabbix/usr/bin/zabbix_get -h
usage:
zabbix_get -s host-name-or-IP [-p port-number] [-I IP-address] -k item-key
zabbix_get -s host-name-or-IP [-p port-number] [-I IP-address]
--tls-connect cert --tls-ca-file CA-file
[--tls-crl-file CRL-file] [--tls-agent-cert-issuer cert-issuer]
[--tls-agent-cert-subject cert-subject]
--tls-cert-file cert-file --tls-key-file key-file -k item-key
zabbix_get -s host-name-or-IP [-p port-number] [-I IP-address]
--tls-connect psk --tls-psk-identity PSK-identity
--tls-psk-file PSK-file -k item-key
zabbix_get -h
zabbix_get -V
Get data from Zabbix agent.
General options:
-s --host host-name-or-IP Specify host name or IP address of a host
-p --port port-number Specify port number of agent running on the host
(default: 10050)
-I --source-address IP-address Specify source IP address
-k --key item-key Specify key of the item to retrieve value for
-h --help Display this help message
-V --version Display version number
TLS connection options:
--tls-connect value How to connect to agent. Values:
unencrypted - connect without encryption
(default)
psk - connect using TLS and a pre-shared
key
cert - connect using TLS and a
certificate
--tls-ca-file CA-file Full pathname of a file containing the top-level
CA(s) certificates for peer certificate
verification
--tls-crl-file CRL-file Full pathname of a file containing revoked
certificates
--tls-agent-cert-issuer cert-issuer Allowed agent certificate issuer
--tls-agent-cert-subject cert-subject Allowed agent certificate subject
--tls-cert-file cert-file Full pathname of a file containing the certificate
or certificate chain
--tls-key-file key-file Full pathname of a file containing the private key
--tls-psk-identity PSK-identity Unique, case sensitive string used to
identify the pre-shared key
--tls-psk-file PSK-file Full pathname of a file containing the pre-shared
key
Example(s):
zabbix_get -s 127.0.0.1 -p 10050 -k "system.cpu.load[all,avg1]"
zabbix_get -s 127.0.0.1 -p 10050 -k "system.cpu.load[all,avg1]" \
--tls-connect cert --tls-ca-file /home/zabbix/zabbix_ca_file \
--tls-agent-cert-issuer \
"CN=Signing CA,OU=IT operations,O=Example Corp,DC=example,DC=com" \
--tls-agent-cert-subject \
"CN=server1,OU=IT operations,O=Example Corp,DC=example,DC=com" \
--tls-cert-file /home/zabbix/zabbix_get.crt \
--tls-key-file /home/zabbix/zabbix_get.key
zabbix_get -s 127.0.0.1 -p 10050 -k "system.cpu.load[all,avg1]" \
--tls-connect psk --tls-psk-identity "PSK ID Zabbix agentd" \
--tls-psk-file /home/zabbix/zabbix_agentd.psk
Report bugs to: <https://support.zabbix.com>
Zabbix home page: <http://www.zabbix.com>
Documentation: <https://www.zabbix.com/documentation>
~~~
これでラッパーも不要になります。
他のロードモジュールも書き換えます。
~~~
$ sudo /usr/local/bin/patchelf --set-interpreter /opt/zabbix/lib64/ld-linux-x86-64.so.2 --set-rpath /opt/zabbix/lib64:/opt/zabbix/usr/lib64:/opt/zabbix/usr/lib64/mysql /opt/zabbix/usr/bin/zabbix_sender
~~~
~~~
$ /opt/zabbix/usr/bin/zabbix_sender -h | head
usage:
zabbix_sender [-v] -z server [-p port] [-I IP-address] -s host -k key
-o value
zabbix_sender [-v] -z server [-p port] [-I IP-address] [-s host] [-T] [-r]
-i input-file
zabbix_sender [-v] -c config-file [-z server] [-p port] [-I IP-address]
[-s host] -k key -o value
zabbix_sender [-v] -c config-file [-z server] [-p port] [-I IP-address]
[-s host] [-T] [-r] -i input-file
zabbix_sender [-v] -z server [-p port] [-I IP-address] -s host
~~~
~~~
$ sudo /usr/local/bin/patchelf --set-interpreter /opt/zabbix/lib64/ld-linux-x86-64.so.2 --set-rpath /opt/zabbix/lib64:/opt/zabbix/usr/lib64:/opt/zabbix/usr/lib64/mysql /opt/zabbix/usr/sbin/zabbix_server_mysql
~~~
~~~
$ /opt/zabbix/usr/sbin/zabbix_server_mysql -h | head
usage:
zabbix_server_mysql [-c config-file]
zabbix_server_mysql [-c config-file] -R runtime-option
zabbix_server_mysql -h
zabbix_server_mysql -V
The core daemon of Zabbix software.
Options:
-c --config config-file Absolute path to the configuration file
~~~
~~~
$ sudo /usr/local/bin/patchelf --set-interpreter /opt/zabbix/lib64/ld-linux-x86-64.so.2 --set-rpath /opt/zabbix/lib64:/opt/zabbix/usr/lib64:/opt/zabbix/usr/lib64/mysql /opt/zabbix/usr/sbin/zabbix_agentd
~~~
~~~
$ /opt/zabbix/usr/sbin/zabbix_agentd -h | head
usage:
zabbix_agentd [-c config-file]
zabbix_agentd [-c config-file] -p
zabbix_agentd [-c config-file] -t item-key
zabbix_agentd [-c config-file] -R runtime-option
zabbix_agentd -h
zabbix_agentd -V
A Zabbix daemon for monitoring of various server parameters.
~~~
OK!