zabbixお引越し

皆さんこんにちは、Infrabbitです。

AWS Organizationsである程度アカウントを整理してはいるものの、発足初期に作成したアカウントが命名規則を外れて残存していて、どうにかしたいな、とずっと思っていましたがなかなか手を付けるに至っていませんでした。

RDSがあっちにもこっちにもあるような状態になってしまっており、コスト的にもよろしくありません。大きなプロジェクトでプロジェクトごとにDBがいるのが当然です、というようなものでもなく、そもそも軽量コンパクトな世界ですので、なんとかまとめてしまっておきたい。
というかInfrabbitのOrganizationsはプロジェクトを基軸に共通コンポーネントとステージ毎のコンポーネントを取り扱えるようにアカウント設計しているので、単一アカウントに全部ぶち込まれている初期アカウントは何かとルールからも外れています。

とりあえずいくつかコンポーネントはあるのですが、まずは監視機構であるZabbixを移設することにしました。ついでに、いくつかのコンポーネントの統合により、将来的にコスト減となりますので、Zabbixの耐障害性を引き上げます。

基本設計はもうDockbixで済ませてしまいます。というか移行元もそうですしね。カスタマイズは極力避け、DockerHubからイメージをそのまま持ち込むことを前提にします。

そのうえで、Web FrontendとZabbix Serverも分離してしまいます。できれば、これらはCloudMapでサービスディスカバリにぶち込んでしまいたいわけですが、ALBで処理できるFrontendはともかく、Server側は10051ポートのTCPでおしゃべりしなければなりません。ALB使えない。のでZabbix用にNLBを引っ張り出してきます。

Serverはさすがにタスク1、最大ヘルス100でやらないとコンフリクト起こすのでダメですが、FrontEndはいくら増えても特に困りません。とりあえずはタスク1ですが、こちらはそのうちApplication Scalingを当て込むことにしましょう(そのために動的ポート構成です)。

Zabbix Server本体だけなら10051だけですが、まあやっぱり監視機構なので162/UDPのSNMP Trapや10052のJMXも動かしておきたい。全部バラバラにしてしまえばNLBとターゲットグループ、そしてサービスディスカバリの組み合わせでSRVレコード利用の動的ポート構成も組めるのでしょうが、さすがにそこまで分割するのもなぁ、ということと、ローカルのフロントエンド側にホストとして登録するときにSRVレコードだと前処理がないといけません。zabbix.conf.phpのパラメータにget_dns_record埋め込んで、パースされた配列からIPとポート吐き出せばいいんですが、もちろんそんなことDockbixのEnvironmentでできることではなく、Dockerfile以下の書き換えが必須です。

DockbixのDockerfile、めんどくさいから書き換えたくないんです。アップデートにも対応しないといけなくなるので。

ということでNLBの外側ポートと静的にバインドして、サービスディスカバリをAレコードに集めます。クラウドフレームでできることはクラウドフレームでやります。コスト的側面に少しダメージが出ますが、呑める範囲ならそれでいいです。そういう割り切りしていくのがクラウドでは大事です。やりたいこと、実現したいこと、可能なこと、それぞれありますが、可能だからと言って無駄に作りこむとあとで泣くのは自分です。自分が泣くだけでいいならいいんですが、クライアントまで泣かせたら目も当てられません。

そもそもこんなポート、SNMP Trapはともかく他はZabbixくらいしか使わないでしょうし、NLBに静的マップしたところで困りはしません。

いやー、コンテナに複数ロードバランサー充てられるようになったのはほんと助かりますね。

ターゲットグループ作成においては、注意点が一つ。162/UDPを作っても、ヘルスチェックがTCPです。というかUDPをヘルスチェックするって意味わかんないですしね。だってお返事パケット何も帰ってこないし。なので、UDPのヘルスチェックは10051/TCPあたりを見るようにしておきましょう。Disableにはできないので、ここを変えておかないとヘルスチェック失敗でコンテナが殺され続けます。

Frontend側は素直なものです。80番にホスト名ルーティングさせて適当なサブドメインを与えます。

次に、ZabbixServerが外に出ていくときのパケット。

HTTP ProxyはOrganizationの構成時に自動構成して作る(yumやapt-getで要るからね!)んですが、Squid立てて動いてるProxyでいわゆるNATインスタンスではありません。そもそも立っている場所がVPCピアリングの先であり、NATしてはいけません。

なので、NATインスタンスを立てる必要がありますが、正直インスタンス増やして面倒ごとを増やしたくありません。NAT Gatewayにしましょう、ちょっとお高いですが。さすがにOne NAT per AZ/Subnetはやりたくない(高い)ので、Singleです。そのうちもう一台立てておけばとりあえず冗長するのでそれで充分。NATのEIPをRoute53のAレコードに割り当てて置き、zabbix agentにホスト名で書けるようにしておきます。

これでサーバ側の主要な構成は終わりです。あとは現在のZabbixからDMSでデータをフルロード&継続レプリケートしておきます。切り替え時にある程度ロスするのはしょうがないとして、まあ一応過去データは持ってきたいですから。データは大事ですしね。いずれ消えるとは言え。

さて、zabbix-agent側にはServer/Server ActiveにNAT GatewayとNLBのアドレスを放り込むことになります。
ServerはZabbixからの通信を受けるので、NAT、ServerActiveはAgentからの発呼なのでNLBです。こちらは設定前にDockbixのコンテナごと停止しておきます。Frontendは動いていてもいいといえばいいんですが、データレプリケートしているのでメール発呼とかダブルで行ってしまいますし、フロントエンドも止めておきます。データ見えること確認できてればいい。
こちらはさっさと反映したらAgentは再起動して反映しておいて構いません。コンテナさえ止まっていれば問題ありません。

で、DMSは外部キー制約や追加のインデックスをコピーしないので、これらをいれてあげないといけません。docbixの中にもありますし、zabbixのパッケージ引っ張ってきてもいいんですが、dockbixの中から持ってきました。コンテナ内の/usr/local/src/zabbix/databaseあたりだった気がします。schema.sqlの中身ですね。

Create Tableとかいらないんで、grep INDEXで引っ張り出したINDEXと、grep ALTERで引き抜いたALTER文(外部キー制約記述)を抜き取り、Auroraに垂れ流します。ALTERあるのとINDEXで少し時間を覚悟しておきます。これで、Zabbixの最新データ表示が速くなります。っていうかやらないとまず表示がタイムアウトします。まあそりゃインデックスなかったらうん千万とかあるレコードの総なめになりますしね、最新データ表示。RDSめっちゃ強くしててもなかなかの無理ゲーです。

さて、ここまでやるとInfrabbitではこんな構成になっています。

シンプルなもんですね。まあOrganizationsとTerraformのスタックで他にごてごてといろいろくっついていたりはするので、これだけ、ってわけではないのですが。

インデックスもつき、Alterも終わればもうあとは楽勝です。DMSをカットし、コンテナを起動します。

あたらしく起動したZabbixがAgentからのデータを受信していることを確認出来たら、すきなタイミングで旧Zabbixから新Zabbixへ乗り換えるだけです。その間は並行運用の状態ですので、アラート飛ばしたくないほうのZabbixのメディアを無効化しておくだけですね。これ以降はもうZabbixの設定操作です。

手間暇はそれなりにありますが、実際のところそんなに大変なものでもありません。要するに冗長化したAct-StandByのZabbixを作っているだけですね。監視系統のAct-Actは面倒くさい(本音がぼろぼろもれますね)のですが、Act-Stbなら楽なもんです。

とはいえ、Prometheusも動かし始めているので、Zabbixいつまで使うんだ、という話もあったりはするのですが、なんだかんだで使いやすいんですよね、Zabbix。Log型をElasticSearchに入れれるようにもなったので、正直そこまでパワー不足感はないです。まあホストを基軸にするせいでマイクロサービスと相性あまりよくないんですが。ホストディスカバリがもうちょっと良くなってくるとそこまできにならなくなるんじゃないかな、と思ってたりもします。

まあでもやっぱりサービスディスカバリも統合されてるPrometheusはなんだかんだと強いなぁ、と思いますが、鶏捌くのに牛刀、って感はあるんですよね、小規模なシステムだと。Zabbixもたいがい牛刀ではあるんですが。ぶっちゃけCloudWatchである程度事足りたりはします。

なお、DockbixではZBX_GRAPH_FONT_NAME=ipagpをセットしておけば日本語グラフのフォント直してくれる、ってことになっていますが、どう見てもphpのconfigだけ直しているのでフォントは入っていません。本当にありがとうございました。入れとけやwwwww

うちはGrafana使うんでどうでもいいですけれど、Dockbix直して使う、もしたくないので。

どうしてもって人はFROM: monitoringartist/dockbix:latestでRUN yum insallでも突っ込んでフォント入れればいいんじゃないかと思います。現行Latestは4.0.19だし、5系までもうアップデートもないでしょうし。というか4年放置していますし、Dockbixも5系にする気あるんだかないんだか…。まあ、5.0のLTSはまだ昨年リリース品ですし、何かやってるのかもしれないですが。

zabbix冗長化だとそれぞれに独立DB持たせて、みたいな話が前提なので、AWSでどうその独立DBをうまく作るか、というところで何かの参考になればなぁ、と思います。