kakakakakku blog

Weekly Tech Blog: Keep on Learning!

Fargate でも使える!FireLens の init プロセスを活用して設定ファイルを S3 から読み込む

Amazon ECS で FireLens (Fluent Bit) を使ってログをルーティングするときに Fluent Bit の「設定ファイル」を書いて挙動をカスタマイズしたくなる場面は多くある.そして FireLens は設定ファイルタイプ config-file-type として s3file をサポートしているけど,ECS タスクを AWS Fargate で動かす場合は file を使う必要がある💨

AWS Fargate でホストされるタスクは、file 設定ファイルタイプのみをサポートします。
FireLens 設定を使用するタスク定義の作成 - Amazon ECS

1. 独自コンテナイメージを作る file

config-file-typefile を使う場合,FireLens のコンテナイメージをベースに extra.conf など Fluent Bit の設定ファイルを COPY コマンドで追加した「独自コンテナイメージ」を作る必要がある.

Dockerfile サンプル

以下に Dockerfile のサンプルを載せる.

FROM public.ecr.aws/aws-observability/aws-for-fluent-bit:2.28.5
COPY ./extra.conf /fluent-bit/etc/extra.conf

extra.conf サンプル

以下に Fluent Bit の設定ファイル extra.conf のサンプルを載せる.今回は Apache HTTP Server (httpd) のログを Amazon CloudWatch Logs と Amazon Kinesis Data Firehose にログをルーティングするようにした.

[OUTPUT]
    Name cloudwatch_logs
    Match *
    region ap-northeast-1
    log_key log
    log_group_name /sandbox/httpd
    log_stream_prefix httpd/
    auto_create_group true

[OUTPUT]
    Name firehose
    Match *
    region ap-northeast-1
    delivery_stream sandbox-log-stream

Amazon ECR に独自コンテナイメージを登録する

そして,Dockerfile をビルドして Amazon ECR に独自コンテナイメージを登録する.今回コンテナイメージ名は firelens-extra:1.0.0 にした.

$ docker build -t firelens-extra .
$ docker tag firelens-extra:latest 000000000000.dkr.ecr.ap-northeast-1.amazonaws.com/firelens-extra:1.0.0
$ docker push 000000000000.dkr.ecr.ap-northeast-1.amazonaws.com/firelens-extra:1.0.0

Amazon ECS タスク定義

以下に Amazon ECS タスク定義のサンプルを載せる.

Apache HTTP Server (httpd) のログを FireLens (Fluent Bit) 経由でルーティングしている.firelensConfigurationoptions で独自コンテナイメージに追加した設定ファイル /fluent-bit/etc/extra.conf を指定している.ちなみに log-routerlogConfiguration では,FireLens 自体のログを Amazon CloudWatch Logs に保存している.FireLens の設定ファイルを間違えたときなどの調査に使える.

{
  "containerDefinitions": [
    {
      "name": "httpd",
      "image": "public.ecr.aws/docker/library/httpd:2.4",
      "essential": true,
      "logConfiguration": {
        "logDriver": "awsfirelens"
      }
    },
    {
      "name": "log-router",
      "image": "000000000000.dkr.ecr.ap-northeast-1.amazonaws.com/firelens-extra:1.0.0",
      "essential": true,
      "firelensConfiguration": {
        "type": "fluentbit",
        "options": {
          "config-file-type": "file",
          "config-file-value": "/fluent-bit/etc/extra.conf"
        }
      },
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "firelens-container",
          "awslogs-region": "ap-northeast-1",
          "awslogs-create-group": "true",
          "awslogs-stream-prefix": "firelens"
        }
      }
    }
  ]
}

アーキテクチャ図を書くならこんな感じ🎨

また FireLens の概要や独自コンテナイメージを作る詳細な手順などは「AWS コンテナ設計・構築 [本格] 入門」の Chapter 3 と 5 にも載っている.あわせて読んでみると良いのではないでしょうか📕

2. FireLens の init プロセスを活用する

さて,ここから本題❗️

