ECSでfluentdを使ってコンテナ毎にlogging



背景
---

nginx -> appという流れのコンテナを組んでいます。
nginxはawslogsドライバを使って、cloudwatchにログを流しても全然問題無いんですが、appコンテナは諸事情でそうもいかない背景があり、fluentd経由でcloudwatchにログを送りたいと考えました。

願望
---

* コンテナ内でlogrotationの設定はしたくない。
* cloudwatchのログストリーム名はコンテナ毎にユニークにしたい。
* FluentdコンテナをECSで起動する

つくるもの
---

下記の図のようなものをつくります。


![Untitled Diagram (1).png](https://qiita-image-store.s3.amazonaws.com/0/18331/2df413a3-4982-4aea-293c-ae00727f2322.png "Untitled Diagram (1).png")


やること
---

* ECSでfluentd log driverを使うための起動テンプレートの設定
* appコンテナ、nginxコンテナからfluentdコンテナに送らるログをユニークにする


ECSでfluentd log driverを使うための起動テンプレートの設定
---

EC2インスタンス内で動くecsの設定が下記になる必要があります。
設定ファイルは `/etc/ecs/ecs.config`にあります。


```
ECS_CLUSTER=クラスター名
ECS_AVAILABLE_LOGGING_DRIVERS=["awslogs","fluentd","gelf","json-file","journald","splunk"]
```

これを、EC2の起動時に設定できるように、ユーザーデータ等にわたすようにしています。
`ECS_AVAILABLE_LOGGING_DRIVERS` を設定しないとコンテナが起動しなかったの注意です。

cloudwatchのログストリーム名はコンテナ毎にユニークにしたい
---

このようなECSの設定をしています。

![スクリーンショット 2019-02-28 13.23.05.png](https://qiita-image-store.s3.amazonaws.com/0/18331/edfb6343-4c9a-02d2-86f8-a37c16a558bf.png "スクリーンショット 2019-02-28 13.23.05.png")

下記のようすることでCloudwatchのログストリーム名はコンテナ毎にユニークになります。

```
app.{{.Name}}.{{}.ID}
```

FluentdコンテナをECSで起動する
---

起動するECSインスタンスそれぞれにfluentdコンテナはいてほしいので `DAEMON` で起動します。

![スクリーンショット 2019-02-28 13.28.12.png](https://qiita-image-store.s3.amazonaws.com/0/18331/aac8fc94-89eb-8757-3662-8342a17b6dc9.png "スクリーンショット 2019-02-28 13.28.12.png")

（おまけ）docker-composeでは
---

こんな書いてます。

```
  nginx:
  	 ~ 省略 ~
    logging:
      driver: "fluentd"
      options:
        fluentd-address: "localhost:24224"
        fluentd-async-connect: "true"
        tag: "nginx.{{.Name}}.{{.ID}}"
  fluentd:
    ~ 省略 ~ 
    ports:
      - "24224:24224"
```

(おまけ)fluentコンテナの設定
---

まずベースとなるイメージはfluentd公式のイメージを使っています。
https://hub.docker.com/r/fluent/fluentd/

Dockerfileは下記の用に書き換えています。
特にcloudwatch-logsのプラグインをいれている部分が重要です。

Dockerfile 

```
FROM fluent/fluentd:v1.3.3-debian-1.0
# https://hub.docker.com/r/fluent/fluentd

# Use root account to use apk
USER root

RUN buildDeps="sudo make gcc g++ libc-dev ruby-dev" \
 && apt-get update \
 && apt-get install -y --no-install-recommends $buildDeps \
 && sudo gem install \
        fluent-plugin-elasticsearch \
        fluent-plugin-cloudwatch-logs \
        fluent-plugin-stdin \
    && sudo gem sources --clear-all \
 && SUDO_FORCE_REMOVE=yes \
    apt-get purge -y --auto-remove \
                  -o APT::AutoRemove::RecommendsImportant=false \
                  $buildDeps \
 && rm -rf /var/lib/apt/lists/* \
           /home/fluent/.gem/ruby/2.3.0/cache/*.gem

RUN apt-get update && apt-get install -y uuid-runtime logrotate gzip
COPY fluent.conf /fluentd/etc/fluent.conf
```

`/fluentd/etc/fluent.conf` の内容はこんなかんじです。
（fluentd初心者）


```
<source>
  type forward
  port 24224
</source>

<match app.**>
  @type cloudwatch_logs
  log_group_name /fluentd/my_container/
  auto_create_stream true
  localtime true
  include_time_key true
  use_tag_as_stream true
  use_log_stream_name_prefix true
</match>

<match nginx.**>
  @type cloudwatch_logs
  log_group_name /fluentd/my_container/
  auto_create_stream true
  localtime true
  include_time_key true
  use_tag_as_stream true
  use_log_stream_name_prefix true
</match>
```