Closed10
ECS/FargateのログルーティングをFirelensで実装する
参考
terraform
FireLensとは
ECSで使用できるログルータのひとつ。タスク定義から設定可能。
実体はFluentbit,Fluentdがサイドカーとして動作している
ハマったところ
name
と指定する
① コンテナ定義でこんなログが出た。そもそもタスクは起動できていない。
InternalError: unable to generate fireLens config file: unable to generate fireLens config content: unable to generate fluent config output section: unable to apply log options of container nginx to fireLens config: missing output key Name which is required for fireLens configuration of type fluentbit. Launch a new task to retry.
コンテナ定義でのFirelens設定を確認すると
container-definisions.json
"LogConfiguration": {
"logDriver": "awsfirelens",
"options": {
"name": "firehose",
"region": "ap-northeast-1",
"delivery_stream": "xxxxxxxxxxx"
}
}
となっていました。
正しくは
container-definisions.json
"LogConfiguration": {
"logDriver": "awsfirelens",
"options": {
- "name": "firehose",
+ "Name": "firehose",
"region": "ap-northeast-1",
"delivery_stream": "xxxxxxxxxxx"
}
}
なので注意する。
他のオプションが小文字っぽいから間違える可能性高そう
② firehoseへログを転送する権限が足りない
このようなログがfirelensサイドカーから出てきたらログ転送先への権限が足りていません。
タスクロールを適切に設定します
time="2023-07-17T07:44:25Z" level=error msg="[firehose 0] PutRecordBatch failed with AccessDeniedException: <taskrole arn> is not authorized to perform: firehose:PutRecordBatch on resource: <firehose-stream> because no identity-based policy allows the firehose:PutRecordBatch action\n\tstatus code: 400, request id: xxxyyyzzz123
例えばこんな感じ(terraform)のものを追加します
data "aws_iam_policy_document" "firehose" {
statement {
effect = "Allow"
actions = [
"firehose:PutRecord",
"firehose:PutRecordBatch"
]
resources = ["${aws_kinesis_firehose_delivery_stream.s3_stream.arn}"]
}
}
resource "aws_iam_policy" "firehose" {
name = "firehose"
path = "/"
policy = data.aws_iam_policy_document.firehose.json
}
設定箇所
コンテナ定義
ここに設定例があるため、元にして設定します。
[
{
"name": "${container-name}",
"image": "${container-image}",
"cpu": 256,
"essential": true,
"memory": 128,
"portMappings": [
{
"containerPort": 80,
"hostPort": 80
}
],
"LogConfiguration": {
"logDriver": "awsfirelens",
"options": {
"Name": "firehose",
"region": "ap-northeast-1",
"delivery_stream": "my-firehose-stream"
}
}
},
{
"essential": true,
"image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:stable",
"name": "log_router",
"firelensConfiguration": {
"type": "fluentbit"
},
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/logs/firelens",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "firelens"
}
},
"memoryReservation": 50
}
]
ポイントは
- ログを飛ばしたいコンテナで
"logDriver": "awsfirelens"
を設定する - firelens用のコンテナを追加する
- 今回はfluentbitを使用するため、
firelensConfiguration
で指定する。
詳細についてはタスク定義の該当ページで確認する
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-firelensconfiguration.html
権限設定
- タスクから
PitRecord
できるようにする - タスクロールに設定する(notタスク実行ロール)
{
"Statement": [
{
"Action": [
"firehose:PutRecordBatch",
"firehose:PutRecord"
],
"Effect": "Allow",
"Resource": "<deliverystream arn>",
"Sid": ""
}
],
"Version": "2012-10-17"
}
確認
問題なければs3にログが飛びます。
年月日で階層化されて、delivery_stream名
-<ランダム文字列>というフォーマットで定期的に出力されるイメージです。
確認②
firehoseのdelivery_streamのメトリクスも確認してみます。
特に問題はなさそう
確認③
ファイルの中身を確認します。
curl -I
でリクエストを投げたところ、このようなログで記録されていました
{"container_id":"<コンテナランタイム ID>","container_name":"<コンテナ名>","ecs_cluster":"<ECSクラスタ>","ecs_task_arn":"<ECSタスクARN>","ecs_task_definition":"<タスク定義名>","log":"10.10.2.75 - - [17/Jul/2023:08:37:02 +0000] \"HEAD / HTTP/1.1\" 200 0 \"-\" \"curl/7.81.0\" \"<グローバルIP>\"","source":"stdout"}
- container_id:コンテナランタイムID
- container_name:コンテナ名
- ecs_cluster:ECSクラスタ名
- ecs_task_arn:ECSタスクARN
- ecs_task_definition:タスク定義名
- log:nginxが吐いたログ
- source:不明なので今度調べる。おそらくコンテナの標準出力であることを表している
イメージ図
このスクラップは2023/07/23にクローズされました