概要
こんにちは、キュービックでSREをやっているYuhta28です。キュービック内のテック技術について発信します。
前回の記事で弊社のモニタリング運用をDatadogに集約したことを紹介しました。OpenSearch時代に活用していた集約サーバーのFluentdの設定ファイルをDatadogに向き先を変えて、さらにDatadogエージェントをインストールして、集約サーバーから弊社メディアへの外形監視とDBのパフォーマンスモニタリングを実施しています。
アーキテクチャ図
課題
ただ単なる集約サーバーだったものにDatadogエージェントを導入して、外形監視も担うとなるとサーバー運用が必要となり、負荷が生じてきました。
そこでEC2ではなく、ECSに移行してDatadogモニタリングクラスターを構築してみることにしました。
新アーキテクチャ図
FargateのアーキテクチャはFluentdのECSサービスとDatadogのECSサービスを組み合わせたクラスタ構成になります。
Fluentdコンテナ構築
図では省略していますが、FluentdのECSに転送する際にメディアサーバー群とFargateの間にNLBを置いています。これによってIPアドレス単位で集約先を指定したものをNLBのドメイン単位で宛先を指定することが可能になります。
# fluentd設定ファイル(メディアサーバー側) <source> @type tail path /var/log/nginx/access.log format ltsv time_format %d/%b/%Y:%H:%M:%S %z types size:integer,status:integer,upstream_response_time:float,time:time,response_time:float tag nginx </source> <match nginx> @type forward <server> # host XXX.XXX.XXX.XXX #IPアドレス host XXXXXXXXXXXXXXX.elb.ap-northeast-1.amazonaws.com port XXXXXXX </server> </match>
# fluentd設定ファイル(fluentd ECS側) <source> @type forward port 24224 bind 0.0.0.0 </source> <match nginx> @type copy <store> @type datadog @id nginx-access api_key "#{ENV['ddapikey']}" #fluentd設定ファイル内の環境変数設定 include_tag_key true tag_key @log_name dd_source 'nginx' service 'access-log' </store> </match>
幸いなことにFluentdのDockerイメージは公式がDocker Hubに用意していました。後は先のfluentd設定ファイルをコンテナにコピーするDockerfileを書いてECSにデプロイします。
# Fluentdコンテナ FROM fluent/fluentd:v1.15.3-debian-1.0 USER root RUN buildDeps="sudo make gcc g++ libc-dev" \ && apt-get update && apt-get upgrade -y \ && apt-get install -y --no-install-recommends $buildDeps \ && sudo gem install fluent-plugin-datadog \ && sudo gem sources --clear-all \ && SUDO_FORCE_REMOVE=yes \ apt-get purge -y --auto-remove \ -o APT::AutoRemove::RecommendsImportant=false \ $buildDeps \ && rm -rf /var/lib/apt/lists/* \ && rm -rf /tmp/* /var/tmp/* /usr/lib/ruby/gems/*/cache/*.gem COPY fluentd/etc/fluent.conf /fluentd/etc/ USER fluent
ちなみにFluentdの設定ファイルにDatadogのAPIキーを埋め込む場合、ECSタスク定義から環境変数を設定しますが、認証情報系は直打ちせずにSecrets Manager*1やSystems Managerのパラメータストア*2から呼び出すようにしておいたほうが安全です。
"secrets": [ { "name": "ddapikey", "valueFrom": "arn:aws:ssm:ap-northeast-1:XXXXXXXXXXXX:parameter/datadog/apikey" } ]
Datadogエージェントコンテナ構築
Datadogエージェントも公式がコンテナイメージを配布しているので、必要な環境変数をセットしてECSサービスに組み込みました。
# Datadogエージェントコンテナ FROM public.ecr.aws/datadog/agent:latest USER dd-agent RUN mkdir /etc/datadog-agent/secrets # HTTPチェック設定ファイル配置 COPY etc/datadog-agent/conf.d/http_check.d/conf.yaml /etc/datadog-agent/conf.d/http_check.d/conf.yaml # DB Application Performance Monitoring設定ファイル&DBパスワード情報配置(db_password情報は暗号化) COPY etc/datadog-agent/conf.d/mysql.d/conf.yaml /etc/datadog-agent/conf.d/mysql.d/conf.yaml COPY etc/datadog-agent/secrets/db_password /etc/datadog-agent/secrets/db_password
http_check.d/conf.yaml
の中に監視したいメディアの情報を記載しています。
# コーポレートサイト - name: cuebic website url: https://cuebic.co.jp/ timeout: 5 tags: - "env:prd"
実は当初DatadogエージェントのコンテナはApp Runner*3を使って実装してみようと思いました。App RunnerならECRにコンテナイメージをセットして指定するだけで自動デプロイの実装までマネージドにやってくれるので、新規メディアへの外形監視作業も先述のHTTPチェックの設定ファイルを更新し、ECRにプッシュするだけで自動的に監視されて運用が楽になるからだと考えました。
ところがApp RunnerではDatadogエージェントのようなコンテナからのプッシュ型通信とは相性が悪くうまくいかないことが判明しました。このあたりの詳細はこちらのブログを御覧ください。
zenn.dev
妥協案としては自前でGitHub Actions☓ECSの自動デプロイ基盤を実装することで解決しました。ECSへデプロイしてくれるGitHub Actionsワークフローファイルは公式が用意してくれているのでそちらを活用します。*4
GitHub Actions☓ECS自動デプロイアーキテクチャ図
これでHTTPチェック設定ファイルに新規メディア情報を記載してGitHubリポジトリにプッシュすることでGitHub Actionsが起動し、リポジトリ内のDockerfileをビルド、プッシュしてECRに格納されます。その後ECRのイメージを基にFargateへデプロイすることでECSによるDatadogモニタリングクラスタ基盤が構築できます。
所感
EC2上で動かしていたDatadog監視をECSへ移行できました。ガッツリとECSクラスタをイチから構築するのは今回が初めてで、セキュリティ設定ミスやネットワーク設定の不備など不慣れから生じるミスが多かったですが、最終的に実現したいことができてよかったと思います。App Runnerを使った挑戦は残念ながらできませんでしたが、違う機会で再挑戦してみようと思います。
*1:https://aws.amazon.com/jp/secrets-manager/
*2:https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-parameter-store.html
*3:https://aws.amazon.com/jp/apprunner/
*4:https://docs.github.com/en/actions/deployment/deploying-to-your-cloud-provider/deploying-to-amazon-elastic-container-service