Docker日志处理—ELK

Docker_ELK

高效的监控和日志管理对保持生产系统持续稳定地运行以及排查问题至关重要。

在微服务架构中,由于容器的数量众多以及快速变化的特性使得记录日志和监控变得越来越重要。考虑到容器短暂和不固定的生命周期,当我们需要 debug(调试) 问题时有些容器可能已经不存在了。因此,一套集中式的日志管理系统是生产环境中不可或缺的组成部分。

监控容器的各种可用技术和方案,首先先看一下 Docker 自带的 logs 子命令,然后讨论 Docker 的 logging driver,接着就尝试去部署ELK进行日志的收集和管理

Docker logs

默认配置下 Docker 的日志功能。

对于一个运行的容器,Docker 会将日志发送到 容器的 标准输出设备(STDOUT)和标准错误设备(STDERR),STDOUT 和 STDERR 实际上就是容器的控制台终端。也就是发送到了物理机,后面会说到是通过什么机制去发送到物理机的什么位置。

例如:运行一个容器

如果不使用-d选项,将会直接把日志信息输出到屏幕上

[root@localhost ~]# docker run -p 80:80 --name test httpd
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
[Wed Apr 08 09:50:24.016624 2020] [mpm_event:notice] [pid 1:tid 139784209921152] AH00489: Apache/2.4.41 (Unix) configured -- resuming normal operations
[Wed Apr 08 09:50:24.016822 2020] [core:notice] [pid 1:tid 139784209921152] AH00094: Command line: 'httpd -D FOREGROUND'

删除容器

[root@localhost ~]# docker rm -f test
test

如果使用了-d选项,又怎么去查看日志

[root@localhost ~]# docker run -p 80:80 -d --name test1 httpd
575cec7f272ae2453c594f1d4f0c6c072240ff43e72a6e73e3e8e891317e1a00
  1. 使用docker attch进入容器阻塞去查看日志
[root@localhost ~]# docker attach test1 
# 运行之后会阻塞,没有任何输出信息,这时使用另一个终端或者主机去访问这个端口
# curl 192.168.1.11
# 会输出以下信息,也就是test1容器的日志
192.168.1.11 - - [08/Apr/2020:09:56:18 +0000] "GET / HTTP/1.1" 200 45

attach 的方法在实际使用中不太方便,因为:

只能看到 attach 之后的日志,以前的日志不可见。

退出 attach 状态比较麻烦(Ctrl+p 然后 Ctrl+q 组合键),一不小心很容器将容器杀掉(比如按下 Ctrl+C)。

使用各种方法退出之后,发现该容器确实也被停止了,这时就可以去使用docker logs来查看日志比较方便

2.使用docker logs查看容器日志

这个方法可以看到容器内的所有日志信息

# 重新运行刚才停止的容器
[root@localhost ~]# docker start test1
test1
[root@localhost ~]# docker logs test1
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
[Wed Apr 08 09:51:46.095262 2020] [mpm_event:notice] [pid 1:tid 140106547037312] AH00489: Apache/2.4.41 (Unix) configured -- resuming normal operations
[Wed Apr 08 09:51:46.095674 2020] [core:notice] [pid 1:tid 140106547037312] AH00094: Command line: 'httpd -D FOREGROUND'
192.168.1.12 - - [08/Apr/2020:09:53:10 +0000] "GET / HTTP/1.1" 200 45
...

logging driver

将容器日志发送到 STDOUT 和 STDERR 是 Docker 的默认日志行为。实际上,Docker 提供了多种日志机制帮助用户从运行的容器中提取日志信息。这些机制被称作 logging driver。

json-file

json-file这种格式的文件是一种交互式的文件,可以很方便的发送到其他主机,读取解析也很方便。

Docker 的默认 logging driver 是 json-file。可以通过查看docker info看到docker默认的logging driver

[root@localhost ~]# docker info | grep "Logging Driver"
 Logging Driver: json-file

如果容器在启动时没有特别指明,就会使用这个默认的 logging driver。

json-file 会将容器的日志保存在 json 文件中,Docker 负责格式化其内容并输出到 STDOUT 和 STDERR。

可以在 Host 的容器目录中找到这个文件

查找该文件,以刚才运行的test1容器为例

