Help us understand the problem. What is going on with this article?

FargateでFireLensログドライバを使い自前で用意したfluentdを動かす

背景

FargateのログドライバはCloudWatch Logs,Splunkしか使用できず、その他のログ基盤に連携を行いたい場合はCloudWatch Logsから転送するか(CloudWatch Logsの料金がかかる)、ログドライバを使用せず共有ボリュームにログファイルを出力してサイドカーのFluentdで収集する(ボリュームは8GBまで)といろいろと制約があり、なかなかFargateに移行ができないでいました。

この度、FireLensがGAになり、自前のFluentdに転送できるとのことだったので試してみたところ、色々と詰まりましたのでメモとして残します。

開発

0. FireLensについて

クラスメソッド様の記事がとてもわかり易いと思います。

1. 概要

作成、使用した環境はGitHubにあります。
構成としてはFargateでnginxのログをFirelens(fluentd)を使い、S3に出力しています。
nginx -> firelens(fluentd) -> S3

2. パッケージ構成

ざっくりとしたパッケージ構成とその説明です。

.
├── fluentd                         
│   ├── conf.in                 <-- fluentdのcofigディレクトリ。input情報を書いている
│   ├── conf.out                <-- fluentdのcofigディレクトリ。output情報を書いている
│   ├── Dockerfile              <-- fluentdのDockerfile
│   ├── build.sh                <-- Dockerfileでbuildし、ECRにpushしています
│   └── fluent.conf             <-- fluentdのcofigファイル。conf.inとconf.outをincludeしている
├── nginx                    
│   ├── Dockerfile              <-- nginxのDockerfile
│   └── build.sh                <-- Dockerfileでbuildし、ECRにpushしています
├── terraform                   <-- AWS環境一式をterraform化してあります 
└── README.md

3. メモ

fluentdのDockerfileです。
firelensに対応するため、COPY fluent.conf /fluentd/etc/fluent-custom.confと名前を変更しています。これは後述のtask-definition.jsonで使用するためです。

Dockerfile
FROM fluent/fluentd:v1.7-1

# Use root account to use apk
USER root

# below RUN includes plugin as examples elasticsearch is not required
# you may customize including plugins as you wish
RUN apk add --no-cache --update --virtual .build-deps \
        sudo build-base ruby-dev \
 && sudo gem install fluent-plugin-rewrite-tag-filter -v 2.2.0 \
 && sudo gem install fluent-plugin-s3 -v 1.1.11 \
 && sudo gem sources --clear-all \
 && apk del .build-deps \
 && rm -rf /tmp/* /var/tmp/* /usr/lib/ruby/gems/*/cache/*.gem

COPY fluent.conf /fluentd/etc/fluent-custom.conf
COPY conf.in      /fluentd/etc/conf.in
COPY conf.out     /fluentd/etc/conf.out

USER fluent

次にfluent.confですが、input情報である<source>の記述を消しています。理由は記述するともうポートが空いているとerrorになるため削除しています。おそらく、AWS側で記述があるためだと思われます。

fluent.conf
<match>
  @type relabel
  @label @firelens_log
  @id    in_forward_all
</match>

@include conf.in/*.conf
@include conf.out/*.conf

最後にtask-definition.jsonですが、

  • config-file-type -> file
  • config-file-value -> /fluentd/etc/fluent-custom.conf

としています。fluent.confと記述してしまうと予約後なのか、errorになるため、このような記述になります。
公式ドキュメントには特に記述は見当たりませんでした。

task-definition.json
[
  {
    "name": "nginx",
    "image": "xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/infra/nginx-1.17.4:latest",
    "cpu": 256,
    "memory": 512,
    "essential": true,
    "portMappings": [
      {
        "containerPort": 80,
        "protocol": "tcp",
        "hostPort": 80
      }
    ],
    "logConfiguration": {
      "logDriver": "awsfirelens"
    }
  },
  {
    "name": "fluentd",
    "image": "xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/infra/fluentd-1.7:latest",
    "cpu": 256,
    "memory": 512,
    "essential": true,
    "logConfiguration": {
      "logDriver": "awslogs",
      "options": {
        "awslogs-group": "/ecs/firelens-fluentd",
        "awslogs-region": "ap-northeast-1",
        "awslogs-stream-prefix": "ecs"
      }
    },
    "firelensConfiguration": {
      "type": "fluentd",
      "options": {
        "config-file-type": "file",
        "config-file-value": "/fluentd/etc/fluent-custom.conf"
      }
    }
  }
]

他に気をつけることとしては、tagがコンテナ名-firelens-コンテナIDとハイフン区切りで渡されてきます。
fluentdはドット区切りなため、rewrite_tag_filterを使い、正規表現でtagをrewriteしています。
ソースコードを見たのですが、こちらから上書きする手段はなさそうです。
Fluent Bitだったらドット区切りではないため、困らないからでしょう。
ECSのfluentdログドライバだったらoptionでtagを渡せたため、そうしてくれるとありがたいと思いました。

in-match.conf
<label @firelens_log>
  <filter>
    @type record_transformer
    <record>
    tag ${tag}
    </record>
  </filter>
  <match>
    @type rewrite_tag_filter
    @label @create_tag
    <rule>
      key tag
      pattern /^nginx-firelens-(\w.+)$/
      tag "nginx.sample.$1"
    </rule>
  </match>
</label>

〜〜省略〜〜

まとめ

色々と書きましたが、十分本番環境に耐えられる状態として提供されたのではないでしょうか。
既存のログ基盤がすでにあるサービスにとっては、Fargateへの移行に関しての懸念事項がまた一つ消えたと思います。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした