Zabbix AgentによるDockerコンテナ上のMySQLサーバー監視

# 背景

Dockerコンテナで構築したMySQLサーバーをZabbix Agentでリモート監視しようと思ったら意外とハマったのでメモ書きしてみました。

# 動作環境

基本的には以下の投稿にあるZabbix Server構築に準じます。

- [DockerでZabbix ServerとZabbix Proxyを構築してみた - Qiita ](https://qiita.com/ohhara_shiojiri/items/90e692c19af760ab4e53)

またZabbix Agentについても以下の投稿に準じます。

- [Docker Zabbix AgentでMySQL監視 - Qiita ](https://qiita.com/ohhara_shiojiri/items/e51f14738a3c22d1621b)

# Zabbix AgentのMySQLサーバー監視の大まかな仕組み

基本的なおさらいとして以下の仕組みで動作します。

- Zabbix Agentから特定のMySQLコマンドを実行
- 実行した結果をZabbix Agent経由でZabbix Serverに送信

通常のホスト側にインストールされたMySQLの場合は特に問題ありませんがDockerコンテナ上のMySQLサーバー場合は以下の問題があります。

- Zabbix Agentサービスはホスト側か？コンテナ側か？
- MySQLコマンドの実行はホスト側か？コンテナ側か？

この中の組み合わせで出来なかったのが、

- Zabbix Agentはホスト側
- MySQLコマンド実行はホスト側

MySQLのサービスポート(3306)に対してコマンドを実行しますがプロトコルバージョンのエラーで結果が取得出来ません。
ホスト側からは出来ないのでMySQLコマンドもDockerコンテナ上で実行させます。
必要なMySQLコマンドはMySQLサーバーのコンテナに含まれているのでDockerコマンド経由で実行させます。


## MySQLサーバーに監視用アカウントの作成

Zabbix Agentで監視する為に専用のアカウント「zbx_monitor」を作成します。

### アカウント作成

アカウントを新規作成する為に「SQLコマンド」から以下のsqlコマンドを実行します。
またその際にパスワード「\<password\>」は適切なモノを設定します。

```
CREATE USER 'zbx_monitor'@'%' IDENTIFIED BY '<password>';
GRANT REPLICATION CLIENT,PROCESS,SHOW DATABASES,SHOW VIEW ON *.* TO 'zbx_monitor'@'%';
```

これでMySQLサーバー側の準備は完了


## Zabbix Agentの設定

### ホスト側にZabbix Agentをインストールします。

- Ubuntu Server 20.04LTSの場合

```
$ wget https://repo.zabbix.com/zabbix/5.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_5.0-1+focal_all.deb
$ sudo dpkg -i zabbix-release_5.0-1+focal_all.deb
$ sudo apt update && sudo apt upgrade
$ sudo apt install zabbix-agent
$ sudo systemctl start zabbix-agent
$ zabbix_agentd -V
zabbix_agentd (daemon) (Zabbix) 5.0.25
```

Zabbix Agentの設定ファイルにリモートコマンドの実行設定を有効化します。

```:/etc/zabbix/zabbix_agentd.conf
AllowKey=system.run[*]
```

Zabbix Agentを再起動

```
$ sudo systemctl restart zabbix-agent
$ sudo systemctl enable zabbix-agent
```

### dockerコマンドの実行権限をzabbixアカウントに付与します。

```
$ sudo gpasswd -a zabbix docker
```

### MySQL監視プラグインファイル設定

Zabbix AgentでMySQLを監視するテンプレート用のプラグインファイル設定は以下の公式ファイルを参照します。

- [zabbix/userparameter_mysql.conf at master ・ zabbix/zabbix Github](https://github.com/zabbix/zabbix/blob/master/conf/zabbix_agentd/userparameter_mysql.conf)

特定のMySQLコマンドを実行する設定ですがサンプル内容をDockerコマンド経由で実行するように修正します。

```:/etc/zabbix/zabbix_agentd.d/userparameter_mysql.conf
#template_db_mysql.conf created by Zabbix for "Template DB MySQL" and Zabbix 4.2
#For OS Linux: You need create .my.cnf in zabbix-agent home directory (/var/lib/zabbix by default) 
#For OS Windows: You need add PATH to mysql and mysqladmin and create my.cnf in %WINDIR%\my.cnf,C:\my.cnf,BASEDIR\my.cnf https://dev.mysql.com/doc/refman/5.7/en/option-files.html
#The file must have three strings:
#[client]
#user=zbx_monitor
#password=<password>
#
UserParameter=mysql.ping[*],docker exec "$1" /usr/bin/mysqladmin --defaults-extra-file=/var/lib/mysql/my.cnf -s ping
UserParameter=mysql.get_status_variables[*],docker exec "$1" /usr/bin/mysql --defaults-extra-file=/var/lib/mysql/my.cnf -sNX -e "show global status"
UserParameter=mysql.version[*],docker exec "$1" /usr/bin/mysqladmin --defaults-extra-file=/var/lib/mysql/my.cnf -s version
UserParameter=mysql.db.discovery[*],docker exec "$1" /usr/bin/mysql --defaults-extra-file=/var/lib/mysql/my.cnf -sN -e "show databases"
UserParameter=mysql.dbsize[*],docker exec "$1" /usr/bin/mysql --defaults-extra-file=/var/lib/mysql/my.cnf -sN -e "SELECT SUM(DATA_LENGTH + INDEX_LENGTH) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='$3'"
UserParameter=mysql.replication.discovery[*],docker exec "$1" /usr/bin/mysql --defaults-extra-file=/var/lib/mysql/my.cnf -sNX -e "show slave status"
UserParameter=mysql.slave_status[*],docker exec "$1" /usr/bin/mysql --defaults-extra-file=/var/lib/mysql/my.cnf -sNX -e "show slave status"
```

各行のコマンド設定では基本的に、

- Dockerコマンドは「docker exec」で実行され
- 特定のMySQLコマンドはMySQLサーバーのコンテナ「mysql-server」サービス名を指定($1)
- MySQLサーバーのアカウント情報などの環境変数は「/var/lib/mysql/my.cnf」に記載して読み込む

設定が完了したらZabbix Agentを再起動させます。

```
$ sudo systemctl restart zabbix-agent
```

## MySQL監視ホスト設定

Zabbix Serverの設定画面にてホスト設定する際にテンプレート「Template DB MySQL by Zabbix agent」を追加します。
また、ホストマクロにて「{\\$MYSQL.HOST}」にMySQLサーバーのコンテナ名「mysql-server」を指定します。
これでリモートホスト側のDockerコンテナ上のMySQLサーバーが監視出来ます。