Sionの技術ブログ

SREとして日々の学習を書いて行きます。twitterは@sion_cojp

Fargateでfirelensを利用し、datadog logsとs3にログを保存する

f:id:sion_cojp:20200207102418p:plain

firelens is 何?

fluentd/fluent-bitに連携することが可能なログドライバーです。

なぜfirelensか

firelensが出るまでFargateはawslogsドライバくらいしか選択肢がありませんでした。

s3に生ログの保存、解析+アラート用にdatadog logsに送るためには

fargate -> cloudwatch -> firehose -> lambda -> datadog logs, s3 といった構成を取る必要があり、そこには2つ問題がありました。

  • cloudwatch使わないのに無駄な費用が発生
  • lambdaがたまにこけていた(これは我々の実装の問題だと思います)

fargate(firelens) -> firehose -> datadog logs, s3 とfirelensを使うとこの構成になり、上記解決 + cloudwatch, lambda費用もかからなくなります。

fluent-bitのイメージについて

今回サイドカーで立てるfluent-bitのイメージは

https://hub.docker.com/r/sioncojp/fluent-bit-datadog-firehose を使います。

なぜこのイメージを使うかというと、Fargateはs3にあるconfigファイルを利用できないので、firehose, datadogに送るconfigを設定したカスタムイメージを作成する必要がありました。

ここで注意するのは、 /fluent-bit/etc/fluent-bit.conf/fluentd/etc/fluent.conf のファイルパスは予約されてるので、/fluent-bit/etc/extra.conf などの名前で保管しましょう。

ref: s3にあるconfigが使えない + ファイルパスの予約

ECS task definition

タイミーではecs-deployというGoの自社ツールでecsのtask設定 + service updateをしてますが、そちらで自動的にfluent-bitのContainerDefinition設定がされるようになってます。

fluent-bitの管理はSREなので、開発者には動かしたいコンテナの設定だけしてもらうよう意識してます。

設定されるjsonについて、firelens部分だけ紹介するとこのような感じになります

# サービス側
      "logConfiguration": {
        "logDriver": "awsfirelens",
        "secretOptions": null,
        "options": null
      },
# fluent-bit側
      "environment": [
        {
          "name": "AWS_REGION",
          "value": "ap-northeast-1"
        },
        {
          "name": "DD_SERVICE",
          "value": "koyama"
        },
        {
          "name": "DD_SOURCE",
          "value": "fargate"
        },
        {
          "name": "DD_TAGS",
          "value": "env:sandbox"
        },
        {
          "name": "DELIVERY_STREAM",
          "value": "koyama_koyama"
        }
      ],
      "secrets": [
        {
          "valueFrom": "SSMのDD_API_KEYパス",
          "name": "DD_API_KEY"
        }
      ],
      "firelensConfiguration": {
        "type": "fluentbit",
        "options": {
          "config-file-type": "file",
          "config-file-value": "/fluent-bit/etc/extra.conf"
        }
      },

全task definitionはこちら。

datadogに飛ばす

firelens -> サイドカーのfluentbit -> datadog

### タグ付け
- source: fargate/cron/runtask
- service: コンテナのサービス名
- env: prod/stg/sandbox...

s3に飛ばす

firelens -> fluentbit-> firehose -> s3

https://github.com/cosmo0920/fluent-bit-go-s3 も検証しましたが、1リクエスト1ファイルだったので管理が辛く断念しました。

またfirehoseは各サービスで1つ作るのがベストです。そうしないと同じs3ディレクトリに全ファイルが集約されてしまいます。

### 共有firehose
s3://生ログ保存バケット/共通ディレクトリ/YYYY/MM/DD/ファイル名

### サービス毎にfirehose
s3://生ログ保存バケット/クラスタ名/サービス名/YYYY/MM/DD/ファイル名

1つずつ作り クラスタ名/サービス名 にfirehose prefixを設定することでディレクティブに保管できます。データ分析の際に使いやすくなるよう意識しました。

fluent-bit自体のロギング

awslogsドライバーでcloudwatchに吐くことができますが、特に必要な情報が今の所なさそうだったので出してません。

もし必要になった場合、cloudwatch logsで全fluent-bitログを保管するlog groupを作り、そこのグループにlogstreamにサービス名を定義して保管するのがベストだと思います。

fluent-bit自体のモニタリング

今の所はしてません。問題が起きたらそれに合わせてすると思います。

またessential:trueなので、落ちた場合、taskにある全コンテナ落ちますので、datadogでサービス単位のコンテナ変動をモニタリングはしております。