目录
Docker日志
高效的监控和日志的管理对保持成产系统持续稳定地运行以及排查问题至关重要。在微服务架构中,由于容器的数量众多以及快速变化的特性使得记录日志和监控变得越来越重要,考虑到容器短暂和不固定的生命周期,当我们要debug问题时有些容器可能已经不存在了,因此,一套中式的日志管理系统是生产环境中不可或缺的组成部分。
这篇文章我们将讨论监控容器的各种技术个方案,首先会介绍Docker自带的logs子命令,然后讨论Docker的logging driver,接下来通过实践来学习几个已经广泛应用的日志管理方案:ELK、Fluentd和Graylog
Dokcer logs
我们首先来看一下默认配置下Docker的日志功能,对于一个正在运行的容器,Docker会将日志发送到容器的标准输出设备(STDOUT)和标准错误设备(STDERR),STDOUT和STDERR实际上就是容器的控制台终端。接下来举个例子,用先下面的命令运行httpd容器
[root@localhost ~]# docker run -p 80:80 httpd
0954cc1af252d824860b2c5dc0a10720af2b7a3d3435581ca788dff8480c7b32
Status: Downloaded newer image for httpd:latest
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Sat May 20 05:27:36.178829 2023] [mpm_event:notice] [pid 1:tid 140277663821120] AH00489: Apache/2.4.52 (Unix) configured -- resuming normal operations
[Sat May 20 05:27:36.180417 2023] [core:notice] [pid 1:tid 140277663821120] AH00094: Command line: 'httpd -D FOREGROUND'
因为我们在启动日志的时候没有用-d的参数,httpd容器就以前台的方式启动了,日志会直接打印在当前的终端窗口。如果加上-d参数是以后台的方式运行容器,我们就看不到数据的日志了
[root@localhost ~]# docker run -p 80:80 -d httpd
735706cc9b3148a4d0a7aa3a6a854733d809a5c6f444aa9e851640761002d39b
如果我们在运行容器的时候加上-d的参数了,如果我们要查看日志有两种方法:我们可以用attach方式到该容器
[root@localhost ~]# docker attach 735706cc9b3148a4d
当我们执行docker attach命令之后不会显示之前的日志信息,他只会显示执行这条命令之后的标准输出个标准错误输出
当我们把这个容器放到后台时想要查看之前的日志信息可以使用 docker logs命令
[root@localhost ~]# docker logs -f 735706cc9b3148a4d
ELK
在开源的日志管理方案中,最出名的莫过于ELK了。
ELK是三个软件的合称:Elasticsearch、Logstash、Kibana。
Elasticsearch:一个近乎实时查询的全文搜索引擎。Elasticsearch的设计目标就是要能够处理个搜索巨量的日志数据。
Logstash:是读取原始日志,并对其进行分析和过滤,然后将其转发给其他组件(比如Elasticsearch)进行索引或存储。Logstash支持丰富的lnput和Output类型,能够处理各种应用的日志。
Kibana:一个基于javaScript的web图形界面程序,专门用于可视化Elasticsearch的数据。Kibana能够查询Elasticsearch并通过丰富的图标展示结果。用户可以创建Dashboard来监控系统的日志
接下来将讨论如何用ElK这组黄金搭档来监控Docker容器的日志
首先我们来看一下Docker部署环境下典型的ELK日志处理流程:
Logstash负责从各个Docker容器中提取日志,然后Logstash将日志转发到Elasticsearch进行索引和保存,Kibana分析和可视化数据。
ElK的部署方案可以是非常灵活的,在规模比较大的成产系统中,ELK有自己的群集,实现了高可用和负载均衡
现在来部署ELK,然后还有安装的前提条件:
-
Docker至少需要分配3GB的内存
-
Elasticsearch至少需要单独2G的内存
-
需要防火墙开放相关的端口,或者关闭防火墙
-
vm.max_map_count至少需要262144
我们可以查看一下
[root@localhost ~]# sysctl vm.max_map_count
如果不是然后在修改/etc/sysctl.conf文件
[root@localhost ~]# cat /etc/sysctl.conf
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
vm.max_map_count = 262144
修改完成之后不需要重启,然后在下载elk镜像
[root@localhost ~]# docker pull sebp/elk
然后运行elk镜像
[root@localhost ~]# docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 -itd -e ES_HTAP_SIZE='2g' -e LS_HEAP_SIZE='1g' --name elk sebp/elk
启动之后可以访问的端口,我们在网页上访问的时候等待的时间有点长
5601(Kibana web界面)
9200(Elasticsearch json接口)
5044 (Logstash Beats界面,从Beats接收日志,如Filebeat)
前面我们已经部署了容器化的ELK,下面讨论如何将日志导入ElK并进行图形化展示,几乎所有的软件和应用都有自己的日志文件,容器也不例外。前面我们已经知道Docker会将容器日志记录到/var/lib/docker/containers//-json.log,那么只要我们能够将此文件发送给ELK就可以实验日志管理,要是先这一步并不难,因为ELK提供了一个配套小工具Filebeat,它能将指定路径下的日志文件转发给ELK。同时Filbeat很聪明,他会监控日志文件,当日志更新时,Filebeat会将新的内容发送给ELK。
下面安装Filebeat来收集docker 容器中的日志
curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.16.2-x86_64.rpm
sudo rpm -vi filebeat-7.16.2-x86_64.rpm
Filebeat的配置文件为/etc/filebeat/filebeat.yml,我么只需要告诉Filebeat:监控哪些日志和将日志发送到哪里
修改/etc/filebeat/filebeat.yml文件 添加dodcker容器的日志文件位置
paths:
# - /data/*.log
- /var/lib/docker/containers/*/*.log
#- /var/log/messages
#- /var/log/*.log
#- c:\programdata\elasticsearch\logs\*
接下来告诉Filebeat将这些日志发送给ELK。Filebeat可以将日志发送给Elasticsearch进行索引和保存;也可以先发送给Logstash进行分析和过滤,然后由Logstash转发给Elasticsearch。为了不引入过多的复发性,我们这里将日志直接发送给Elasticsearch
修改Kibana模块的ip地址
#============================== Kibana =====================================
# Starting with Beats version 6.0.0, the dashboards are loaded via the Kibana API.
# This requires a Kibana endpoint configuration.
setup.kibana:
host: "192.168.8.6:5601"
在修改Elasticsearch模块的ip地址
#-------------------------- Elasticsearch output ------------------------------
output.elasticsearch:
# Array of hosts to connect to.
hosts: ["192.168.8.10:9200"]
# Optional protocol and basic auth credentials.
#protocol: "https"
#username: "elastic"
#password: "changeme"
然后保存退出
启用和配置弹性搜索模块
sudo filebeat modules enable elasticsearch
启动文件节拍
sudo filebeat setup
sudo service filebeat start
下面我们启动一个新的容器,该容器将向控制台打印信息,模拟日志输出
[root@localhost filebeat]# docker run busybox sh -c 'while true; do echo "this a log message form container busybox!";sleep 1; done'
然后在访问网页192.168.8.6:5601就可以发现日志信息
万能数据收集器fluentd
上面的ELK中我们是用Filebeat收集Docker容器日志,利用的是Docker默认的logging driver json-file,接下来我们将使用fluentd来收集容器的日志。
fluentd是一个开源的数据收集器,它目前有超过500种的plugin,可以连接各种数据源的数据输出组件,在接下来的实践中,Fluentd负责收集容器日志,然后发送给Elasticsearch。
同样的,最高效的实践方法是运行一个fluentd容器
[root@localhost filebeat]# docker run -d -p 24224:24224 -p 24224:24224/udp -v /data:/fluentd/log fluent/fluentd
af8841b12da1a0eca8c737bc5cdab4be29e4914a49c5436883a94cd196dfefdf
fluentd会在24224端口上接收日志数据,日志将保存在Host的/data目录中,然后重新配置Filebeat编辑Filebeat的配置文件/etc/filebeat/filebeat.yml,将/data添加到监控路径中
paths:
- /data/*.log
#- /var/lib/docker/containers/*/*.log
#- /var/log/messages
#- /var/log/*.log
#- c:\programdata\elasticsearch\logs\*
重启filebeat
[root@localhost filebeat]# systemctl restart filebeat.service
我们监控容器日志,启动测试容器
[root@localhost filebeat]# docker run -d --log-driver=fluentd --log-opt fluentd-address=192.168.8.6:24224 --log-opt tag="log-test-container-A" busybox sh -c 'while true; do echo "this is a log message form container A";sleep 1; done'
a6416675062aebf5e007aa2c413fde4f0d4afb25a825f3d2cafa89be95eaa86d
[root@localhost filebeat]# docker run -d --log-driver=fluentd --log-opt fluentd-address=192.168.8.6:24224 --log-opt tag="log-test-container-B" busybox sh -c 'while true; do echo "this is a log message form container B";sleep 1; done'
--log-driver=fluentd告诉Docker使用Fluentd的logging driver
--log-opt fluentd-address=localhost:24224将容器日志发送到Fluentd的数据接收端口
--log-opt tag='log-test-container-A'和'log-test-container-B'在日志中添加一个可选的tag,用于区分不同的容器
在访问192.168.8.10:5601就可以发现测试的日志信息