Docker Zabbix AgentでMySQL監視

# 背景

DockerでZabbix Serverを構築した際に自身のデータベースを監視出来るようにZabbix Agentを再構成してみました。

ここではZabbix Server専用のMySQLサーバーを監視する場合の話ですが、リモートホスト側の個別のDockerコンテナ上のMySQLサーバーを監視する場合は以下の別の投稿を参考にしてください。

- [Zabbix AgentによるDockerコンテナ上のMySQLサーバー監視 - Qiita ](https://qiita.com/ohhara_shiojiri/items/8d55e7646682ff412303)

# 動作環境

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

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

# DockerコンテナのZabbix AgentによるMySQL監視設定

Dockerコンテナで稼働しているZabbix AgentとMySQLサーバーはDockerコンテナの内部ネットワークで稼働しています。
いずれもホスト側のネットワークからはサービスポートが開放されていない点を注意しましょう。
外部開放されていれば通常の方法で監視出来ますからね。

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

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

### adminerコンテナの作成

MySQLサーバーのDockerコンテナはサービスポートがホスト側に開放されていないので同じDockerネットワーク上にadminerコンテナを用意します。
Zabbix ServerのDocker Compose設定ファイルにadminerコンテナ設定を追記します。

```:compose.yaml
 adminer:
  image: adminer
  ports:
    - "8080:8080"
  depends_on:
   - mysql-server
  networks:
   zbx_net_backend:
     aliases:
      - zabbix-adminer
   zbx_net_frontend:
```

docker composeの起動

```
$ docker compose up -d
```

サービスポート番号「8080」を指定してWebブラウザで開くとadminer管理画面が利用出来ます。

### アカウント作成

アカウントを新規作成する為にadminer管理画面からMySQLサーバーにログインします。
その際に管理権限のあるrootアカウントが必要になります。
標準では以下のファイルに記述されてZabbix Serverでは設定されています。

- env_vars/.MYSQL_ROOT_PASSWORD
- env_vars/.MYSQL_ROOT_USER

adminer管理画面からMySQLサーバーにrootアカウントでmysqlのデータベースを選択してログインします。ホスト名はMySQLのコンテナ名「mysql-server」です。
アカウントを新規作成する為に「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の設定

### 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)

ホームディレクトリを追記指定する必要があります。Linuxの場合は「HOME=/var/lib/zabbix」を各行に追記します。

```:zbx_env/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[*],HOME=/var/lib/zabbix mysqladmin -h"$1" -P"$2" ping
UserParameter=mysql.get_status_variables[*],HOME=/var/lib/zabbix mysql -h"$1" -P"$2" -sNX -e "show global status"
UserParameter=mysql.version[*],HOME=/var/lib/zabbix mysqladmin -h"$1" -P"$2" -s version
UserParameter=mysql.db.discovery[*],HOME=/var/lib/zabbix mysql -h"$1" -P"$2" -sN -e "show databases"
UserParameter=mysql.dbsize[*],HOME=/var/lib/zabbix mysql -h"$1" -P"$2" -sN -e "SELECT SUM(DATA_LENGTH + INDEX_LENGTH) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='$3'"
UserParameter=mysql.replication.discovery[*],HOME=/var/lib/zabbix mysql -h"$1" -P"$2" -sNX -e "show slave status"
UserParameter=mysql.slave_status[*],HOME=/var/lib/zabbix mysql -h"$1" -P"$2" -sNX -e "show slave status"
```

なお参考までに変数はテンプレートのホストマクロで\\$1は「{\\$MYSQL.HOST}」、\\$2は「{\\$MYSQL.PORT}」に対応しています。

### MySQLの認証情報設定ファイル

Zabbix AgentからMySQLサーバーにログインする為の認証情報を以下のファイルに設定します。パスワード「\<password\>」は適切なモノを設定します。

```:env_vars/.my.cnf
[client]
user='zbx_monitor'
password='<password>'
```

### Zabbix Agentコンテナの再構成

公式のZabbix Agentコンテナイメージには、mysqlクライアント用の各コマンドが含まれていません。
Dockerfileを修正してZabbix Agentコンテナイメージをビルドして再構成します。

#### Dockerfileの追加修正

まずはDockerfileをバックアップしておきます。

```
$ cp Dockerfiles/agent/alpine/Dockerfile Dockerfiles/agent/alpine/Dockerfile.bak
```

以下のように追加編集します。

- Zabbix 5.0の場合

```diff_xml:Dockerfiles/agent/alpine/Dockerfile
ARG MAJOR_VERSION=5.0
+ARG ZBX_VERSION=${MAJOR_VERSION}.25 # zabbixのマイナーバージョン指定修正
+ARG BUILD_BASE_IMAGE=zabbix/zabbix-build-mysql:alpine-${ZBX_VERSION} # zabbixプロジェクト名「zabbix/」を追加修正

RUN set -eux && \
    INSTALL_PKGS="tini \
            bash \
            tzdata \
            coreutils \
            iputils \
            pcre \
+            mariadb-client \ # 追加
+            mariadb-connector-c \ # 追加
            libcurl \
            libmodbus \
            libldap" && \
```

予め必要なDocker Imageを用意しておきます。

```
$ docker pull alpine:3.14
$ docker pull zabbix/zabbix-build-mysql:alpine-5.0.25
```

Docker Composeの設定ファイルをビルド出来るように修正します。
またZabbix Agentコンテナ側から先程用意したホスト側のMySQLの認証情報設定ファイル「.my.cnf」をマウントする設定も追加します。

```diff_xml:compose.yaml
services:
 zabbix-agent:
+  container_name: zabbix-agent-mysql
+  build: ./Dockerfiles/agent/alpine
-  #image: zabbix/zabbix-agent:alpine-5.0-latest

  volumes:
+   - ./env_vars/.my.cnf:/var/lib/zabbix/.my.cnf:ro
```

- Zabbix 6.0の場合

```diff_xml:Dockerfiles/agent/alpine/Dockerfile
ARG MAJOR_VERSION=6.0
+ARG ZBX_VERSION=${MAJOR_VERSION}.6 # zabbixのマイナーバージョン指定修正
+ARG BUILD_BASE_IMAGE=zabbix/zabbix-build-mysql:alpine-${ZBX_VERSION} # zabbixプロジェクト名「zabbix/」を追加修正

RUN set -eux && \
    INSTALL_PKGS="tini \
            bash \
            tzdata \
            coreutils \
            iputils \
            pcre \
+            mariadb-client \ # 追加
+            mariadb-connector-c \ # 追加
            libcurl \
            libmodbus \
            libldap" && \
```

予め必要なDocker Imageを用意しておきます。

```
$ docker pull alpine:3.16
$ docker pull zabbix/zabbix-build-mysql:alpine-6.0.6
```

Docker Composeの設定ファイルをビルド出来るように修正します。
またZabbix Agentコンテナ側から先程用意したホスト側のMySQLの認証情報設定ファイル「.my.cnf」をマウントする設定も追加します。

```diff_xml:compose.yaml
services:
 zabbix-agent:
+  container_name: zabbix-agent-mysql
+  build: ./Dockerfiles/agent/alpine
-  #image: zabbix/zabbix-agent:alpine-6.0-latest

  volumes:
+   - ./env_vars/.my.cnf:/var/lib/zabbix/.my.cnf:ro
```

- Dockerイメージのビルド作成

これで準備が出来たのでDocker Composeでビルドして新しいZabbix AgentのDockerイメージを作成します。

```
$ docker compose build
```

無事に新しいZabbix AgentのDockerイメージが作成出来たらZabbix Serverを再構成します。

```
$ docker compose up -d
$ docker compose ps
NAME                                     COMMAND                  SERVICE                  STATUS              PORTS
zabbix-agent-mysql                       "/sbin/tini -- /usr/…"   zabbix-agent             running
```

新しいZabbix Agentイメージから新しいZabbix Agentコンテナが稼働します。

## MySQL監視ホスト設定

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