TECHLOGICS

HYLOGICS分室。作業メモやガジェットのレビューなど、主に技術系のエントリを取り扱います。

【備忘録】dockerのログをfluentdでS3に保存する

要件

AWS EC2で動かしているdockerのログの管理が面倒臭いので、S3に集約したい。

大事なこと

S3へのアクセスコントロールは幾つか手段があってややこしいように見えるが、サーバからファイルをputするだけならIAMでEC2インスタンスにロールを設定するだけで良い。アクセスキーを取得する必要さえないし、インスタンスが増えても生成時に既存のポリシーを使い回し可能なので追加の設定も必要ない。

S3にバケット作成

バケット側に特に設定の必要はない。ただ、バケット名は後で変更が出来ないため注意。

f:id:kirine:20180604223141p:plain

ロールの作成

IAMダッシュボードからロールの作成。

f:id:kirine:20180604223220p:plain

対象のサービスにEC2を選択。

f:id:kirine:20180604223257p:plain

適用するポリシーを選択する。ここではログの読み書きのためAmazonS3FullAccessを選択。

f:id:kirine:20180604223345p:plain

ロール名を入力。ロール名は後で変更できないため注意が必要。

f:id:kirine:20180604223437p:plain

あとは新規にインスタンスを建てる時に適用するだけ。既存のインスタンスにもオンラインで適用可。

f:id:kirine:20180604223457p:plain

docker-compose.yml

#テスト用にApacheのコンテナを立てているが、logging driverにfluentdを指定していれば何でもいい。

$ cat docker-compose.yml
version: '3'
services:
  php7:
    build: "./httpd-jp:2.4.33-alpine-php7"
    container_name: "php7"
    ports:
      - "8080:80"
    volumes:
      - "/mnt/data/www:/usr/local/apache2/htdocs"
    logging:
      driver: "fluentd"
    depends_on:
      - "fluentd"
  fluentd:
    build: "./fluentd:v1.1.3-alpine"
    container_name: "fluentd"
    ports:
      - "24224:24224"
    logging:
      driver: "json-file"

Dockerfile

fluentd v1.1.3 alpine-onbuildのDockerfileを元にしています。

fluentd-docker-image/v1.1/alpine-onbuild at master · fluent/fluentd-docker-image · GitHub

$ cat ./fluentd\:v1.1.3-alpine/Dockerfile
# AUTOMATICALLY GENERATED
# DO NOT EDIT THIS FILE DIRECTLY, USE /Dockerfile.template.erb


# libc-dev make gcc
#RUN gem i bson_ext

FROM alpine:3.7
LABEL Description="Fluentd docker image" Vendor="Fluent Organization" Version="1.1"

ENV DUMB_INIT_VERSION=1.2.0

ENV SU_EXEC_VERSION=0.2

ARG DEBIAN_FRONTEND=noninteractive

# Do not split this into multiple RUN!
# Docker creates a layer for every RUN-Statement
# therefore an 'apk delete' has no effect
RUN apk update \
 && apk upgrade \
 && apk add --no-cache \
        ca-certificates \
        ruby ruby-irb \
        su-exec==${SU_EXEC_VERSION}-r0 \
        dumb-init==${DUMB_INIT_VERSION}-r0 \
 && apk add --no-cache --virtual .build-deps \
        build-base \
        ruby-dev wget gnupg \
 && apk add tzdata \
 && update-ca-certificates \
 && echo 'gem: --no-document' >> /etc/gemrc \
 && gem install oj -v 3.3.10 \
 && gem install json -v 2.1.0 \
 && gem install fluentd -v 1.1.3 \
 && gem install fluent-plugin-s3 \
 && apk del .build-deps \
 && rm -rf /var/cache/apk/* \
 && rm -rf /tmp/* /var/tmp/* /usr/lib/ruby/gems/*/cache/*.gem

# set Timezone JST
RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

# for log storage (maybe shared with host)
RUN mkdir -p /fluentd/log
# configuration/plugins path (default: copied from .)
RUN mkdir -p /fluentd/etc /fluentd/plugins

COPY fluent.conf /fluentd/etc/
COPY entrypoint.sh /bin/
RUN chmod +x /bin/entrypoint.sh

ONBUILD COPY fluent.conf /fluentd/etc/
ONBUILD COPY plugins /fluentd/plugins/

ENV FLUENTD_OPT=""
ENV FLUENTD_CONF="fluent.conf"

ENV LD_PRELOAD=""
ENV DUMB_INIT_SETSID 0

EXPOSE 24224 5140

ENTRYPOINT ["/bin/entrypoint.sh"]

CMD exec fluentd -c /fluentd/etc/${FLUENTD_CONF} -p /fluentd/plugins $FLUENTD_OPT

差分は以下の通り。

  • localtimeをJSTに変更
  • fluent-plugin-s3を導入
$ diff Dockerfile fluentd\:v1.1.3-alpine/Dockerfile
3a4,7
>
> # libc-dev make gcc
> #RUN gem i bson_ext
>
26a31
>  && apk add tzdata \
31a37
>  && gem install fluent-plugin-s3 \
34a41,43
>
> # set Timezone JST
> RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

ちょっとゴミが混ざっているけど今回はこのまま進める。

$ cat fluentd\:v1.1.3-alpine/fluent.conf
<source>
  @type  forward
  @id    input1
  @label @mainstream
  port  24224
</source>

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

<label @mainstream>
  <match **>
    @type copy
    <store>
      type s3
      s3_bucket hylogics-log
      s3_region ap-northeast-1
      s3_object_key_format %{path}%{time_slice}/%{index}.%{hostname}.%{file_extension}
      path access-logs/
      time_slice_format %Y%m%d-%H
      time_slice_wait 5m
      localtime
      include_time_key true
    </store>
  </match>
</label>

entrypoint.shは特に変更なし。

動作確認

ログが吐き出されればOK。

$ aws s3 ls hylogics-log --recursive | sort
2018-06-04 20:06:17        650 access-logs/20180604-19/0.753c898f1a28.gz
2018-06-04 20:08:15        329 access-logs/20180604-20/0.753c898f1a28.gz
2018-06-04 20:08:48        461 access-logs/20180604-20/1.753c898f1a28.gz
2018-06-04 20:22:29       1065 access-logs/20180604-20/2.753c898f1a28.gz
2018-06-04 21:06:10       2041 access-logs/20180604-20/3.753c898f1a28.gz
2018-06-04 21:41:27       4224 access-logs/20180604-21/0.753c898f1a28.gz