知识卡片

让日志与监控数据彻底脱离容器本体:支撑容器"随时可被销毁重建"的前提

普通读书笔记卡

内容

容器要真正具备弹性伸缩、随时被创建和销毁的能力,一个容易被忽视但至关重要的前提是:容器内部不能保留任何”一旦销毁就找不回来”的重要数据,日志和监控信息也不例外。雪球在日志处理上的做法是:以读写方式把物理机上一个与Docker IP对应的目录映射到容器内的/persist目录,再把/persist/logs软链接成业务代码里习惯写入的相对logs路径——这样一来,业务代码完全不需要感知”日志要考虑持久化”这件事,只管按照自己熟悉的相对路径正常写日志,实际数据早已经被透明地写到了容器外部的物理机上,容器本身即使被销毁,日志数据也完好保留。在Java场景下更进一步用logback appender方式直接把日志推送出去做收集,减少了依赖文件落盘再tail的环节;少数确实需要用tail -F方式收集的场景,才退回到在物理机层面处理。监控数据的采集也遵循同样的原则:把宿主机的cgroup目录以及一个统一管理的监控采集脚本映射进容器内部,由这个脚本定期采集所需数据并主动上报,而不是依赖Docker exec API去容器内执行采集命令——放弃Docker exec的原因很直接,实测性能太差,不适合高频定期采集这种场景。这两个设计共同贯彻了同一条原则:”去状态化”不能只停留在业务数据层面,日志、监控这类看起来是”运维附属品”的数据,同样需要被认真地从容器生命周期里剥离出去,否则容器一旦被销毁重建,这些数据就会连带丢失,容器”随时可以销毁重建”这个核心承诺就会因为这些被忽视的附属数据而名存实亡。

参考来源

- 位置:《高可用架构(第1卷)》第4章《容器与云计算》"4.2 互联网金融创业公司Docker实践"节,"4.2.3 应用迁移"(源文件:_epub-src/OEBPS/Text/Chapter4_2_4.xhtml) - 结论依据:原文说明"我们以rw方式映射了物理机上的一个与Docker IP对应的目录到容器的/persist目录,并把/persist/logs目录软连接为业务的相对logs目录……这样做也有助于去掉Docker的状态,让数据和服务分离……不在宿主机上使用Docker exec API采集的原因是性能太差",直接支撑本卡片结论。 - 原始内容:我们以rw方式映射了物理机上的一个与Docker IP对应的目录到容器的/persist目录,并把/persist/logs目录软连接为业务的相对logs目录……这样做也有助于去掉Docker的状态,让数据和服务分离……不在宿主机上使用Docker exec API采集的原因是性能太差。