导读:网易从 2015 年就开始了云原生的摸索与实际,作为可观测性的重要一环,日志平台也经验了从主机到容器的演进,撑持了团体内各业务部门的大规模云原生化革新。本文会讲述在这个过程中咱们遇到的问题,如何演进和革新,并从中积淀了哪些教训与最佳实际。
次要内容包含:
- Operator 化的⽇志采集
- ⼤规模场景下的窘境与挑战
- 开源 Loggie 的当初与将来
01 云原⽣最后的摸索 Operator 化的⽇志采集
晚期公司外部业务跑在物理机上时,各业务应用的日志采集工具、日志直达和存储、配置下发都比拟凌乱,选型品种多。公司内基于轻舟平台推动了各服务容器化和云原生化,随着服务一直地迁徙到 K8s 上,咱们对于采集 K8s 容器日志和日志平台方面积攒很多实践经验。
云原生日志是什么样的,容器日志采集和主机上服务的日志采集有什么差别?首先 Pod 在 K8s 中会频繁地产生迁徙,手动去节点上变更配置日志采集配置不太切实际。同时,云原生环境中日志存储的形式多样,有容器规范输入和 HostPath,EmptyDir,PV 等。另外,采集日志后,个别会依据云原生环境的 Namespace、Pod、Container、Node 甚至容器环境变量、Label 等维度进行检索和过滤,这些元信息须要在日志采集时被注入。
常见的云原生环境日志采集有以下三种思路:
- 只采集规范输入
日志打印到规范输入的操作尽管合乎云原生十二因素,然而很多业务还是习惯输入到日志文件中,而且只采集规范输入日志难以满足一些简单业务的需要。惯例的采集规范输入日志的形式是挂载 /var/lib/docker,/var/log/pods 下的目录。同时须要留神选型的日志 Agent 是否反对注入 k8s 元信息。
- Agent ⽇志门路全局挂载
日志能够放在 EmptyDir,HostPath 或 PV 存储中,通过 DaemonSet 形式把日志采集 Agent 部署到每一台 k8s 节点上。EmptyDir 等存储映射到节点的目录能够通过通配的形式配置到 Agent 进行采集,由 Agent 读取配置门路下的日志文件。
但这种通用匹配的形式无奈依据服务级别进行独自配置。如果须要配置只采集某些服务的日志、或是某一个利用和其余利用的格局不同,例如某个利用的日志是多行的日志,此时须要独自批改配置,治理老本比拟高。
- Sidecar ⽅式
每个业务 Pod 在部署时都减少一个日志采集的 Agent SideCar,能够通过容器平台或 k8s webhook 的形式把日志采集 Agent 注入到 Pod 内。Agent 能够通过挂载雷同的 HostPath 或 EmptyDir 的形式采集到业务容器的日志。
这种形式的弊病是对 Pod 侵入性强,Pod 数量多时资源耗费较大。
比照 DaemonSet 和 SideCar 两种部署形式,DaemonSet 在稳定性、侵入性、资源占用方面有劣势,但隔离性、性能方面 SideCar 形式更好。咱们实际中会优先应用 DaemonSet 形式采集日志。如果某个服务日志量较大、吞吐量较高,能够思考为该服务的 Pod 配置 Sidecar 形式采集日志。
针对日志采集方面的痛点,咱们提出的第一个初步计划是:自研的 Ripple Operator 配合开源的日志采集客户端 Filebeat 进行业务日志采集。
部署方面,FileBeat、Ripple 通过 SideCar 形式部署在一起,Ripple 监听 k8s。在应用方面,用户通过 CRD,一个 CRD 能够示意一个服务的日志采集配置,Ripple 能够和 k8s 交互感知到 Pod 生命周期。Ripple 能够下发配置到 Agent,主动增加 Pod 相干元信息并注入到日志中。存储方面 HostPath、EmptyDir、PV、Docker Rootfs 都能够反对。
图中日志采集的架构先在网易严选进行了利用,前面逐步地被公司内绝大多数部门参考落地,具体架构会依据理论环境有所区别。首先日志平台下发配置,Ripple 监听到 K8s 的 CRD 配置变动后,把配置下发给 Filebeat。Filebeat 把采集到的日志发送到中转折,中转折发送给 Kafka,Flink 生产 Kafka 数据进行解决后转发给后端日志存储。
02 进⼊深⽔区 ⼤规模场景下的窘境与挑战
随着接入的业务越来越多,1.0 版本的日志架构逐步裸露了一些问题:超大规模下零碎的稳定性问题、日志平台性能问题、排障艰难和排障需要一直增多、保护人力老本直线升高等。
在后面介绍的架构中,Filebeat 会把每个服务的日志发送给中转折。然而 Filebeat 是一个繁多的队列架构,在中转折的阻塞会影响整个节点的 Filebeat 日志上报。
咱们尝试把 Filebeat 革新成多队列的模式加强隔离性,然而因为 Filebeat 自身的设计架构局限,重构的成果和运行状态都不现实,同时与开源版本的保护和降级存在很大艰难。
Filebeat 只反对单个 Output,当用户须要把日志发送到多个 Kafka 集群时,只能在同一个节点上部署多个 Filebeat。导致运维老本高、计算资源耗费大、程度扩大艰难。
Filebeat 设计之初是为了解决 Logstash 的问题,作为轻量级的日志采集端运行,不适宜作为直达。Logstash 在日志切分、解析等方面表现出色,然而问题在于性能较弱。尽管 Flink 性能和表现出色,但咱们的很多场景只须要简略的日志切分,Flink 个别依赖流式解决根底平台的反对,同时在交付过程中用户要额定付出 Flink 的机器和运维老本,所以咱们须要一个更轻量、老本更低的计划。
此外,日志采集过程的可观测性和稳定性也很重要。在用户应用过程中常常会遇到日志没有按预期采集、日志采集提早、日志失落、日志量增长速度过快磁盘爆满等问题,Filebeat 没有提供这些欠缺等监控指标,同时还须要额定部署 prometheus exporter。
咱们以一个线上问题为例。线上某集群常常遇到磁盘使用量短时间内暴增到 90% 以上并触发报警的状况。理论登录节点排查问题后,发现报警的起因在于上游 Kafka 吞吐量不够,一些日志文件没有齐全采集结束,Filebeat 过程默认保留文件句柄直到文件采集结束,因为文件句柄没有开释,底层的文件无奈被真正删除。但在这种状况下,Filebeat 不足输出提早、发送提早和沉积状况等指标,影响稳定性。
在一个大流量的节点,咱们发现 Filebeat 发送数据到上游 Kafka 时整体数据处理速度不现实,于是进行了很多优化的尝试,比方换 SSD 的 Kafka 集群、改 Kafka 配置、优化 Filebeat 配置等调优。咱们发现在 Filebeat 不关上数据压缩的状况下,最大数据发送速度达到 80MB/ s 后很难再有晋升,关上数据压缩后 Filebeat 的 CPU 的耗费又暴增。调整 Kafka 或 Filebeat 参数、机器等配置的优化成果不显著。
那么除了 Filebeat 外,其余的日志采集工具能不能满足需要?以后支流的日志采集 Agent 对容器化场景下的日志采集反对不太现实,大部分开源日志采集工具仅反对到容器规范输入的采集,对云原生下日志采集也没有整体解决方案。
03 新的征程 开源 Loggie 的当初和将来
基于 Filebeat 和现有支流数据采集工具的状况,咱们决定自研日志采集 Agent——Loggie。它是基于 Golang 的轻量级、⾼性能、云原⽣⽇志采集、聚合 Agent,⽀持多 Pipeline 和组件热插拔,整体架构如图。
咱们增强了 Agent 的监控和稳定性,能够利用 Monitor EventBus 上报 Agent 运行状况,同时裸露了可调用的 Restful API 和 Prometheus 拉取监控数据的接口。配置管理方面,目前应用 K8S 进行配置下发和治理,后续会接入更多配置核心供用户治理配置。
Loggie 提供了一栈式日志解决方案,新 Agent 不再离开保护 Agent 和中转折。作为一个可插拔组件,Agent 既能够作为日志采集端应用,也能够作为中转折应用,同时反对日志直达、过滤、解析、切分、⽇志报警。Loggie 同时提供了云原生日志采集残缺解决方案,比方通过 CRD 的模式利用 K8s 的能力下发配置、部署等。基于咱们长期的大规模运维日志收集服务的教训,Loggie 积淀了全⽅位的可观测性、疾速排障、异样预警、⾃动化运维能⼒的性能。Loggie 基于 Golang 开发,性能十分好,它资源占⽤小、吞吐性能优异、开发效率高保护成本低。
- ⼀栈式⽇志解决⽅案
Agent 既能够作为日志采集客户端,也能够作为中转折应用。在日志直达方面,咱们通过实现 Interceptor 模块逻辑实现日志的分流、聚合、转存、解析、切分等。通过 K8s 的 CRD 能够下发日志采集 Agent 配置。新的日志采集架构整体保护老本更低。
在采纳 Loggie 之前咱们有两种报警计划:第一种是基于 ElastAlert 轮询 Elasticsearch 进行日志报警,该计划存在配置下发须要手动配置、告警接入不能自动化和高可用不欠缺等问题;第二种是基于 Flink 解析关键字或是对日志进行正则匹配进行报警,在后面咱们曾经介绍过,对于整体日志采集服务而言 Flink 是比拟重量级的。
在采纳 Loggie 后,咱们能够应用 logAlert Interceptor,在日志采集过程中就能够通过关键字匹配辨认 info 或 error 进行报警。也能够通过独自部署 Elasticsearch Source 的 Loggie Aggregator 对 Elasticsearch 进行轮询,把信息发送到 Prometheus 进行报警。新版日志报警架构更轻量,保护起来也更简略。
在我的项目开发方面,咱们秉承微内核、插件化、组件化的准则,把所有组件形象为 component。开发者通过实现生命周期接口,能够疾速开发数据发送端逻辑、数据源读取逻辑、解决逻辑和服务注册逻辑。这样的设计让需要能更快更灵便地实现,大大了日志采集侧的开发效率。
基于灵便高效的 Agent 数据源设计,咱们能够配置 kubeEvent source 采集 K8S Event 数据作为监控报警的补充。相比从新实现一个采集 K8S Event 我的项目,只须要在 Loggie 上实现对应的 source,其余如队列缓存、解析日志、发送日志的逻辑都能够复用。
- 云原⽣的⽇志状态
用户通过配置 LogConfig CRD,能够指定采集 Pod、节点、集群日志信息。图中的例子是通过 labelSelector 匹配要采集的 Pod,并配置容器内日志门路;通过 Sink CRD 和 Interceptor CRD 能够配置日志发送和日志解决、解析形式。
通过 CRD 的形式买通日志解决链路,用户能够通过配置 CRD 定义日志直达、聚合和发送的计划,能够配置日志的解析、限流、报警规定,在进行私有化部署和将日志服务平台化时大大降低了配置管理的复杂度,一旦有配置变更,k8s 能够疾速地把配置同步到日志采集服务中。
在 k8s 中咱们提供了多种部署计划, 作为 Agent 部署时,咱们提供了 DaemonSet 或 SideCar 形式进行部署。作为直达节点部署时能够作为 StatefulSet 部署。日志采集的架构上更加灵便,能够间接发送到 ES,也能够发送给 Kafka 再交给直达节点,部署不便。
- ⽣产级个性
咱们为日志采集 Agent 增加了欠缺的指标,包含日志采集进度、长期采集未实现、采集发送提早、FD 数量、输入 QPS 和其余服务级别指标,提供了原生 Prometheus 格局的接口、RestAPI 和指标发送 Kafka 等形式裸露指标。
日志采集服务大规模部署的稳定性和排障两方面有很大晋升。咱们通过独立各个采集工作 Pipeline 加强服务隔离性,还能够通过 Interceptor 提供了 QPS 限度,定时清理日志避免磁盘写满,减少了日志文件突发增长检测和正当的 Fd 保留机制等。
- 资源与性能
咱们利用 Filebeat 进行了基准测试,在解决单⾏、单⽂件、雷同发送并发度、⽆解析的场景下,发送日志⾄ Kafka。
测试后果上看 Loggie 性能大幅度晋升,耗费 CPU 为 Filebeat 的 1 /4、吞吐量为 Filebeat 的 1.6-2.6 倍,且极限吞吐量与 Filebeat 的 80MB/ s 瓶颈晋升到 200MB/ s 以上。
04Loggie 开源打算
Loggie 曾经开源,上面是咱们我的项目推动的 RoadMap 和正在做的事,欢送感兴趣的开发者一起参加我的项目。
Loggie 我的项目地址:https://github.com/loggie-io/…
分享嘉宾:傅轶 网易数帆 轻舟日志平台负责人、架构师
目前专一网易数帆轻舟云原生日志平台研发,致力于云原生技术及其生态体系建设和商业化落地,对 Kubernetes、Serverless、可观测性等有较深入研究,具备丰盛的云原生分布式架构设计开发教训与我的项目实际。