この記事は Supership株式会社 Advent Calendar 2018の23日目の記事です。
今年Supershipに転職していて、業務でログ基盤のリプレースとアプリケーションのリプレースを行っておりFluentdに機能追加のPull Requestを送る機会があったので何ができるようになったのか、どんな問題があったのかをまとめるという趣旨の記事になります。
Fluentdのout_forwardとは
Fluentdはデータ転送を行うRubyで書かれたデータコレクタです。
FluentdとFluentdのノード間においてデータ転送を行う際に出力する側のプラグインの名称です。
Fluentdの本体に含まれていて、TCP/UDPのコネクション確立を含めたデータ転送処理を行います。
どのような問題があったか
Fluentdにはv0.14.12 からout_forwardでのデータ転送時に暗号化処理する機能があります。
それ以前のバージョンでは別途プラグインを導入する必要があり、 tagomoris/fluent-plugin-secure-forward が用いられていました。
私が担当しているログ転送基盤部分ではAWSからGCPにグローバルネットワークを介して接続しているため、暗号化処理は必須要件になります。
このような構成の時にAWS側とGCP側で事前共有が必要な認証情報の不一致があった場合どのような状態になるでしょうか。
それを知るにはまずFluentdのout_forwardがどのタイミングでコネクションを張るかを知る必要があります。
out_forwardではFluentdプロセスが起動した時にconfによって指定されたノードとの接続を試みません。
デフォルト設定では名前解決を試みて名前解決が行えるかを試しますが*1、接続は試みません。
そのため実際にログを受け取り、転送する段階になって転送先のノードとコネクションを張ります。
通常の平文でのログ転送においてはリトライが可能なためそこまで多くの問題は生じないでしょう。
もし、誤った認証情報をもったFluentdがデプロイされたらデータ受け取り転送する段階になってconfの認証情報では繋がらないということが判明します。
一般的なコネクションの問題であれば時間経過によりリカバリーが見込めることもありますが、誤った認証情報というケースにおいては時間経過でリカバリーを待つより異常終了でエラーがあったことが明確になるほうが良いかと思います。
そしてその異常終了のタイミングはFluentdがデータを受け取る前の段階であると望ましいでしょう。
この件をFluentdのメーリングリストに相談し、起動時に疎通できなければそのままFluentdが異常終了するようにするという verify_connection_at_startup オプションを追加するPull Requestを送りました。
ちなみにこのPull Request適用前のFluentd version 1.3.1以前では認証情報(Shared key)の不一致の場合はwarnレベルでFluentdのログに出力されるだけで異常終了することはありませんでした。
なぜログを確認する運用にしなかったか
warnレベルでログにエラーがでるということは前述しましたが、運用体制としてログを確認するフローになぜしなかったのかを以下で説明します。
メトリクス監視ツールなどでFluentdのログを監視して認証情報の不一致が発生していることを監視することも可能でした。
しかし、こちらも前述している通り最も良い解決方法としては起動時に異常終了することであると考えています。
私が担当しているログ転送基盤は属人的でブラックボックスが存在したシステムからの脱却を行っており、アプリケーションからログ転送基盤までをCI/CDによる継続的デプロイメント環境へ移行しています。
その一環としてログ転送基盤もDockerコンテナへ移行し自動デプロイが行われる構成へと移行しています。
自動デプロイ環境への移行中の検証で認証情報の不一致があってもFluentd起動時に異常終了しないため、自動デプロイの切り戻しが容易ではないことが判明しました。
メトリクス監視ツールなどを使用してFluentdのログを監視してもログの欠損がない安全な自動切り戻しが難しく起動時に異常終了させたいという思いがありました。
この事情をFluentdのメーリングリストに相談したところ機能追加が必要だというレスポンスを得て、この機能追加のPull Requestを送ったところマージされて、Fluentd version 1.3.1よりこの機能が利用できるようになりました。
*1 ignore_network_errors_at_startup時はDNSの名前解決を行わない