标签:双十二 udp 展开 关键词 推出 包括 targe 分析 and
自 2013 年 dotCloud 公司开源 Docker 以来,以 Docker 为代表的容器产品凭借着隔离性好、可移植性高、资源占用少、启动迅速等特性迅速风靡世界。下图展示了 2013 年以来 Docker 和 OpenStack 的搜索趋势。
容器技术在部署、交付等环节给人们带来了很多便捷,但在日志处理领域却带来了许多新的挑战,包括:
本文以 Docker 为例,依托阿里云日志服务团队在日志领域深耕多年积累下的丰富经验,介绍容器日志处理的一般方法和最佳实践,包括:
采集日志首先要弄清日志存在的位置,这里以 Nginx、Tomcat 这两个常用容器为例进行分析。
Nginx 产生的日志包括 access.log 和 error.log,根据 nginx Dockerfile 可知 access.log 和 error.log 被分别重定向到了 STDOUT 和 STDERR 上。
Tomcat 产生的日志比较多,包括 catalina.log、access.log、manager.log、host-manager.log 等,tomcat Dockerfile 并没有将这些日志重定向到标准输出,它们存在于容器内部。
容器产生的日志大部分都可以归结于上述情形。这里,我们不妨将容器日志分成以下两类。
容器日志分类 | 定义 |
---|---|
标准输出 | 通过 STDOUT、STDERR 输出的信息,包括被重定向到标准输出的文本文件。 |
文本日志 | 存在于容器内部并且没有被重定向到标准输出的日志。 |
容器的标准输出会由 logging driver 统一处理。如下图所示,不同的 logging driver 会将标准输出写往不同的目的地。
通过 logging driver 采集容器标准输出的优势在于使用简单,例如:
# 该命令表示在 docker daemon 级别为所有容器配置 syslog 日志驱动
dockerd -–log-driver syslog –-log-opt syslog-address=udp://1.2.3.4:1111
# 该命令表示为当前容器配置 syslog 日志驱动
docker run -–log-driver syslog –-log-opt syslog-address=udp://1.2.3.4:1111 alpine echo hello world
除了 json-file 和 journald,使用其他 logging driver 将使 docker logs API 不可用。
例如,当您使用 portainer 管理宿主机上的容器,并且使用了上述两者之外的 logging driver,您会发现无法通过 UI 界面观察到容器的标准输出。
对于那些使用默认 logging driver 的容器,我们可以通过向 docker daemon 发送 docker logs 命令来获取容器的标准输出。使用此方式采集日志的工具包括 logspout、sematext-agent-docker 等。下列样例中的命令表示获取容器自2018-01-01T15:00:00
以来最新的5条日志。
docker logs --since "2018-01-01T15:00:00" --tail 5 <container-id>
当日志量较大时,这种方式会对 docker daemon 造成较大压力,导致 docker daemon 无法及时响应创建容器、销毁容器等命令。
默认 logging driver 会将日志以 json 的格式写入宿主机文件里,文件路径为/var/lib/docker/containers/<container-id>/<container-id>-json.log
。这样可以通过直接采集宿主机文件来达到采集容器标准输出的目的。
该方案较为推荐,因为它既不会使 docker logs API 变得不可用,又不会影响 docker daemon,并且现在许多工具原生支持采集宿主机文件,如 filebeat、logtail 等。
采集容器内文本日志最简单的方法是在启动容器时通过 bind mounts 或 volumes 方式将宿主机目录挂载到容器日志所在目录上,如下图所示。
针对 tomcat 容器的 access log,使用命令docker run -it -v /tmp/app/vol1:/usr/local/tomcat/logs tomcat
将宿主机目录/tmp/app/vol1
挂载到 access log 在容器中的目录/usr/local/tomcat/logs
上,通过采集宿主机目录/tmp/app/vol1
下日志达到采集 tomcat access log 的目的。
使用挂载宿主机目录的方式采集日志对应用会有一定的侵入性,因为它要求容器启动的时候包含挂载命令。如果采集过程能对用户透明那就太棒了。事实上,可以通过计算容器 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> | id 可以从如下文件读到。/var/lib/docker/image/aufs/layerdb/mounts/\<container-id\>/mount-id |
overlay | /var/lib/docker/overlay/<id>/merged | 完整路径可以通过如下命令得到。docker inspect -f ‘{{.GraphDriver.Data.MergedDir}}‘ <container-id> |
overlay2 | /var/lib/docker/overlay2/<id>/merged | 完整路径可以通过如下命令得到。docker inspect -f ‘{{.GraphDriver.Data.MergedDir}}‘ <container-id> |
devicemapper | /var/lib/docker/devicemapper/mnt/<id>/rootfs | id 可以通过如下命令得到。docker inspect -f ‘{{.GraphDriver.Data.DeviceName}}‘ <container-id> |
在充分比较了容器日志的各种采集方法,综合整理了广大用户的反馈与诉求后,日志服务团队推出了容器日志一站式解决方案。
logtail 方案包含如下功能:
和 K8s 生态深度集成,能非常方便地采集 K8s 容器日志是日志服务 logtail 方案的又一大特色。
采集配置管理:
采集模式:
关于 Logtail 方案的详细说明可参考文章全面提升,阿里云Docker/Kubernetes(K8S) 日志解决方案与选型对比。
完成日志采集工作后,下一步需要对这些日志进行查询分析和可视化。这里以 Tomcat 访问日志为例,介绍日志服务提供的强大的查询、分析、可视化功能。
容器日志被采集时会带上 container name、container IP、目标文件路径等信息,因此在查询的时候可以通过这些信息快速定位目标容器和文件。查询功能的详细介绍可参考文档查询语法。
日志服务实时分析功能兼容 SQL 语法且提供了 200 多种聚合函数。如果您有使用 SQL 的经验,能够很容易写出满足业务需求的分析语句。例如:
* | SELECT request_uri, COUNT(*) as c GROUP by request_uri ORDER by c DESC LIMIT 10
* | SELECT diff[1] AS c1, diff[2] AS c2, round(diff[1] * 100.0 / diff[2] - 100.0, 2) AS c3 FROM (select compare( flow, 3600) AS diff from (select sum(body_bytes_sent) as flow from log))
该语句使用同比环比函数计算不同时间段的网络流量。
为了让数据更加生动,您可以使用日志服务内置的多种图表对 SQL 计算结果进行可视化展示,并将图表组合成一个仪表盘。
下图展示了基于 Tomcat 访问日志的仪表盘,它展示了错误请求率、网络流量、状态码随时间的变化趋势等信息。该仪表盘展现的是多个 Tomcat 容器数据聚合后的结果,您可以使用仪表盘过滤器功能,通过指定容器名查看单个容器的数据。
查询分析、仪表盘等功能能帮助我们把握全局信息、了解系统整体运行情况,但定位具体问题往往需要上下文信息的帮助。
上下文指的是围绕某个问题展开的线索,如日志中某个错误的前后信息。上下文包含两个要素:
下表展示了不同数据源的最小区分粒度。
分类 | 最小区分粒度 |
---|---|
单机文件 | IP + 文件 |
Docker 标准输出 | Container + STDOUT/STDERR |
Docker 文件 | Container + 文件 |
K8s 容器标准输出 | Namespace + Pod + Container + STDOUT/STDERR |
K8s 容器文件 | Namespace + Pod + Container + 文件 |
SDK | 线程 |
Log Appender | 线程 |
在日志集中式存储的背景下,采集端和服务端都很难保证日志原始的顺序:
日志服务通过给每条日志附加一些额外的信息以及服务端的关键词查询能力巧妙地解决了上述难题。原理如下图所示。
想了解更多有关上下文分析的功能可参考文章上下文查询、分布式系统日志上下文查询功能。
除了查看日志的上下文信息,有时我们也希望能够持续观察容器的输出。
下表展示了传统模式下实时监控容器日志的方法。
类别 | 步骤 |
---|---|
标准输出 | 1. 定位容器,获取容器 id; 2. 使用命令 docker logs –f <container id> 或kubectl logs –f <pod name> 在终端上观察输出;3. 使用 grep 或grep –v 过滤关键信息。 |
文本日志 | 1. 定位容器,获取容器 id; 2. 使用命令 docker exec 或kubectl exec 进入容器;3. 找到目标文件,使用命令 tail –f 观察输出;4. 使用 grep 或grep –v 过滤关键信息。 |
通过传统方法监控容器日志存在以下痛点:
针对这些问题,日志服务推出了 LiveTail 功能。相比传统模式,它有如下优点:
在实现上,LiveTail 主要用到了上一章中提到的上下文查询原理快速定位目标容器和目标文件。然后,客户端定期向服务端发送请求,拉取最新数据。
您还可以通过观看视频,进一步理解容器日志的采集、查询、分析和可视化等功能。
原文链接
本文为云栖社区原创内容,未经允许不得转载。
标签:双十二 udp 展开 关键词 推出 包括 targe 分析 and
原文地址:https://www.cnblogs.com/yunqishequ/p/9994263.html