Zabbix ServerをECSで動かすのは厳しいと思った話
はじめに
ECSのFargateでZabbixの構築を試すことがあり、結論私は無理というか、EC2のほうがよいと感じたので、詳細を紹介します。
前提
- Dockerイメージは
zabbix/zabbix-server-mysql:alpine-7.4.0を使用 - DBはRDS for MySQLを使用
- ECSは(EC2ではなく)Fargateを使用
以下、ECSでうまくいかなかったことを紹介します。
Service ConnectだとZabbixのWebUIがServerを認識しない
画像のように、WebUIからはサーバーが起動していない旨の表示がされます。

が、サーバーのログは問題なく、またホストのエージェントとサーバーは通信できており、WebUIからは登録したホストのデータも閲覧できます。
確認したこと
セキュリティグループはもちろん確認しています。
WebUIのコンテナからService Connect経由でServerのTCP 10051ポートに接続できること
WebUIのコンテナの ZBX_SERVER_HOST は zabbix-server にしています。
# WebUIのコンテナに入る
# コンテナ名は zabbix-web にしています
$ aws --profile xxx ecs execute-command --cluster <cluster-name> --command "ash" --interactive --container zabbix-web --task <taskid>
# /etc/hosts を確認
# 127.255.0.1 zabbix-server があり、ServiceConnectを認識している
$ cat /etc/hosts
127.0.0.1 localhost
10.2.17.174 ip-10-2-17-174.ap-northeast-1.compute.internal
127.255.0.1 zabbix-server
2600:f0f0:0:0:0:0:0:1 zabbix-server
# WebUIのコンテナからServerへの通信を試す
# nc コマンドを入れる(zabbix server にはTCPで接続するので、HTTPリクエストを送るcurlでは試せません)
$ apk add --update-cache --no-cache iputils
# 確認
$ nc -vz zabbix-server 10051
zabbix-server (127.255.0.1:10051) open
WebUIのコンテナからNLB経由でServerのTCP 10051ポートに接続できること
Zabbix Serverの前段にNLBを配置し、NLBのドメインは zabbix-server.hoge.com とします。WebUIのコンテナの ZBX_SERVER_HOST は zabbix-server.hoge.com にしています。
同じくWebUIのコンテナに入り試しました。
$ apk add --update-cache --no-cache iputils
$ nc -vz zabbix-server.hoge.com 10051
zabbix-server.hoge.com (xxx.xxx.xxx.xxx:10051) open
他にもいろいろ試しましたが、私には解決が無理だったのでService Connectで接続することは諦めました。
なお、以下の記事だとサービスディスカバリでは接続できているようです。私は試しませんでしたが。
デプロイするとZabbixのHAでServerの起動が失敗する
WebUIとServerを同一ECSサービスにして、ZBX_SERVER_HOST を localhost にしたら、あっさりWebUIがServerを認識しました。
が、変更をしてローリングアップデートをすると、Serverで以下のエラーが起きてコンテナが落ちました。
HA manager has been paused
HA manager error: multiple servers have been started without configuring "HANodeName" parameter
HA manager has been stopped
Zabbix Server stopped. Zabbix 7.4.0 (revision xxxxxx).
上記は、Zabbix6.0から実装されたHA機能が原因です。
ZBX_HANODENAME をECSタスクごとにユニークな値にする
これを解決するには、Serverの環境変数 ZBX_HANODENAME をECSタスクごとにユニークな値にする必要があります。
ということで、以下のDockerfileとentrypointを作り、ECSタスクIDを使ってユニークな値にしました。
FROM zabbix/zabbix-server-mysql:alpine-7.4.0
COPY entrypoint.sh /usr/local/bin/my-entrypoint.sh
ENTRYPOINT ["/usr/local/bin/my-entrypoint.sh"]
# 明示的に指定しないとベースイメージのCMDが実行されなかった
CMD ["/usr/sbin/zabbix_server", "--foreground", "-c", "/etc/zabbix/zabbix_server.conf"]
#!/bin/sh
set -e
# ECSのタスクIDを抜き出す
# ECS_CONTAINER_METADATA_URI_V4 の最後は該当ECSタスクのタスクIDである
ECS_TASK_ID=$(echo "${ECS_CONTAINER_METADATA_URI_V4}" | sed -E 's#.*/v4/([^/]+)$#\1#')
echo "ECS_TASK_ID: ${ECS_TASK_ID}"
export ZBX_HANODENAME="zabbix-node-${ECS_TASK_ID}"
echo "ZBX_HANODENAME: ${ZBX_HANODENAME}"
# デバッグ用
echo "Starting original entrypoint with args: $@"
# https://github.com/zabbix/zabbix-docker/blob/7.4/Dockerfiles/server-mysql/alpine/Dockerfile
exec /usr/bin/docker-entrypoint.sh "$@"
エージェントの設定ファイルにノード名を登録するのが無理ゲーだった
上記でHAのエラーは起こらないようになりましたが、エージェントの設定ファイルの Server や ServerActive に、Serverのノード名( ZBX_HANODENAME )を登録する必要がありました、、、
https://www.zabbix.com/documentation/current/jp/manual/concepts/server/ha の Zabbixエージェントの設定 に記載があります。
デプロイするたびに設定ファイルを変えるのは運用上無理なので、私は諦めました。。。
ECSでHAの問題なくデプロイする方法
ローリングアップデートの設定で、最小実行タスクを0%、最大実行タスクを100%にすればデプロイできます。ECSタスクが一つ=Serverが一つしか起動しないため、ZBX_HANODENAME がユニークでなくともHAのエラーは起きません。
が、デプロイで7分ほどZabbix自体のダウンタウンが生まれます。監視するサービス自体が7分も止まるのはちょっと、、、と私は感じたので、やめました。
とはいえ、Serverの環境変数やスペックを変更することは、構築を終えたらそうは起きないでしょうから、ありかもしれません。
その他RDS for MySQLのアドバイス
データベース作成時に collate utf8mb4_bin を指定しましょう
データベース作成時は、以下のように collate に utf8mb4_bin を指定しましょう。
CREATE DATABASE IF NOT EXISTS zabbix CHARACTER SET utf8mb4 collate utf8mb4_bin;
RDSのデフォルト設定だと utf8mb4_0900_ai_ci になり、Serverが警告を出していました。
Serverの初回起動時はパラメータグループで log_bin_trust_function_creators を有効にしておきましょう
こういうったページに記載があるように、Zabbixの初期データを投入するには、MySQLは log_bin_trust_function_creators を有効にする必要があります。
なお、初期データはDockerのentrypointでの投入されています。詳細はこのあたりのコードをご覧ください。
- https://github.com/zabbix/zabbix-docker/blob/7.4/Dockerfiles/server-mysql/alpine/Dockerfile
- https://github.com/zabbix/zabbix-docker/blob/7.4/Dockerfiles/server-mysql/alpine/docker-entrypoint.sh
話を戻して、 log_bin_trust_function_creators を有効にしないと、初回のECSタスク起動時に以下のエラーが起きてコンテナが起動できません。
cannot use database "zabbix": its "users" table is empty (is this the Zabbix proxy database?)
そして、RDSでは、コマンドで log_bin_trust_function_creators を有効にできません。
-- デフォルトはOFF
mysql> SHOW GLOBAL VARIABLES LIKE 'log_bin_trust_function_creators';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | OFF |
+---------------------------------+-------+
1 row in set (0.04 sec)
-- 管理者ユーザーでも有効にできない
mysql> SET GLOBAL log_bin_trust_function_creators = 1;
ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation
ということで log_bin_trust_function_creators は、パラメータグループで有効にします。
- RDSの新規パラメータグループを作成
- RDSのMySQLのバージョンに合わせる
- 作成後に、パラメータグループの編集画面で
log_bin_trust_function_creatorsを検索し、値を1にする - RDSのパラメータグループを作成したものに変更する
- RDSを再起動する
一度ECSタスクが起動したら、もとのパラメータグループに戻しても構いません。
おわりに
EC2で構築し直したらあっさり動きました。おわり。
Discussion