简易Docker日志持久化&中心化方案 Loki

前言

笔者在家庭服务器上运行了一组业务Docker容器,有查看容器日志的需求。docker logs只能查看单个容器的日志,且在容器被删除、需要指定时间范围查询等情况下表现不是很好,所以笔者开始寻找一种简单易用的日志集中管理方案。

Docker提供了logging drivers的配置项[1]来管理日志,可以将日志发送到Logstashfluentd。经过笔者的了解,发现这种方案是比较耳熟的ELK/FEK方案:

elk fek

虽然这套方案比较成熟,应用案例也很多,但对于笔者的个人简单使用场景来说太麻烦了。由于笔者已经部署了Grafana看板,所有笔者最后选择了Grafana生态下的Loki来管理日志。

Loki架构图

最终效果如下图所示,笔者可以在Grafana看板上通过时间范围、关键字、容器名称等参数来查看日志,简单易用且符合笔者需求。

grafana看板

部署

promtail

promtail用于转发容器产生的日志。从Github releases页可以下载到最新版本的二进制文件。虽然promtail也提供官方镜像,但对于promtail这种静态编译的单个执行文件,笔者更喜欢用Supervisor管理。更详细的安装流程参考官方文档[3]

1
2
3
4
$ wget https://github.com/grafana/loki/releases/download/v2.9.3/promtail-linux-amd64.zip
$ unzip promtail-linux-amd64.zip && rm promtail-linux-amd64.zip
$ # 下载默认配置文件
$ wget https://raw.githubusercontent.com/grafana/loki/main/clients/cmd/promtail/promtail-local-config.yaml

配置文件很简单:连上Docker daemon,将标签中带有logging=promtail的容器输出发送给localhost:3100处的loki服务器。因为要区分容器,所以这里还用容器名和jobname标签值来区分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
server:
http_listen_port: 9080
grpc_listen_port: 0

positions:
filename: /tmp/positions.yaml

clients:
- url: http://localhost:3100/loki/api/v1/push

scrape_configs:
- job_name: docker_containers
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
filters:
- name: label
values: ["logging=promtail"]
relabel_configs:
- source_labels: ['__meta_docker_container_name']
regex: '/(.*)'
target_label: 'container'
- source_labels: ['__meta_docker_container_log_stream']
target_label: 'logstream'
- source_labels: ['__meta_docker_container_label_logging_jobname']
target_label: 'job'

启动也很简单,运行(或在 supervisor配置文件中输入)如下命令即可。

1
$ ./promtail-linux-amd64 -config.file promtail-local-config.yaml.yaml

启动后就可以用curl或浏览器访问9080端口进行验证了:

1
2
$ curl 127.0.0.1:9080
<a href="/targets">See Other</a>.

容器配置

上面的配置文件会让promtail只抓取特定容器的日志,所以我们需要在启动业务容器时写入标签。以docker-compose文件为例,在配置文件中写入两个标签即可。

1
2
3
4
5
6
7
8
version: '2.4'

services:
xxx-service:
image: xxx-image:latest
labels:
logging: "promtail" # 表明日志需要被promtail抓取
logging_jobname: "xxx-service" # 将该值加入日志标签,方便后续查看和筛选日志

这也是Loki方案相比ELK/FEK方案的一个优点:只需要重启容器就可以抓取日志,不需要重启Docker服务本身。

Loki

Loki用于接收容器产生的日志。从Github releases页可以下载到最新版本的二进制文件。更详细的安装流程参考官方文档[4]

1
2
3
4
$ wget https://github.com/grafana/loki/releases/download/v2.8.7/loki-linux-amd64.zip
$ unzip loki-linux-amd64.zip && rm loki-linux-amd64.zip
$ # 下载默认配置文件
$ wget https://raw.githubusercontent.com/grafana/loki/main/cmd/loki/loki-local-config.yaml

配置文件很简单:监听本机3100端口,将接收到的日志存储在/tmp/loki/chunks/里。笔者用的就是默认配置(更详细的配置说明参考官方文档[5]),直接启动即可。

1
$ ./loki-linux-amd64 -config.file loki-local-config.yaml

启动后就可以用curl或浏览器访问3100端口进行验证了:

1
2
$ curl 127.0.0.1:3100
404 page not found

Grafana

Grafana的配置更简单。较新版本的Grafana内置了对Loki的支持,在网页中的Data sources配置页面增加一个Loki数据源,输入Loki的HTTP地址,就可以像文章开头那样在Grafana面板的Explore页面里查询日志了。

data sources配置界面

引用


简易Docker日志持久化&中心化方案 Loki
https://www.yooo.ltd/2023/12/26/docker-log-center/
作者
OrangeWolf
发布于
2023年12月26日
许可协议