🦔

Zabbix ServerをECSで動かすのは厳しいと思った話

に公開

はじめに

ECSのFargateでZabbixの構築を試すことがあり、結論私は無理というか、EC2のほうがよいと感じたので、詳細を紹介します。

前提

以下、ECSでうまくいかなかったことを紹介します。

Service ConnectだとZabbixのWebUIがServerを認識しない

画像のように、WebUIからはサーバーが起動していない旨の表示がされます。

が、サーバーのログは問題なく、またホストのエージェントとサーバーは通信できており、WebUIからは登録したホストのデータも閲覧できます。

確認したこと

セキュリティグループはもちろん確認しています。

WebUIのコンテナからService Connect経由でServerのTCP 10051ポートに接続できること

WebUIのコンテナの ZBX_SERVER_HOSTzabbix-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_HOSTzabbix-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で接続することは諦めました。

なお、以下の記事だとサービスディスカバリでは接続できているようです。私は試しませんでしたが。

https://qiita.com/ctlike/items/ca678cdbe1967b84af71

デプロイするとZabbixのHAでServerの起動が失敗する

WebUIとServerを同一ECSサービスにして、ZBX_SERVER_HOSTlocalhost にしたら、あっさり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機能が原因です。

https://www.zabbix.com/documentation/current/jp/manual/concepts/server/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"]
entrypoint.sh
#!/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のエラーは起こらないようになりましたが、エージェントの設定ファイルの ServerServerActive に、Serverのノード名( ZBX_HANODENAME )を登録する必要がありました、、、

https://www.zabbix.com/documentation/current/jp/manual/concepts/server/haZabbixエージェントの設定 に記載があります。

デプロイするたびに設定ファイルを変えるのは運用上無理なので、私は諦めました。。。

ECSでHAの問題なくデプロイする方法

ローリングアップデートの設定で、最小実行タスクを0%、最大実行タスクを100%にすればデプロイできます。ECSタスクが一つ=Serverが一つしか起動しないため、ZBX_HANODENAME がユニークでなくともHAのエラーは起きません。

が、デプロイで7分ほどZabbix自体のダウンタウンが生まれます。監視するサービス自体が7分も止まるのはちょっと、、、と私は感じたので、やめました。

とはいえ、Serverの環境変数やスペックを変更することは、構築を終えたらそうは起きないでしょうから、ありかもしれません。

その他RDS for MySQLのアドバイス

データベース作成時に collate utf8mb4_bin を指定しましょう

データベース作成時は、以下のように collateutf8mb4_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での投入されています。詳細はこのあたりのコードをご覧ください。

話を戻して、 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 は、パラメータグループで有効にします。

  1. RDSの新規パラメータグループを作成
    • RDSのMySQLのバージョンに合わせる
  2. 作成後に、パラメータグループの編集画面で log_bin_trust_function_creators を検索し、値を1にする
  3. RDSのパラメータグループを作成したものに変更する
  4. RDSを再起動する

一度ECSタスクが起動したら、もとのパラメータグループに戻しても構いません。

おわりに

EC2で構築し直したらあっさり動きました。おわり。

Discussion