こんにちは、エンジニアの田代です。
今回は以前投稿した下記の記事と同様、ECS+Fargateの環境をCloudFormationで構築します。
こちらの記事で解説している部分は今回の記事では割愛しているので、併せて参考にしてみて下さい。
blog.tech-monex.com
はじめに
FireLensとはAWS ECSの環境において、Fluentd或いはFluent Bitのコンテナをタスク定義に含め、ログドライバーとして動作させることでコンテナログを種々の宛先へ転送させることが出来る機能です。
今回はAWSが提供しているFluent Bitのイメージを基にして、nginxコンテナのログをDatadogとS3へ転送してみます。
尚、CloudFormationテンプレートを使って構築しますが、CLIを使ってタスク定義を作成する際にも参考にして頂ける内容かと思います。
aws.amazon.com
やりたいこと
上図のように、nginxとFluent Bitのコンテナを1つずつ含むタスク定義を作成し、nginxコンテナの標準出力をDatadog及びS3に転送させられるようにすることが今回のゴールです。
前提事項
当記事ではタスク定義の作成をメインに扱うので、ECRリポジトリや、タスクを動作させるためのクラスター及びサービスと付随する各リソースについては既に用意されているものとします。
そちらについての情報を求めている方は冒頭のリンク先の記事もご覧頂ければと思います。
Fluent Bitコンテナの作成
まずFluent BitコンテナをビルドしてECRにプッシュします。
今回のようにログ転送先を複数指定する場合は独自のFluent Bit設定ファイルが必要となるため、logDestinations.conf
を用意します。
FROM amazon/aws-for-fluent-bit:latest ADD logDestinations.conf /logDestinations.conf
[OUTPUT] Name datadog Match * Host http-intake.logs.datadoghq.com TLS on compress gzip apikey ${DD_API_KEY} dd_service sample_nginx_service dd_source nginx dd_tags environment:sample_env provider ecs [OUTPUT] Name s3 Match * region ap-northeast-1 bucket ${S3_BUCKET} total_file_size 10M upload_timeout 1m store_dir /tmp/fluent-bit/s3 s3_key_format /fluent-bit-logs/$TAG/%Y/%m/%d/%H/%M/%S use_put_object On
各項目は必要であれば公式ドキュメントを参考に適宜書き換えて頂ければと思います。
また、Datadogのapikeyと転送先S3バケットの値は実行時にSSMパラメーターから取得するため、ここでは環境変数名を指定しています。
docs.fluentbit.io
各ファイルが用意出来たら、CLIから下記のコマンドを実行してDockerイメージをECRにプッシュします。
$ aws ecr get-login-password --region {YOUR_REGION}
$ docker login -u AWS -p {YOUR_TOKEN} https://{YOUR_ECR_URL}.amazonaws.com
$ # -> Login Succeeded
$ docker build -t sample-log-router .
$ docker tag sample-log-router:latest {YOUR_ECR_URL}.amazonaws.com/sample-log-router:latest
$ docker push {YOUR_ECR_URL}.amazonaws.com/sample-log-router:latest
タスク定義の作成
続いてタスク定義を作成します。
CloudFormationテンプレートを実行する前に、まずはSSMパラメータストアにDatadog apikey(datadog_api_key
)とS3バケット名(fluent_bit_bucket
)をSecureStringとして登録しておきましょう。
登録が出来たら、CloudFormationでsample_nginx_task.yaml
を実行してタスク定義を作成します。
FirelensConfiguration
で事前に用意したlogDestinations.conf
を設定ファイルとして指定しています。
AWSTemplateFormatVersion: "2010-09-09" Parameters: FluentBitImageUri: Type: String TaskExecutionRoleArn: Type: String TaskRoleArn: Type: String Resources: SampleNginxTaskDefinition: Type: AWS::ECS::TaskDefinition Properties: ContainerDefinitions: # nginxコンテナの設定 - Name: 'NginxContainer' Essential: true # 公式のnginxイメージを利用 Image: 'public.ecr.aws/nginx/nginx:latest' # ログ出力先にFireLensを指定 LogConfiguration: LogDriver: 'awsfirelens' PortMappings: - HostPort: 80 Protocol: 'tcp' ContainerPort: 80 # Fluent Bitコンテナの設定 - Name: 'FluentBitContainer' DependsOn: - Condition: 'START' ContainerName: 'NginxContainer' Essential: true # FireLensの設定 FirelensConfiguration: Options: enable-ecs-log-metadata: true # logDestinations.confを設定ファイルとして指定 config-file-type: 'file' config-file-value: '/logDestinations.conf' Type: 'fluentbit' Image: !Ref FluentBitImageUri LogConfiguration: # Fluent BitコンテナのログはCloudWatchに保管 LogDriver: 'awslogs' Options: awslogs-group: '/ecs/SampleNginxTask' awslogs-region: !Ref 'AWS::Region' awslogs-stream-prefix: 'ecs' Secrets: # SSMパラメーターの値を環境変数に設定 - Name: 'DD_API_KEY' ValueFrom: 'datadog_api_key' - Name: 'S3_BUCKET' ValueFrom: 'fluent_bit_bucket' Cpu: 256 ExecutionRoleArn: !Ref TaskExecutionRoleArn Family: 'SampleNginxTask' Memory: 512 NetworkMode: 'awsvpc' RequiresCompatibilities: - 'FARGATE' TaskRoleArn: !Ref TaskRoleArn
スタック作成が完了したら、予め用意しておいたサービスでタスクを実行し、nginxにアクセスしてみます。
nginxのデフォルトページが表示されました。
最後に、アクセスログがDatadogとS3に転送されているかを確認します。
ねらい通りDatadogとS3にそれぞれログが転送されました。
Datadogのタグや、S3の保管先プレフィックスもlogDestinations.conf
で設定した通りになっていますね。
まとめ
以上で、 CloudFormationのテンプレートを使って、コンテナログを複数の宛先へ転送するタスク定義を作成することが出来ました。
Fluent BitやFireLensが備える機能の一部の紹介に留まりましたが、今回の記事がECSを運用する上での参考になれば嬉しいです。
