为啥 Loki 的 Docker 驱动程序客户端在一段时间后停止登录?

Posted

技术标签:

【中文标题】为啥 Loki 的 Docker 驱动程序客户端在一段时间后停止登录?【英文标题】:Why is Loki's Docker Driver Client stopping to log after some time?为什么 Loki 的 Docker 驱动程序客户端在一段时间后停止登录? 【发布时间】:2021-04-27 16:11:32 【问题描述】:

我想将我的 Docker 容器的日志发送到 Grafana Loki。因此,我安装了 Loki 的 Docker Driver Client 并用它启动了我的容器。一开始我可以看到日志,但一段时间后我看不到更多日志。

安装

我在我的 Docker 引擎(版本 20.10.2)上以 Docker plugin 的形式安装了 Loki 的 Docker 驱动程序客户端:

$ docker plugin install grafana/loki-docker-driver:master-54d1d3b --alias loki --grant-all-permissions

我没有使用标签lastest,因为错误Unable to connect to logging plugin in Swarm

配置

我使用 Loki 的 Docker Driver Client 作为日志驱动程序启动了我的 Docker 容器:

$ docker container run
  --log-driver=loki
  --log-opt loki-url="$LOKI_URL"
  --log-opt loki-retries=5
  --log-opt loki-batch-size=400
  --log-opt max-size="10m"
  --log-opt max-file=5
  --detach
  --name $CONTAINER_NAME
  --restart unless-stopped
  $IMAGE:$TAG

我还添加了json-log驱动的max-sizemax-file来限制磁盘空间,见Configuring the Docker Driver。

问题

首先我可以在Grafana 和docker container logs 的命令行中看到日志,但一段时间后不再显示日志。如果我尝试查看 Docker 主机上的日志并看到错误:

$ docker container logs 75d4b13eb3e8
error from daemon in stream: Error grabbing logs: error getting log reader: LogDriver.ReadLogs: logger does not exist for 75d4b13eb3e8203b9247ecdeb41fdf495cc8fea7dcfc4775fd8261263b1dcd32

研究

我查看了容器的目录(请参阅Where is a log file with logs from a container?),但看不到任何日志文件:

$ sudo ls /var/lib/docker/containers/75d4b13eb3e8203b9247ecdeb41fdf495cc8fea7dcfc4775fd8261263b1dcd32
checkpoints  config.v2.json  hostconfig.json  hostname  hosts  mounts  resolv.conf  resolv.conf.hash

我也检查了日志路径(见Get an instance’s log path),但它是空的:

$ docker inspect --format='.LogPath' 75d4b13eb3e8

我在插件目录中找到了容器的日志(参见Loki log driver not storing logs as files on disk, even with keep-file: true),但日志文件不再更改:

$ sudo ls -la /var/lib/docker/plugins/eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288/rootfs/var/log/docker/75d4b13eb3e8203b9247ecdeb41fdf495cc8fea7dcfc4775fd8261263b1dcd32
total 912
drwxr-xr-x  2 root root   4096 Jan 22 12:59 .
drwxr-xr-x 17 root root   4096 Jan 22 15:46 ..
-rw-r-----  1 root root 923177 Jan 22 13:34 json.log

我查看了 Docker 守护程序的日志(请参阅 Read the logs)并发现错误和警告(同时记录停止):

$ sudo journalctl -u docker.service | grep eac33cc9913c
[...]
[...]level=error msg="panic: send on closed channel" plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=error plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=error msg="goroutine 153 [running]:" plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=error msg="main.(*loki).Log(0xc0000c5e00, 0xc0001d81c0, 0xc0000c5e80, 0x0)" plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=error msg="\t/src/loki/cmd/docker-driver/loki.go:69 +0x2fb" plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=error msg="main.consumeLog(0xc0002c0480)" plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=error msg="\t/src/loki/cmd/docker-driver/driver.go:165 +0x4c2" plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=error msg="created by main.(*driver).StartLogging" plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=error msg="\t/src/loki/cmd/docker-driver/driver.go:116 +0xa75" plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=warning msg="Unable to connect to plugin: /run/docker/plugins/eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288/loki.sock/LogDriver.StopLogging: Post http://%2Frun%2Fdocker%2Fplugins%2Feac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288%2Floki.sock/LogDriver.StopLogging: EOF, retrying in 1s"
[...]

我做错了什么?

【问题讨论】:

【参考方案1】:

我遇到了同样的问题。

我在配置上的唯一区别是我正在试用最新的企业版 (19.03),因为它带来了dual logging capability,尽管最新的 CE 版本也支持这一点,而且我现在使用的是最新的 Loki Docker 驱动程序客户端前面提到的 Github 问题已经解决。

我最终在 docker-compose.yml 中设置了 log-opts properties no-filekeep-file

logging:
  driver: "loki"
  options:
    loki-url: "http://$LOKI_URL:3100/loki/api/v1/push"
    loki-batch-size: "400"
    no-file: "false"
    keep-file: "true"
    max-size: "5m"
    max-file: "3"

自从进行此更改后,我在 Loki 中收到了日志,并且仍然可以在我的 Docker 主机上使用 docker 容器日志和 docker 服务日志。

no-file: "false" 告诉驱动程序继续在磁盘上创建日志,keep-file: "true" 告诉驱动程序在容器停止时保留 json 日志(默认情况下会删除文件)。

注意:最初我将这些设置添加到主机上的 /etc/docker/daemon.json 但仍然会看到 error getting log reader 问题,我不得不切换到为每个容器/群服务指定日志驱动程序。

【讨论】:

no-file: "false" 是默认值,所以我也在使用它。我没有设置keep-file: "true"。我会试试看。但是我还必须使用max-file 来清理日志文件。【参考方案2】:

关于这个问题

首先我可以在 Grafana 和命令行中使用 docker 容器日志查看日志,但一段时间后不再显示日志。

Grafana 上,请选择 Query type: Range 而不是 Instant,您将看到所选时间段内的所有日志(如果存在)在洛基。

【讨论】:

使用Grafana不是问题。 Loki 中没有日志了。

以上是关于为啥 Loki 的 Docker 驱动程序客户端在一段时间后停止登录?的主要内容,如果未能解决你的问题,请参考以下文章

隐藏 docker 驱动参数

如何从本地 Docker 守护进程获取 GELF 日志到 Loki?

为啥 Loki 库没有得到更广泛的使用?

docker-compose Install loki+promtail

docker-compose Install loki+promtail

Loki生产环境集群方案