Docker 日志分为两类:

  • Docker 引擎日志(也就是 dockerd 运行时的日志),
  • 容器的日志,容器内的服务产生的日志。

一 、Docker 引擎日志

Docker 引擎日志一般是交给了 Upstart(Ubuntu 14.04) 或者 systemd (CentOS 7, Ubuntu 16.04)。前者一般位于 /var/log/upstart/docker.log 下,后者我们一般 通过 journalctl -u docker.service 来进行查看。

二、容器日志

2.1、常用查看日志命令——docker logs

docker logs CONTAINER 显示当前运行的容器的日志信息, UNIX 和 Linux 的命令有三种 输入输出,分别是 STDIN(标准输入)、STDOUT(标准输出)、STDERR(标准错误输出),docker logs 显示的内容包含 STOUT 和 STDERR。在生产环境,如果我们的应用输出到我们的日志文件里,所以我们在使用 docker logs 一般收集不到太多重要的日志信息。

nginx 官方镜像,使用了一种方式,让日志输出到 STDOUT,也就是 创建一个符号链接/var/log/nginx/access.log 到 /dev/stdout。
httpd 使用的是 让其输出到指定文件 ,正常日志输出到 /proc/self/fd/1 (STDOUT) ,错误日志输出到 /proc/self/fd/2 (STDERR)。
当日志量比较大的时候,我们使用 docker logs 来查看日志,会对 docker daemon 造成比较大的压力,容器导致容器创建慢等一系列问题。
只有使用了 `local 、json-file、journald` 的日志驱动的容器才可以使用 docker logs 捕获日志,使用其他日志驱动无法使用 `docker logs`

2.2 、Docker 日志 驱动

Docker 提供了两种模式用于将消息从容器到日志驱动。

  • (默认)拒绝,阻塞从容器到容器驱动
  • 非阻塞传递,日志将储存在容器的缓冲区。

当缓冲区满,旧的日志将被丢弃。

在 mode 日志选项控制使用 blocking(默认) 或者 non-blocking, 当设置为 non-blocking需要设置 max-buffer-size 参数(默认为 1MB)。

支持的驱动

使用 Docker-CE 版本,docker logs命令 仅仅适用于以下驱动程序(前面 docker logs 详解也提及到了)

  • local
  • json-file
  • journald

Docker 日志驱动常用命令

查看系统当前设置的日志驱动

docker  info |grep  "Logging Driver"
docker info --format '{{.LoggingDriver}}'

查看单个容器的设置的日志驱动

docker inspect  -f '{{.HostConfig.LogConfig.Type}}'   容器id

Docker 日志驱动全局配置更改

修改日志驱动,在配置文件 /etc/docker/daemon.json(注意该文件内容是 JSON 格式的)进行配置即可。

示例:

{
"log-driver": "syslog"
}

以上更改是针对所有的容器的日志驱动的。我们也可以单独为单一容器设置日志驱动。

Docker 单一容器日志驱动配置

在 运行容器的时候指定 日志驱动 --log-driver

docker  run  -itd --log-driver none alpine ash # 这里指定的日志驱动为 none

日志驱动 一 、local

local 日志驱动 记录从容器的 STOUT/STDERR 的输出,并写到宿主机的磁盘。

默认情况下,local 日志驱动为每个容器保留 100MB 的日志信息,并启用自动压缩来保存。(经过测试,保留100MB 的日志是指没有经过压缩的日志)

local 日志驱动的储存位置 /var/lib/docker/containers/容器id/local-logs/ 以container.log 命名。

local 驱动支持的选项

全局日志驱动设置为—local

在配置文件 /etc/docker/daemon.json(注意该文件内容是 JSON 格式的)进行配置即可。

{
"log-driver": "local",
"log-opts": {
"max-size": "10m"
}
}

重启 docker 即可生效。

单个容器日志驱动设置为—local

运行容器并设定为 local 驱动。