[root@localhost ~]# docker inspect test1 | grep LogPath
"LogPath": "/var/lib/docker/containers/575cec7f272ae2453c594f1d4f0c6c072240f
f43e72a6e73e3e8e891317e1a00/575cec7f272ae2453c594f1d4f0c6c072240ff43e72a6e73
e3e8e891317e1a00-json.log"

json-file文件的路径就是/var/lib/docker/containers/容器id/容器id-json.log

也可以通过cat去查看该文件中的内容,就是容器中的日志信息

docker支持的logging driver

除了 json-file,Docker 还支持多种 logging driver。如下图所示,是官网中的内容,已使用谷歌翻译

logging_driver

以下简单说明一个logging driver

none:用于关闭容器日志功能

json-file:docker默认使用的,就是将日志存放到物理机的一个json文件中

syslog/journald:Linux上的两种日志管理服务

awslogs/splunk/gcplogs:第三方日志托管服务

gelf/fluentd:开源日志管理方案

后面会有几种驱动器的使用

修改默认的logging driver

修改logging driver有两种方法

1、修改文件

针对所有启动的容器

[root@localhost ~]# vim /usr/lib/systemd/system/docker.service 
# 找到14行或者以ExecStart开头的一行
# 在这行末尾添加--log-driver=
# 引号内可以写以上在官网中查到的类型,如:
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --log-driver=none

2、运行容器时添加

指定单独容器使用的logging driver

[root@localhost ~]# docker run -itd --name test --rm --log-driver none httpd
9543f7aa5d02e8c5844016037dfddc7bcd7b866fe8f1962bd6517408a1ef6f82

查看是否有日志路径生成

[root@localhost ~]# docker inspect test | grep LogPath
        "LogPath": "",

ELK

在开源的日志管理方案中,最出名的莫过于 ELK 了,ELK 是三个软件的合称:Elasticsearch、Logstash、Kibana

上述内容中说到,json文件可以方便的进行交互数据,使用ELK方案,json格式的日志文件就会传递给ELK。

Elasticsearch
一个近乎实时查询的全文搜索引擎。Elasticsearch 的设计目标就是要能够处理和搜索巨量的日志数据。

Logstash
读取原始日志,并对其进行分析和过滤,然后将其转发给其他组件(比如 Elasticsearch)进行索引或存储。Logstash 支持丰富的 Input 和 Output 类型,能够处理各种应用的日志。

Kibana
一个基于 JavaScript 的 Web 图形界面程序,专门用于可视化 Elasticsearch 的数据。Kibana 能够查询 Elasticsearch 并通过丰富的图表展示结果。用户可以创建 Dashboard 来监控系统的日志。

日志处理流程

Docker_ELK

Logstash 负责从各个 Docker 容器中提取日志,Logstash将日志转发到 Elasticsearch 进行索引和保存,Kibana 分析和可视化数据。

部署ELK

ELK 的部署方案可以非常灵活,在规模较大的生产系统中,ELK 有自己的集群,实现了高可用和负载均衡。我们的目标是在最短的时间内学习并实践 ELK,因此将采用最小部署方案:在容器中搭建 ELK。

由于之前的测试中,启动了两个test容器,这里先将他们删除

[root@localhost ~]# docker rm -f test  test1

ELK环境

ip 服务 备注
192.168.1.11 Docker 内存8G

部署ELK容器的环境中,对物理机的内存有明确要求,Elasticsearch需要至少使用2G内存,Docker需要使用4G,为了保证运行正常,这里将虚拟机关机,调整内存为8G,推荐cpu内核为2,官方说明在此

elk_先决条件

实验目的

使用ELK监控容器日志,在web页面中可以查看到

实验步骤

下载ELK镜像

下载ELK镜像,这个镜像需要下载很时间,大小2个G

[root@elk ~]# docker pull sebp/elk

查看镜像

[root@elk ~]# docker images
REPOSITORY      TAG           IMAGE ID            CREATED             SIZE
sebp/elk        latest        c21727ae794b        2 weeks ago         2.07GB
busybox         latest        83aa35aa1c79        4 weeks ago         1.22MB
httpd           latest        c5a012f9cf45        6 weeks ago         165MB
centos          latest        5e35e350aded        4 months ago        2

