問題
FireLens でユーザー独自の fluentd を使う場合、設定ファイルに以下のような <source> セクションが自動で追加される。
<source>
@type unix
path /var/run/fluent.sock
</source>
<source>
@type forward
bind 127.0.0.1
port 24224
</source>
設定ファイルに上記のような記述が既にされていた場合、重複が生じてしまい以下のようなエラーが発生してしまう。
[error]: unexpected error error_class=Errno::EADDRINUSE error=#<Errno::EADDRINUSE: Address in use - bind(2) for "0.0.0.0" port 24224>
fluentd コンテナをローカル環境などで開発する段階においては、何らかの <source> がないと入力が得られずテストができないため、ECS で動かすタイミングで上記エラーに遭遇することがある。
対応策
- 開発時だけ設定ファイルに <source> を入れて、開発が終わったら消す
- 愚直なパターン。
- Dockerfile の ARG などを活用して、開発ビルド時のみ <source> を入れるようにする
- 開発以外のときは <source> が入らないように RUN をうまいこと書く。
-
@type file
など重複しない type で代用する
- ファイルなど別の type 経由でデバッグする方法。
- 別のコンテナから起動して、コンテナ上で設定ファイルに <source> を追加する
- 後述。
1 に関しては手間がかかってしまうほか、設定の消し忘れで FireLens のエラーを誘発してしまう恐れが常につきまとう。
2./3. は、開発用のロジックがプロダクション環境にも含まれてしまう問題がある。これをどう捉えるかは人次第だが、個人的には若干の気持ち悪さが残る。
主題: 別のコンテナから起動させる
4 の方法について: 基本的には 1. と似たアプローチだが、これをコンテナという仮想環境上で行う点が違いとなる。
FROM <開発中のコンテナ>
# localhost を listen する設定を追加
RUN sed -e '1i<source>' \
-e '1i @type forward' \
-e '1i port 24224' \
-e '1i bind 0.0.0.0' \
-e '1i</source>' \
-i <設定ファイルへのパス>
上記をビルドして実行すれば、fluentd 本体の設定ファイルには手を加えることなく、ローカル開発時のみ <source> を追加することができる。これにより fluent-cat で自由にデバッグ入力が可能となる。
また、上記例では forward type を指定したが、sample (dummy) type を指定することで fluent-cat が不要になる。
https://docs.fluentd.org/input/sample
リポジトリにしたのでよければどうぞ。
https://github.com/tsubasaogawa/aws-firelens-fluentd-dev-kit
むすび
本手法の欠点として、FROM で fluentd コンテナを指定している都合上、 fluentd コンテナにビルドが生じるたびに本コンテナのビルドも必要になる。頻繁に fluentd コンテナをビルドするような開発スタイルだと、多少の手間がどうしても発生してしまう。
願わくば FireLens 側でエラーの発生を避ける方法があればこんなことをせずに済むのだけど、なにかご存知な方教えてください。