#  运行一个容器 ,并设定日志驱动为 local ,并运行命令 ping www.baidu.com
[root@localhost docker]# docker run -itd --log-driver local alpine ping www.baidu.com
3795b6483534961c1d5223359ad1106433ce2bf25e18b981a47a2d79ad7a3156
# 查看运行的容器的 日志驱动是否是 local
[root@localhost docker]# docker inspect -f '{{.HostConfig.LogConfig.Type}}' 3795b6483534961c
local
# 查看日志
[root@localhost local-logs]# tail -f /var/lib/docker/containers/3795b6483534961c1d5223359ad1106433ce2bf25e18b981a47a2d79ad7a3156/local-logs/container.log
NNdout????:64 bytes from 14.215.177.38: seq=816 ttl=55 time=5.320 ms
NNdout?μ???:64 bytes from 14.215.177.38: seq=817 ttl=55 time=4.950 ms
注意事项: 经过测试,当我们产生了100 MB 大小的日志时 会有 四个压缩文件和一个container.log:
[root@localhost local-logs]# ls -l
total 32544
-rw-r-----. 1 root root 18339944 May 16 09:41 container.log
-rw-r-----. 1 root root 3698660 May 16 09:41 container.log.1.gz
-rw-r-----. 1 root root 3726315 May 16 09:41 container.log.2.gz
-rw-r-----. 1 root root 3805668 May 16 09:41 container.log.3.gz
-rw-r-----. 1 root root 3744104 May 16 09:41 container.log.4.gz 那么当超过了 100MB 的日志文件,日志文件会继续写入到 container.log,但是会将 container.log 日志中老的日志删除,追加新的,
也就是 当写满 100MB 日志后 ,再产生一条新日志,会删除 container.log 中的一条老日志,保存 100MB 的大小。这个 对我们是会有一些影响的,
当我运行系统时 第一天由于bug产生了 100MB 日志,那么之前的日志就已经有 80MB 日志变成的压缩包,所以我在后续的运行中,只能获取最近的 20MB日志。

日志驱动 二、 默认的日志驱动—JSON

所有容器默认的日志驱动 json-file。

json-file 日志驱动 记录从容器的 STOUT/STDERR 的输出 ,用 JSON 的格式写到文件中,日志中不仅包含着 输出日志,还有时间戳和 输出格式。下面是一个 ping www.baidu.com 对应的 JSON 日志

{"log":"64 bytes from 14.215.177.39: seq=34 ttl=55 time=7.067 ms\r\n","stream":"stdout","time":"2019-05-16T14:14:15.030612567Z"}

json-file 日志的路径位于 /var/lib/docker/containers/container_id/container_id-json.log

json-file 的 日志驱动支持以下选项:

json-file 的日志驱动示例

# 设置 日志驱动为 json-file ,我们也可以不设置,因为默认就是 json-file
docker run -itd --name test-log-json --log-driver json-file alpine ping www.baidu.com
199608b2e2c52136d2a17e539e9ef7fbacf97f1293678aded421dadbdb006a5e # 查看日志,日志名称就是 容器名称-json.log
tail -f /var/lib/docker/containers/199608b2e2c52136d2a17e539e9ef7fbacf97f1293678aded421dadbdb006a5e/199608b2e2c52136d2a17e539e9ef7fbacf97f1293678aded421dadbdb006a5e-json.log {"log":"64 bytes from 14.215.177.39: seq=13 ttl=55 time=15.023 ms\r\n","stream":"stdout","time":"2019-05-16T14:13:54.003118877Z"}
{"log":"64 bytes from 14.215.177.39: seq=14 ttl=55 time=9.640 ms\r\n","stream":"stdout","time":"2019-05-16T14:13:54.999011017Z"}
{"log":"64 bytes from 14.215.177.39: seq=15 ttl=55 time=8.938 ms\r\n","stream":"stdout","time":"2019-05-16T14:13:55.998612636Z"}
{"log":"64 bytes from 14.215.177.39: seq=16 ttl=55 time=18.086 ms\r\n","stream":"stdout","time":"2019-05-16T14:13:57.011235913Z"}
{"log":"64 bytes from 14.215.177.39: seq=17 ttl=55 time=12.615 ms\r\n","stream":"stdout","time":"2019-05-16T14:13:58.007104112Z"}
{"log":"64 bytes from 14.215.177.39: seq=18 ttl=55 time=11.001 ms\r\n","stream":"stdout","time":"2019-05-16T14:13:59.007559413Z"}

