将日志输出到Docker容器外
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将日志输出到Docker容器外相关的知识,希望对你有一定的参考价值。
参考技术A 我们可以利用 docker logs 命令查看 Docker 容器内部应用程序运行时所产生的日志,可以免除首先进入 Docker 容器,再打开应用程序的日志文件的过程。docker logs 会监控容器中操作系统的标准输出设备(STDOUT),一旦 STDOUT 有数据产生,就会将这些数据传输到另一个“设备”中,该 Docker 的被称为“日志驱动(Logging Driver)”例如,我们有一个容器实例 ID 为 “da6743d61e1a” ,随后我们使用 docker logs 命令,查看 da6743d61e1a 容器的日志
此时,Docker 日志也在同步输出,输出的日志类似下面这样。
Docker 是怎样做到的呢?或者说,所谓的 Docker 日志驱动,到底做了些什么事情?
我们使用 docker info 命令,可以看到 Docker 容器的相关信息,其中有一项 Logging Driver 的字段。
通过输入以上命令,将得到Docker 当前所设置的日志驱动类型:journald
其实,Docker 已为我们提供了大量的日志驱动类型。
通过 --log-opt 参数为 json-file 日志驱动添加了两个选项,max-size=10m 表示 JSON 文件最大为 10MB(超过 10MB 就会自动生成新文件),max-file=3 表示 JSON 文件最多为3个(超过3个就会自动删除多余的旧文件)
除了在启动 Docker 容器时,可指定日志驱动以外,还可以通过修改 Docker 配置文件来指定日志驱动。
打开配置文件 /etc/sysconfig/docker ,找到以下配置片段:
可以看出,默认的日志驱动为 journald,把它修改为 syslog
然后重启 docker
以上众多日志驱动类型中,较为常用 的是 Syslog,因为 Syslog 是 Linux 的日志系统,很多日志分析工具都可以从 Syslog 中获取日志,比如流行的 ELK(Elasticsearch、Logstash、Kibana)日志中心。Logstash 用于收集日志,Syslog 中写入的日志可转发到 Logstash 中,随后将日志存入 Elasticsearch 中,最后可通过 Kibana 来查询日志。
接下来咱们的目标是将 Docker 容器中输出的日志写入 Syslog,那么后面需要做的就是将 Syslog 接入 ELK 了。
默认,Linux 操作系统已经安装了 Syslog 软件包,但它叫 Rsyslog。实际上,Rsyslog 是 Syslog 标准的一种实现,还有一种叫 Syslog-ng 的第三方实现。虽然 Syslog-ng 的功能较为强大,但我们还是选择使用 Rsyslog,因为操作系统已经预装了,我们无须单独安装,可以通过以下命令查看 Rsyslog 是否已安装。
如果要开启 Rsyslog 服务,我们必须对 Rsyslog 进行配置,打开文件 vi /etc/rsyslog.conf
在 rsyslog.conf 文件中有一段配置,我们需要手工去开启
重启 Rsyslog 服务,否则配置无法生效
此时,我们可以查看本地是否对外开启了 514 端口
如何将多个 docker 容器的日志发送和聚合到日志中?
【中文标题】如何将多个 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 withjournalctl
? CONTAINER_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容器外的主要内容,如果未能解决你的问题,请参考以下文章