やりたいこと
ローカルでFluentdコンテナを動かして、他のコンテナの標準出力を集めてS3にログを保存したい。
構成
Fluentdコンテナと、サンプルとしてそこに出力を送り込むNginxコンテナを作ります。
├─fluentd
│ docker-compose.yml
│ Dockerfile
│ fluent.conf
│
└─nginx
docker-compose.yml
Fluentdコンテナ
Dockerfile
FROM fluent/fluentd:v1.12.2-1.0
# Timezone
ARG TZ
RUN echo ${TZ}
USER root
RUN apk add --update --no-cache tzdata && \
cp /usr/share/zoneinfo/${TZ} /etc/localtime && \
echo ${TZ} > /etc/timezone && \
apk del tzdata
# AWS
ARG AWS_KEY_ID
ARG AWS_SEC_KEY
ARG S3_BUCKET
ARG AWS_REGION
ENV AWS_KEY_ID=${AWS_KEY_ID}
ENV AWS_SEC_KEY=${AWS_SEC_KEY}
ENV S3_BUCKET=${S3_BUCKET}
ENV AWS_REGION=${AWS_REGION}
# for fluentd v1.0 or later
RUN gem install fluent-plugin-s3 --no-document
# Config
USER fluent
COPY fluent.conf /fluentd/etc/
デフォルトだとログのタイムスタンプがUTCになってしまうのでタイムゾーンの設定と、S3出力のためのプラグインをインストールします。
docker-compose.yml
version: '3.7'
services:
fluentd:
build:
context: ./
args:
TZ: Asia/Tokyo
AWS_KEY_ID: XXXXXXXXXXXXXXXX
AWS_SEC_KEY: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
S3_BUCKET: mybucket
AWS_REGION: ap-northeast-1
restart: always
ports:
- 24224:24224
- 24224:24224/udp
タイムゾーンとAWSのアクセスキーと出力先のバケットを渡します。
fluent.conf
<source>
@type forward
port 24224
bind 0.0.0.0
</source>
<match debug.**>
@type copy
<store>
@type file
path /fluentd/log/debug
time_slice_format %Y%m%dT%H%M
time_slice_wait 5m
</store>
<store>
@type stdout
</store>
</match>
<match s3.**>
@type s3
aws_key_id "#{ENV['AWS_KEY_ID']}"
aws_sec_key "#{ENV['AWS_SEC_KEY']}"
s3_bucket "#{ENV['S3_BUCKET']}"
s3_region "#{ENV['AWS_REGION']}"
check_object false
time_slice_format %Y%m%dT%H%M
time_slice_wait 5m
path fluentd_logs/
s3_object_key_format %{path}%{time_slice}/%{hms_slice}.%{file_extension}
</match>
<match **>
@type stdout
</match>
s3.**
タグにマッチした入力がS3に保存されるように設定します。
確認用に保存のタイミングを短くしています。
コンテナの起動・確認
Fluentdコンテナを起動して、直接データを入力してみます。
>docker-compose up -d
>docker-compose exec fluentd sh
$ echo '{"hello":"fluentd"}' | fluent-cat debug.test
$ ls -l /fluentd/log/debug/
-rw-r--r-- 1 fluent nogroup 57 Apr 28 14:00 buffer.b5c1014353321a2e64426684b2464c202.log
-rw-r--r-- 1 fluent nogroup 79 Apr 28 14:00 buffer.b5c1014353321a2e64426684b2464c202.log.meta
$ ls -l /fluentd/log/
drwxr-xr-x 2 fluent nogroup 4096 Apr 28 14:07 debug
-rw-r--r-- 1 fluent nogroup 57 Apr 28 14:04 debug.20210428T1400.log
$ cat /fluentd/log/debug.20210428T1400.log
2021-04-28T14:00:52+09:00 debug.test {"hello":"fluentd"}
$ echo '{"hello":"fluentd"}' | fluent-cat s3.test
>aws s3 ls s3://mybucket/fluentd_logs/
PRE 20210428T1400/
コンテナ内部とS3にログが保存されることが確認できました。
S3にはgzip形式でログが保存されます。
Nginxコンテナ
docker-compose.yml
version: '3.7'
services:
web:
image: nginx:latest
ports:
- "80:80"
logging:
driver: "fluentd"
options:
fluentd-address: "localhost:24224"
tag: "s3.docker.{{.Name}}"
fluentd-async-connect: "true"
Nginxの公式イメージはデフォルトでアクセスログを標準出力にエラーログを標準エラー出力に吐くのでロギング・ドライバにFluentdを指定すればそのままログが流れます。
コンテナを起動して、NginxデフォルトページにアクセスするとS3にアクセスログが保存されているのが確認できます。
2021-04-28T14:55:31+09:00 s3.docker.nginx_web_1 {"source":"stdout","log":"172.23.0.1 - - [28/Apr/2021:05:55:31 +0000] \"GET / HTTP/1.1\" 200 612 \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36\" \"-\"","container_id":"410c2125509ef500c8a22a3093c95ac1b9ee51d9ff893a4d062f7bb7fb56a8c9","container_name":"/nginx_web_1"}