日志驱动 三、syslog

syslog 日志驱动将日志路由到 syslog 服务器,syslog 以原始的字符串作为 日志消息元数据,接收方可以提取以下的消息:

  • level 日志等级 ,如debug,warning,error,info。
  • timestamp 时间戳
  • hostname 事件发生的主机
  • facillty 系统模块
  • 进程名称和进程 ID
  • syslog 日志驱动全局配置

编辑 /etc/docker/daemon.json 文件

{
"log-driver": "syslog",
"log-opts": {
"syslog-address": "udp://1.2.3.4:1111"
}
}

重启 docker 即可生效。

Option Description Example value
syslog-address 指定syslog 服务所在的服务器和使用的协议和端口。 格式:`[tcp udp
syslog-facility 使用的 syslog 的设备, 具体设备名称见 syslog documentation. --log-opt syslog-facility=daemon
syslog-tls-ca-cert 如果使用的是 tcp+tls的地址,指定CA 证书的地址,如果没有使用,则不设置该选项。 --log-opt syslog-tls-ca-cert=/etc/ca-certificates/custom/ca.pem
syslog-tls-cert 如果使用的是 tcp+tls的地址,指定 TLS 证书的地址,如果没有使用,则不设置该选项。 --log-opt syslog-tls-cert=/etc/ca-certificates/custom/cert.pem
syslog-tls-key 如果使用的是 tcp+tls的地址,指定 TLS 证书 key的地址,如果没有使用,则不设置该选项。** --log-opt syslog-tls-key=/etc/ca-certificates/custom/key.pem
syslog-tls-skip-verify 如果设置为 true ,会跳过 TLS 验证,默认为 false --log-opt syslog-tls-skip-verify=true
tag 将应用程序的名称附加到 syslog 消息中,默认情况下使用容器ID的前12位去 标记这个日志信息。 --log-opt tag=mailer
syslog-format syslog 使用的消息格式 如果未指定则使用本地 UNIX syslog 格式,rfc5424micro 格式具有微妙时间戳。 --log-opt syslog-format=rfc5424micro
labels 启动 docker 时,配置与日志相关的标签,以逗号分割 --log-opt labels=production_status,geo
env 启动 docker 时,指定环境变量用于日志中,以逗号分隔 --log-opt env=os,customer
env-regex 类似并兼容 env, --log-opt env-regex=^(os|customer)

**单个容器日志驱动设置为—syslog **

Linux 系统中 我们用的系统日志模块时 rsyslog ,它是基于syslog 的标准实现。我们要使用 syslog 驱动需要使用 系统自带的 rsyslog 服务。

# 查看当前 rsyslog 版本和基本信息
[root@localhost harbor]# rsyslogd -v
rsyslogd 8.24.0, compiled with:
PLATFORM: x86_64-redhat-linux-gnu
PLATFORM (lsb_release -d):
FEATURE_REGEXP: Yes
GSSAPI Kerberos 5 support: Yes
FEATURE_DEBUG (debug build, slow code): No
32bit Atomic operations supported: Yes
64bit Atomic operations supported: Yes
memory allocator: system default
Runtime Instrumentation (slow code): No
uuid support: Yes
Number of Bits in RainerScript integers: 64 See http://www.rsyslog.com for more information.

配置 syslog , 在配置文件 /etc/rsyslog.conf 大约14-20行,我们可以看到两个配置,一个udp,一个tcp ,都是监听 514 端口,提供 syslog 的接收。选择 tcp 就将 tcp 的两个配置的前面 # 号注释即可。

# Provides UDP syslog reception
#$ModLoad imudp
#$UDPServerRun 514 # Provides TCP syslog reception
#$ModLoad imtcp
#$InputTCPServerRun 514

然后重启 rsyslog,我们可以看到514端口在监听。

systemctl restart  rsyslog
[root@localhost harbor]# netstat -ntul |grep 514
tcp 0 0 0.0.0.0:514 0.0.0.0:* LISTEN
tcp6 0 0 :::514 :::* LISTEN

启动一个以 syslog 为驱动的容器。

docker  run -d -it  -p 87:80 --log-driver syslog --log-opt syslog-address=tcp://127.0.0.1:514  --name nginx-syslog   nginx

日志驱动 四、Journald

journald 日志驱动程序将容器的日志发送到 systemd journal, 可以使用 journal API 或者使用 docker logs 来查日志。

除了日志本身以外, journald 日志驱动还会在日志加上下面的数据与消息一起储存。



journald 日志驱动全局配置

编辑 /etc/docker/daemon.json 文件

{
"log-driver": "journald"
}

单个容器日志驱动设置为—journald

docker  run  -d -it --log-driver=journald \
--log-opt labels=location \
--log-opt env=TEST \
--env "TEST=false" \
--label location=china \
--name nginx-journald\
-p 80:80\
nginx

查看日志 journalctl

# 只查询指定容器的相关消息
journalctl CONTAINER_NAME=webserver
# -b 指定从上次启动以来的所有消息
journalctl -b CONTAINER_NAME=webserver
# -o 指定日志消息格式,-o json 表示以json 格式返回日志消息
journalctl -o json CONTAINER_NAME=webserver
# -f 一直捕获日志输出
journalctl -f CONTAINER_NAME=webserver
如果我们的容器在启动的时候加了 -t 参数,启用了 TTY 的话,那么我查看日志是会像下面一样
May 17 17:19:26 localhost.localdomain 2a338e4631fe[6141]: [104B blob data]
May 17 17:19:32 localhost.localdomain 2a338e4631fe[6141]: [104B blob data] 显示[104B blob data] 而不是完整日志原因是因为有 \r 的存在,如果我们要完整显示,需要加上参数 --all 。

容器的日志实际是有两大类的

1.标准输出的 ,也就是 STDOUT 、STDERR ,这类日志我们可以通过 Docker 官方的日志驱动进行收集。

可以选择 json-file 、syslog、local 等 Docker 支持的日志驱动。

2.文本日志,存在在于容器内部,并没有重定向到 容器的标准输出的日志。

方案一 挂载目录,创建一个目录,将目录挂载到 容器中产生日志的目录。

方案二 使用数据卷 volume,创建数据卷,创建容器时绑定数据卷,

--mount  type=volume  src=volume_name  dst=/usr/local/tomcat/logs/

方案三 计算容器 rootfs 挂载点

采用这种方法相当于登录到容器中查看日志

使用挂载宿主机目录的方式采集日志对应用会有一定的侵入性,因为它要求容器启动的时候包含挂载命令。如果采集过程能对用户透明那就太棒了。事实上,可以通过计算容器 rootfs 挂载点来达到这种目的。

和容器 rootfs 挂载点密不可分的一个概念是 storage driver。实际使用过程中,用户往往会根据 linux 版本、文件系统类型、容器读写情况等因素选择合适的 storage driver。不同 storage driver 下,容器的 rootfs 挂载点遵循一定规律,因此我们可以根据 storage driver 的类型推断出容器的 rootfs 挂载点,进而采集容器内部日志。下表展示了部分 storage dirver 的 rootfs 挂载点及其计算方法。

Storage driver rootfs 挂载点 计算方法
aufs /var/lib/docker/aufs/mnt/ id 可以从如下文件读到。 /var/lib/docker/image/aufs/layerdb/mounts//mount-id
overlay /var/lib/docker/overlay//merged 完整路径可以通过如下命令得到。 docker inspect -f '{{.GraphDriver.Data.MergedDir}}'
overlay2 /var/lib/docker/overlay2//merged 完整路径可以通过如下命令得到。 docker inspect -f '{{.GraphDriver.Data.MergedDir}}'
devicemapper /var/lib/docker/devicemapper/mnt//rootfs id 可以通过如下命令得到。 docker inspect -f '{{.GraphDriver.Data.DeviceName}}'

示例:

# 创建容器 tomcat-test
[root@fy-local-2 /]# docker run -d --name tomcat-test -P tomcat
36510dd653ae7dcac1d017174b1c38b3f9a226f9c4e329d0ff656cfe041939ff
# 查看tomcat-test 容器的 挂载点位置
[root@fy-local-2 /]# docker inspect -f '{{.GraphDriver.Data.MergedDir}}' 36510dd653ae7dcac1d017174b1c38b3f9a226f9c4e329d0ff656cfe041939ff
/var/lib/docker/overlay2/c10ec54bab8f3fccd2c5f1a305df6f3b1e53068776363ab0c104d253216b799d/merged
# 查看挂载点的目录结构
[root@fy-local-2 /]# ls -l /var/lib/docker/overlay2/c10ec54bab8f3fccd2c5f1a305df6f3b1e53068776363ab0c104d253216b799d/merged
total 4
drwxr-xr-x 1 root root 179 May 8 13:05 bin
drwxr-xr-x 2 root root 6 Mar 28 17:12 boot
drwxr-xr-x 1 root root 43 May 22 17:27 dev
lrwxrwxrwx 1 root root 33 May 8 13:08 docker-java-home -> /usr/lib/jvm/java-8-openjdk-amd64
drwxr-xr-x 1 root root 66 May 22 17:27 etc
drwxr-xr-x 2 root root 6 Mar 28 17:12 home
drwxr-xr-x 1 root root 6 May 16 08:50 lib
drwxr-xr-x 2 root root 34 May 6 08:00 lib64
drwxr-xr-x 2 root root 6 May 6 08:00 media
drwxr-xr-x 2 root root 6 May 6 08:00 mnt
drwxr-xr-x 2 root root 6 May 6 08:00 opt
drwxr-xr-x 2 root root 6 Mar 28 17:12 proc
drwx------ 1 root root 27 May 22 17:29 root
drwxr-xr-x 3 root root 30 May 6 08:00 run
drwxr-xr-x 2 root root 4096 May 6 08:00 sbin
drwxr-xr-x 2 root root 6 May 6 08:00 srv
drwxr-xr-x 2 root root 6 Mar 28 17:12 sys
drwxrwxrwt 1 root root 29 May 16 08:50 tmp
drwxr-xr-x 1 root root 19 May 6 08:00 usr
drwxr-xr-x 1 root root 41 May 6 08:00 var
# 查看日志
[root@fy-local-2 /]# ls -l /var/lib/docker/overlay2/c10ec54bab8f3fccd2c5f1a305df6f3b1e53068776363ab0c104d253216b799d/merged/usr/local/tomcat/logs/
total 20
-rw-r----- 1 root root 14514 May 22 17:40 catalina.2019-05-22.log
-rw-r----- 1 root root 0 May 22 17:27 host-manager.2019-05-22.log
-rw-r----- 1 root root 1194 May 22 17:40 localhost.2019-05-22.log
-rw-r----- 1 root root 0 May 22 17:27 localhost_access_log.2019-05-22.txt
-rw-r----- 1 root root 0 May 22 17:27 manager.2019-05-22.log

方案四 在代码层中实现直接将日志写入redis

docker ——》redis ——》Logstash——》Elasticsearch

通过代码层面,直接将日志写入redis,最后写入 Elasticsearch

Docker 容器日志管理的更多相关文章

  1. docker容器日志管理(清理)

    原文:docker容器日志管理(清理) 前言 在使用docker容器时候,其日志的管理是我们不得不考虑的事情.因为docker容器的日志文件会占据大量的磁盘空间.下面介绍的就是对docker容器日志的 ...

  2. docker容器日志管理

    docker容器日志分为两类:docker引擎日志(Docker本身运行的日志)和容器日志(各个容器内产生的日志) 一.Docker引擎日志: Centos系统下的docker引擎日志一般给syste ...

  3. Docker容器日志管理最佳实践

    目录 一 .Docker 引擎日志 二.容器日志 2.1.常用查看日志命令--docker logs 2.2 .Docker 日志 驱动 三. 生产环境中该如何储存容器中的日志 一.当是完全是标准输出 ...

  4. docker 容器日志集中 ELK + filebeat

    docker 容器日志集中 ELK ELK 基于 ovr 网络下 docker-compose.yaml version: '2' networks: network-test: external: ...

  5. docker容器日志收集方案汇总评价总结

    docker日志收集方案有太多,下面截图罗列docker官方给的日志收集方案(详细请转docker官方文档).很多方案都不适合我们下面的系列文章没有说. 经过以下5篇博客的叙述简单说下docker容器 ...

  6. docker容器日志收集方案(方案二 filebeat+syslog本地日志收集)

    与方案一一样都是把日志输出到本地文件系统使用filebeat进行扫描采集 不同的是输出的位置是不一样的 我们对docker进行如下设置 sudo docker service update  --lo ...

  7. docker容器日志收集方案(方案一 filebeat+本地日志收集)

    filebeat不用多说就是扫描本地磁盘日志文件,读取文件内容然后远程传输. docker容器日志默认记录方式为 json-file 就是将日志以json格式记录在磁盘上 格式如下: { " ...

  8. Docker 容器日志格式化

    Docker容器的日志文件每一行都是一个json对象,其包含log.stream.time三个属性,下面的HTML从textarea中读取输入的日志信息,格式化为表格显示. <!DOCTYPE ...

  9. 实时查看docker容器日志

    实时查看docker容器日志 $ sudo docker logs -f -t --tail 行数 容器名 例:实时查看docker容器名为s12的最后10行日志 $ sudo docker logs ...

随机推荐

  1. API管理之利剑 -- Eolink

    随着信息化飞速增长的还有各信息系统中的应用接口( API ),API 作为信息系统内部及不同信息系统之间进行数据传输的渠道,其数量随着软件系统的不断庞大而呈指数型增长,如何管理这些 API 已经在业界 ...

  2. 如何优雅的升级 Flink Job?

    Flink 作为有状态计算的流批一体分布式计算引擎,会在运行过程中保存很多的「状态」数据,并依赖这些数据完成任务的 Failover 以及任务的重启恢复. 那么,请思考一个问题:如果程序升级迭代调整了 ...

  3. 【New】Code Insertion

    #include <bits/stdc++.h> using namespace std; #define Multicase() for(int T = read() ; T ; T-- ...

  4. Hippo4J v1.3.1 发布,增加 Netty 监控上报、SpringCloud Hystrix 线程池监控等特性

    文章首发在公众号(龙台的技术笔记),之后同步到博客园和个人网站:xiaomage.info Hippo4J v1.3.1 正式发布,本次发布增加了 Netty 上传动态线程池监控数据.适配 Hystr ...

  5. WPF 截图控件之绘制箭头(五)「仿微信」

    前言 接着上周写的截图控件继续更新 绘制箭头. 1.WPF实现截屏「仿微信」 2.WPF 实现截屏控件之移动(二)「仿微信」 3.WPF 截图控件之伸缩(三) 「仿微信」 4.WPF 截图控件之绘制方 ...

  6. P4983忘情

    今天挺开心的\(\sim\),省选加油\(!\) \(P4893\)忘情 我能说今晚我才真正学会\(wqs\)和斜率优化吗\(?\) 恰好选几个,必然需要\(wqs\)二分一下 那么考虑不考虑次数情况 ...

  7. 8. 利用Ansible快速构建MGR | 深入浅出MGR

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 目录 1. 安装ansbile 2. 配置ansible 3. 建立ssh信任 4. 测试ansible 5. 使用ans ...

  8. k8s驱逐篇(2)-kubelet节点压力驱逐

    kubelet节点压力驱逐 kubelet监控集群节点的 CPU.内存.磁盘空间和文件系统的inode 等资源,根据kubelet启动参数中的驱逐策略配置,当这些资源中的一个或者多个达到特定的消耗水平 ...

  9. 彩虹女神跃长空,Go语言进阶之Go语言高性能Web框架Iris项目实战-项目入口与路由EP01

    书接上回,我们已经安装好Iris框架,并且构建好了Iris项目,同时配置了fresh自动监控项目的实时编译,万事俱备,只欠东风,彩虹女神蓄势待发.现在我们来看看Iris的基础功能,如何编写项目入口文件 ...

  10. SpringMvc 如何同时支持 Jsp 和 Json 接口?

    后端同学基本都会见过这种场景:在同一个工程中,有些页面使用jsp模版渲染,同时还有其他接口提供Json格式的返回值.为了同时支持这两种场景,我们一般是如何处理的呢? 其实非常简单: 1.在项目中为 S ...