1 - Servicemesh开源项目之Linkerd

Servicemesh开源项目之Linkerd

1.1 - (2019)Linkerd v2: 从生产应用中得到的教训如何导致服务网格的重写

Linkerd v2: 从生产应用中得到的教训如何导致服务网格的重写

内容出处

Linkerd v2: How Lessons from Production Adoption Resulted in a Rewrite of the Service Mesh

https://www.infoq.com/articles/linkerd-v2-production-adoption/

作者 William Morgan, CEO - Buoyant,发表于2019年7月

Linkerd v2: 从生产应用中得到的教训如何导致服务网格的重写

https://blog.fleeto.us/post/linkerd-v2-production-adoption/

翻译 崔秀龙


关键信息

  • Linkerd 2.0 在一个被广泛接受的服务网格产品的基础上进行了大量改造,原产品使用 Scala 实现,从 Twitter 的 Finagle RPC 系统中受益良多。
  • 新版本产品从 JVM 转为使用 Go(控制平面)和 Rust(数据平面)协作实现。
  • Buoyant 团队在 Rust 网络栈方向进行了深入的探索,并简化 UX,提升易用性,降低学习门槛。最终造就了更快、更轻更简单的运维体验。
  • Linkerd 2.0 诞生至今已经过了 6 个多月,团队相信这次重写已经开始获得回报,很多从前面对 Linkerd 1.x 感觉无从下手的用户,现在已经满意的开始使用 2.x。

服务网格正成为现代云原生技术栈的重要成员。它把服务间通信(数据中心的惯用语中称之为东西向流量)的机制从应用代码迁移到了平台层,并提供了用于对通信进行度量和处理的工具,让运维人员以及平台所有者得到一个基本独立于应用代码的观察和控制层。

服务网格这个名词的历史还很短,背后的概念却不是那么新潮。这些概念在 Twitter、Netflix 和 Google 等公司中使用了超过十年,一般是通过 FinagleHystrix 以及 Stubby 这样的胖客户端形式实现的。从技术视角来看,现代服务网格中,部署协作代理(Sidecar)的方式是胖客户端组件的变体,将客户端库换成代理服务器,这种方式因为 Docker 和 Kubernetes 这样的容器和容器编排系统的流行而逐步成为可能。

服务网格的流行趋势始于 Linkerd,它是服务网格的最早产品和项目。在 2016 年发布第一个版本开始,目前有两条并行的开发路线:原始的 1.x 分支,构建在 “Twitter 技术栈” 之上,包含了 Scala、Finagle、Netty 以及 JVM;2.x 分支使用 Rust 和 Go 从头做起。

Linkerd 2.0 的出现,不仅是对底层的重新实现、还因为在多年以来的生产环境中的应用过程中总结了很多经验教训,所以在方法层面也有了很大改观。本文将对这些实践经验进行讨论,并探究其成为 Linkerd 2.0 哲学、设计和实现基础的原因。

Linkerd 是什么?值得注意么?

Linkerd 是一个开源的服务网格项目,也是 CNCF 成员。它在 2016 年出现,为全球各种规模的公司提供生产级别的架构支持,客户不仅包含 Strava 和 Planet Labs 这样的初创公司,还有 ComCast、Expedia、Ask 和 Chase Bank 等大型企业。

Linkerd 为微服务应用提供了可观察行、韧性和安全性方面的支撑。尤其重要的是,这些功能是属于平台层的。这意味着 Linkerd 的功能是跨越所有服务、独立于实现方式的,这就让平台的所有者能够跳出对开发团队的路线图和路线选择的依赖,进行独立思考。例如 Linkerd 能够在服务之间的通信中加入 TLS,让平台运维人员能够配置证书的生成、分发和验证过程,无需在服务开发团队的路线图中加入 TLS 的相关工作。

Linkerd 是通过在网格中的服务中加入透明的 L5/L7 代理完成工作的。这些代理构成了 Linkerd 的数据平面,负责处理各自代理服务的所有出入流量。数据平面受到控制平面的管理,Linkerd 的控制平面是一组进程,为运维人员提供集中的对流量进行观测和管理的服务。

Linkerd 基于对现实的一个认识:流经微服务的通信,和应用自身的代码一样,都是其运维工作的重要组成部分。Linkerd 无法介入微服务的内部,但是可以通过对成功率、吞吐量以及响应延迟的观测,来报告服务的健康情况。与此类似,Linkerd 无法修改应用的错误处理逻辑,但是可以通过对失败或缓慢的请求进行重试,来提高服务的健康程度。Linkerd 还能对连接进行加密,提供安全的服务身份认证,使用流量迁移的方式完成金丝雀和蓝绿部署等功能。

Linkerd 1.x

我们在 Twitter 运行的应用,是业界最早、最大规模的微服务应用之一,Linkerd 就诞生于这种运维经验之中。Twitter 从三层的 RoR 应用迁移到了 Mesos 和 JVM 基础之上的类似云原生的架构,这个过程中创建了一个库:Finagle,它为每个服务提供了服务发现、重试、监控等功能。Finagle 是 Twitter 进入大规模微服务阶段的重要一步。

Linkerd 1.x 诞生于 2016 年,根植于经过生产考验的 Twitter 技术栈:Finagle、Scala、Netty 和 JVM。我们最初的目标很简单:把 Finagle 的强力语义公诸于世。用 Scala 库的形式提供异步 RPC 支持是很受限的,因此我们将 Finagle 绑定为代理服务器的形式,这样就可以为各种语言编写的应用提供服务了。与此同时,容器和编排系统的快速蹿红,很好的降低了为每个服务实例部署代理的成本。Linkerd 增长强劲,尤其是在快速推进 Docker 和 Kubernetes 之类新技术的云原生社区。

从无到有,Linkerd 和服务网格模型本身都得到了长足的进步。今天 Linkerd 的 1.x 分支正在世界各地的公司中广泛采用,并在持续的发展之中。

Linkerd 的经验教训

Linkerd 虽然很成功,很多组织还是不想将 Linkerd 部署到生产环境,或者愿意这样做,但是要进行大量投入。

这种情况的形成,有很多方面的原因。有的组织不想把 JVM 引进到自己的环境之中。JVM 的运维较为复杂,有些运维团队因为这样那样的原因,拒绝任何基于 JVM 的软件进入他们的系统——尤其是 Linkerd 这样担任关键角色的系统。

其它的组织不愿意为 Linkerd 分配系统资源。一般来说,Linkerd 1.0 在资源充足的情况下,是很能承受规模负载的——单一进程每秒能够处理几万的的请求;然而对付小负载的能力让人不太满意——单进程的 RSS 很难降低到 150MB 以下。Scala、Netty 和 Finagle 加剧了资源问题——它们的共同目标都是在资源充足的环境下提供最大的吞吐量。

一个组织可能要部署成百上千个 Linkerd 代理,资源消耗颇为可观。作为妥协,我们建议用户为每个节点而非进程部署数据平面,这样用户能够降低资源消耗。然而这样一来就提高了运维的复杂性,限制了 Linkerd 的能力实现,例如为每个服务提供 TLS 证书。

最近 JVM 在这方面有了长足的进步。Linkerd 1.x 的资源消耗和尾部延迟在 IBM OpenJ9 上都大有改观,并且 Oracle 的 GraalVM 承诺会作出进一步的改善。

最后一点,还有复杂性方面的问题。Finagle 是一个功能非常丰富的库,我们将其中的很多功能直接通过配置文件的形式暴露给了用户。结果是 Linkerd 1.x 具有很好的定制性和弹性,但是也有了陡峭的学习曲线。其中一个设计失误就是引入了 dtab 这一来自 Finagle 的路由语言作为基础配置原语。任何想要对 Linkerd 行为进行定制的用户都会陷入到 dtab 之中,在投入使用之前都需要进行很多的智力投入。

重新开始

尽管 Linkerd 的接受度还在上升之中,我们在 2017 年底得出共识,我们必须重新审视我们的方案。Linkerd 的价值主张无疑是正确的,但是它对运维团队的高要求可能不太必要。当我们反思我们在协助组织采用 Linkerd 的经验时,我们确认了一些面向未来的关键原则:

  1. 节省资源:Linkerd 应该尽可能的降低性能和资源成本,尤其是代理层。
  2. 开箱即用:Linkerd 不应该扰乱现存的应用,也不应该依赖复杂的配置。
  3. 简单易用:Linkerd 应该能够用较低的认知门槛来进行运维。组件应该让用户感觉到清晰,其行为应该易于理解。

每一项需求都是一系列的挑战,为了降低系统资源需求,我们只能告别 JVM。为了开箱即用,我们需要在网络协议检测等复杂技术上进行钻研。最后,简单是最复杂的需求,我们要在每个方面明确的落实极简主义、渐进性和内省的原则。

面对这次重写,我们认为我们首先应该专注于一个初始的用例。我们决定聚焦在 Kubernetes 环境下的通用协议,包括 HTTP、HTTP/2 以及 gRPC,这只是一个起点,以后会突破这些约束进行扩展。

目标 1:节省资源

Linkerd 1.x 中,控制平面和数据平面都是同一个平台的产物。然而这两个组件的需求是很不一样的。数据平面会伴随每个服务的每个实例一同部署,处理进出该服务的所有流量,因此必须又快又小。另外它还必须安全:Linkerd 的用户相信它能够用于处理敏感信息,符合 PCI 和 HIPAA 的合规性要求。

而控制平面是单独部署的,并不存在于请求的处理路径之中,对速度和资源的需求较低。它更看重对扩展和迭代的支持。

很明显 Go 是控制平面的理想实现平台。Go 具有运行时支持,以及类似 JVM 的垃圾回收机制,这一平台为现代网络服务而进行了优化,其运行成本大大低于 JVM。相对于 JVM,Go 语言的静态二进制、内存占用和启动时间都是很吸引人的。我们的性能测试结果中,Go 比本地编译的语言稍慢,但是对于控制平面来说就足够快了。最后,Go 的生态系统让我们获得了很多关于 Kubernetes 的相关功能支持,另外我们认为这个语言的低门槛和流行度也都有助于开源社区的贡献。

我们考虑过用 Go 和 C++ 开发数据平面,然而 Rust 注定是最符合我们需求的选择。Rust 专注于安全,尤其是它强大的 Borrow checker,在编译时强制执行安全内存实践,避免了一整类内存相关的安全漏洞,这就使他比 C++ 更有吸引力。它能够被编译为本地代码,并有细粒度的内存管理能力,这使 Rust 比 Go 具有更好的性能和内存控制能力。Rust 兼具丰富功能和表现力的语言特性,对我们的 Scala 程序员很有吸引力,零成本抽象模型声明让我们在不牺牲安全性或性能的情况下提高了表达能力。

Rust 的最大问题是(2017 年):它的生态系统比其它语言来说相对落后。我们知道选择 Rust,就意味着要在网络方面进行深耕。

目标 2:开箱即用

解决了底层平台的决策问题之后,我们就要着手解决下一个设计目标了:开箱即用。对于 Kubernetes 应用,向既有应用中加入 Linkerd 不应破坏原有功能,也不应该依赖复杂的配置。

为了满足这个需要,我们做了很多设计抉择。我们给 Linkerd 的代理加入了协议检测的能力:它能够代理 TCP 流量,与此同时还能自动检测其中的 7 层协议。在 Pod 创建时用 Iptables 设置流量劫持,业务代码中的任何 TCP 连接都会被透明的经过本地的 Linkerd 代理,如果这些连接中使用的是 HTTP、HTTP/2 或者 gRPC,Linkerd 会自动的使用 L7 的方式进行干预——例如报告成功率、重试幂等请求、在请求级进行负载均衡等。这些目标都可以在无需用户配置的情况下完成。

