Service Mesh Virtual Meetup 是 ServiceMesher 社区和 CNCF 联合主办的线上系列直播。本期为 Service Mesh Virtual Meetup#1 ,邀请了四位来自不一样公司的嘉宾,从不一样角度展开了 Service Mesh 的应用实践分享,分享涵盖如何使用 SkyWalking 来观测 Service Mesh,来自陌陌和百度的 Service Mesh 生产实践,Service Mesh 的可观察性和生产实践以及与传统微服务监控的区别。html
本文根据5月14日晚,G7 微服务架构师叶志远的主题分享《Service Mesh 高可用在企业级生产中的实践》整理。文末包含本次分享的视频回顾连接以及 PPT 下载地址。git
谈到 Service Mesh,人们老是想起微服务和服务治理,从 Dubbo 到 Spring Cloud (2016开始进入国内研发的视野,2017年繁荣)再到 Service Mesh (2018年开始被你们所熟悉),正所谓长江后浪推前浪,做为后浪,Service Mesh 别无选择,而 Spring Cloud 对 Service Mesh 满怀羡慕,微服务架构的出现与繁荣,是互联网时代架构形式的巨大突破。Service Mesh 具备必定的学习成本,实际上在国内的落地案例很少,大可能是云商与头部企业,随着性能与生态的完善以及各大社区推进容器化场景的落地,Service Mesh 也开始在大小公司生根发芽,弥补容器层与 Kubernetes 在服务治理方面的短缺之处。本次将以一个选型调研者的视角,来看看 Service Mesh 中的可观察性主流实践方案。github
可观察性(Observability)不是一个新名词,它在好久以前就已经诞生了,可是它在 IT 领域倒是一个新兴事物。可观察性在维基百科中原文是这样定义的:“In control theory, observability is a measure of how well internal states of a system can be inferred from knowledge of its external outputs. ”。云原生领域第一次出现这个词,是在云原生理念方兴未艾的2017年,在云原生的思潮之下,运用传统的描述方式已经不足以归纳这个时代的监控诉求,而 Observability 就显得贴切许多。数据库
回想一下传统的监控方式,除去运维层面的主机监控、JVM 监控、消息队列监控以外,有多少监控是事先就想好怎么作的?不多!其实不少时候,咱们作的事情就是在故障发生以后,对故障复盘的过程当中,除了 bug 重现与修复,也会去定制加一些监控,以指望下次发生一样的状况时有一个实时的告警。研发人员收到告警以后得以快速地处理问题,尽量地减小损失。因此,传统的监控模式大多都是在作亡羊补牢的事情,缺乏一个主动性。编程
在云原生时代的容器化体系当中就不同了,容器和服务的生命周期是紧密联系在一块儿的,加上容器完美的隔离特性,再加上 Kubernetes 的容器管理层,应用服务跑在容器当中就显得更加地黑盒化,相较在传统物理主机或者虚拟机当中,排查问题的时候显得很是不便。因此在云原生时代强调的是可观察性,这样的监控永远都是兵马未动而粮草先行的,须要提早想好咱们要如何观察容器内的服务以及服务之间的拓扑信息、各式指标的搜集等,这些监测能力至关重要。后端
关于可观察性在云原生领域是什么时候开始流行起来的,没有一个很明确的时间。业界认为可观察性最先是由 Cindy Sridharan 提出的,其实一位德国柏林的工程师 Peter Bourgon 早在2017年2月就已经有文章在讨论可观察性了,Peter 算是业界最先讨论可观察性的开发者,他写的著名的博文《Metrics, Tracing, and Logging》被翻译成了多种语言。真正可观察性成为一种标准,是来自 Pivotal 公司的 Matt Stine 定义的云原生标准,可观察性位列其中,由此可观察性就成为了云原生时代一个标准主题。安全
Peter Bourgon 提出的可观察性三大支柱围绕 Metrics、Tracing 和 Logging 展开,这三个维度几乎涵盖了应用程序的各类表征行为,开发人员经过收集并查看这三个维度的数据就能够作各类各样的事情,时刻掌握应用程序的运行状况,关于三大支柱的理解以下:架构
此外,Peter Bourgon 在博文中还提到了三大支柱结合态的一些理想输出形式,以及对存储的依赖,Metrics、Tracing、Logging 因为聚合程度的不一样,对存储依赖由低到高。更多细节,感兴趣的同窗能够查看文末的原文连接。app
Peter Bourgon 关于可观察性三大支柱的思考不止于此,他还在2018年的 GopherCon EU 的分享上面再次讨论了 Metrics、Tracing 和 Logging 在工业生产当中的深层次意义,此次他探讨了4个维度。框架
在 CNCF Landscape 当中,有一块区域专门用做展现云原生场景下的可观察性解决方案,里面又分为好几个维度,图中是截至2020年5月14日的最新版图,将来还会有更多优秀的解决方案涌现出来。CNCF 目前毕业的10个项目库当中,有3个是和可观察性有关的,可见 CNCF 对可观察性的重视程度。
谈到这里,不少同窗也许对于可观察性相关的协议比较感兴趣。目前比较火的有好几个,OpenTracing、OpenCensus、OpenTelemetry、OpenMetrics 等等,目前比较火的是前三个。OpenMetrics 这个项目已经不维护了。
OpenTracing 能够说是目前使用最广的分布式链路追踪协议了,大名鼎鼎的 SkyWalking 就是基于它实现的,它定义了与厂商无关,与语言无关的链路追踪协议 API,使得构建跨平台的链路追踪成为一件比较轻松的事情,目前它在 CNCF 的孵化器当中茁壮成长。
OpenCensus 是谷歌提出的一个针对 Tracing 和 Metrics 场景的协议,背靠 Dapper 的加持与历史背景,就连微软也十分拥护,目前在商用领域十分流行。
其余的协议好比 W3C Trace Context,呼声也很高,它甚至对数据在头部进行了压缩,与实现层无关。也许 CNCF 意识到各类协议又在层出不穷,之后各成气候,群雄逐鹿,每个中间件都要作许多兼容,这对整个技术生态自己不利,所以 OpenTelemetry 横空出世。从字面意思就知道,CNCF 会将可观察性的“遥测”进行到底,它融合了 OpenTracing 和 OpenCensus 的协议内容,旨在提升云原生时代可观察性指标的统一收集与处理,目前 OpenTelemetry 已经进入 beta 版本,其中使人欣喜的是,Java 版本的 SDK 已经有一个相似 SkyWalking 的基于 byte-buddy 框架的无侵入式探针。目前已经能够从47种 Java 库当中自动探测获取遥测数据,另外推出了可供使用的 Erlang、Go、Java、JavaScript、Python 的 API 和 SDK。此外,数据收集器 OpenTelemetry Collector 也可使用了,能够用它接收 OpenTelemetry client 发射过来的数据,统一收集处理。目前 CNCF 对 Logging 相关的协议制定暂缓,可是有一个工做小组也在作这方面规范的事情。
要说 Service Mesh 与可观察性的关系,那就是可观察性是 Service Mesh 的功能子集。Service Mesh 是当今最为火爆的技术理念之一,它致力于为云原生时代运行在容器当中的大规模服务提供统一的服务发现、边缘路由、安全、流量控制、可观察性等能力,它是对 Kubernetes 服务治理能力的补充强化。能够说,Service Mesh 是云原生容器化时代的必然产物,它将对云上服务架构产生深远的影响。Service Mesh 的架构理念是将容器服务运行单元当成一个个网格,在每组运行单元中劫持流量,而后由一个统一的控制面板作统一处理,全部网格与控制面板维持必定的联系,这样,控制面板就得以做为可观察性解决方案与容器环境之间的桥梁。
市面上最为常见的 Service Mesh 技术有 Linkerd、Istio、Conduit 等,可是要在生产环境落地必需要经受住严苛的性能、合理的架构、社区活跃度的评估。
Linkerd 是由 Buoyant 开发维护,算是 Service Mesh 领域第一代的产品,Linkerd1.x 基于 Scala 编写,可基于主机运行,你们都知道 Scala 运行环境依赖 JDK,所以对资源的消耗相对较大。随后官方进行了整改,推出了新一代的数据平面组件 Conduit,基于 Rust 和 Go 编写,与 Linkerd 双剑合璧,成为 Linkerd2.x。整体来讲,Linkerd2.x 性能有了较大的提高,也有可视化界面供操做,可是在国内就是不愠不火的,社区始终发展不起来。
转头看2017年出现的 Istio,也算是含着金汤勺出生的,由谷歌、IBM、Lyft 发起,虽然晚了 Linkerd 一年,可是一经推出,就受到普遍的关注与追捧。Istio 基于 Golang 编写,完美契合 Kubernetes 环境,数据平面整合 Envoy,在服务治理方面职责分明,国内落地案例相较 Linkerd 更加普遍。
Istio 目前整体还算是一个年轻的开源中间件,大版本之间的组件架构有比较大的区别,好比 1.0 引入了Galley(如图左),1.5 去掉了 Mixer,而且控制平面整合成单体,增长了 WASM 扩展机制(如图右)。整体的架构形式没有太大变化,数据面仍是关注流量的劫持与转发策略的执行,控制面依然作遥测收集、策略下发、安全的工做。目前国内业界对于 Istio 的使用上,云商与头部公司处于领先位置,好比蚂蚁金服自研了本身基于 Golang 的数据平面 MOSN,兼容 Istio,作了许多优化工做,对 Istio 在国内落地作出了表率,更多的信息能够深刻了解,看如何打造更适合国内互联网的 Service Mesh 架构。
虽然在 1.5 版本当中 Mixer 已经基本被废弃掉,进入维护阶段直到 1.7 版本,默认状况下 Mixer 彻底关闭,可是目前多数落地方案仍是基于 1.0-1.4 这个版本区间,因此在没有总体升级的状况下,以及 WASM 性能不明朗的彷佛还,始终仍是离不开 Mixer 的。前面说到 Service Mesh 是云原生容器环境与可观察性之间的桥梁,Mixer 的 Adapter 能够算得上是这个桥梁的钢架主体了,而且具备良好的可扩展性。Mixer Adapter 除了为流量作 Check 以外,更重要的是在预检阶段和报告阶段收集遥测数据,遥测数据经过 Adapter 暴露或发射数据到各类观察端,观察端基于数据绘制丰富的流量轨迹与事件快照。经常使用的用于可观察性的 Adapter 有对各类商用方案的适配,好比 Datadog、New Relic 等,开源方案 Apache SKyWalking、Zipkin、Fluentd、Prometheus 等,相关内容会在下文展开。
数据平面好比 Envoy 会向 Mixer 上报日志信息(Log)、链路数据(Trace),监控指标(Metric)等数据,Envoy 上报的原始数据都是一些属性信息(Attributes),属性信息是名称和类型的元数据,用来描述入口和出口流量和流量产生时的环境信息,而后 Mixer 会依照 LogEntry、Metric 或者 TraceSpan 模板配置的格式对属性进行格式化,最后再交给 Mixer Adapter 作进一步处理,固然对于数据量庞大的 Log 信息和 Trace 信息能够选择直接上报处理端,Envoy 也原生支持一些特定组件。不一样的 Adapter 须要不一样的 Attributes,模板定义了 Attributes 到 Adapter 输入数据映射的 schema,一个 Adapter 能够支持多个模板。Mixer 当中又能够抽象出三种配置模型:
下图是 Metric 模板与 LogEntry 模板,在映射关系之上还能够设定默认值,更多的设定能够查看官方文档。
下图是 TraceSpan 模板,熟悉 OpenTracing 的同窗可能对映射内容比较熟悉,不少信息都是 OpenTracing 协议的标准值,好比 Span 的各类描述信息以及 http.method、http.status_code 等等,感兴趣的同窗也能够去看看 OpenTracing 的标准定义。
另外在Service Mesh中对于链路追踪广泛有一个问题,就是不管你在数据平面如何作流量劫持,如何透传信息,以及如何生成或者继承Span,入口流量和出口流量都有一个没法串联的问题,这个问题要解决仍是须要服务主容器来埋点透传,将链路信息透传到下一次请求当中去,这个问题是没法避免的,而OpenTelemetry的后续推行,能够解决这方面的标准化问题。
在 Istio Mixer Adapter 当中咱们能够获知,Istio 支持 Apache SKyWalking、Zipkin、Jaeger 的链路追踪,这三个中间件都支持 OpenTracing 协议,因此使用 TraceSpan 模板同时接入也没有什么问题。三者稍有不一样的地方是:
说到这里要提一下 SkyWalking,它是由国人吴晟自主研发并开源的 APM 中间件了,能够说是国人的骄傲吧。本次的分享第二场由高洪涛老师,SkyWalking 的核心贡献者之一,也对 SkyWalking 作了题为《Apache SkyWalking 在
Service Mesh 中的可观察性应用》的分享,感兴趣的同窗能够关注一下。
Skywalking 提供了 Java、.NET、NodeJS、PHP、Python 的无侵入式插桩 SDK,另外提供 Golang 和 Lua 的有侵入式 SDK。
为何 Golang 不能作成无侵入式的?这还得从语言特性提及,一般编程语言分为编译型语言、解释型语言、中间型语言,像 Java 这种语言,在编译的时候是编译成字节码,而后运行时再经过 JVM 去运行字节码,这样就能够在这其中作不少的事情,能够在编译的过程当中把本来的代码改掉。而像 Python、PHP、JS 和 Erlang,是使用的时候才会进行逐行翻译,因此也能够在用的时候去加入一些额外的代码。Golang、C、C++ 则是编译型语言,在编译与连接的时候已经将源码转换成了机器码,因此在运行的时候是很难去改动的,这也就是 Golang 为何不能作自动探针的缘由。另外 SkyWalking 是由国人发起的,因此用户群体基数很是大,迭代也很是地快,7.0版本之前支持基于 Mixer 的遥测与显示,8.0以后又加入了从 Prometheus 或 Spring Sleuth 当中收集数据,另外8.0以后支持 Envoy ALS(access log service),不过须要开启 ALS 接收器。
在 SkyWalking 的使用上,基本是使用 ES 来作存储,可是有一些改动,将 service、endpoint、instance 这些信息放到关系数据库,各个插桩 SDK 也加入到基础镜像,也能够基于 SkyWalking 轻松实现服务接口粒度的调用次数统计。
另一个在云原生链路追踪领域收到普遍使用的是中间件是 Jaeger,它是由 Uber 开源,被 CNCF 接纳,目前已是一个毕业项目。它原生支持 OpenTracing 协议,与市面上的其余中间件也具备互通性,支持多种后端存储以及具有灵活的扩展性。在 Envoy 中原生支持 Jaeger,当请求到达 Envoy 的时候,Envoy 会选择建立 Span 或继承 Span,以保证链路的连贯性,它支持 Zipkin 的 B3 系列 Header 透传,以及 Jaeger 与 LightStep 的 Header。下图是 Jaeger 当中对链路的展现,能够经过 TraceId 准肯定位某一次请求。
传统的日志解决方案,ELK 能够说是家喻户晓的,从 Spring Cloud 盛行开始,它即是日志解决方案的优良选择。随着技术的发展,近几年又出现了 EFK 这种解决方案,存储组件 ElasticSearch 和界面 Kibana 却是没有什么特别大的变化,可是在严苛的线上环境与容器环境中,以及各类对资源敏感的场景下,对于日志采集组件的要求也愈来愈高,目前比较流行的方案是使用 Fluentd 或者 Filebeat 替代 Logstash,下面是它们三者的一些介绍:
对于 Istio 中的日志解决方案,尽管 Mixer 当中有提供 Fluentd Adapter,可是日志的量级你们也知道,这种方式并很差,因此从 Envoy 去拿到原始的属性日志再进行加工发射到存储端对应用是比较友好的,能够节省出很大一部分资源。
在日志维度中,若是要定位问题,最好与请求绑定起来,而绑定请求与日志,须要一个特定的标识,能够是 TransactionId 或者是 TraceId,因此链路追踪与日志融合是一个势在必行的行业诉求,所以在选择链路追踪中间件的时候,必定要考虑到如何更好地获取 TraceId 并与日志结合起来。
那么 Fluentd 就是最好的日志收集和发射解决方案了吗?
不是。Fluentd 的研发团队又推出了更加轻量级的 Fluent Bit,它是使用纯C编写的,占用资源更加少,从Fluentd 的 MB 级别直接降为 KB 级别,更加适合做为日志收集器。而 Fluentd 插件种类很是繁多,目前共有接近上千种的插件了,因此它更适合做为日志的聚合处理器,在日志收集以后的加工与传输中使用。在实际应用中,使用 Fluent Bit 可能会遇到一些问题,使用比较早期的版本可能会有配置动态加载的问题,解决方法就是另起一个进程控制 Fluent Bit 的启停,同时监听配置的变化,有变化则 reload。
关于上图中的 Loki,它的核心思想正如项目介绍,“Like Prometheus, but for logs”,相似于 prometheus 的聚合日志解决方案,2018年12月开源,短短两年,却已有接近1万个 Star 了!它由 Grafana 团队开发,由此能够看出 Grafana 对于一统云原生可观察性的目的。
在云原生时代,像之前那样用昂贵的全文索引,如 ES,或者列式存储,如 HBase,将大量的原始日志直接存储到昂贵的存储介质之中的作法,彷佛已经不太稳当。由于原始日志99%是不会被查询到的,因此日志也是须要作一些归并,归并以后压缩成 gzip,而且打上各式标签,这样可能会更加符合云原生时代精细化运做的原则。
而 Loki 能够将大量的日志存储于廉价的对象存储中,而且它为日志打标归并成日志流的这种方式得以让咱们快速地检索到对应的日志条目。可是注意一点,想要使用 Loki 替代 EFK 是不明智的,它们针对的场景不同,对数据的完整性保证和检索能力也有差异。
自从 Prometheus 出现以来,就紧紧占据着监控指标的主要地位。Prometheus 应该是当前应用最广的开源系统监控和报警平台了,随着以 Kubernetes 为核心的容器技术的发展,Prometheus 强大的多维度数据模型、高效的数据采集能力、灵活的查询语法,以及可扩展、方便集成的特色,尤为是和云原生生态的结合,使其得到了愈来愈普遍的应用。
Prometheus 于2015年正式发布,于2016年加入 CNCF,并于2018年成为第2个从 CNCF 毕业的项目(第一个是 Kubernetes,其影响力可见一斑)。目前 Envoy 支持 TCP 和 UDP statsd 协议,首先让 Envoy 推送指标到 statsd,而后可使用 Prometheus 从 statsd 拉取指标,以供 Grafana 可视化展现。另外咱们也能够提供 Mixer Adapter,接收处理遥测数据供 Prometheus 采集。
在 Prometheus 的实际使用当中可能会存在一些问题,好比 pod 被杀掉须要另外启一个,致使 Prometheus 数据丢失,这就须要一个 Prometheus 的数据可持久化的高可用方案。CNCF 的沙箱项目里面有一个项目叫作 Thanos,它的核心思想至关因而在 Prometheus 之上作了一个相似数据库 sharding 的方案,它有两种架构模式:Sidecar 与 Receiver。目前官方的架构图用的 Sidecar 方案,Receiver 是一个暂时尚未彻底发布的组件,Sidecar 方案相对成熟一些,更加高效也更容易扩展。
Service Mesh 解决方案当中的 Linkerd 和 Conduit 都有可视化界面。Istio 相对来讲比较黑盒,一直被诟病,不过 Istio 社区联合 Kiali,共同推出了一个可视化方案,提供以下功能:
下面是 Kiali 的架构,能够比较清楚地看出,其自己是一个先后端分离的架构,而且能够从 Prometheus 或者集群特定 API 获取指标数据,另外也囊括了 Jaeger 链路追踪界面与 Grafana 展现界面,不过它们并不是开箱即用,Kiali 依赖的三方组件须要单独部署。
在许多的中小型公司内部,其实 Service Mesh 仍是处于一个预研阶段,实际落地的时候须要考虑的因素繁多,如何才能得到较好的的投入产出效能比,是每个作选型的人员都必需要经历的。其实无论落地状况,鉴于云原生的可观察性哲学来讲,在落地的同时作好可观察性,能够同步解决不少问题,避免耗费过多的资源在无心义的事情上面,综合可观察性的三大支柱以及 Service Mesh 中对可观察性的支持来讲,总结以下:
叶志远,G7 微服务架构师,Spring Cloud 中国社区联合创始人,ServiceMesher 社区成员,《从新定义 Spring Cloud 实战》做者,国内微服务领域早期实践者,云原生追随者。
视频回顾:https://www.bilibili.com/video/BV13K4y1t7Co
PPT 下载:https://github.com/servicemesher/meetup-slides/tree/master/2020/05/virtual