本节书摘来自华章出版社《ELK Stack权威指南(第2版)》一书中的第3章,第3.8节,作者 饶琛琳 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
3.8 Docker日志
Docker是目前大规模互联网基础架构解决方案中最热门的技术。它带给运维工程师一个截然不同的思考角度和工作方式。
就日志层面看,Docker最大的影响在于:其最佳实践要求一个容器内部只有一个生命周期随时可以消亡的服务进程。这也就意味着:传统的写入磁盘,固定采集方式的日志系统,无法正常发挥作用。所以,在容器服务中,记录日志需要采用另外的方式。本节将介绍其中最常见的两种:记录到主机磁盘,或通过logspout收集。
3.8.1 记录到主机磁盘
默认情况下,Docker会将容器的标准输出和错误输出,保存在主机的/var/lib/docker/containers/目录下。所以,在规模比较稳定的情况下,直接记录到主机磁盘,然后通过主机上的Logstash收集日志,也是不错的方案。
以Nginx为例,将Nginx访问日志和错误日志输出到标准输出的配置如下:
daemon off;
error_log /dev/stdout info;
http {
access_log /dev/stdout;
...
}
不过,容器的特殊性在这里又一次体现出来,容器中其实是没有/dev/stdout设备的。所以我们需要自己单独处理一下,在Dockerflie里加上一句:
RUN ln -sf /proc/self/fd /dev/
这样,既保证了nginx.conf是主机和容器通用的配置,又顺利达到目的。
然后通过如下Logstash配置收集即可:
3.8.2 通过logspout收集
logspout是Docker生态圈中最有名的日志收集方式,其设计思路是:每个主机上启动一个单独容器运行logspout服务,负责将同一个主机上其他容器的日志,根据route设定,转发给不同的接收端。
logspout的基本用法如下:
这个配置的意思是,将容器名带有db字样的走错误输出的采集的日志,以syslog协议发送到remoteaddr2主机的5140端口。
注意,logspout采用的是RFC5424版本的syslog协议,所以如果使用的接收方是RFC3164版本的syslog协议解析,需要自己调整一下。比如logstash-input-syslog采用的就是RFC3164协议,所以需要自己来另外完成:
input {
tcp {
port => 5140
}
}
filter {
grok {
match => [“message”, “<SYSLOG5424PRI:syslog_pri> %{SYSLOG5424LINE:message}“]
}
}
此外,logspout支持模块化扩展,所以,我们也可以直接在logspout上处理成对Logstash更友好的格式。扩展logspout支持Logstash格式的方法如下:
1)编辑Dockerfile,修改成如下内容:
FROM gliderlabs/logspout:master
ENV ROUTE_URIS=logstash://host:port
2)编辑modules.go,修改成如下内容:
package main
import (
_ "github.com/looplab/logspout-logstash"
_ "github.com/gliderlabs/logspout/transports/udp"
)
3)构建镜像:
docker build
这样,后续Logstash就直接进行JSON解析即可。