我们还努力提供尽可能多的缺省功能。Linkerd 1.x 中提供了丰富的代理级指标,把聚合和报告留给用户去做。在 Linkerd 2.0 中,我们将 Prometheus 作为控制平面的成员,这样我们就可以在 Grafana 中提供开箱可用的聚合指标视图了。我们使用这套指标构建了一套 UNIX 风格的命令,让运维人员可以在命令行中观察运行中的服务。结合协议检测功能,平台运维人员可以从 Linkerd 获得丰富的服务级的指标,无需进行配置。

1linkerd-v2-production-adoption-1-1554327726494

进出应用的 TCP 连接都被路由到 Linkerd 的数据平面(Linkerd-proxy),Linkerd 数据平面让这些流量可以被控制平面进行观测和管理。

目标 3:简单易用

这是最重要的目标,简单和易用在某种程度上是矛盾的(感谢 Rich Hickey 的 《Simple Made Easy》,让我们茅塞顿开)。我们意识到,Linkerd 是一款面向运维的产品,也就是说,这并不是一个云厂商代你运维的服务网格产品,我们希望你会自己运行自己的 Linkerd。这样的话,减小 Linkerd 的运维面是一个重点。幸运的是,几年来帮助用户采纳 Linkerd 1.x 的经验,给我们很大帮助:

  • Linkerd 不应藏在幕后或过于神奇。
  • Linkerd 的内部状态应该是可观察的。
  • Linkerd 的组件应该具备良好的定义、充分解耦并具备清晰的边界。

为了这个目标,我们在服务中做了很多的设计决策。我们放弃了把控制平面集成到单一进程中的尝试,而是使用其自然形态进行了边界拆分:一个提供 Web 界面的 Web 服务;一个 Proxy API 服务来和数据平面进行通信等。我们在 Linkerd 的仪表盘上向用户直接公开了这些组件,我们还设计了符合 Kubernetes 生态系统中惯用的仪表盘和命令行客户端的界面:linkerd install 命令会输出一个 Kubernetes 清单文件,使用 kubectl apply 提交之后就能进行安装,Linkerd 仪表盘的观感和 Kubernetes 仪表盘类似。

我们还用加入约束的方式来避免复杂性。我们在 Kubernetes 核心名词,例如 Deployment 和 Pod 的基础上进行工作,尽量少定义自己的名词。我们尽可能的使用 Kubernetes 的自有功能,例如 Secret 和 Admission Controller。我们限制对 CRD 的使用,因为我们深知,CRD 也是重要的复杂性的来源。

最后,我们加入了扩展检测,让运维人员能够观测到 Linkerd 的内部状态并进行校验。我们把控制平面也加入了网格,这样运维人员就可以使用 Linkerd 丰富的遥测数据来观测和了解 Linkerd 的内部状态了。我们还加入了 linkerd endpoints 命令,用于导出 Linkerd 的内部服务发现信息,以及用于验证 Kubernetes 集群和 Linkerd 设置的 linkerd check 命令。

简而言之,我们尽了最大的努力,希望 Linkerd 能够清晰可见,而非简陋或奇幻。

1linkerd-v2-production-adoption-2-1554327725994

今天的 Linkerd 2.0

在经过了接近一年的内部投入之后,在 2018 年 9 月,我们启动了 Linkerd 2.0。虽然有着基本相同的价值主张,但是我们对易用性、可运维以及降低资源用量的关注,催生了一个和 1.x 截然不同的产品。六个月后,我们已经得到了回报,许多无法采用 1.x 的用户已经开始采用 2.x。

我们对Rust的选择引起了极大的兴趣;虽然这最初是一场赌博(事实上,我们以 “Conduit “的名义发布了早期版本,害怕玷污Linkerd的品牌),但现在很明显,这场赌博已经得到了回报。自2017年以来,我们对核心Rust网络库进行了大量投资,如Tokio、Tower和Hyper。我们已经调整了Linkerd 2.0的代理(简单地称为 “linkerd2-proxy”),以便在请求终止时有效地释放分配给请求的内存,允许令人难以置信的尖锐延迟分布,因为内存分配和取消分配在请求流中被摊销。Linkerd的代理现在的特点是p99延迟小于1毫秒,内存足迹远低于10MB,比Linkerd 1.x小一个数量级。

目前 Linkerd 的用户和贡献者社区正在蓬勃发展,未来一片光明。2.x 分支有 50 多个贡献者,每周都能规律的完成发布,还有积极友好的 Slack 频道可以进行沟通。我们为我们的努力深感自豪,并期待为我们的用户继续解决实际问题,同时也会继续坚持我们的设计理念。

2 - Servicemesh开源项目之Envoy

Servicemesh开源项目之Envoy

2.1 - Envoy的演进

Envoy的演进

2.1.1 - (2020)应用交付老兵眼中的 Envoy, 云原生时代下的思考

Envoy 是云原生时代的明星,其本质是反向代理负载均衡类软件,领域上归于应用交付,那么作为应用交付领域的老兵如何看待 Envoy,Envoy 又引发了哪些关于传统应用交付领域的思考?

内容出处

应用交付老兵眼中的 Envoy, 云原生时代下的思考

Envoy 是云原生时代的明星,其本质是反向代理负载均衡类软件,领域上归于应用交付,那么作为应用交付领域的老兵如何看待 Envoy,Envoy 又引发了哪些关于传统应用交付领域的思考?

https://cloudnative.to/blog/thoughts-to-envoy-from-adn-perspective/

作者 林静 (F5) 发表于 2020年6月30日


译者注:本文译自 Envoy 代理的创始人 Matt Klein 于昨晚在个人博客上发布的文章 5 year of Envoy OSS。他在 Twitter 因为自己的程序 bug 造成重大事故而离职,后加入 Lyft,在开源 Envoy 之前几乎没有贡献和管理开源项目的经验,这篇文章分享了他个人及 Envoy 开源的心路历程,在投身开源 Envoy 还是为雇主 Lyft 效命,该如何抉择?看完本文,相信对于开源项目的维护者、创业者及投资人都会大有收获。


本文作者:林静,F5 软件方向解决方案架构师,历任 F5 Global Service ENE,APAC Professional Service 顾问,技术专家。拥有超过 10 多年的应用交付领域工作经验,秉承持续学习和反馈的理念,致力于现代应用体系下的应用服务研究。CNCF Kubernetes CKA 664 号认证获得者,中国首位 F5 Security Solution Expert 认证获得者。

感谢邱世达对本文的审校。

前言

Envoy,使者,使节,代表!就像其单词含义本身一样,带着一种权威感,一种全代理的神圣感。结合其本身用途与角色,真是 “人如其名”,不禁为 Lyft 点赞,不知是得到了哪位大师的指点来起这个名字。在当前火热的微服务时代下,Envoy 是个绝对的明星,用众人皆知来形容可以说一点也不为过。曾有人问我如何看 Envoy 以及在云原生时代下是否 Envoy 将取代 F5 取代 NGINX,作为一个经历了两次应用交付技术领域更迭浪潮的老兵,在本文中我将来浅谈一下 Envoy,以及试图从个人角度来理解与回答一下这个问题。为什么说浅谈一下,这真的不是谦虚,而是客观上真的没有那么深入的大规模长时间使用和研究 Envoy 的所有技术细节,因此我将结合我的从业经历与经验来对 Envoy 做一个浅谈。

星光熠熠的 Envoy

首先我们看一下 Envoy 官方是如何介绍 Envoy 的:

ENVOY IS AN OPEN SOURCE EDGE AND SERVICE PROXY, DESIGNED FOR CLOUD-NATIVE APPLICATIONS Envoy 是一个开源的边缘以及服务代理,为云原生应用而生。

从网站首页的这一段描述可以清晰的看出官方对 Envoy 的定义,简单来说就是云原生时代下东西南北流量的代理。Lfyt 公司是微服务应用架构的先导者,在大量的微服务类布道文章中我们都可以看到 Lfyt 的身影,在从单体应用大规模转向微服务架构后,一个严重的问题摆在了开发与架构人员面前,一方面 Lyft 的服务采用了多种语言开发,而采用类库来解决分布式架构下的各种问题需要进行大量的语言适配以及对代码的侵入,另一方面 Lyft 的业务都是部署在 AWS 上的,大量依赖 AWS 的 ELB 以及 EC2,但是 ELB 以及 AWS 在当时所提供的服务间流量管控、洞察与问题排除都不能满足 Lyft 的需求,正是基于这样的背景,Lfyt 于 2015 年 5 月开始了 Envoy 的开发,最早是作为一个边缘代理进行部署并开始替代 ELB,随后开始作为 sidecar 方式进行大规模部署。2016 年 9 月 14 日,Lyft 在其博客上正式对外宣布了这一项目: Envoy C++ L7 代理与通信总线。 一时间 Envoy 得到了大量的关注,Google 等公司开始贡献到这个项目里,并在一年后的 2017 年 9 月将项目捐献给 CNCF。有了 Lyft 这样一个好妈,又过继给了 CNCF 这样一个富爸,再加上同父异母的 Istio 明星兄弟的加持,可以说 Envoy 一时风光无两,赚足了眼球与开发者的支持,仅一年多点时间便从 CNCF 毕业了。

容器技术助推了企业实践 Devops 与进行微服务改造,k8s 容器编排平台则让企业能够更加自信的将更多业务从传统架构迁移到基于容器的现代基础架构之上,k8s 解决了容器编排、应用发布等问题,但是当服务之间的通信从以前的内存之间调用变成了基于 TCP 的网络通信后,网络对应用服务的影响变得更加巨大与不确定,基于传统的应用架构的运维手段无法适应与解决巨大且复杂的服务间通信洞察、排错,为了解决这样的问题,sevice mesh 应用而生,并迅速成为关注的热。Istio 项目则是此生态中最重要的玩家,Istio 的架构是一个典型的管理平面与数据分离的架构,在数据平面的选择上是开放的,但是 Istio 默认选择了 Envoy 作为数据平面。两大人气明星强强联手,让几乎同一时期的 linkerd 变得黯然失色。而在这个时间点,NGINX 同样也曾短暂的进行了 Nginmesh 项目,试图让 NGINX 作为 Istio 的数据平面,但最终在 2018 年底放弃了,为什么会放弃,这个本文后面会提到。

当前除了 Istio 选择 Envoy 作为数据平面外,以 Envoy 为基础的项目还有很多,例如 k8s 的多个 Ingress Controller 项目:Gloo, Contur, Ambassador。 Istio 自身的 Ingress gateway 与 Egress gateway 同样选择的是 Envoy。来看下其官方首页列出的 Envoy 用户,说星光熠熠一点也不为过。注意列表里的 F5,是不是很有意思。 envoy-end-user (Envoy 最终用户列表)

后浪:为时代而生

下面我将从技术方面来看看为何 Envoy 能够得到社区的如此重视。将从以下几个方面来总结:

  • 技术特征
  • 部署架构
  • 软件架构

技术特征

  • 接口化与 API
  • 动态性
  • 扩展性
  • 可观测性
  • 现代性

接口化与 API

当我第一次打开 Envoy 的配置时候,我的第一感觉是,天啊,这样一个产品用户该怎么配置和使用。先来直观的感受下,在一个并不复杂的实验环境下,一个 Envoy 的实际配置文件行数竟然达到了 20000 行。

#  kubectl exec -it productpage-v1-7f4cc988c6-qxqjs -n istio-bookinfo -c istio-proxy -- sh
$ curl http://127.0.0.1:15000/config_dump | wc -l
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  634k    0  634k    0     0  10.1M      0 --:--:-- --:--:-- --:--:-- 10.1M
20550

尽管这是 Istio 环境下的动态配置,虽然还有方式去优化使得实际配置量减少,或者说当完全使用静态配置方式进行配置的时候我们不会做如此大量的配置,但是当我们看到以下实际的配置结构输出就会感觉到对于这样一个软件,如果以普通方式进行配置与维护显然是不切实际的,其配置完全 json 结构化,并拥有大量的描述性配置,相对于 NGINX 等这些反向代理软件来说,其配置结构实在是过于复杂。 复杂的配置结构 (复杂的配置结构)

显然,Envoy 的设计天生就不是为手工而设,因此 Envoy 设计了大量的 xDS 协议接口,需要用户自行设计一个 xDS 的服务端实现对所有配置处理,Envoy 支持 gRPC 或者 REST 与服务端进行通信从而更新自身的配置。 xDS 是 Envoy DS(discover service)协议的统称,具体可分为 Listener DS(LDS), Route DS (RDS), Cluster DS (CDS), Endpoint DS (EDS), 此外还有 Secret DS,为了保证配置一致性的聚合 DS-ADS 等,更多的 xDS 可 查看这里。这些接口用于自动化产生各种具体不同的配置对象。可以看出,这是一个高度动态性的运行时配置,要想用好它则必须开发一个具有足够能力的 server 端,显然这不是传统反向代理软件的设计思维。 envoyxDS (图片来自 https://gist.github.com/nikhilsuvarna/bd0aa0ef01880270c13d145c61a4af22)

动态性

正如前面所述,Envoy 的配置高度依赖接口自动化产生各种配置,这些配置是可以进行 Runtime 修改而无需 reload 文件,在现代应用架构中,一个服务端点的生命周期都变得更短,其运行的不确定性或弹性都变得更大,所以能够对配置进行 runtime 修改而无需重新 reload 配置文件这个能力在现代应用架构中显得尤其珍贵,这正是 Istio 选择 Envoy 作为数据平面的一个重要考虑。Envoy 同时还具备热重启能力,这使得在升级或必须进行重启的时候变得更加优雅,已有连接能够得到更多的保护。

在 Istio 场景下,Envoy 的容器里运行两个进程,一个叫 pilot-agent,一个是 envoy-proxy 本身,pilot-agent 负责管理与启动 Envoy,并产生一个位于 /etc/istio/proxy/ 下的 envoy-rev0.json 初始配置文件,这个文件里定义了 Envoy 应该如何与 pilot server 进行通信以获取配置,利用该配置文件最终启动 Envoy 进程。但是 Envoy 最终运行的配置并不仅仅是 envoy-rev0.json 里的内容,它包含上文所说的通过 xDS 协议发现的所有动态配置。

#  kubectl exec -it productpage-v1-7f4cc988c6-qxqjs -n istio-bookinfo -c istio-proxy -- sh
$ ps -ef
UID         PID   PPID  C STIME TTY          TIME CMD
istio-p+      1      0  0 Jun25 ?        00:00:33 /usr/local/bin/pilot-agent proxy sidecar --domain istio-bookinfo.svc.cluster.local --serviceCluster productpage.istio-bookinfo --proxyLogLevel=warning --proxyComp
istio-p+     14      1  0 Jun25 ?        00:05:31 /usr/local/bin/envoy -c etc/istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45 --parent-shutdown-time-s 60 --service-cluster productpage.istio-bookin
istio-p+    142      0  0 15:38 pts/0    00:00:00 sh
istio-p+    148    142  0 15:38 pts/0    00:00:00 ps -ef

在下图的 envoy 整体配置 dump 中可以看到包含了 bootstrap 的内容以及其它静态以及动态配置: envoy-config-dump (Envoy 配置结构)

结合下图可以看出基本的 Envoy 配置结构及其逻辑,无论是入口 listener(类似 F5 的 VS 以及部分 profile 配置,NGINX 的 listener 以及部分 Server 段落配置)还是路由控制逻辑(类似 F5 LTM policy,NGINX 的各种 Locations 匹配等),还是 Clusters(类似 F5 pool, NGINX 的 upstream)、Endpoints(类似 F5 pool member,NGINX 的 upstream 里的 server),乃至 SSL 证书完全可以通过接口从服务侧自动化的发现过来 envoy-objects (图片来自 https://gist.github.com/nikhilsuvarna/bd0aa0ef01880270c13d145c61a4af22)

扩展性

Envoy 的配置中可以看到大量的 filter,这些都是其扩展性的表现,Envoy 学习了 F5 以及 NGINX 的架构,大量使用插件式,使得开发者可以更加容易的开发。 从 listener 开始就支持使用 filter,支持开发者开发 L3,L4,L7 的插件从而实现对协议扩展与更多控制。

在实际中,企业在 C++ 的开发储备方面可能远不如 JavaScript 等这样的语言多,因此 Envoy 还支持 Lua 以及 Webassembly 扩展, 这一方面使得无需经常重新编译二进制并重启,另一方面降低了企业插件开发难度,让企业可以使用更多兼容 Webassembly 的语言进行插件编写,然后编译为 Webassenmbly 机器码实现高效的运行。目前来说 Envoy 以及 Istio 利用 Webassembly 做扩展还在早期阶段,走向成熟还需一段时间。 envoy-traffic-logic (图片来自 https://www.servicemesher.com/istio-handbook/concepts/envoy.html)

从上面的图可以看出,这样的请求处理结构非常的接近于 F5 TMOS 系统的设计思想,也在一定程度上与 NGINX 类似。连接、请求在不同的协议层面与阶段对应不同的处理组件,而这些组件本身是可扩展的、可编程的,进而实现对数据流的灵活编程控制。

可观测性

说 Envoy 生来具备云原生的特质,其中一大特点就是对可观测性的重视,可以看到可观测的三大组件:logs,metrics,tracing 默认都被 Envoy 所支持。

Envoy 容许用户以灵活的方式在灵活的位置定义灵活的日志格式,这些变化可以通过动态配置下发从而实现立即生效,并容许定义对日志的采样等。在 Metrics 则提供了能够与 Prometheus 进行集成的诸多指标,值得一提的是 Envoy 容许 filter 本身来扩充这些指标,例如在限流或者验证等 filter 中容许插件本身定义属于自己的指标从而帮助用户更好的使用和量化插件的运行状态。在 Tracing 方面 Envoy 支持向 zipkin,jaeger,datadog,lightStep 等第三方集成,Envoy 能够生产统一的请求 ID 并在整个网络结构中保持传播,同时也支持外部的 x-client-trace-id,从而实现对微服务之间关系拓扑的描述。 envoy-kiali

Envoy 生成的每个 span 包含以下数据:

  • 通过设置 --service-cluster 的原始服务集群信息。
  • 请求的开始时间和持续时间。
  • 通过设置 --service-node 的原始主机信息。
  • 通过 x-envoy-downstream-service-cluster 标头设置的下游集群。
  • HTTP 请求 URL,方法,协议和用户代理。
  • 通过 custom_tags 设置的其他自定义标签。
  • 上游集群名称和地址。
  • HTTP 响应状态代码。
  • GRPC 响应状态和消息(如果可用)。
  • HTTP 状态为 5xx 或 GRPC 状态不是 “OK” 时的错误标记。
  • 跟踪特定于系统的元数据。

现代性

其实,说 Envoy 具有现代性显然是正确的废话,Envoy 天生为现代应用架构而生,这里主要是想从几个我们最容易能够感受到的方面来说明一下。首先是其特殊的结构设计,在 Envoy 里它支持利用 iptables 截取流量并做透明处理,其本身能够利用 getsockopt () 实现对 NAT 条目中原始目的信息的提取,并在 listener 监听上容许在从被跳转的端口 listener 中跳跃到实际能匹配原始目的信息的非绑定型 listener,尽管从反向代理角度看这就有点像 F5 的 VS 内部跳转,NGINX 的 subrequest,但是其最大的特点和能力在于对连接的透明性,这在 Pod sidecar 模式的部署中显得尤其重要, 具体原理可参考 这里

对于现代应用最爱的灰度发布,流量镜像,断路器,全局限流等等功能,其在配置上也非常的简洁,这一点尽管 F5/NGINX 等软件也能完成类似的工作,但在原生性上以及配置的难易程度上 Envoy 具有更大优势。

现代性的另一个表现就是对协议的支持,看看以下支持的协议,熟悉应用交付、反向代理软件的同学可能会情不自禁的表示赞叹,而这些协议的支持更从另一方面表现了 Envoy 作为更加面向开发者和 SRE 的一个特质。

  • gRPC
  • HTTP2
  • MongoDB
  • DynamoDB
  • Redis
  • Postgres
  • Kafka
  • Dubbo
  • Thrift
  • ZooKeeper
  • RockeMQ

部署架构

在了解完 Envoy 的技术特征后,再来从部署架构角度看 Envoy。

完整 Sidecar 模型部署,这是 Envoy 最大的部署特征,services 之间的通信完全转化为 Envoy 代理之间的通信,从而实现将诸多非业务功能从服务代码中移出到外部代理组件,Envoy 负责网络通信控制与流量的可观测。也可以部署为简化的 sidecar,其仅充当 service 入站方向的代理,无需额外的流量操纵,这个结构在我对外阐述的基于 NGINX 实现业务可观测性中所使用 envoy-topo-1 (图片来自 https://www.envoyproxy.io/docs/envoy/latest/intro/life_of_a_request#request-flow)

Hub 型,这与 NGINX 的 MRA 中的 Router-mesh 型理念相同,所有服务使用一个集中的 Envoy 进行通信,这种部署结构一般适用于中小型服务,可通过与服务注册的适配将服务流量导向到 Envoy envoy-topo-hub (图片来自 https://www.envoyproxy.io/docs/envoy/latest/intro/life_of_a_request#request-flow)

Envoy 也可以作为 Ingress edge 网关或 Egress 网关,在这种场景下一般 Envoy 多用于 Ingress controller 或 API 网关,可以看到很多的此类实现喜欢使用 Envoy 作为底层,例如 Gloo, Ambassador 等 envoy-topo-in-out (图片来自 https://www.envoyproxy.io/docs/envoy/latest/intro/life_of_a_request#request-flow)

下面这个部署结构应该是大家比较熟悉的,Envoy 作为一个 Edge 网关,并同时部署额外一层微服务网关(或代理平台层) envoy-topo-in-out (图片来自 https://www.envoyproxy.io/docs/envoy/latest/intro/life_of_a_request#request-flow)

最后,这是将所有形态的 Envoy 部署集中到了一起,这种架构可能会在服务从传统架构向微服务架构迁移过程的中间形态 envoy-topo-all (图片来自 https://www.envoyproxy.io/docs/envoy/latest/intro/life_of_a_request#request-flow)

最后,来看一下 Istio 里是如何使用 Envoy 的 envoy-istio (图片来自网络)

总结来看,由于 Envoy 的跨平台性,使其具有和 NGINX 一样的灵活部署结构,但是实际上部署结构往往与最终的配置实现机制有着强关系,软件的能力能否适应在此结构下的灵活与简单的配置实现是最终考验。客观的讲,在这方面 Envoy 更具有优势。

软件架构

Envoy 采用了单进程多线程的设计结构,主线程负责配置更新,进程信号处理等。请求则是由多个 worker 线程来处理,为了简化与避免处理复杂,一个连接始终由一个线程处理,这样可尽量减少线程间的数据共享而引发的一些锁操作。Envoy 尽可能的避免线程之间的状态共享,为此设计了 Thread Local Store 机制。在日志的写入上,实际上是 worker 线程写入到内存缓存,最后再由文件刷新线程来负责写入到磁盘,这样可以在一定程度上提高效率。整体上来说,Envoy 在设计时候还是比较偏重于简化复杂性,并强调灵活性,因此与 NGINX 不同它并没有把对性能的追求放在第一位,这一点在 Envoy 的相关官方博客里可以得到验证。 envoy-threads

与 NGINX 类似,Envoy 整体是异步非阻塞的设计,采用的是事件驱动方式。每个线程都负责每一个 listener,可以采用 SO_REUSEPORT 也可以共享 socket,NGINX 也有类似的机制。 envoy-listener

当请求由 listener 监听并开始处理后,根据配置连接将会被后续的 L3、4、7 等多个 filter 进行处理。 envoy proxy arch

  • 图片取自 jimmysong.io*

前浪:宝刀未老

在了解完 Envoy 的技术特性及其架构后,我们再回到此文的原点。Envoy 从出生就带着现代应用架构的基因,是不是说对于 NGINX/F5 等这些前浪就落伍了呢。

记得 NGINX 的作者 Igor 在 F5 中国 520 大会上曾这样对大家介绍 NGINX 为何如此成功。他说,他没有想到会如此成功,究其原因是他在正确的时间点开发了一个正确的软件。 我们知道,在 2003 年左右那个时期,还谈不上什么分布式架构、微服务,那时候主要要解决的是单机性能问题,正是基于这样的背景,NGINX 无论从架构设计还是代码质量都严格苛求于性能。在功能上,NGINX 本来是一款 Web Server 软件,L7 反向代理则是其能力的延伸,而 L4 代理能力的增加则更晚,鉴于这样的背景,从现代应用架构角度来看,确实有一些能力是较难覆盖的。同样,Envoy 诞生和发展于现代应用架构时代,正如 Envoy 自我阐述,其参考了大量已有的软硬件反向代理、负载均衡产品,从上面的技术分析中也可以看出 Envoy 有很多 NGINX 以及 F5 架构理念,可以说 Envoy 从成熟的反向代理产品中吸取了诸多精华,并在设计时候充分考虑现代应用架构的需求,它也是一个在正确的时间的一个正确软件。

微服务架构下,很多问题都变成了如何控制服务之间的通信与流量洞察,这是典型的应用交付领域,作为这个领域的前浪一方面需积极拥抱和适应新时代的应用架构,一方面需要创新并继续引领新的方向。历史上这个领域发生了两次技术革新,第一次是在 2006 年左右,当时一度关于 “负载均衡已死” 话题被炒爆,实质是当时市场开始发生变换,大家不再满足于简单的负载均衡,需求衍生到应用安全、网络优化、应用优化、接入控制、流量控制等更多复杂的场景,应用交付概念开始被提出,可以说在 2006 年前,市场的主要概念和技术方向是以四层交换机为核心理念的负载均衡技术,大部分玩家是传统网络厂商,思维与概念都是以网络交换为基础,而 F5 就像一个奇怪的家伙,产品设计思想完全在另一个维度之上,自 2004 年就开始发布的 TMOS V9 操作系统自此开始引领市场,此后 10 年,无人超越。第二次技术革新发生在 2016 年左右,受云、微服务的影响,软件化、轻量化变为市场主流,同时 Devops 思想意味着使用者角色发生了变化,传统的面向网络运维人员的设计开始变得难以满足市场需求。以 F5 为主导的这个领域在市场上也发生了新的变化,Gartner 不再对应用交付领域发布魔力象限分析,转而形成以 Guide 方式的指导。 F5stock *F5 股价走势图 *

看当下,历史总是惊人的相似。

现代应用架构飞速发展,大量应用开始微服务化,但从业务访问的整体链条来看,Envoy 还不能解决所有问题,例如应用安全防护,复杂的企业协议,以及不同的组织关系导致的不同需求。可以看到以 F5/NGINX 为代表的应用交付产品在 Devops 大潮下也开始积极的实现产品融入,F5 发布了完整的自动化工具链,从产品的 bootstrap 到网络配置、到应用服务配置,到最后的监控遥测都已经形成了完整的接口,并采用声明式接口来将产品管理提升到更高角色人群与管理系统中。NGINX 同样构建了自身的 API 以及 Controller 平面,对外提供声明式 API 接口,开发者可以更好的利用接口融入自身的控制平面。这些变化都是为了让开发者或者 SRE 能够更好的使用 F5/NGINX, 详细可以参考我的《从传统 ADC 迈向 Cloud Native ADC》系列文章slides3

F5 在收购 NGINX 与 Shape 之后,提出了新的 view,将充分利用可广泛触达的数据平面能力,借助 AI 进一步挖掘数据潜能帮助用户更好的掌握和了解应用行为、性能,为业务运营提出参考,并反馈到组件配置与运行管理,从而形成闭环。

现代应用交付依然不能缺少一个重要场景,那就是应用安全,尽管 Istio 等产品在安全通信,身份,策略方面做了不少的尝试,但是应用安全本身则比较缺乏,F5 作为 WAF 安全领域的领导厂商,通过将安全能力转移到 NGINX 上形成了新的 NGINX APP Protect,利用其跨平台的能力帮助用户更好的管理微服务场景下的应用安全能力,帮助企业更好的落地 DevSecOps。

如果将 Envoy 的那些技术特征与 F5 进行对比的话,我们可以看到 F5 一定程度上欠缺在扩展性与现代性上,F5 具有较好的编程控制能力,但是相对于更大的插件开发来说是不足的,这和现代性往往可以联系到一起看,比如想针对某个很新的协议做一个类似 Envoy 的复杂 7 层 filter 是无法实现的,尽管 iRule 或者 iRuleLX 可以一定程度上做一些事情。然而无论怎样,最终 F5 的产品形态本身决定了 F5 的 BIGIP 是无法完全跨平台的,因为它无法以容器来运行。值得期待的是,这样的形态限制将会被 F5 下一代 TMOS 系统打破。

Service Mesh 是当前热门的技术方向,F5 基于 Istio 打造了企业级的 Aspen Mesh 服务网格产品,帮助企业更好、更容易的部署和使用 Istio。 Aspen mesh 团队成员进入仅有 7 个位置的的 Istio Technical Oversight Committee,负责 Istio 的 RFCs/Designs/APIs 等方面的重要职责。尽管 Istio 在 service mesh 领域拥有绝对的生态与热度,但这并不表示 Istio 是唯一的选择,在很多时候客户可能希望采用一种更加简洁的 Service Mesh 去实现大部分所需功能而不是去部署一整套复杂的 Istio 方案,基于 NGINX 组件打造的 NGINX Service Mesh (NSM) 将为用户带来新的选择,一个更加简单易用的 Service Mesh 产品,这是我们在文章最开始提到 NGINX 终止 Nginmesh 的原因。

总结

技术发展是一个必然的过程,2006 年从传统的负载均衡技术演变为应用交付,除了负载均衡之外,引入安全、访问控制、接入控制、流量控制等诸多方面。2016 年左右,这个领域再次发生新的技术变革,大量新生代反向代理开源软件的出现对传统应用交付类产品产生了一次新的冲击,积极适应与改变并创新是制胜的关键。Envoy 作为新代表有着优秀的能力,但它也不是解决所有问题的银弹,Envoy 拥有更陡峭的学习曲线以及更高开发成本与维护成本,对于企业来说应根据实际情况选择合适的解决方案与产品来解决架构中的不同问题,避免追赶潮流而让自己陷入陷阱。

F5 则更加需要让开发人员了解 TMOS 系统所拥有的巨大潜能(特别是下一代产品在架构以及形态上的颠覆),了解其优秀全代理架构以及可以在任意层面进行的编程控制, 让开发者、SRE 以 F5 TMOS 作为一种能力平台和中间件进行开发,更好的利用 F5 自身已经拥有的应用交付能力来快速实现自身需求。

最后,再次引用 Envoy 官方网站首页的一句话:

正如微服务从业者很快意识到的那样,当转移到分布式体系结构时出现的大多数操作问题最终都基于两个方面:网络和可观察性。

而保证更可靠的网络交付与更好的可观察性正是前浪们的强项。创新吧,前浪。

写在最后: 无论技术如何更迭,人的因素依旧是核心,不论企业自身还是厂商,在这样一轮技术浪潮中都应具备足够的技术储备,就像传统金融行业通过建立科技公司寻求转变一样,厂商同样需要转型,F5 中国的 SE 几乎 100% 的通过了 CKA 认证,无论相对比例还是绝对数量在业界应该是惟一了,转型不只在产品,更在于思想。

2.1.2 - (2021)网络代理 Envoy 开源五周年,创始人 Matt Klein 亲述开源心路历程及经验教训

开源网络代理 Envoy 的创始人 Matt Klein,在 Twitter 因为自己的程序 bug 造成重大事故而离职,后加入 Lyft,在开源 Envoy 之前几乎没有贡献和管理开源项目的经验,这篇文章分享了他个人及 Envoy 开源的心路历程,在投身开源 Envoy 还是为雇主 Lyft 效命,该如何抉择?

说明

5 years of Envoy OSS

https://mattklein123.dev/2021/09/14/5-years-envoy-oss/

作者 Matt Klein

Istio 开源四周年回顾与展望

网络代理 Envoy 开源五周年,创始人 Matt Klein 亲述开源心路历程及经验教训

开源网络代理 Envoy 的创始人 Matt Klein,在 Twitter 因为自己的程序 bug 造成重大事故而离职,后加入 Lyft,在开源 Envoy 之前几乎没有贡献和管理开源项目的经验,这篇文章分享了他个人及 Envoy 开源的心路历程,在投身开源 Envoy 还是为雇主 Lyft 效命,该如何抉择?

https://cloudnative.to/blog/envoy-oss-5-year/

译者 宋净超(Jimmy Song) 发表于 2021年9月15日


译者注:本文译自 Envoy 代理的创始人 Matt Klein 于昨晚在个人博客上发布的文章 5 year of Envoy OSS。他在 Twitter 因为自己的程序 bug 造成重大事故而离职,后加入 Lyft,在开源 Envoy 之前几乎没有贡献和管理开源项目的经验,这篇文章分享了他个人及 Envoy 开源的心路历程,在投身开源 Envoy 还是为雇主 Lyft 效命,该如何抉择?看完本文,相信对于开源项目的维护者、创业者及投资人都会大有收获。


前言

今天是 Envoy Proxy 开源5 周年。毫不夸张地说,在专业方面,过去的 5 年是一个史诗般的过山车,我的情绪介于兴奋、自豪、焦虑、尴尬、无聊、倦怠之间。我想分享一下这个项目的前传和历史,以及我在发展大型开源软件项目的过程中所学到的一些经验教训。

前传和历史

前传

除了一些小的弯路,我在技术行业二十年的职业生涯一直专注于底层系统:嵌入式系统,操作系统,虚拟化,文件系统,以及最近的分布式系统网络。我的分布式系统网络之旅始于 2010 年初在亚马逊,我有幸帮助开发了第一批高性能计算(HPC)EC2 实例类型。我学到了大量的底层高性能计算机网络知识,尽管我对分布式系统的概念接触有限。

2012 年,我加入了 Twitter,在经历了几次错误的开始后,我最终加入了边缘网络团队。这是我第一次真正接触到分布式系统应用网络概念。我领导了一个新的 HTTP 边缘代理的开发,称为 Twitter 流式聚合器(TSA),它在 2013 年首次推出,以扩大 Twitter 的 “firehose” API(流式所有推文)的交付。在 2014 年世界杯前夕,我们决定将 TSA 作为一个通用的 HTTP/HTTP2/TLS 边缘代理,在靠近巴西赛事的存在点(POPs)推出。这样做的主要原因是不可能在 POP 的少量主机托管机架上部署现有的基于 JVM 的资源匮乏的边缘代理。项目周期特别紧张,我的团队成功地完成了一届没有事故的世界杯。(我还清楚地记得有一段时间,当软件崩溃时,不管是什么时候,我都会给自己打上一页,修复错误,然后重新进行金丝雀部署,继续测试)。在 Twitter 工作期间,我还接触到了该公司通过 Finagle 库进行服务间网络通信的方式,并取得了巨大成功。

2015 年元旦前后,我在 Twitter 的日子里,因为我写的一个 bug,TSA 系统故障导致数百万 Twitter 的安卓用户被下线,这将是我在 Twitter 工作的尾声。

008i3skNly1guh3vblu9xj60tu0eu76p02

加入 Lyft 和创建 “Lyft 代理”

我在 2015 年春天离开了 Twitter,部分原因是下线事件的影响,部分原因是对没有得到晋升的挫败感,部分原因是想尝试新的东西。我跟着我的老板从 Twitter 到了 Lyft,还有我在 Twitter 的其他同事。

当我加入 Lyft 时,公司规模相对较小(少于 100 名工程师),并且正在努力从单体架构迁移到微服务架构。我已经多次谈到了 Envoy 的这部分历程,所以我不会再重述,在此简短的总结下,Lyft 遇到了所有典型的微服务迁移问题,主要是源于网络和可观察性。此外,Lyft 已经是 “多面手”(使用多种语言和框架),所以使用基于库的解决方案来解决这些问题似乎不切实际。因此,根据我以前建立 TSA 的经验和观察服务间通信在 Twitter 的工作方式,由于得到在 Lyft 的前 Twitter 同事们的信任,我提议建立一个新的应用网络系统,称为 “Lyft 代理”。

经过一些激烈的讨论,包括新的代理是否应该用 Python 构建(是的,真的),我们就项目的大致轮廓达成一致,并决定使用 C++ 作为实现语言。在当时,C++ 似乎是唯一合理的选择。今天我还会选择 C++ 吗?然而,如今已经不是 2015 年初了。

如果不说 “Envoy” 这个名字的由来,这部分的历史就不完整了。我们正在为这个项目建立最初的开发脚手架的时候,一个有远见的同事(Ryan Lane)说,我们不能把这个新项目叫做 “Lyft 代理”,我们必须选择一个更好的名字。我总是很实际,就去找辞典,查了一下 “代理”,然后决定用 Envoy 作为新名字。

在 Lyft 上线

直到 2015 年夏天,我才开始认真地研究 Envoy 的源代码。那几个月是我职业生涯中最有趣的几个月。我们应该珍惜这段初创时期,因为它不会持续很久。我花了很长时间,争取在合理的时间内(根据我的定义,这种类型的项目需要 3-4 个月的时间)做出能给 Lyft 带来价值的东西。俗话说,Lyft 给了我大量的绳子来吊死自己,而我致力于确保这种吊死不会发生。

当然,我的效率主要归功于刚从压缩的开发时间表和许多错误(主要是我自己的)中走出来,在 Twitter 的 TSA。我知道哪些错误是不能犯的,哪些抽象是需要的,哪些测试有效,哪些无效,等等。

2015 年秋天准备投入生产的 Envoy 的最初版本只包含了该项目今天所包含的功能和复杂性的一小部分。它不支持 TLS,只支持 HTTP/1,并且有极其简单的路由和弹性功能。它所拥有的是你今天所看到的东西的骨架。在这个项目的历史上,很少有重大的重构,主要是因为,正如我之前所说的,我知道将要发生什么,以及为了支持这些功能,需要有哪些抽象。Envoy 从一开始就拥有一流的可观察性输出,以指标和日志的形式。在 2021 年,这种类型的网络可观察性是桌面上的赌注(这在很大程度上要归功于 Envoy 的成功),但在当时却不是这样。

Envoy 最初是作为边缘代理在 Lyft 上线的,位于提供 TLS 终止的 AWS ELB 后面。到 2015 年秋末,Envoy 为 Lyft 的 100% 流量提供服务,该系统产生的边缘仪表盘立即得到了回报(例如,提供 API 调用百分点延迟直方图,每个终端的成功率和请求率等)。

在最初推出后不久,另一位 Twitter 同事(Bill Gallagher)加入了我的项目,我们迅速增加了一些功能,如 TLS 终止、HTTP/2 支持、更多路由和负载平衡功能等。

与此同时,Lyft 基于 Envoy 的 “服务网格 " 也开始成形了。首先,Envoy 被部署在 PHP 单片机旁边,以取代 HAProxy 及其一些固有的运维问题(例如,当时 HAProxy 仍然是单线程的),以帮助 MongoDB 的代理。可以毫不夸张地说,Envoy 的早期开发有很大一部分是针对 MongoDB 的稳定性(负载均衡、速率限制、可观察性等)。

基于 Envoy 的边缘机群和单体之间的直接观察能力的好处是非常明显的。不久之后,我们在一些高 RPS 分解的微服务旁边部署了 Envoy,以帮助排除网络问题。这方面的价值也得到了证明。随着时间的推移,我们超越了对可观察性的关注,增加了帮助系统可靠性的功能,如直接连接和服务发现(跳过内部 ELB)、异常值检测、健康检查、重试、断路等。Lyft 的基于负载的重大事件的数量从每 1-2 周一次慢慢减少。当然,Envoy 不能将所有此类事件的减少归功于此,但它提供的网络抽象确实有很大的帮助。

2016 年初,我们决定推动一个 100% 覆盖的服务网格。最初,我们认为这将是一个艰难的过程,需要自上而下的授权。在实践中,团队报名参加了迁移,因为他们将得到的好处是显而易见的。“胡萝卜 “式的迁移几乎总是成功的。而 “大棒” 式的迁移则很少成功,或者即使成功了,也会在组织内留下眼泪和愤怒。

到 2016 年中期,Envoy 被用于 Lyft 的所有网络通信,包括边缘服务、服务间通信、数据库、外部合作伙伴等。无论从哪个角度来看,该项目都取得了巨大的成功,帮助 Lyft 完成了微服务的迁移,提高了整体的可靠性,并对网络进行了抽象,使大多数工程师不需要了解真实的系统拓扑结构。此后,Bill 离开了这个项目,在 Lyft 从事其他工作,接替他的是 Roman Dzhabarov 和 Constance Caramanolis 加入我的团队。我们的小团队为整个 Lyft 开发和运维 Envoy。

开放源码

到 2016 年夏天,我们开始认真讨论开源 Envoy 的问题。早期的 Lyft 员工对开源和它为公司所做的事情很欣赏。很明显,Envoy 并不是 Lyft 的主要业务,那么为什么不把它放在那里并给予回报呢?我可以坦率地说,我们都带着不同的目标和期望来对待开放源代码的过程,以及对项目获得巨大成功后会发生什么感到非常天真。

在加入 Envoy 之前,我已经使用了相当多的开源软件,但我几乎没有开源贡献的经验,也没有维护者的经验。(虽然我在 Linux 内核中有过一次提交!)开源 Envoy 似乎是一个很好的机会,可以扩展我的技能组合,学习新的东西,可能会促进我的职业生涯,坦率地说,我不希望有一个 TSA v3 在第三家公司出现。对于 Lyft 来说,Envoy 是一个重要的工程项目,领导层认为,开放源代码将使 Lyft 作为一个工程组织具有可信度,并有助于招聘工作。正如我之前所说,我们所有人都对创建成功的开源,更重要的是在它获得成功的情况下培育它所需要的东西感到天真。

但是,我们决定给它一个机会。我们在 2016 年夏天花了很大一部分时间来编写文档(Jose Nino 在这个时候加入了团队,他的第一个任务就是阅读并帮助改进所有的文档),清理存储库,使其 " 不那么尴尬”,制作网站,发布博文等等。我真的很感谢这段时间里我在 Lyft 的同事,他们不仅支持我们,还帮助我们完成了无数的任务,包括网站设计、logo 等等。即使在这个早期阶段,我们也觉得第一印象很重要,如果我们要在开源领域有所作为,就必须通过高质量的文档、网站等给人留下良好的第一印象。

在此期间,我们还利用我们的行业关系,与 Lyft 的一些 “同行公司”(湾区的 “独角兽 " 互联网创业公司)会面,向他们展示我们在 Envoy 方面所做的工作,并获得他们的反馈,我们认为如果我们在正式开源前成功获得一个启动合作伙伴,这将是对项目的一个重大帮助。所有这些会议都非常友好,总的来说,所有与我们会面的公司都对我们所取得的成就印象深刻。但是,事后看来,他们都表示,以他们的小型基础设施团队,不可能马上采用 Envoy。他们祝愿我们在开放源代码方面取得最好的成绩,并说他们以后会回来看看。我们不禁对这些会议的结果感到沮丧,但我们还是向前推进了。

2015 年 8 月,我与谷歌进行了第一次友好的会面。一个 Lyft 的同事(Chris Burnett)在一个 gRPC 聚会上发言,提到了 Envoy,因为它与 Envoy 的 gRPC 桥接支持有关。我不知道的是,谷歌在发现 Envoy 的时候,正准备在 NGINX 的基础上推出 Istio。一次会议引出了另一次会议,然后是更多的会议,在 Envoy 开源之前,大量的谷歌员工已经看到了源代码和文档。(稍后会有更多关于这方面的内容)。

到 9 月初,我们已经准备好了,并将开源日定为 9 月 14 日。总的来说,我是一个(过度?)自信的人,但在我的生活中,有几次我对自己成功的能力有很大的焦虑。我立即想到的是:开始上高中,开始上大学,以及大学毕业后在微软工作。而开源的 Envoy 就是其中之一。我记得我被公众的反应吓坏了。人们会怎么说?反馈会是积极的还是恶毒的?虽然我们在开源时是一个小团队,但我仍然写了 90% 或更多的代码,并且觉得把它放到公共领域是对我自己和我的能力的一种反映。

如期而至,Envoy 在 2016 年 9 月 14 日 成为开源产品。我记得我和妻子一起庆祝,并说了一些话。“如果我们能让其他公司像 Lyft 一样使用 Envoy,我就会很高兴。”

对开放源码发布的反应几乎是普遍的积极。令我们惊讶的是,几乎是立刻,我们开始听到大公司的声音,而不是小公司。在几周内,我们与苹果、微软进行了交谈,与谷歌的对话也不断加快。大公司在现有的解决方案中存在问题,并且有大量的团队准备投入到解决这些问题的工作中。具有讽刺意味的是(至少在 Twitter 的观点中),C++ 在这里是一种帮助,而不是一种阻碍。这些大公司都已经拥有充足的 C/C++ 开发资源,以及他们想要整合的现有库,等等。对他们来说,C++ 是一个卖点。

在这段时间里,毫不奇怪,我们与谷歌的人有最多的互动。最初主要是构建 Istio 的团队,但渐渐地,我们与 Anna Berenberg 花了更多时间,她现在是谷歌的杰出工程师,领导各种网络和负载均衡工作。这种关系将产生 " 喷气燃料”,在 2017 年初真正启动该项目。

开始起飞

到了 2017 年初,很明显,Envoy 的开发正在加速。谷歌承诺用 Envoy 取代 NGINX,用于 Istio(最终在 2017 年春季推出),对项目的未来来说更重要的是,Anna 的大型团队致力于 GCP 云负载均衡功能,他们开始向使用 Envoy 的各种云负载均衡产品以及内部用例(这在这个时期都是非常秘密的,但现在已经众所周知)。

我将永远记得与谷歌互动的那段时间是我职业生涯中最紧张的时期之一。说实话,那感觉就像一个收购(审讯)过程。我记得长长的会议和电子邮件线程,以证明我们的技术决定,“面试 “中,谷歌试图确定我们是否会成为一个好的开源项目合作伙伴,等等。当时我们很痛苦地发现,这次” 收购 " 将使 Envoy 进入一个我们自己永远无法实现的轨道,所以我们尽一切努力使它获得成功,最终也获得了成功。而且,在过去 4 年多的时间里,我们与谷歌的合作确实是一种杰出的伙伴关系。早期的谷歌云工程师最终成为维护者,Harvey Tuch 和 Alyssa Wilk,为项目带来了大量的人才,包括技术上的,以及对开源和社区的支持。我对他们的感激之情溢于言表,没有他们,项目就不会有今天的成就。多年来为该项目做出贡献的其他谷歌工程师(现在有很多),除了普遍是优秀的社区管理者之外,还为该项目增加了大量的工程力量,否则该项目就不会有。我当然对最初的谷歌合作关系有顾虑(技术和理念上的分歧,等等),但我可以诚实地说,这些顾虑都没有成为现实。

除了确保 Istio 和 GCP 团队与谷歌合作的成功之外,我们还花了大量时间与其他公司和维护者合作并加入他们,其中许多人对项目产生了巨大的影响,至今仍作为维护者、贡献者或用户大量参与。如果没有这些早期的社区成员,这个项目就不会有今天,我也非常感谢他们对项目的信任。

同时,随着项目的不断深入,我开始收到大量投资者对 Enovy 的兴趣。有强烈的愿望让我离开 Lyft,围绕这个项目开一家公司。我写过这部分的旅程,所以我不会在这里重述,留在 Lyft 我会有大量的时间和精力来处理所有这些互动。正如链接的文章所描述的,我最终决定留在 Lyft,不开公司,以支持 Envoy 的持续成功。

与此同时,我仍然在 Lyft 工作,正如我将在后面进一步讨论的那样,我越来越多地从事两份工作。我的第一份工作是在内部领导网络团队,并在运营上支持 Lyft 的 Envoy。我的第二份工作是作为 Envoy 的公众形象,包括 OSS 领导,代码审查,修复错误,编写可以促进项目的功能,在会议上发言,帮助其他公司采用和部署 Envoy,等等。我开始变得过于分散,并出现了倦怠的迹象。然而,到了 2017 年年中,不可否认的事实是,Envoy 的发展轨迹是大大的 “向上和向右”。各大公司、“同行公司”、垂直产品和服务等的采用率继续攀升。

捐赠给 CNCF 且感到倦怠

到 2017 年秋天,有两件事是清楚的。

  1. Envoy 已经超出了 Lyft OSS 设备所能提供的范围。该项目需要法律、公共关系、营销、活动组织等方面的帮助。
  2. 我很快就完全倦怠了,需要找出一条可持续发展的道路。

为了解决第一点,我们最终同意考虑将 Envoy 转交到 CNCF。数月来,CNCF 一直在追求该项目,但似乎从来没有任何令人信服的理由来加入。到 2017 年底,很明显,CNCF 的资源即使不是净收益,也至少对项目是中性的。我们开始了提交程序,并最终在我们最初开放项目资源的几乎整整一年后加入了该基金会。我很感谢 Alexis Richardson 和 Chris Aniszczyk 在这个过程中对项目的指导。

第二点则要复杂得多。从根本上说,我的工作时间超过了我的工作能力,有效地跨越了两个不同的工作。此外,我正在期待我的第一个孩子,预产期在 2018 年初,随着到来的日期越来越近,这让我越来越焦虑。到这个时候,我已经很清楚,我在设定期望和界限方面做得不够好,不知道自己能够为 Lyft 提供什么,同时也没有从行业的角度关注 Envoy 的持续增长。在 Lyft,我越来越放任自流,陷入人际关系的争吵,在为更多的初级团队成员提供指导和领导方面,没有达到我这个级别的期望。

简而言之,我当时正处于崩溃的边缘,最终我选择了 Envoy 而不是 Lyft,这对我的 Lyft 同事造成了伤害。我想,如果我在 2017 年初至年中对我的工作量与 Lyft 的领导层更加透明,我可能会避免一些最糟糕的结果,但不幸的现实是,为开源软件行业的工作提供资源,而这些工作对雇主没有立即明显的作用,这是一个复杂的努力。它可能会更顺利,也可能不会。在任何情况下,虽然我对一些我本可以处理得更好的人际关系问题感到遗憾,但无论好坏,我都不后悔把精力放在 Envoy 上。我优先考虑的是 Envoy,而不是 Lyft,我做了我认为当时必须做的事情,以使它成功

可持续发展道路

我的第一个孩子在 2018 年 2 月出生,Lyft 极其慷慨的陪产假政策为我提供了休息和放空自己的时间。我从 Lyft 获得了一些空间,并开始更深入地思考我想要什么以及什么对我来说是可持续的。

当我休完陪产假回来后,我与 Lyft 领导层明确表示,我不能再参与 Lyft 的 Envoy 的 “日常” 运维。相反,由于 2017 年底的一些后果,基础设施团队也希望与我分开一些。由于这个原因,我大幅后退,实际上完全停止了在 Lyft 的基础设施工作,在 2018 年年中至年末的 Lyft Bikes 和 Scooters 初始版本中编写固件网络代码。这是一个了不起的团队努力,在压缩的时间范围内得到了一些东西,我真的很喜欢在几个月内做一些完全不同的事情。

2018 年也是我积极开始琢磨在 Envoy OSS 社区中 “取代自己” 的那一年。我花了大量的时间(并将继续花大量的时间)来培养维护者、新的贡献者,组织第一次专门的 EnvoyCon,等等。任何领导者都应该有一个目标,那就是确保该组织在有一天该领导者退位时能够继续良好地运作。

到 2018 年底,我的主要职业倦怠风险已经得到解决,我又开始了合理的工作时间,并花了很多时间与我的妻子和儿子在一起,我的时间大致在 Envoy OSS 工作和 Lyft 的一般基础设施领导之间各占一半。明确地说,Envoy 的成功带来的特权使我能够在 Lyft 的工作生活中取得这种平衡。随着时间的推移,随着我的行业地位的提高,我的影响力也在同步增加,这使得我更容易按照自己的意愿设定就业条款。没有多少人有这样的运气,我明白我是多么幸运,能够 “突破 “倦怠墙的另一边而不必离开我的工作。

Envoy 长大了

自 2019 年以来,因为新冠疫情,我在 Lyft 的基础设施领导和 OSS 领导之间继续保持着我上面描述的五五开的比例。当然也有单调和渴望不同的时候(从历史上看,我是一个习惯性换工作的人,6.5 年是迄今为止我在一件事情上工作的最长时间),但总的来说,我很高兴看到 Envoy 从一个 “新秀 " 变成更多的 “少年”。我不再专注于做我所能想到的一切,使 Envoy 获得巨大的成功,因为坦率地说,Envoy 是一个巨大的成功,已经席卷了市场,并改变了用户对应用负载均衡工具的期望。相反,我更关注项目的可持续性。我们是在做长期的工作,这些天我觉得自己更像一个 CEO,看减员人数、优先级、预算编制、安全问题等等。这并不是说这不是有用的工作;它显然是有用的,它只是与早期的工作不同,早期的工作技术性更强,节奏更快。

截止到 2021 年末,我对 Envoy 最引以为豪的事情是,在我看来,这个社区已经可以自我维持了。我们有一群令人难以置信的维护者、贡献者和用户,他们对项目的成功充满热情,并在使 Envoy 成为今天的样子中发挥了作用。这确实是一个团队的努力。

经验教训

过去的 5 年是一个史诗般的旅程。虽然我觉得我在技术上学到的东西相对较少,但我在领导力、社区建设和所有其他非技术性的东西方面都得到了成长和学习,这些都是建立一个成功的企业,无论是企业还是一个主要的开源成功故事。以下是我对一些主要学习内容的简短总结。

成功的开源软件就像创办一个企业

也许有争议的是,我认为如果一个人有目标要创建一个非常成功的开源软件项目,他们需要把它想成一个企业。除了核心技术之外,创业还涉及很多因素:

  • 招聘(在开源软件中,这意味着招聘贡献者和维护者)
  • 获取客户(在开源软件中,这被转化为用户)
  • 文档和技术写作
  • 公共关系
  • 市场营销
  • 法律(商标、许可等)
  • 人力资源(在开源软件中,这将转化为解决社区纠纷和制定文化)
  • 资金(在开源软件中,这转化为辅助费用,如 CI、为维护者找到允许他们在项目中部分或全部时间工作的工作,等等)
  • 总的说来,就是领导和方向的确定。资源有限,有很多事情可以做。企业 / 项目需要专注于最重要的事情,以实现产品的市场适应性。

直观地说,我知道这一点,在最初为 Envoy 进行开源努力时,我积极地追求上述所有的领域,努力使项目从开始发展到今天的规模。上述列表中的每一项都很关键,如果没有所有这些,一个项目是不可能成功的,尤其是在技术领域有很多资金雄厚的公司竞争对手的情况下。

我强烈鼓励那些考虑进行大规模开源工作的人提前在上述领域进行投资,以便在第一天就给人留下最佳印象。此外,新的开源项目应该准备在项目成长并开始看到采用时,在上述领域进行更多的投资。

毫不奇怪,这些天我在 Envoy 上做的编码工作相对较少。我在项目上的时间主要是管理项目的所有非技术方面(上述列表中的所有内容,甚至更多!),并确保事情按计划进行。我所做的大多数编码项目都是 “清洁 " 的幕后项目,对项目有好处,但没有什么乐趣,也不可能激励其他贡献者(当然,我对他们每天的工作没有发言权,我有动力让他们尽可能的开心,这样他们就不会离开)。

终端用户驱动的开源软件是一种结构性优势

这些天来,很多 “大的开源软件”,特别是在基础设施领域,是由大公司和风险投资支持的初创公司资助的。我不会绕到关于开源软件的困难经济的讨论,因为我已经写过了。我想说的是,我坚信终端用户的开源软件比企业和风险投资支持的开源软件有很大的优势:最初的客户几乎肯定会从软件中获得价值,否则软件就不会得到资助。这种与客户一起建立东西的良性循环是非常强大的。它几乎普遍导致了更好的结果:软件更可靠、更专注、功能更少。有很多由最终用户驱动的开源软件的例子,然后取得了巨大的商业成功。鉴于坚实的基础和内在的产品市场适应性,这对我来说并不奇怪。我希望看到比今天更多的最终用户驱动的开源软件,尽管我认识到经济上是困难的。对于那些有机会的人来说,请向这种类型的软件所具有的结构性优势靠拢!

不要跟风,要跟随客户

这也许是 “成功的开源软件就像创业” 和 “最终用户驱动的开源软件是一种结构性优势” 的必然结果,但我无法强调坚持不懈地关注客户的实际需求而不是炒作周期所认为的客户需求是多么关键。例如,多年来,人们一直在嘲笑 Envoy 是用 C++ 编写的,这引起了无数的笑话。我喜欢 C++ 吗?不,不是很喜欢。它是否在 2015 年完成了工作,并吸引了最初的一批主要用户?肯定是的。这是一个关注客户和市场的例子,而不是屈服于没有实际 “商业 " 影响的炒作。如果一个人把开源软件当做一个企业,就会立刻明白,以客户和市场为中心是取得巨大成功的唯一途径。在 Envoy,我花了大量的时间为终端用户争论,以确保我们建立的东西能让所有人受益,而不仅仅是一小部分小众用户。

可扩展性是至关重要的

跟着客户走往往会导致客户的要求不能很好地融入项目的架构中。从开源软件的角度来看,失去对项目主要目标的关注会导致功能蔓延、软件无法维护和维护人员负担过重。同时,说 “不 " 也是失去潜在用户的一个保证。

对于 Envoy,我想确保我们至少可以说 “是的,但是……",即提供一个强大的可扩展性模型,让用户可以满足他们的需求,而不需要将每一个改动和功能都推到上游。这种策略已经多次得到回报,它减轻了维护者的负担,让用户能够解决他们自己的问题,更重要的是,将 Envoy 推向了我在最初设计该软件时从未想象过的用例。

可扩展性,特别是对于开源软件的构建模块,是至关重要的。

质量问题

跟随客户的另一个推论是,质量确实很重要。用户希望软件易于操作,相对来说没有错误,关心安全,等等。曾几何时很多人会觉得因为开源软件是 " 免费的”,所以质量就得不到保证。这在理论上也许是正确的,但实际上,在一个项目对软件质量认真对待之前,用户不会大量地聚集在一个软件上。因为获得用户是一个飞轮,可以获得更多的用户(特别是当从早期采用者转向晚期采用者时),所以确保为整个软件质量编列时间预算就更加关键了。

关于 Envoy,我一直有一个 “零碰撞” 的理念。任何崩溃都会被调查和修复,无论多么不频繁的错误。这种对稳定性和质量的关注不会被忽视。

社区是扩大规模的唯一途径

这很明显,但我还是要说:社区是扩展开源软件的唯一途径。这是一个由维护者、贡献者和用户组成的社区。此外,社区的基调在项目开始时就已经确定,而且极难改变。人类倾向于遵循规范。一旦规范被确定下来,无论规范是什么,与这些规范不一致的人都会被避开。因此,项目最初的公共基调对于设定其长期的社区轨迹极为关键

当我们把 Envoy 做成开源软件时,我在 GitHub 上投入了大量的精力与人们一起工作,使用建设性和欢迎性的语言。总的来说,我尽我所能让 Envoy 成为一个受欢迎的地方,让人们愿意来贡献自己的力量,无论是维护、偶尔的贡献,还是用户帮助其他用户。

在 Envoy 所取得的所有不同类型的成功中,到目前为止,给我带来最多个人满足感的部分是,有相当多的人告诉我,他们已经发誓不再使用开源软件,尤其是基础设施开源软件,因为他们觉得大多数项目中的人对彼此感觉都很糟糕。相反的,他们喜欢为 Envoy 做贡献,因为这个社区是如此的尊重和欢迎彼此。这需要大量的努力和纪律,尤其是在项目的早期,才能达到这样的结果,而这已经得到了众多的回报。

不要低估从一开始就确定项目的文化和基调的复合效应。

混合商业和开源软件的利益是非常困难的

已经有很多关于开源软件的困难经济学的文章(包括我自己的文章,我在上面提到的)。我只想说,试图将商业上的成功和开放源码的成功结合起来是非常困难的,主要是因为这些成功往往是相互矛盾的

我相信,Envoy 通过其强大的 API 和可扩展性系统穿透了这个矛盾。从本质上讲,Envoy 已经成为一个工具,现在被大量的垂直产品和服务所使用。这就产生了一个社区,该社区充满了选择在一个共同的基底上合作的公司,即使是通过在扩展 / API / 控制平面 / UI/UX 层上的创新,推出相互竞争的上层产品。

任何成功的开源项目都会看到大量的商业 / 投资人的兴趣。如果一个项目的目标是保持一个充满活力的社区,同时又能取得商业上的成功(我认为这对整个项目的成功是必要的,因为钱必须来自某处),那么预先考虑如何将核心层和商业层分开是极其重要的。这样做的实用性和策略会因项目和技术的不同而不同,但我相信专注于强大的 API / 扩展性的分割是一个富有成效的策略。

基金会是很棘手的

在现代的开源讨论中,有很多关于基金会的作用的讨论。我不打算对这一话题做大量的评论,但我的主要建议是不要被基金会和它们可能提供的理论利益所干扰。相反,要积极地关注产品的市场适应性,生产高质量的软件,并为用户提供价值。如果这些事情得以实现,其余的事情就会自然而然地发生。

对于非常成功的项目来说,基金会,更确切地说,中立的商标持有地,是非常有用的,所以我肯定会在那个时候考虑加入一个。随着项目的成熟,Envoy 从成为 CNCF 的一部分所获得的价值也在不断增加。CNCF 雇佣了开源软件律师、营销人员、公共关系人员、一流的活动人员等等。这些额外的资源在 “经营业务 " 方面是非常宝贵的。

提前考虑治理问题

008i3skNly1guh3vqvywcj60tw0h8go702

开源治理是非常困难的。就其本质而言,开放源代码是无政府的,没有明确的领导结构。没有一个适合所有项目的治理方法,每个项目都必须找到自己的前进方向,可以通过 “BDFL”/CEO 类型的模式、指导委员会、类似 Apache PMC 的程序等。所有的治理模式都有优点和缺点,并且有不同的失败模式。

最重要的是,在项目变得庞大和成功之前,先认真思考治理问题。写下一套规则和规范,特别是花时间记录项目的冲突解决过程。

同时也要意识到,根据我在上面关于社区规范如何在早期设定的评论,早期的项目维护者将对整个对话和冲突解决的风格产生巨大的影响,就像公司的早期员工对公司的文化产生巨大的影响一样。

在我的印象中,我们在 Envoy 内部非常幸运,没有发生过任何重大分歧,出现的问题也可以迅速友好地解决。在项目的历史上,我们从来没有需要援引维护者投票程序来解决冲突。在我看来,这是一个巨大的成就,也是对所有维护者的素质和专业性的证明,尤其是考虑到该项目已经变得如此受欢迎,以及围绕它的所有商业利益。

对开源贡献的期望是至关重要的

我在上面提到过这个问题,但我自己的职业倦怠很大程度上是由于我没有很好地与我的雇主就我需要花多少时间来管理 Envoy 的开源增长设定合理的期望。我不会撒谎说,进行这样的对话就能神奇地使雇主为某人腾出大量时间来从事开源工作,特别是那些可能不直接适用于其日常工作的项目。话虽如此,我确信对所有参与的人来说,对开源过程有公开和诚实的期望是非常重要的。以下是在开源项目之前或开始以开源身份工作之前要问的合理问题:

  • 雇员应该问他们的雇主,为什么他们要开放源代码?
  • 雇主应该问他们的员工,为什么他们要开放源代码?(这个问题的答案和前一个问题的答案不同是完全合理的,但应该在公开场合讨论)。
  • 雇员应该问他们的雇主,如果项目成功了,会发生什么?该项目将有哪些资源可用?员工将有多少时间可以在通用的开源软件问题上工作,目的是直接推动项目的发展?

雇主和雇员之间不匹配的期望是未来怨恨和倦怠的根本原因。

代理容易,API 难

对一些人来说,Envoy 提供的底层网络代理机制似乎是这个项目的复杂部分。事实证明,与为 Envoy 发展一个稳定的 API 生态系统所做的工作相比,代理部分(在我看来)相对简单。平衡人类和计算机消费的 API 人体工程学,保持不同版本的稳定性,发展 API 以支持其他客户端,如 gRPC,指定协议语义以使 Envoy 能够与数百(可能是数千)个不同的管理服务器对话,等等,都是非常复杂的。我为团队在这一领域取得的成就感到骄傲(特别要感谢推动这一工作的 Harvey),即使在这一过程中出现了一些错误(比如从 API 的 V2 版本强制迁移到 V3 版本)。

如果一个软件提供了一个 API,而且更重要的是希望这个 API 成为其他系统的关键组件,那么不要低估提供一个稳定和符合人体工程学的 API 的成本和复杂性。反过来说,强大的 API 是一个生态系统飞轮的重要组成部分,会以此产生更多的产品和用户,所以在我看来,这些努力是非常值得的。

不要忽视职业倦怠

如果一个人想成就大事业,我不相信他可以 100% 实现良好的工作生活平衡。现实情况是,任何成功都是由现有的特权 / 机会、一个好的想法、良好的执行力和大量的运气(包括在正确的时间出现在正确的地点)组成的。所有这些东西都在 Envoy 中发挥作用,我不会假装我没有把自己搞得很累,特别是在 2017 年。我也会重新做一遍 2017 年的工作,因为从我的角度来看,我做了我必须做的事情,使项目获得成功。(有时我想,如果我已经有了孩子,Enovy 是否还会诞生。我不确定它是否会发生,但这是一个更长的谈话主题!)

综上所述,我在 2017 年描述的那种史诗般的推动力只能持续这么久,直到一个人崩溃。我鼓励大家不断反思自己的工作生活平衡,并为自己找出一条可持续发展的道路。每个人的情况都不同,我不能提供任何一个避免职业倦怠的建议,但我认为反思是一个好的开始,也是我自己不得不努力的事情。

感谢

在过去 6 年半的时间里,在 Envoy 上工作,其中 5 年是作为开源软件,这是我职业生涯中的亮点。这个项目的成功确实是一个团队的努力,我一个人是不可能完成的,我为我们所有人(维护者、贡献者和用户)共同完成的事情感到非常自豪。在这个项目上工作的维护者和贡献者是我所共事过的最好的工程师群体,他们才华横溢,他们就职在不同公司,位于不同的地理位置,这真是开源的理论潜力在实践中的体现。作为一个团队,我们已经产生了世界性的影响,改变了用户对软件负载均衡系统的期望,同时也建立了一个充满活力和热情的社区。在我最疯狂的梦想中,我从未想过这个项目会成为今天的样子。

对我来说,未来会发生什么就不那么清楚了。正如我上面所说的,我的重点已经转移到了可持续性上。我想确保,如果有一天我离开了,这个项目将保持健康。尽管如此,这一天还没有到来,我期待着在可预见的未来帮助领导项目前进,希望能取得更大的成功和采用。向前迈进!

2.2 - Envoy的WASM支持

Envoy的WASM支持

2.2.1 - Envoy的WASM支持概述

Envoy的WASM支持概述

使用基于 Web Assembly 的 Get Envoy 工具包扩展 Envoy

https://cloudnative.to/blog/introducing-getenvoy-extension-toolkit-for-webassembly-based-envoy-extensions/

Envoy WASM 源码抽丝剥茧

本文旨在从源码角度解析 Envoy 和 WASM 沙箱是如何桥接的。希望读者通过阅读本文,能够对 Envoy WASM 的接入有一定的了解。在实践的过程之中,能够帮助读者在繁杂的类型关系和调用链路中理清思路。本文默认读者具备一定的 Envoy 知识基础并且对 Envoy Filter 机制具备一定的了解。如果仅仅是希望使用 WASM 而不需要深入了解或者二次开发 Envoy WASM,那么可以阅读 SDK 文档即可。

https://cloudnative.to/blog/envoy-wasm-source-deep-dive/

Istio 进阶学习系列 基于 Web Assembly 实现 Envoy 与 Istio 的功能扩展

本文对 WebAssembly 和 Envoy 技术进行了介绍,通过 WASM Filter 的构建、发布和部署过程,方便读者了解 Envoy WASM Filter 的扩展方式及其实现原理。

https://cloudnative.to/blog/envoy-wasm/

3 - Servicemesh开源项目之Istio

Servicemesh开源项目之Istio

3.1 - Istio概述

Istio项目概述

3.2 - Istio的演进

Istio的演进

3.2.1 - (2021)Istio 开源四周年回顾与展望

今天是 Istio 开源四周年,让我们一起来回顾一下 Istio 四年来的发展并展望一下它的未来。

前言

Istio 开源四周年回顾与展望

今天是 Istio 开源四周年,让我们一起来回顾一下 Istio 四年来的发展并展望一下它的未来。

https://cloudnative.to/blog/istio-4-year-birthday/

作者 宋净超(Jimmy Song) 发表于 2021年5月25日


Istio 是由 Tetrate 创始人 Varun Talwar 和谷歌首席工程师 Louis Ryan 命名并在 2017 年 5 月 24 日开源。今天是 Istio 开源四周年,让我们一起来回顾一下 Istio 四年来的发展并展望一下它的未来。

Istio 的开源历史

2017 年是 Kubernetes 结束容器编排之战的一年,Google 为了巩固在云原生领域的优势,并弥补 Kubernetes 在服务间流量管理方面的劣势,趁势开源了 Istio。下面是截止目前 Istio 历史上最重要的几次版本发布。

日期 版本 说明
2017-05-24 0.1 正式开源,该版本发布时仅一个命令行工具。确立了功能范围和 sidecar 部署模式,确立的 Envoy 作为默认 sidecar proxy 的地位。
2017-10-10 0.2 支持多运行时环境,如虚拟机。
2018-06-01 0.8 API 重构。
2018-07-31 1.0 生产就绪,此后 Istio 团队被大规模重组。
2019-03-19 1.1 企业就绪,支持多 Kubernetes 集群,性能优化。
2020-03-03 1.5 回归单体架构,支持 WebAssembly 扩展,使得 Istio 的生态更加强大。
2020-11-18 1.8 正式放弃 Mixer,进一步完善对虚拟机的支持。

Istio 开源后经过了一年时间的发展,在 1.0 发布的前两个月发布了 0.8 版本,这是对 API 的一次大规模重构。而在 2018 年 7 月底发布 1.0 时, Istio 达到了生产可用的临界点,此后 Google 对 Istio 团队进行了大规模重组,多家以 Istio 为基础的 Service Mesh 创业公司诞生,可以说 2018 年是服务网格行业诞生的元年。

2019年 3 月 Istio 1.1 发布,而这距离 1.0 发布已经过去了近 9 个月,这已经远远超出一个开源项目的平均发布周期。我们知道迭代和进化速度是基础软件的核心竞争力,此后 Istio 开始以每个季度一个版本的固定发布节奏,并在 2019 年成为了 GitHub 增长最快的十大项目中排名第 4 名

Istio 社区

Istio 开源四年来,已经在 GitHub 上收获了 2.7 万颗星,获得了大量的社区用户。下图是 Istio 的 GitHub star 数增长情况。

008i3skNly1gqtm7n2hm1j31me0n2tag

2020 年 Istio 的项目管理开始走向成熟,治理方式也到了进化的阶段。2020 年,Istio 社区进行了第一次管委会选举,还把商标转让给了 Open Usage Commons。首届 IstioCon 在 2021 年 2 月份成功举办,几千人参加了线上会议。在中国也有大量的 Istio 社区用户,2021 年也会有线下面对面的 Istio 社区 meetup 在中国举办。

008i3skNly1gquicfqg14j31lw0smwl2

根据 CNCF 2020 年调查,46% 的组织在生产中使用服务网格或计划在未来 12 个月内使用。Istio 是在生产中使用的最多的网格。

未来

经过 4 年的发展,围绕 Istio 不仅形成了庞大的用户群,还诞生了多家 Istio 供应商,你可以在最近改版的 Istio 的官网首页中看到。在最近几个版本中,Istio 已经将发展中心转移到了提升 Day 2 Operation 体验上来了。我们还希望看到更多的 Istio 的采纳路径建议、案例研究、学习资料、培训及认证(例如来自 Tetrate 的业界的第一个 Istio 管理员认证),这些都将有利于 Istio 的推广和采用。

3.3 - Istio存在的问题

Istio存在的问题

3.3.1 - (2019)以Istio为例说明何时不做微服务

以Istio为例说明何时不做微服务

内容出处

Istio as an Example of When Not to Do Microservices

https://blog.christianposta.com/microservices/istio-as-an-example-of-when-not-to-do-microservices/

作者 Christian Posta 发表于2019年


3.4 - Istio的版本发布

Istio的版本发布

3.4.1 - Istio的版本发布概述

Istio的版本发布概述

3.4.2 - Istio 1.10的版本发布

Istio 1.10的版本发布

3.4.2.1 - Istio 1.10 版本发布并改版官网

我们很高兴地宣布Istio 1.10的发布!我们要特别感谢我们的发布经理Sam Naser和张之晗,以及整个测试和发布工作组在1.10中的工作。

内容出处

Istio 1.10 版本发布并改版官网

我们很高兴地宣布Istio 1.10的发布!我们要特别感谢我们的发布经理Sam Naser和张之晗,以及整个测试和发布工作组在1.10中的工作。

https://cloudnative.to/blog/istio-1-10-release/

作者 Istio Team 发表于 2021年5月19日


北京时间 5 月 19 日,我们很高兴地宣布 Istio 1.10 的发布!我们要特别感谢我们的发布经理 Sam Naser张之晗,以及整个测试和发布工作组在 1.10 中的工作。

这是我们 2021 年的第二个版本,和过去几个版本一样,我们继续为 Istio 用户改善 Day 2 操作。

该版本的亮点如下。

发现选择器

在以前的 Istio 版本中,Istio 的控制平面一直在观察和处理集群中它所关心的所有 Kubernetes 资源的更新。这在大型集群或配置快速变化的集群中可能是一个可扩展性瓶颈。发现选择器(Discovery Selector)限制了 Istiod 监视的资源集,所以你可以很容易地忽略那些与网格无关的命名空间的变化(例如一组 Spark Job)。

你可以认为它们有点像 Istio 的 Sidecar API 资源,但对于 Istiod 本身来说:Sidecar 资源限制了 Istiod 将发送至 Envoy 的配置集。发现选择器限制了 Istio 从 Kubernetes 接收和处理的配置集。

请看 Lin、Christian 和 Harvey 的精彩文章,深入了解这项新功能的情况。

稳定的修订版标签

早在 1.6 版本中,Istio 就增加了对安全部署多个控制平面的支持,并且我们一直在稳步提高支持度。关于修订版的一个主要的可用性抱怨是需要大量的命名空间重新标记来改变修订版(revision),因为一个标签(label)直接映射到一个特定的 Istio 控制平面部署。

有了修订版标签,现在有了一个间接层:你可以创建像 canaryprod 这样的标签,把使用这些标签的命名空间标记为修订版(即 istio.io/rev=prod),并把特定的 Istiod 修订版与该标签联系起来。

例如,假设你有两个修订版,1-7-61-8-0。你创建一个指向 1-7-6 版本的修订标签 prod,并创建一个指向较新的 1-8-0 版本的修订标签 canary

img

命名空间 A 和 B 指向 1-7-6,命名空间 C 指向 1-8-0

现在,当你准备将 1-8-0 修订版从 canary 推到 prod 时,你可以将 prod 标签与 1-8-0 Istiod 修订版重新关联。现在,所有使用 istio.io/rev=prod 的命名空间将使用较新的 1-8-0 版本进行注入。

img

命名空间 A、B 和 C 指向 1-8-0

请查看更新后的 Canary 升级指南

Sidecar 网络变化

在以前的 Istio 版本中,Istio 已经重写了 pod 网络,从 eth0 捕获流量,并将其发送到 lo 上的应用程序。大多数应用程序都绑定了这两个接口,并没有注意到任何区别;但有些应用程序被特别编写为只期望在其中一个接口上获得特定的流量(例如,通常只在 lo 上暴露管理端点,而从不通过 eth0,或者有状态的应用程序只绑定 eth0)。这些应用程序的行为可能会受到 Istio 引导流量进入 pod 的影响。

在 1.10 版本中,Istio 正在更新 Envoy,默认在 eth0 而不是 lo 上向应用程序发送流量。对于新用户来说,这应该只是一个改进。对于现有的用户,istioctl experimental precheck 将识别出监听 localhost 的 pod,并可能受到影响,如 IST0143

请参阅 John Howard 的文章,以更深入地了解这一变化,如何以及为什么它可能会影响你,以及如何实现无缝迁移。

Istio.io 改版

我们对 Istio.io 进行了改造,采用了全新的外观!这是 Istio 项目启动近四年以来,网站的第一个重大变化(我们将在 5 月 24 日,北京时间 5 月 25 日,庆祝这个周年纪念日!)。我们希望这些变化有助于使网站更方便用户,更容易浏览,总体上更有可读性。

Istio 官网全新改版,效果如图。

img

网站左下角有中英文切换功能。

img

感谢云原生社区 Istio SIG 翻译和维护了 Istio 官网中文文档。

这项工作由 Google Cloud 赞助,我们要特别感谢 Craig BoxAizhamal Nurmamat kyzy 和 Srinath Padmanabhan 推动这项工作,并感谢所有帮助审查和提供早期修订反馈的人们。

请在 istio.io 资源库上提交问题,给我们任何反馈。

开放我们的设计文件

从 2021 年 5 月 20 日开始,Istio 的设计和规划文件将向互联网上的所有人开放,无需登录。此前,查看这些文件需要谷歌登录和群组成员资格。这一变化将使技术文件的分享更容易、更开放。文件将保持在与以前相同的 URL,但 Community Drive 及其文件夹将改变位置。我们将在本周内联系所有的贡献者和 Drive 成员,并告知新的细节。

弃用

在 1.10 版本中,有两个功能将被废弃。

  • Kubernetes 第一方 JWT 支持(values.global.jwtPolicy=first-party-jwt)将被删除;它的安全性较低,仅用于向后兼容旧版 Kubernetes。
  • values.global.arch 选项已经被 Kubernetes 配置中的 Affinity 设置所取代。

请参阅 1.10 变更说明以了解这些废弃的详细情况。

反馈

如果你已经将你的服务网格升级到 Istio 1.10,我们想听听你的意见!请考虑参加这个简短的(约 2 分钟)调查,以帮助我们了解我们在哪些方面做得好,以及在哪些方面还需要改进。

4 - Servicemesh开源项目之Linkerd2

Servicemesh开源项目之Linkerd2