FireLens には :init-latest など init というキーワードを含んだイメージタグがあって,これを使うと FireLens を起動するときに Amazon S3 から Fluent Bit の設定ファイルを自動的に読み込めるようになっている❗️この init プロセスを活用すると,独自コンテナイメージを作らなくて良くなる👏

\( 'ω')/ うおおおおお!最高だ〜

  • :init-latest
  • :init-2.28.5
  • :init-arm64-2.28.5
  • etc

gallery.ecr.aws

init プロセスに関して

「init プロセス」に関する詳細な情報は GitHub に載っていた📝

  • Init process for Fluent Bit on ECS, multi-config support
  • FireLens Example: Multiple Config support - using the Fluent Bit image with init tag

github.com

github.com

Amazon ECS タスク定義

以下に init プロセスを活用する Amazon ECS タスク定義のサンプルを載せる.

まず,独自コンテナイメージを作らなくて良くなるため,log-routerimagepublic.ecr.aws/aws-observability/aws-for-fluent-bit:init-2.28.5 など公開イメージで OK になる👌 そして,読み込ませる Fluent Bit の設定ファイル extra.conflog-routerenvironment に Amazon S3 オブジェクトの ARN として設定する.nameaws_fluent_bit_init_s3 プレフィックスを使って aws_fluent_bit_init_s3_${連番} のようにする必要がある.

もちろん複数の設定ファイルを読み込ませることもできる❗️

{
  "containerDefinitions": [
    {
      "name": "httpd",
      "image": "public.ecr.aws/docker/library/httpd:2.4",
      "essential": true,
      "logConfiguration": {
        "logDriver": "awsfirelens"
      }
    },
    {
      "name": "log-router",
      "image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:init-2.28.5",
      "essential": true,
      "firelensConfiguration": {
        "type": "fluentbit"
      },
      "environment": [
        {
          "name": "aws_fluent_bit_init_s3_1",
          "value": "arn:aws:s3:::kakakakakku-firelens-configs/extra.conf"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "firelens-container",
          "awslogs-region": "ap-northeast-1",
          "awslogs-create-group": "true",
          "awslogs-stream-prefix": "firelens"
        }
      }
    }
  ]
}

アーキテクチャ図を書くならこんな感じ🎨

init プロセスのメリットとデメリット

あくまで個人的な考えだけど,init プロセスを活用すれば独自コンテナイメージを作らなくて良く,運用面で楽になるメリットがあると思う.extra.conf を更新するときも Amazon S3 にアップロードして,ECS タスクを再デプロイすれば OK👌逆に言えば,init プロセスだと FireLens コンテナを起動するときに毎回 Amazon S3 から設定ファイルを取得するため,起動時間への影響と s3:GetObject のコストは多少デメリットに感じる.

よって,必ずしも init プロセスを使うべきという話ではなく,メリットとデメリットを比較して決める必要がありそう❗️

github.com

まとめ

FireLens (Fluent Bit) の設定ファイルをカスタマイズするときに init プロセスを使えば独自コンテナイメージを作らなくても良くなるよー❗️という紹介記事を書いた.

参考になれば〜

おまけ : aws-for-fluent-bit の stable バージョンを確認する

AWS Systems Manager Parameter Store のパブリックパラメータを使えば aws-for-fluent-bit の stable バージョンを確認できる💡

$ aws ssm get-parameters \
    --names /aws/service/aws-for-fluent-bit/stable \
    --region ap-northeast-1
{
    "Parameters": [
        {
            "Name": "/aws/service/aws-for-fluent-bit/stable",
            "Type": "String",
            "Value": "906394416424.dkr.ecr.ap-northeast-1.amazonaws.com/aws-for-fluent-bit:2.28.5",
            "Version": 13,
            "LastModifiedDate": "2023-04-15T03:50:41.141000+09:00",
            "ARN": "arn:aws:ssm:ap-northeast-1::parameter/aws/service/aws-for-fluent-bit/stable",
            "DataType": "text"
        }
    ],
    "InvalidParameters": []
}