FireLens で ECS の FluentBit サイドカーに設定を配置しログが転送されるようにする

awsfluentd

FireLens は ECS のアプリケーションコンテナに awsfirelens ログドライバーを指定し、Fluent Bit/Fluentd サイドカーコンテナに firelensConfiguration を設定すると、stdout/stderr を /var/run/fluent.sock 経由でサイドカーコンテナに送信し、CloudWatch Logs や S3 などへの出力設定ファイルを自動生成してサイドカーコンテナ内に配置してくれる機能。

const taskRole = new iam.Role(this, 'TaskRole', {
  assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
})

const logBucket = new s3.Bucket(this, 'LogBucket')
logBucket.grantWrite(taskRole)

const executionRole = new iam.Role(this, 'ExecutionRole', {
  assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonECSTaskExecutionRolePolicy'),
  ]
})
    
const taskDef = new ecs.FargateTaskDefinition(this, 'TaskDef', {
  cpu: 256,
  memoryLimitMiB: 512,
  taskRole,
  executionRole,
})

taskDef.addContainer('AppContainer', {
	containerName: 'app',
  image: ecs.ContainerImage.fromRegistry('nginx'),
  portMappings: [{ containerPort: 80 }],
  logging: ecs.LogDrivers.firelens({
    options: {
      Name: 's3',
      region: cdk.Stack.of(this).region,
      bucket: logBucket.bucketName,
    }
  }),
})

taskDef.addFirelensLogRouter('FluentBitContainer', {
	containerName: 'fluent-bit',
  image: ecs.ContainerImage.fromRegistry('amazon/aws-for-fluent-bit:latest'),
  firelensConfig: {
    type: ecs.FirelensLogRouterType.FLUENTBIT,
  },
  logging: ecs.LogDrivers.awsLogs({ streamPrefix: 'firelens' }),
})

サイドカーの中に入って FireLens の設定ファイルが配置されていることを確認する。

AWS CopilotでECS on Fargate上にコンテナをデプロイしECS Execによるコマンドの実行やSession Managerによるポートフォワーディングを行う - sambaiz-net

$ aws ecs execute-command \
  --cluster (cluster_name) \ 
  --task (task_name) \
  --container fluent-bit \
  --interactive \
  --command "/bin/sh"

# cat /fluent-bit/etc/fluent-bit.conf

[INPUT]
    Name tcp
    Listen 127.0.0.1
    Port 8877
    Tag firelens-healthcheck

[INPUT]
    Name forward
    Mem_Buf_Limit 25MB
    unix_path /var/run/fluent.sock

[INPUT]
    Name forward
    Listen 127.0.0.1
    Port 24224

[FILTER]
    Name record_modifier
    Match *
    Record ecs_cluster *****
    Record ecs_task_arn *****
    Record ecs_task_definition *****

[OUTPUT]
    Name null
    Match firelens-healthcheck

[OUTPUT]
    Name s3
    Match app-firelens*
    bucket ****
    region ap-northeast-1

configFileValue で独自の設定を追加することもできる。EC2 の場合 FileType に S3 を設定できるが、Fargate は FILE のみなので image に入れておくなどする。

/*
# assets/fluent-bit/Dockerfile 
FROM amazon/aws-for-fluent-bit:latest
COPY fluent-bit.conf /extra.conf
*/

taskDef.addFirelensLogRouter('FluentBitContainer', {
  containerName: 'fluent-bit',
  image: ecs.ContainerImage.fromAsset('assets/fluent-bit', {
    platform: ecrassets.Platform.LINUX_AMD64,
  }),
  firelensConfig: {
    type: ecs.FirelensLogRouterType.FLUENTBIT,
    options: {
      configFileType: ecs.FirelensConfigFileType.FILE,
      configFileValue: '/extra.conf',
    },
  },
  logging: ecs.LogDrivers.awsLogs({ streamPrefix: 'firelens' }),
})

すると指定したファイルが @INCLUDE で読み込まれるようになる。

# cat /fluent-bit/etc/fluent-bit.conf
...

[FILTER]
    Name record_modifier
    Match *
    Record ecs_cluster *****
    Record ecs_task_arn *****
    Record ecs_task_definition *****

@INCLUDE /extra.conf

[OUTPUT]
    Name null
    Match firelens-healthcheck

...