限制进程使用VMA

Elasticsearch默认使用目录来存储其索引。默认的操作系统对mmap计数的限制可能太低,这可能会导致内存不足异常。以致于Elasticsearch无法启动

[root@elk ~]# vim /etc/sysctl.conf 
# 添加
vm.max_map_count = 262144
[root@elk ~]# sysctl -p

max_map_count\文件包含限制一个进程可以拥有的VMA(虚拟内存区域)的数量。虚拟内存区域是一个连续的虚拟地址空间区域。在进程的生命周期中,每当程序尝试在内存中映射文件,链接到共享内存段,或者分配堆空间的时候,这些区域将被创建。调优这个值将限制进程可拥有VMA的数量。限制一个进程拥有VMA的总数可能导致应用程序出错,因为当进程达到了VMA上线但又只能释放少量的内存给其他的内核进程使用时,操作系统会抛出内存不足的错误。如果你的操作系统在NORMAL区域仅占用少量的内存,那么调低这个值可以帮助释放内存给内核用

启动ELK

[root@elk ~]# systemctl start docker
[root@elk ~]# docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 -itd \
-e ES_HEAP_SIZE="2g" -e LS_HEAP_SIZE="2g" --name elk sebp/elk
2620103dda58f8183f5f977e896c82d2dc9a07d7dccab9af8ce039c06e766c0c

建议检测这几个端口是否启动,netstat -anput | grep 5044netstat -anput | grep 5061netstat -anput | grep 9200

5601 - Kibana web 接口

9200 - Elasticsearch JSON 接口

5044 - Logstash 日志接收接口

防火墙放行端口

[root@elk ~]# firewall-cmd --add-port=5601/tcp
success
[root@elk ~]# firewall-cmd --add-port=5044/tcp
success
[root@elk ~]# firewall-cmd --add-port=9200/tcp
success

添加日志数据

使用浏览器访问http://192.168.1.11:5601

运行之后多等一会,这是cpu会疯转,会在网络上下载一些东西

进入之后的界面,选择Explore on my own,自己创建数据

my_own

添加日志数据

5601_index

日志数据为使用elasticsearch存储的日志

Elasticsearch_logs

根据页面提示下载安装filebeat,Linux系统选择RPM

image-20200408194428134

安装filebeat

复制第一步中的第一条命令进行下载filebeat

[root@elk ~]# curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.6.1-x86_64.rpm

安装filebeat

[root@elk ~]# sudo rpm -vi filebeat-7.6.1-x86_64.rpm

修改filebeat配置文件

根据网页的提示修改两处的URL之外,还要将filebeat.inputs的功能开启

[root@elk ~]# vim /etc/filebeat/filebeat.yml
# 24行修改为
  enabled: true
# 28行添加一行,指定收集本机日志的路径,这个路径就是所有容器json-file存放的位置
    - /var/lib/docker/containers/*/*.log
# 125行,kibana的配置下,修改或者添加以下,ip为本机ip
  host: "192.168.1.11:5601"
# 152行,Elasticsearch output的配置下
  hosts: ["192.168.1.11:9200"]

启动filebeat

# 启动并配置elasticsearch
[root@elk ~]# sudo filebeat modules enable elasticsearch
Enabled elasticsearch
# 加载kibana仪表盘
[root@elk ~]# sudo filebeat setup
# 启动filebeat
[root@elk ~]# sudo service filebeat start
Starting filebeat (via systemctl):                         [  OK  ]

发现日志数据

回到刚才的页面中,完成所有步骤可以,检测数据,由于没有数据也是检测不到的,可以点击**Discover**,进行发现数据

check_data

never_data

模拟容器生成日志

[root@elk ~]# docker run busybox sh -c \
'while true; do echo "This is a log message from container FeiYi"; sleep 10; done;'

等待数据几条信息后,去刷新页面,我这里好像因为虚拟机的时间与宿主机不同步的原因,我需要将时间选择为检测本周内的日志,搜索日志中的关键字**FeiYi**,如图所示

select_logs_data

评论




正在载入...
PoweredHexo
HostedAliyun
DNSAliyun
ThemeVolantis
UV
PV
BY-NC-SA 4.0