简介:当前,云原生技术以容器技术为基础,通过标准可扩展的调度、网络、存储、容器运行时接口来提供基础设施。
当 Kubernetes 成为云原生事实标准,可观测性挑战随之而来
当前,云原生技术以容器技术为基础,通过标准可扩展的调度、网络、存储、容器运行时接口来提供基础设施。同时,通过标准可扩展的声明式资源和控制器来提供运维能力,两层标准化推动了开发与运维关注点分离,各领域进一步提升规模化和专业化,达到成本、效率、稳定性的全面优化。
在这样的大技术背景下,越来越对的公司引入了云原生技术来开发、运维业务应用。正因为云原生技术带来了越发纷繁复杂的可能性,业务应用出现了微服务众多、多语言开发、多通信协议的鲜明特征。同时,云原生技术本身将复杂度下移,给可观测性带来了更多挑战:
1、混沌的微服务架构,多语言和多网络协议混杂
业务架构因为分工问题,容易出现服务数量多,调用协议和关系非常复杂的现象,导致的常见问题包括:
- 无法准确清晰了解、掌控全局的系统运行架构;
- 无法回答应用之间的连通性是否正确;
- 多语言、多网络调用协议带来埋点成本呈线性增长,且重复埋点 ROI 低,开发一般将这类需求优先级降低,但可观测数据又不得不采集。
2、下沉的基础设施能力屏蔽实现细节,问题定界越发困难
基础设施能力继续下沉,开发和运维关注点继续分离,分层后彼此屏蔽了实现细节,数据方面不好关联了,出现问题后不能迅速地定界问题出现在哪一层。开发同学只关注应用是否正常工作,并不关心底层基础设施细节,出现问题后需要运维同学协同排查问题。运维同学在问题排查过程中,需要开发同学提供足够的上下游来推进排查,否则只拿到“某某应用延迟高”这么笼统的表述,这很难有进一步结果。所以,开发同学和运维同学之间需要共同语言来提高沟通效率,Kubernetes 的 Label、Namespace 等概念非常适合用来构建上下文信息。
3、繁多监测系统,造成监测界面不一致
复杂系统带来的一个严重副作用就是监测系统繁多。数据链路不关联、不统一,监测界面体验不一致。很多运维同学或许大多都有过这样的体验:定位问题时浏览器打开几十个窗口,在 Grafana、控制台、日志等各种工具之间来回切换,不仅非常耗时巨大,且大脑能处理的信息有限,问题定位效率低下。如果有统一的可观测性界面,数据和信息得到有效地组织,减少注意力分散和页面切换,来提高问题定位效率,把宝贵时间投入到业务逻辑的构建上去。
解决思路与技术方案
为了解决上述问题,我们需要使用一种支持多语言,多通信协议的技术,并在产品层面尽可能覆盖软件栈端到端的可观测性需求,通过调研,我们提出一种立足于容器界面和底层操作系统,向上关联应用性能监测的可观测性解决思路。
要采集容器、节点运行环境、应用、网络各个维度的数据挑战非常大,云原生社区针对不同需求给出了 cAdvisor、node exporter、kube-state-metics 等多种方式,但仍然无法满足全部需求。维护众多采集器的成本也不容小觑,引发的一个思考是能否有一种对应用无侵入的、支持动态扩展的数据采集方案?目前最好的答案是 eBPF。
「数据采集:eBPF 的超能力」
eBPF 相当于在内核中构建了一个执行引擎,通过内核调用将这段程序 attach 到某个内核事件上,实现监听内核事件。有了事件我们就能进一步做协议推导,筛选出感兴趣的协议,对事件进一步处理后放到 ringbuffer 或者 eBPF 自带的数据结构 Map 中,供用户态进程读取。用户态进程读取这些数据后,进一步关联 Kubernetes 元数据后推送到存储端。这是整体处理过程。
eBPF 的超能力体现在能订阅各种内核事件,如文件读写、网络流量等,运行在 Kubernetes 中的容器或者 Pod 里的一切行为都是通过内核系统调用来实现的,内核知道机器上所有进程中发生的所有事情,所以内核几乎是可观测性的最佳观测点,这也是我们为什么选择 eBPF 的原因。另一个在内核上做监测的好处是应用不需要变更,也不需要重新编译内核,做到了真正意义上的无侵入。当集群里有几十上百个应用的时候,无侵入