FluentdとDockerとKinesis Firehose その1(Dockerイメージ作成編)

# はじめに
公式のFluentdのDockerイメージからKinesis Data Firehoseまでの連携までを頑張る作業ログであります。

- [その2](https://qiita.com/arata-honda/items/544563570f35dbc5a9a6)

# Dockerfile
こちらが今回作ったDockerfile

```dockerfile
FROM fluent/fluentd:v1.9-1

USER root

COPY ./fluent.conf /etc/fluent/

# install plugin
RUN apk add --update-cache --virtual .build-deps sudo build-base ruby-dev \
    && gem install fluent-plugin-kinesis -v 3.0.0 --no-document \
    && gem sources --clear-all \
    && apk del .build-deps \
    && rm -rf /var/cache/apk/* \
    /home/fluent/.gem/ruby/*/cache/*.gem

# set timezone (Alpine)
RUN apk --update-cache add tzdata && \
    cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
    apk del tzdata && \
    rm -rf /var/cache/apk/*
```

使った[公式のFluentdのイメージ](https://hub.docker.com/r/fluent/fluentd/)はこちら
<img width="762" alt="スクリーンショット 2020-02-13 15.17.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211139/487f1d8d-7382-4dfd-d1e5-0e4e23620327.png">

alpineを使います。
alpineを使う理由としては不必要なものがインストールされていないので非常に軽量なイメージであるという点で、ゆくゆくはECS + Fragateに載せるときにちゃんと乗るようにという意味で使っています。

必要なパッケージとしては

- sudo: [sudoがもともとない](https://qiita.com/tetsu_koba/items/904b03e908b040ed447d)のと、[gem installの権限エラー](https://qiita.com/tokimari/items/feda1ed61f2d8b5b317c)のため
- build-base: ビルド用のパッケージ?([こういうとき](https://stackoverflow.com/questions/33421965/installing-numpy-on-docker-alpine)にエラーが出るのだとか。)
- ruby-dev: [gem install用](https://rubygems.org/gems/ruby-dev/versions)

`apk add --update-cache --virtual .build-deps ...`
三つのパッケージをbuild-depsという名前で一括インストしますという意味
(delするときに一括で消せたりする)

kinesis data firehoseのプラグインに関しては
[AWSlabの公式プラグイン](https://github.com/awslabs/aws-fluent-plugin-kinesis/tree/v3)
を使っています。現在はv3なので、

`gem install fluent-plugin-kinesis -v 3.0.0 --no-document`

このようにバージョンを指定しております。
--no-ducumentをつけている理由は[こちら](https://qiita.com/ginpei/items/49f2c749c2b12098718e)を参考にしました。

プラグインインストール後はパッケージが残るので消しておくとimageの軽量化に繋がります。

Timezoneに関しては[ここ](https://qiita.com/dtan4/items/8359e389b95cbc60952d)を参照にしました。
confはまだ動くのを確認してないので下記にはあげないですが、buildは成功しました

```
$ docker build . -t fluent/fluentd:v1.9-1
Sending build context to Docker daemon  4.096kB
Step 1/5 : FROM fluent/fluentd:v1.9-1
v1.9-1: Pulling from fluent/fluentd
...

Step 3/5 : COPY ./fluent.conf /fluentd/etc/
 ---> a6c007f06146
Step 4/5 : RUN apk add --update-cache --virtual .build-deps sudo build-base ruby-dev     && gem install fluent-plugin-kinesis -v 3.0.0 --no-document     && gem sources --clear-all     && apk del .build-deps     && rm -rf /var/cache/apk/*     /home/fluent/.gem/ruby/*/cache/*.gem
 ---> Running in e1f69fd761c1
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/community/x86_64/APKINDEX.tar.gz
(1/23) Installing sudo (1.8.25_p1-r3)
(2/23) Installing binutils (2.31.1-r2)
(3/23) Installing libmagic (5.36-r1)
(4/23) Installing file (5.36-r1)
(5/23) Installing isl (0.18-r0)
(6/23) Installing libgomp (8.3.0-r0)
(7/23) Installing libatomic (8.3.0-r0)
...
Executing busybox-1.29.3-r10.trigger
OK: 189 MiB in 50 packages
Successfully installed jmespath-1.4.0
Successfully installed aws-partitions-1.272.0
Successfully installed aws-eventstream-1.0.3
Successfully installed aws-sigv4-1.1.0
Successfully installed aws-sdk-core-3.90.0
Successfully installed aws-sdk-kinesis-1.20.0
Successfully installed aws-sdk-firehose-1.24.0
Building native extensions. This could take a while...
Successfully installed google-protobuf-3.11.3
Successfully installed fluent-plugin-kinesis-3.0.0
9 gems installed
*** Removed specs cache ***
(1/23) Purging .build-deps (0)
(2/23) Purging sudo (1.8.25_p1-r3)
...
(12/23) Purging musl-dev (1.1.20-r5)
...
 ---> 4af7de5e802e
Step 5/5 : RUN apk --update-cache add tzdata &&     cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime &&     apk del tzdata &&     rm -rf /var/cache/apk/*
 ---> Running in 1dc29757e0be
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/community/x86_64/APKINDEX.tar.gz
(1/1) Installing tzdata (2019c-r0)
Executing busybox-1.29.3-r10.trigger
OK: 31 MiB in 28 packages
(1/1) Purging tzdata (2019c-r0)
Executing busybox-1.29.3-r10.trigger
OK: 28 MiB in 27 packages
Removing intermediate container 1dc29757e0be
 ---> f84414ed4cbc
Successfully built f84414ed4cbc
Successfully tagged fluent/fluentd:v1.9-1
```

buildしたら、確認

```
$ docker images
REPOSITORY                                                                                 TAG                 IMAGE ID            CREATED             SIZE
fluent/fluentd                                                                             v1.9-1              f84414ed4cbc        9 seconds ago       50.7MB
```
50.7MBは結構軽いと思います

runしてみる
※runに関しては公式の「How to use this image」を参考
https://hub.docker.com/r/fluent/fluentd/

```
$ docker run -d -p 24224:24224 -v /Users/a-honda/recochoku/learn-fluentd/fluentd-data/:/fluentd/log fluent/fluentd:v1.9-1
a1b12b666ea56c77ee2e17ace9b7eb820628da6af44a7127903a9f38f9e8d15d
```

ポートは24224:24224になっているのは
公式のfluent.confがそうなっているからである
https://github.com/fluent/fluentd-docker-image/blob/master/v1.9/alpine/fluent.conf

ちなみにこんな感じ、また-vでマウントしているのはsymlinkで
/fluentd/log/をマウントしているから.

```config
<source>
  @type  forward
  @id    input1
  @label @mainstream
  port  24224
</source>

<filter **>
  @type stdout
</filter>

<label @mainstream>
  <match docker.**>
    @type file
    @id   output_docker1
    path         /fluentd/log/docker.*.log
    symlink_path /fluentd/log/docker.log
    append       true
    time_slice_format %Y%m%d
    time_slice_wait   1m
    time_format       %Y%m%dT%H%M%S%z
  </match>
  <match **>
    @type file
    @id   output1
    path         /fluentd/log/data.*.log
    symlink_path /fluentd/log/data.log
    append       true
    time_slice_format %Y%m%d
    time_slice_wait   10m
    time_format       %Y%m%dT%H%M%S%z
  </match>
</label>
```

psはこんな感じ

```
$ docker ps
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS                                NAMES
a1b12b666ea5        fluent/fluentd:v1.9-1   "tini -- /bin/entryp…"   5 seconds ago       Up 4 seconds        5140/tcp, 0.0.0.0:24224->24224/tcp   intelligent_yonath
```

続きます。
ちなみになんでこんなことしてるかっていうと
firelensのfluentdのカスタムイメージがないから
https://hub.docker.com/r/amazon/aws-for-fluent-bit
↑はあるのに...

つづく

# 参考ページ

- [ECS FargateでSidecarのFluentdでログをS3に送る構成をCloudFormationで構築する](https://www.sambaiz.net/article/221/)
- [awslabs/aws-fluent-plugin-kinesis](https://github.com/awslabs/aws-fluent-plugin-kinesis/tree/v3)
- [Alpine Linux入門 -内部構造とapkでパッケージインストール編-](https://blog.stormcat.io/post/entry/alpine-entry-apk/)
- [fluent/fluentd](https://hub.docker.com/r/fluent/fluentd/)

# 2020年02月14日追記
Dockerfileのところ,
`COPY ./fluent.conf /fluentd/etc/`
こう書いてたのですが、よくみたら、confを参照するパスが間違っていて
`Not Such file fluent.conf`になっていたので下記に修正します

`COPY ./fluent.conf /etc/fluent/`

/etc下のfluentでした〜汗
dockerfileのところも書き直しておきます。

そうしたあともういっかいビルドして`docker exec -it コンテナID /bin/.bash`ではいって、`fluentd`コマンドをうつと
![スクリーンショット 2020-02-14 10.45.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211139/eb2a497c-4d11-6419-3175-bed9eb5b14b6.png)

こんな感じで読み込んでくれてます。
最初のinfoで`fluent-plugin-kinesis`を読み込んでくれているのがわかります!

この状態で別タブを開いて、`docker exec -it コンテナID /bin/.bash`で入って、
`# echo '{"key":"value"}' | fluent-cat docker.test`
と打つと、デフォルトのconfファイルの`docker.**`にマッチして'{"key":"value"}'がfluentd-data/に書き込まれているはず

```bash
/fluentd/log # ls
docker.b59e7f686c2e2f0d81aedbd8a0a6c887e.log
docker.b59e7f686c2e2f0d81aedbd8a0a6c887e.log.meta

/fluentd/log # cat docker.b59e7f686c2e2f0d81aedbd8a0a6c887e.log
2020-02-14T10:48:53+09:00	docker.test	{"key":"value"}
```
ちゃんとマウントしたホスト側にも同じデータがあればいいと思います。