Grafana Loki:Docker 容器日志解决方案

背景

目前服务是使用 docker compose 管理的,容器化之后部署是方便很多了,但是每次查看日志都需要手动输入docker compose logs -f -n1命令进行查看。

现在要给做日志统一的采集和管理。

基础概念

按照我的理解,现代的日志主要有三个组件

graph LR
Agent --> DB
DB --> Dashboard
Dashboard --> DB
  

Agent 是观测数据的采集组件,用于执行具体的获取数据的步骤。

Agent 获取到数据之后,就将数据发送到 DB 进行保存。

最后,Dashboard 向 DB 查询数据,以友好的方式展示给用户。

Grafana

大家平时听到最多的可能是 Prometheus + Grafana 的组合。在这里 Prometheus 是一个时序数据库,而 Grafana 是一个可视化面板。

简单的来说,就是 Agent 采集了数据放在 Prometheus 里面,然后 Grafana 读取出来展示给用户。

Loki

引用官方的解释

Loki: like Prometheus, but for logs.

就是,和 Prometheus 类似,不过是专门用来存储日志的。

Docker driver client

属于 Agent,专门用来从 docker daemon 中采集日志

Promtail

同样属于 Agent,专门用来采集本地的日志

采集 Docker 日志方案选择

这里的Docker driver client和 Promtail 都可以采集 docker 的日志。区别在于

  • Promtail:类似于外挂式,独立容器,通过使用 /var/run/docker.sock 来调用 docker api 获取容器的日志,发送到 loki
  • Docker driver client:插件式,在主机上注册一个 docker logging driver,配置容器的 logging driver 即可发送日志到 loki

两个方法效果都可以实现获取容器日志的效果,但也有一些区别

  • Promtail配置 后,需要重启 docker daemon,对所有新创建的容器生效
  • Docker driver client:需要 主动声明 使用该 logging driver

这里我选择后者进行配置,因为 官方就是这样建议的 将 logging 配置写在 compose 文件中更符合额 IaC 的理念。

日志系统规划

由于涉及到不同机器的日志统一管理,还是有必要好好规划一下的。

管理端

感觉命名不是很恰当。就是 DB+Dashboard,因为日志要统一管理,所以肯定是 DB 最好在一台机器上面。

为了部署和使用方便,Dashboard 也放在同一台机子上面。

采集端

因为要采集,所以自然是每一台机器都要部署一份。

安装步骤

还是一贯的理念,IaC,能用 compose 就用 compose

管理端

 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
services:
  grafana:
    image: grafana/grafana
    container_name: grafana
    ports:
      - 3000:3000
    volumes:
      - grafana-storage:/var/lib/grafana
    restart: unless-stopped
    networks:
      - grafana
    extra_hosts:
      - host.docker.internal:host-gateway
    entrypoint:
      - sh
      - -euc
      - |
        mkdir -p /etc/grafana/provisioning/datasources
        cat <<EOF > /etc/grafana/provisioning/datasources/ds.yaml
        apiVersion: 1
        datasources:
        - name: Loki
          type: loki
          access: proxy 
          orgId: 1
          url: http://loki:3100
          basicAuth: false
          isDefault: true
          version: 1
          editable: false
        EOF
        /run.sh        
  loki:
    image: grafana/loki:2.9.10
    ports:
      - 3100:3100
    restart: unless-stopped
    command: -config.file=/etc/loki/local-config.yaml
    networks:
      - grafana

volumes:
  grafana-storage:

networks:
  grafana:

采集端

这里我主要是要采集 docker 容器的日志,所以使用 Docker driver client

1
2
docker plugin install grafana/loki-docker-driver:2.9.2 --alias loki --grant-all-permissions
docker plugin ls

安装之后,配置 loki 的地址(Agent 主动 push 到 loki)。

这里需要手动在应用的 compose 文件里面定义

1
2
3
4
5
6
7
8
version: "3.7"
services:
  logger:
    image: grafana/grafana
    logging:
      driver: loki
      options:
        loki-url: "https://<user_id>:<password>@logs-prod-us-central1.grafana.net/loki/api/v1/push"

很简单,就这样加个 logging 选项就行了

如果没有达到预期效果,可以用下面的命令,driver 的日志会显示在这里

1
journalctl -u docker -f

然后,添加 Dashboard,我用的是 这个

image.png

然后,就可以方便的看日志了