如何将多个 docker 容器的日志发送和聚合到日志中?

Posted

技术标签:

【中文标题】如何将多个 docker 容器的日志发送和聚合到日志中?【英文标题】:How can I send and aggregate multiple docker container's logs to journald? 【发布时间】:2019-09-24 12:17:44 【问题描述】:

我正在运行多个包含 Apache 的容器。我希望所有这些特定的容器集将它们的日志输出记录到一个位置 - 一个文件或 - 或者可能是日志?

我可以通过某种方式将他们的日志汇总在一起 - 一起查看


我不是在寻找像 fluentd / ELK 堆栈这样的繁重解决方案。

我怎样才能实现上述目标?目前所有容器都注销到/dev/stdout,因此被收集在“docker日志”中。但这些似乎不可能聚合​​在一起。

根据Save docker-compose logs to a file,我似乎可以设置一个“日志路径”——但是如何设置?记录驱动程序?并且这个日志文件可以在多个容器之间共享吗?

systemd 日志记录驱动程序是否合适?


所以我对journald 日志记录驱动程序感到很幸运。我在这样的容器上设置了一些labels

version: "3"
services:
  nginx-lb:
    labels:
      - "node_service=nginx"
    logging:
      driver: "journald"
      options:
        labels: "node_service=nginx"
    restart: always
    network_mode: host
    build: .
    ports:
      - "80:80"
      - "443:443"

但是现在,在使用journalctl 查看这些标签时,如何按这些标签进行过滤?

这是一个生成的日志条目示例:

 "__CURSOR" : "s=b300aa41db4946f1bcc528e2522627ce;i=1087c;b=e6decf90a91f40c2ad7507e342fda85a;m=8744b1cdfa;t=5934bdb103a24;x=9ba66ecb768eb67", "__REALTIME_TIMESTAMP" : "1569328890657316", "__MONOTONIC_TIMESTAMP" : "580973088250", "_BOOT_ID" : "e6decf90a91f40c2ad7507e342fda85a", "_MACHINE_ID" : "c1339882251041f48f4612e758675ff3", "_HOSTNAME" : "staging", "PRIORITY" : "6", "_UID" : "0", "_GID" : "0", "_CAP_EFFECTIVE" : "3fffffffff", "_SELINUX_CONTEXT" : "unconfined\n", "_SYSTEMD_SLICE" : "system.slice", "_TRANSPORT" : "journal", "_PID" : "3969", "_COMM" : "dockerd", "_EXE" : "/usr/bin/dockerd", "_CMDLINE" : "/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock", "_SYSTEMD_CGROUP" : "/system.slice/docker.service", "_SYSTEMD_UNIT" : "docker.service", "_SYSTEMD_INVOCATION_ID" : "9f1488b462ae478a84bec6e64d72886b", "CONTAINER_NAME" : "3b9b51b4cda1a1e3b21a01f6fe80c7748fb3d231_apache_1", "CONTAINER_TAG" : "497b2f965b76", "SYSLOG_IDENTIFIER" : "497b2f965b76", "CONTAINER_ID" : "497b2f965b76", "CONTAINER_ID_FULL" : "497b2f965b767f897786f3bb8c4789dd91db1a91fe34e5ede368172f44fb3aac", "MESSAGE" : "192.168.240.1 - - [24/Sep/2019:12:41:30 +0000] \"GET / HTTP/1.0\" 200 2697 \"-\" \"curl/7.58.0\"", "_SOURCE_REALTIME_TIMESTAMP" : "1569328890657297" 

【问题讨论】:

你检查过这个吗:Retrieve log messages with journalctlCONTAINER_NAME 是这里的选项吗? 我想查看/聚合一组容器,而不是我假设 CONTAINER_NAME 的单个容器。 【参考方案1】:

我改为使用 tag 日志记录选项。

version: "3"
services:
  nginx-lb:
    labels:
      - "node_service=nginx"
    logging:
      driver: "journald"
      options:
        labels: "node_service=nginx"
        tag: "nginx"
    restart: always
    network_mode: host
    build: .
    ports:
      - "80:80"
      - "443:443"

然后查看/过滤:

journalctl CONTAINER_TAG=nginx  --since "1 hour ago"

【讨论】:

您能否详细说明这如何解决聚合多个容器日志的问题?当我分配相同的标签 foo 并使用 journalctl --since -1d CONTAINER_TAG=foo 它似乎只输出带有该标签的最后创建容器的日志

以上是关于如何将多个 docker 容器的日志发送和聚合到日志中?的主要内容,如果未能解决你的问题,请参考以下文章

通过配置日志驱动程序将 Docker 容器日志发送到 ELK Stack - 简单方法

如何将日志从 docker 容器转发到主机 journald/syslog 服务?

ELK 处理来自多个 docker 镜像的多行日志

如何使用 docker 在微服务架构中发送日志?

ELK 完整部署和使用 - 每天5分钟玩转 Docker 容器技术(90)

ELK 完整部署和使用 - 每天5分钟玩转 Docker 容器技术(90)