简述Kubernetes容器日志收集原理!
作者:H_debug | 来源:互联网 | 2023-09-23 14:28
![](https:upload-images.jianshu.ioupload_images15462057-b4c274d584872627.png?imageMogr2aut
![](https://upload-images.jianshu.io/upload_images/15462057-b4c274d584872627.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
### **概述**
**关于容器日志**
Docker的日志分为两类,一类是Docker引擎日志;另一类是容器日志。引擎日志一般都交给了系统日志,不同的操作系统会放在不同的位置。本文主要介绍容器日志,容器日志可以理解是运行在容器内部的应用输出的日志,默认情况下,docker logs显示当前运行的容器的日志信息,内容包含 STOUT(标准输出)和STDERR(标准错误输出)。日志都会以json-file的格式存储于 /var/lib/docker/containers/<容器id>/<容器id>-json.log,不过这种方式并不适合放到生产环境中。
* 默认方式下容器日志并不会限制日志文件的大小,容器会一直写日志,导致磁盘爆满,影响系统应用。(docker log-driver支持log文件的rotate)
* Docker Daemon收集容器的标准输出,当日志量过大时会导致Docker Daemon成为日志收集的瓶颈,日志的收集速度受限。
* 日志文件量过大时,利用docker logs -f查看时会直接将Docker Daemon阻塞住,造成docker ps等命令也不响应。
Docker提供了logging drivers配置,用户可以根据自己的需求去配置不同的log-driver,可参考官网Configure logging drivers[1]。但是上述配置的日志收集也是通过Docker Daemon收集,收集日志的速度依然是瓶颈。
```
log-driver 日志收集速度
syslog 14.9 MB/s
json-file 37.9 MB/s
```
能不能找到不通过Docker Daemon收集日志直接将日志内容重定向到文件并自动rotate的工具呢?答案是肯定的采用S6[2]基底镜像。
S6-log将CMD的标准输出重定向到/.../default/current,而不是发送到 Docker Daemon,这样就避免了Docker Daemon收集日志的性能瓶颈。本文就是采用S6基底镜像构建应用镜像形成统一日志收集方案。
**关于Kubernetes日志**
Kubernetes日志收集方案分成三个级别:
**应用(Pod)级别**
Pod级别的日志,默认是输出到标准输出和标志输入,实际上跟Docker容器的一致。使用kubectl logs pod-name -n namespace查看,具体参考:https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#logs。
**节点级别**
Node级别的日志 , 通过配置容器的log-driver来进行管理,这种需要配合logrotare来进行,日志超过最大限制,自动进行rotate操作。
![](https://upload-images.jianshu.io/upload_images/15462057-0b8a12a8aba41c1f?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
**集群级别**
集群级别的日志收集,有三种。
节点代理方式,在Node级别进行日志收集。一般使用DaemonSet部署在每个Node中。这种方式优点是耗费资源少,因为只需部署在节点,且对应用无侵入。缺点是只适合容器内应用日志必须都是标准输出。
![](https://upload-images.jianshu.io/upload_images/15462057-5047a7ac0b572c15?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
使用sidecar container作为容器日志代理,也就是在Pod中跟随应用容器起一个日志处理容器,有两种形式:
一种是直接将应用容器的日志收集并输出到标准输出(叫做Streaming sidecar container),但需要注意的是,这时候,宿主机上实际上会存在两份相同的日志文件:一份是应用自己写入的;另一份则是sidecar的stdout和stderr对应的JSON文件。这对磁盘是很大的浪费,所以说,除非万不得已或者应用容器完全不可能被修改。
![](https://upload-images.jianshu.io/upload_images/15462057-8378100ede19da7d?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
另一种是每一个Pod中都起一个日志收集agent(比如Logstash或Fluebtd)也就是相当于把方案一里的logging agent放在了Pod里。但是这种方案资源消耗(CPU,内存)较大,并且日志不会输出到标准输出,kubectl logs会看不到日志内容。
![](https://upload-images.jianshu.io/upload_images/15462057-2bc17d1b3a876dbb?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
应用容器中直接将日志推到存储后端,这种方式就比较简单了,直接在应用里面将日志内容发送到日志收集服务后端。
![](https://upload-images.jianshu.io/upload_images/15462057-66b92cfd2f5cee96?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
### **日志架构**
通过上文对Kubernetes日志收集方案的介绍,要想设计一个统一的日志收集系统,可以采用节点代理方式收集每个节点上容器的日志,日志的整体架构如图所示:
![](https://upload-images.jianshu.io/upload_images/15462057-4c9408031d9e7b8c?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
解释如下:
1. 所有应用容器都是基于S6基底镜像的,容器应用日志都会重定向到宿主机的某个目录文件下比如/data/logs/namespace/appname/podname/log/xxxx.log
2. log-agent内部包含Filebeat,Logrotate等工具,其中Filebeat是作为日志文件收集的agent
3. 通过Filebeat将收集的日志发送到Kafka
4. Kafka在讲日志发送的ES日志存储/kibana检索层
5. Logstash作为中间工具主要用来在ES中创建index和消费Kafka的消息
整个流程很好理解,但是需要解决的是:
1. 用户部署的新应用,如何动态更新Filebeat配置
2. 如何保证每个日志文件都被正常的rotate
3. 如果需要更多的功能则需要二次开发Filebeat,使Filebeat支持更多的自定义配置
### **付诸实践**
解决上述问题,就需要开发一个log-agent应用以DaemonSet形式运行在Kubernetes集群的每个节点上,应用内部包含Filebeat,Logrotate和需要开发的功能组件。
第一个问题,如何动态更新Filebeat配置,可以利用http://github.com/fsnotify/fsnotify工具包监听日志目录变化create、delete事件,利用模板渲染的方法更新Filebeat配置文件。
第二个问题,利用http://github.com/robfig/cron工具包创建CronJob,定期rotate日志文件,注意应用日志文件所属用户,如果不是root用户所属,可以在配置中设置切换用户。
```
/var/log/xxxx/xxxxx.log {
su www-data www-data
missingok
notifempty
size 1G
copytruncate
}
```
第三个问题,关于二次开发filebeat,可以参考博文:https://www.jianshu.com/p/fe3ac68f4a7a
### **总结**
本文只是对Kubernetes日志收集提供了一个简单的思路,关于日志收集可以根据公司的需求,因地制宜。
### **写在最后**
欢迎大家关注我的公众号【**风平浪静如码**】,海量Java相关文章,学习资料都会在里面更新,整理的资料也会放在里面。
觉得写的还不错的就点个赞,加个关注呗!点关注,不迷路,持续更新!!!
推荐阅读
-
本文探讨了Docker的安全挑战、核心安全特性及其管理策略,旨在帮助读者深入理解Docker安全机制,并提供实用的安全管理建议。 ...
[详细]
蜡笔小新 2024-11-21 20:03:03
-
从理想主义者的内心深处萌发的技术信仰,推动了云原生技术在全球范围内的快速发展。本文将带你深入了解阿里巴巴在开源领域的贡献与成就。 ...
[详细]
蜡笔小新 2024-11-21 09:06:54
-
-
线程中通信在裸机编程中,经常会使用全局变量进行功能间的通信,如某些功能可能由于一些操作而改变全局变量的值,另一个功能对此全局变量进行读取& ...
[详细]
蜡笔小新 2024-11-18 14:56:11
-
本文详细介绍了在Windows系统中如何配置Nginx以实现高效的缓存加速功能,包括关键的配置文件设置和示例代码。 ...
[详细]
蜡笔小新 2024-11-21 16:19:57
-
本文探讨了如何利用OBS Studio进行高效录屏,并通过脚本实现场景的自动生成。适合对自动化办公感兴趣的读者。 ...
[详细]
蜡笔小新 2024-11-21 10:44:53
-
本文介绍了如何使用Echarts for Weixin在微信小程序中构建中国地图,并实现区域点击事件。包括效果展示、条件准备和逻辑实现的具体步骤。 ...
[详细]
蜡笔小新 2024-11-18 19:37:06
-
本文总结了近年来在实际项目中使用消息中间件的经验和常见问题,旨在为Java初学者和中级开发者提供实用的参考。文章详细介绍了消息中间件在分布式系统中的作用,以及如何通过消息中间件实现高可用性和可扩展性。 ...
[详细]
蜡笔小新 2024-11-18 10:03:28
-
本文总结了 DirectShow Filter 的开发经验,重点介绍了 Source Filter、In-Place Transform Filter 和 Render Filter 的实现方法。通过使用 DirectShow 提供的类,可以简化 Filter 的开发过程。 ...
[详细]
蜡笔小新 2024-11-16 23:50:16
-
ABP框架是ASP.NET Boilerplate的简称,它不仅是一个开源且文档丰富的应用程序框架,还提供了一套基于领域驱动设计(DDD)的最佳实践架构模型。本文将详细介绍ABP框架的特点、项目结构及其在Web API优先架构中的应用。 ...
[详细]
蜡笔小新 2024-11-16 18:09:51
-
对于初学者而言,搭建一个高效稳定的 Python 开发环境是入门的关键一步。本文将详细介绍如何利用 Anaconda 和 Jupyter Notebook 来构建一个既易于管理又功能强大的开发环境。 ...
[详细]
蜡笔小新 2024-11-21 18:30:23
-
本文探讨了如何通过优化 DOM 操作来提升 JavaScript 的性能,包括使用 `createElement` 函数、动画元素、理解重绘事件及处理鼠标滚动事件等关键主题。 ...
[详细]
蜡笔小新 2024-11-21 18:16:19
-
本文详细介绍了如何在Oracle VM VirtualBox中实现主机与虚拟机之间的数据交换,包括安装Guest Additions增强功能,以及如何利用这些功能进行文件传输、屏幕调整等操作。 ...
[详细]
蜡笔小新 2024-11-21 18:13:22
-
publicclassBindActionextendsActionSupport{privateStringproString;privateStringcitString; ...
[详细]
蜡笔小新 2024-11-21 16:25:41
-
本文档介绍了如何使用OpenStack命令行工具在Keystone身份服务中创建和管理域、项目、用户及角色。随着Keystone命令向OpenStack命令集的迁移,了解这些新的命令格式对于系统管理员来说至关重要。 ...
[详细]
蜡笔小新 2024-11-21 11:46:03
-
本文介绍如何在阿里云环境中利用 Docker 容器化技术部署一个简单的 Flask Web 应用,并确保其可通过互联网访问。内容涵盖 Python 代码编写、Dockerfile 配置、镜像构建及容器运行等步骤。 ...
[详细]
蜡笔小新 2024-11-20 18:35:41
-