使用Fluentd+Elasticsearch+Kibana将Docker中Nginx的访问日志可视化
做的事情 (zuò de
我将使用两个容器来构建Nginx,并将每个容器的索引分开发送到Elasticsearch。
为了构建两台 Nginx,需要切换端口进行访问。但是,由于设置不整洁,我们使用了名为 Traefik 的反向代理,以路径为基础将访问指向不同的 Nginx。这样一来,只需要公开 Traefik 的 80 号端口就好了。

我参考了以下关于Trafik的构成。
- docker-composeでリバースプロキシとしてtraefikを使う
提供一个中国版的选项。
源代码已上传至下方位置。
- v1tam1nb2/traefik-nginx-fluentd-elasticsearch
快速启动
git clone https://github.com/v1tam1nb2/traefik-nginx-fluentd-elasticsearch.git
cd traefik-nginx-fluentd-elasticsearch
docker-compose build
docker-compose up -d
curl http://localhost/service-a.html
curl http://localhost/service-b.html
在访问之后,我们将访问Kibana以查看日志。
在第一次访问时,需要创建以下的数据视图。
- http://localhost:5601/app/management/kibana/dataViews
请参阅以下关于数据视图的内容。
- Create a data view
如果最终能够确认这样的日志,那就没问题了。

请用中文原生方式来解释以下的意思,只需一个选项:
来源
草图(Traefik)
以下是Traefik的部分配置。端口18000:8080用于访问Traefik的仪表板。这次不太需要关注。
# リバプロ
traefik:
image: traefik:latest
container_name: "traefik"
ports:
- "80:80"
- "18000:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- ./src/traefik/traefik.yml:/etc/traefik/traefik.yml
# Provider
providers:
docker:
exposedByDefault: false
# エントリーポイント
entryPoints:
http:
address: ":80"
# clickhouse:
# address: ":9000"
# udp-test:
# address: ":3179/udp"
api:
# Dashboard有効化
dashboard: true
insecure: true
# ログレベル
log:
level: DEBUG
Nginx 反向代理服务器
nginx_a:
image: nginx
container_name: nginx_a
hostname: nginx_a
volumes:
- ${PWD}/src/nginx/service-a.html:/usr/share/nginx/html/service-a.html
labels:
- "traefik.enable=true"
- "traefik.http.routers.service-a.rule=PathPrefix(`/service-a`)"
- "traefik.http.routers.service-a.entrypoints=http"
depends_on:
- fluentd
logging:
driver: "fluentd"
options:
fluentd-address: localhost:24224
tag: nginx.a.access
# 起動時に接続を確立的無くても contaienr は起動する設定
fluentd-async-connect: "true"
nginx_b:
image: nginx
container_name: nginx_b
hostname: nginx_b
volumes:
- ${PWD}/src/nginx/service-b.html:/usr/share/nginx/html/service-b.html
labels:
- "traefik.enable=true"
- "traefik.http.routers.service-b.rule=PathPrefix(`/service-b`)"
- "traefik.http.routers.service-b.entrypoints=http"
depends_on:
- fluentd
logging:
driver: "fluentd"
options:
fluentd-address: localhost:24224
tag: nginx.b.access
# 起動時に接続を確立的無くても contaienr は起動する設定
fluentd-async-connect: "true"
在labels中,使用Traefik来定义路由设置。下面的配置是当访问http://localhost/service-a.html时,将会查看到nginx_a容器的service-a.html文件。
traefik.http.routers.service-a.entrypoints指定了traefik.yml中定义的entrypoint。本次我们定义了一个名为http的entrypoint。
labels:
- "traefik.enable=true"
- "traefik.http.routers.service-a.rule=PathPrefix(`/service-a`)"
- "traefik.http.routers.service-a.entrypoints=http"
以下是用于将容器日志传送到Fluentd的配置。为了根据每个容器的Index进行区分,我们使用标签进行识别。
logging:
driver: "fluentd"
options:
fluentd-address: localhost:24224
tag: nginx.a.access
# 起動時に接続を確立的無くても contaienr は起動する設定
fluentd-async-connect: "true"
Fluentd 流利docker
正在安装Elastisearch的插件。
# https://docs.fluentd.org/output/elasticsearch
FROM fluent/fluentd:v1.15.0-debian-1.0
USER root
# FluentdとElasticsearchを連携させるためのプラグインをインストール
RUN gem install fluent-plugin-elasticsearch --no-document --version 5.2.4
USER fluent
fluentd:
build: ./src/fluentd
container_name: fluentd
hostname: fluentd
restart: always
ports:
- "24224:24224"
- "24220:24220"
- "24224:24224/udp"
# depends_on:
# - es
volumes:
#- ${PWD}/log:/fluentd/log
- ${PWD}/src/fluentd/fluent.conf:/fluentd/etc/fluent.conf:ro
在conf配置中,我们根据标签将输出目标的索引进行分开。nginx_a容器的日志将存储在索引nginx-a-log*中,nginx_b容器的日志将存储在索引nginx-b-log*中。
# Fluentdの内部メトリックをHTTPで取得できる設定
# https://docs.fluentd.org/input/monitor_agent
<source>
@type monitor_agent
bind 0.0.0.0
port 24220
</source>
# データのInput設定
<source>
@type forward
port 24224
bind 0.0.0.0
</source>
# データのOutput設定 (FluentdからElasticsearch)
# tag "nginx.a"にマッチするログをESに転送
<match nginx.a.**>
@type copy
<store>
@type elasticsearch
host elasticsearch
port 9200
logstash_format true
logstash_prefix nginx-a-log
logstash_dateformat %Y%m%d
include_tag_key true
type_name access_log
tag_key @log_name
flush_interval 1s
</store>
<store>
@type stdout
</store>
# バッファの定義
<buffer>
@type file
flush_mode interval
flush_interval 10s
path /var/log/fluentd/elasticsearch
chunk_limit_size 512m
flush_at_shutdown true
</buffer>
</match>
# データのOutput設定 (FluentdからElasticsearch)
# tag "nginx.b"にマッチするログをESに転送
<match nginx.b.**>
@type copy
<store>
@type elasticsearch
host elasticsearch
port 9200
logstash_format true
logstash_prefix nginx-b-log
logstash_dateformat %Y%m%d
include_tag_key true
type_name access_log
tag_key @log_name
flush_interval 1s
</store>
<store>
@type stdout
</store>
# バッファの定義
<buffer>
@type file
flush_mode interval
flush_interval 10s
path /var/log/fluentd/elasticsearch
chunk_limit_size 512m
flush_at_shutdown true
</buffer>
</match>
Elasticsearch/Kibana 弹性搜索/基本分析
请注意,我们这次使用的是8.4.3版本。为了简化操作,我们采用了单节点的建设方式。
# Elasticsearchコンテナ
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.4.3
container_name: elasticsearch
hostname: elasticsearch
restart: always
environment:
- discovery.type="single-node"
- cluster.name="es-cluster"
- node.name="elasticsearch"
- bootstrap.memory_lock=true
- xpack.security.enabled=false
- TZ=Asia/Tokyo
ulimits:
memlock:
soft: -1
hard: -1
# volumes:
# # データを永続化
# - ${PWD}/data:/usr/share/elasticsearch/data
ports:
- 9200:9200
# Kibanaのコンテナ
kibana:
image: docker.elastic.co/kibana/kibana:8.4.3
container_name: kibana
hostname: kibana
ports:
- 5601:5601
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- TZ=Asia/Tokyo
- I18N_LOCALE=ja-JP
depends_on:
- elasticsearch
restart: always
总结
コンテナのログをFluentd経由でElasticsearchに転送し、Kibanaで確認することができました。
Fluentdのtagを利用することでアウトプット先のIndexを分けることができました。
这次我们没有进行日志处理等工作,但如果有机会的话,我想尝试一下。