レガシーだったログ管理基盤を半年かけてリニューアルした話
こんにちは、インフラ基盤グループの松下です。
今回は、7月から取り組んできたログの管理基盤をリニューアルした話を紹介したいと思います。
背景
弊社では ECS on EC2, OKE(Oracle Cloud Infrastructure Container Engine for Kubernetes) を用いてサービスを運用しており、それぞれの環境下で Amazon Elastic File System(以降: EFS)、 Oracle Cloud Infrastructure File Storage Service(以降: FSS) にそれぞれログを出力していました。
その際、出力先の EFS, FSS を別の EC2 インスタンスでマウントし、 Splunk へログデータを送信する Forwarder を起動することで Splunk Cloud でのログの閲覧を実現していました。
また、長期保存用として、圧縮と Amazon S3 へのアップロードに Jenkins + Ansible 用いていました。
ただし、データ基盤チームが扱うデータは別であり、 GCS へアップロード後、 trocco を用いて BigQuery にインサートを行う必要がありました。そのため、データ基盤のデータを扱う Ansible が別で存在しており、さらにそれは Google Cloud の Compute Engine 内にあったため、 Ansible から Compute Engine へ SSH を行い、内部の Ansible を実行するというようなつらい状態となっておりました。
以前からこの構成で運用を行うにあたって、大まかに以下のような課題を抱えておりました。
- データ基盤チームが利用する BigQuery へのデータの挿入までのアーキテクチャが複雑で、問題が発生した場合の調査に時間がかかる
- Jenkins, Ansible を頻繁にメンテするわけではないので認知負荷・運用工数が高い
- Splunk で契約しているプランのキャパシティ的に本番環境のログのみしか送信できなかったため、開発環境のログを見るには、サーバから生のログを見るしかない
そんな中、コストカットなどの観点から Splunk を解約することになり、いいタイミングだということでこれらのアーキテクチャの改善と別ツールの選定を行うことになりました。
そこで今回はまず、
- 開発・本番環境のログをコストを抑えた状態で一つのツールで閲覧できるようにする
- Jenkins + Ansible を利用した 圧縮 + ストレージサービスへのアップロードをやめる
- ログ出力先として EFS, FFS を利用するのをやめる
- データ基盤への連携アーキテクチャをできるだけシンプルにして、認知不可・運用工数を下げる
をスコープとして設計・実装を行うことにしました。
閲覧ツールの選定
ログを閲覧・分析するツールには様々なものがありますが、今回は Grafana Labs が提供している Grafana Loki を利用することにしました。 Loki は OSS のログアグリゲーションシステムであり、Grafana Labs がプロジェクトをリードしています。 Grafana Loki は Grafana Labs が提供するSaaS版の Grafana Cloud もありますが、今回は Loki を 公式の Docker イメージを使って ECS で作成しました。
Loki のデータストア は、以前は NoSQL データストアとストレージサービスの両方を必要としていましたが、現在は Single Store (boltdb-shipper) での運用をサポートしているため、Amazon S3 のみをデータストアとしました。(公式もこの方法を推奨していそうでした)
Single Store (boltdb-shipper) - Recommended for 2.0 and newer index store which stores boltdb index files in the object store
トラフィック量はそこまで多くないので、モノリシックモード で運用することにし、Grafana は Amazon Managed Grafana を利用することにしました。
Amazon Managed Grafana + Loki の選定理由としては
- コストカットの観点からできるだけコストを抑えたい
- ログの検索は、アプリケーションチームだけでなく他チームメンバーも利用する可能性があるため検索の容量などをあまり気にする必要のないツールを選択したい
- 社内ネットワークに構築できる
- SAML 認証が可能
- ラベルを適切に運用することで、リクエストをマイクロサービス間で一括で検索できる
などです。
長期保存用ストレージサービスの選定
これは今までと同様 Amazon S3 を利用することにし、 同時に GCS の利用を廃止することにしました。これはtrocco が S3 からの連携もサポート しており、S3 に保存するキーを整理することができれば、あえてストレージサービスを分ける必要がなかったためです。
また、 Loki のストレージに S3 が使うため、ログデータの保存先の設定等が統一できるのもメリットでした。
本来であれば Fluentd から Loki に送ったデータのみで運用できればよかったのですが、 Loki で保存するチャンクデータは人間が読める形式にはなっておらず、 Loki が提供する API を利用する必要がありました。 Lambda などでその日一日のデータを取得するようなものを作るなどの手段もありましたが、一度に取得できるレコード数が制限されているため、少し複雑な処理を書かなければいけなかったことと、運用するリソースが増えることを避けたかったため、今回はログエージェントから S3 に直接送信することにしました。
Loki の Issue にも似た投稿がありました。
Grafana Cloud ではプレビュー機能ですが、でできるようになっているそうです。(これが人間が読める形式になっているかどうかは検証できていません)
ログ収集システムの選定
最後にログ転送エージェントの選定です。
Grafana Labs は Loki へログを転送するエージェントとして、 Promtail を提供しております。 Promtail は
Currently, Promtail can tail logs from two sources: local log files and the systemd journal (on AMD64 machines only).
とあるように、ログファイルをコンテナからマウントしたホストインスタンス内のボリュームに出力し、サイドカーコンテナなどを利用して Tail することでログデータを Loki に転送することができます。
ただし前章に記載のように S3 へも転送する必要があるのですが、Promtail は S3 への転送をサポートしておらず、 不採用となりました。
次に Fluent Bit を検証しました。 Fluent Bit はアウトプット先として Loki と S3 の両方をサポートしています。
ただし、データ基盤側へと連携する都合上、 S3 へアップロードする際にキーを JST にする必要がありました。以下記事を参考に OS のタイムゾーンを変更してみましたが UTC に変更することができませんでした。
s3_key_formatを使用することでプレフィックスに日付を設定できますが、この時の日付は UTC 固定です。JST とは 9 時間ズレることに注意しましょう。
以下の Issue で議論されていますが、OS のタイムゾーンとは独立しているようです。実際に OS のタイムゾーンをAsia/Tokyoにしてみましたが UTC のままでした。
上記の課題を解決するため、 Fluentd を検証しました。
Fluentd でローカルのタイムゾーンを変更したところ、 S3 へのアップロード時に日時を指定することで JST でキーを指定することができました。
<store>
@type s3
s3_bucket s3-bucket-name
s3_region ap-northeast-1
path "log/%Y/%m/%d/"
</store>
Fluentd は Fluent Bit 同様に S3 と Loki へのアップロードに対応しており、今回は Fluentd を採用することにしました。
最終的なアーキテクチャ
検証の結果、最終的なアーキテクチャは以下のようになりました。
これにより
- 大幅なコストカット
- GCS を廃止して長期保存用ストレージサービスを一本化
- Jenkins, Ansible, EFS, FFS の廃止
- すべての環境ログを一つのツールで閲覧
- SAML認証を利用したことによる IdP でのアカウント管理
などが実現でき、アーキテクチャもシンプルになりました。
まとめ
今回は社内のログ管理基盤をリニューアルした話を紹介しました。そもそもがレガシー?な構成になっていたのですが、少しはメンテしやすい構成にできたのかなと思います。
今回は全体的な構成についての紹介だったのでそれぞれの内部処理に関してはあまり触れていませんが、本記事がどなたかのお役に立てれば幸いです。
株式会社オープンエイトのテックブログです!カジュアル面談大歓迎ですー!エンジニア積極採用中 👉 open.talentio.com/r/1/c/open8/homes/3396
Discussion