为什么Linkerd不使用Envoy

2020-12-11 14:31:56 浏览数 (1)

问卷链接(https://www.wjx.cn/jq/97146486.aspx)


作者:William Morgan

(Photo by Paul Felberbauer on Unsplash)

在这篇文章中,我将描述为什么Linkerd不是建立在Envoy之上。

这是一篇写起来有点奇怪的文章。毕竟,Linkerd没有使用过上百万个项目,而且这些决策都不值得在博客上发表。但是Linkerd没有特别使用Envoy这一事实已经成为一个足够常见的讨论话题,因此它可能值得一个很好的解释。

我还要声明,这不是一篇“糟糕的Envoy”的博客文章。Envoy是一个伟大的项目,显然是许多人的选择,我们对从事这项工作的优秀人士只有尊敬。我们每天都向Linkerd用户推荐使用了Envoy的入口控制器,像Ambassador,而在世界各地的生产系统中,你可以发现Envoy和Linkerd并肩工作。

https://github.com/datawire/ambassador

但是我们没有选择在Envoy之上建立Linkerd。相反,我们构建了一个专用的“微代理”,简称为Linkerd2-proxy,它是针对服务网格边车用例进行优化的。在日益拥挤的同类服务网格项目领域,Linkerd在这方面独树一帜。但我们为什么要走这条路呢?

https://github.com/linkerd/linkerd2-proxy

对这个问题的完整回答本质上是细致入微的和技术性的--确切地说,就是那些在流行的、博客驱动的云原生应用世界中容易被淹没的内容。所以在这篇文章中,我将尽我最大的努力以一种坦率和专注于工程的方式来阐述原因。毕竟,Linkerd是由工程师创建的,也是为工程师服务的,如果说有一件事让我感到骄傲的话,那就是我们是在工程权衡的基础上做出决定的,而不是市场压力。

简而言之:Linkerd不使用Envoy,因为使用Envoy不允许我们建立世界上最轻、最简单、最安全的Kubernetes服务网格。

作为最轻、最简单、最安全的Kubernetes服务网格是Linkerd对用户的承诺,这也使得Linkerd在服务网格中独一无二:它非常简单,更轻,更安全。而我们能够做到这一点的原因是--你猜对了--因为我们建立在Linkerd2-proxy而不是Envoy的基础上。不是因为Envoy不好,而是因为Linkerd2-proxy更好--至少对于作为Kubernetes边车代理的非常具体和有限的用例来说。

让我们来看看原因。

Linkerd2-proxy是什么?

在深入讨论细节之前,有必要进一步了解一下Linkerd2-proxy。

Linkerd2-proxy是专门为服务网格边车用例设计的“微代理”。Linkerd2-proxy构建在大约2020年的世界上最现代的网络编程环境之上,并驱动了许多需求:Rust异步网络生态系统,包括像Tokio、Tower和Hyper这样的库。就纯粹的技术进步而言,Linkerd2-proxy是整个CNCF景观中最先进的技术之一。

像Envoy一样,Linkerd2-proxy是一个100%开源的Apache v2 CNCF项目,其特点是定期的第三方审计,一个活跃的社区,以及在世界各地的关键任务系统中的大规模生产使用。与Envoy不同的是,Linkerd2-proxy仅设计用于一种用例:在从Linkerd控制平面接收配置的同时,将请求从一个Kubernetes pod代理到另一个Kubernetes pod。与Envoy不同的是,Linkerd2-proxy被设计成一个实现细节:它不是面向用户的,它不能作为一个通用的构建块使用,它有一个无聊的名字。这意味着Linkerd2-proxy往往会被忽视,尽管我们最近在一些文章中对其进行了深入研究,并在路线图中给出了一些解释。

那么,为什么叫“微代理(micro-proxy)”呢?尽管我们要在词典中引入另一个术语,但“代理”这个词并不能完全代表Linkerd2-proxy。代理类似于Envoy、NGINX、Apache或httproxy。这些项目可以做各种各样的事情(“将带有匹配此通配符的路径的HTTP请求发送到此后端,同时重写这些头文件、压缩任何Javascript文件和旋转访问日志”),并且它们有一个配置和调优表面来匹配。在生产环境中使用代理需要大量的操作投资:如果你正在运行Apache,那么你将在某个地方找到Apache专家。

但是Linkerd2-proxy是不同的。它被设计成一个实现细节,不需要专门的知识或专门的操作投资(尽管Linkerd作为一个整体,当然,确实需要投资)。没有面向用户的YAML;相反,通过注入时设置的少量环境变量和运行时由Linkerd控制平面自动配置Linkerd2-proxy。我们将Linkerd2-proxy的调优范围保持在最低限度,以便最终用户很少需要直接接触它。简而言之:Linkerd2-proxy被设计成隐藏在幕后,作为一个实现细节,并且仅仅工作。

简而言之:Linkerd2-proxy与Envoy、NGINX和Apache等代理有很大的不同,“proxy”这个词并不能很好地代表它。

复杂性

那么为什么我们要建立Linkerd2-proxy而不是Envoy呢?一个主要原因是复杂性。

Envoy是一种灵活的、通用的代理,这也是它受欢迎的主要原因。你可以使用Envoy作为一个入口,作为一个出口,作为一个服务网格边车,以及在许多其他方式。但是这种灵活性带来了复杂性。

作为一个比较,截至2020年11月,Envoy仓库的C 代码为172 KLOC,“复杂性得分”(以分支和循环衡量)为19k。相比之下,Linkerd2-proxy只有30 KLOC,复杂度得分为1.5k。换句话说:Linkerd2-proxy代码基比Envoy小5倍,通过这种方法,它的复杂性比Envoy小10倍

当然,这不是一个苹果对苹果的计算。它不捕获仓库之外的库或依赖项;复杂性分数不能在语言之间严格地移植;等等。但它可以让你大致了解这些项目的相对规模:就内部而言,Linkerd2-proxy比Envoy要小几个数量级,也要简单几个数量级。

这种复杂性是Envoy的失败吗?不。Envoy有很多复杂的代码因为它可以做很多复杂的事情。但是,这种复杂性是构建专注于简单性(尤其是操作简单性)的项目的非常困难的基础。

简而言之:Envoy是瑞士军刀。Linkerd2-proxy是一根针。

资源消耗

对于任何基于边车的服务网格,有一点是清楚的:你将会有很多代理。

这意味着数据平面消耗的CPU和内存是运行服务网格成本的关键组成部分,尤其是在应用程序扩展时。

使用Linkerd2-proxy允许我们严格控制Linkerd的资源消耗。例如,在我们使用Kinvolk的开源基准测试工具对Linkerd和Istio进行的内部基准测试中,以每秒4000个请求的接入流量,我们看到Linkerd2-proxy实例的内存始终在14mb到15mb之间,而Istio的Envoy的内存在135mb到175mb之间,是这个大小的10倍。类似地,Linkerd2-proxy在测试运行中的CPU使用始终为每个实例15ms (CPU毫秒),而Istio的Envoy在22ms到156ms之间--多50%到多10倍。

https://github.com/kinvolk/service-mesh-benchmark

同样,这不是一个完全公平的比较。这些是针对特定应用程序和特定配置的内部基准测试,毫无疑问,Istio的一些设计决策在这里扮演了重要角色。但Istio是由世界一流的工程师建造的,关键是:如果Linkerd是在Envoy上建造的,我们将不得不自己做出许多同样的设计决定。

简而言之:在实践中,在服务网格上下文中,Linkerd2-proxy使用的系统资源只是Envoy所使用的系统资源的一部分。

安全

最后一点也许是最富哲理的一点:安全。数据平面的安全性对于任何服务网络都是一个巨大的问题。例如,Linkerd在世界各地的生产中被用于处理异常敏感的数据,从健康信息到个人可识别的细节再到金融交易。

我们没有理由认为Envoy是不安全的。但是从某种程度上说,它是安全的(特别是在C 代码的170 KLOC的情况下),它是安全的,它是通过让许多非常聪明的工程师使用它、检查它、归档CVEs、修复bug和重复的手工和昂贵的过程来实现的。这是软件安全的“传统过程”,而且至少在适当的时候是有效的。它也很昂贵、困难而且容易失败。C 代码的安全性是出了名的难,即使对最有经验的程序员也是如此。

https://alexgaynor.net/2020/may/27/science-on-memory-unsafety-and-security/

https://www.vice.com/en/article/a3mgxb/the-internet-has-a-huge-cc-problem-and-developers-dont-want-to-deal-with-it

更重要的是,这不是我们希望Linkerd所依赖的安全模型,也不是我们所相信的系统编程安全的未来。我们选择Rust作为Linkerd2-proxy是有意为之的:Rust的内存安全性使我们可以放心地在Linkerd2-proxy中编写安全代码,从而将我们对人类发现问题的依赖最小化。当然,这并不是说Linkerd2-proxy不存在安全漏洞!相反,它将拥有更少的;我们需要少依赖自己卑微的才能来避免它们;我们将不再经常要求我们的用户对他们的系统进行关键升级,以保持安全。

简而言之:Linkerd2-proxy的Rust基础让我们对Linkerd的数据平面的安全性有了信心。

Linkerd可以使用Envoy吗?

简单性、资源消耗和安全性是我们决定不采用Envoy的驱动因素。然而,我们相信代理的选择最终是一个实现细节。虽然我们在Linkerd2-proxy上投入了大量的资金,但我们也会定期重新评估Envoy。我可以明确地说,如果对我们的用户来说,这个折衷方案对Envoy有利,我们将毫无疑问地采用它。

不过,我们对未来的服务网络采纳者的建议很简单:忽略这些噪音。你的工作不是“使用服务网络”或“采用Envoy”,甚至“只使用CNCF技术”。你的工作是清楚地了解你要解决的问题,然后选择最能解决它的解决方案。无论你选择什么,你都将不得不接受它--所以确保你的决策是基于具体的需求和充分理解的工程权衡,而不是基于时尚或趋势。

常见问题解答

那么为什么这么多的服务网格使用Envoy?

因为编写自己的现代、可伸缩、高性能网络(微)代理非常困难。真的很难。在过去的几年里,构建Linkerd2-proxy和Rust网络库使之成为可能是许多人付出的巨大努力。除非你的项目既具备技术实力,又有解决这一挑战的愿望,否则使用Envoy要容易得多。

但是Envoy不是服务网格的“标准”吗?

不是。一个标准是互操作性所必需的东西。对服务网格至关重要的标准是TCP或HTTP,或者像SMI这样允许在服务网格之上构建工具的标准。(例如,这是Argo通过SMI为canary发布驱动Linkerd的绝佳例子。)

https://smi-spec.io/

https://argoproj.github.io/argo-rollouts/getting-started/smi/

Envoy作为服务网格数据平面代理的普遍选择并不是一个标准,而是一个简单的共性。Envoy成为一个“服务网格标准”意味着什么?我们可以把数据平面保留在原来的位置,然后换掉控制平面?我们可以用不同的控制平面操作同一个数据平面?这些都是牵强附会的用例。

但如果我们要求使用Envoy呢?

我认为这不是一个真正的要求。你的工作不是采用某一特定的技术。你的工作是解决问题。

如果你的问题是“我们需要建立一个可靠的、安全的、可观察的Kubernetes平台,而不需要付出疯狂的复杂性成本”,那么我强烈建议你考虑看看Linkerd。

现在谁在生产中使用Linkerd2-proxy?

每个使用Linkerd的人都使用Linkerd2-proxy。这意味着你可以找到Linkerd2-proxy为Nordstrom、微软、H-E-B、Chase、Clover Health、HP等公司的关键生产架构提供支持。

其他的服务网格项目可以使用Linkerd2-proxy吗?

不太能够。但是任何对构建高性能超轻网络代理感兴趣的人都可以使用支持Linkerd的底层Rust网络库。

听起来令人惊叹!我如何开始使用Linkerd?

我没想到你会问。你可以在大约5分钟内安装Linkerd,包括相互TLS,不需要配置。从我们的入门指南开始。

https://linkerd.io/2/getting-started/

Linkerd适用于所有人

Linkerd是一个社区项目,由CNCF托管。如果你有功能需求、问题或评论,我们欢迎你加入我们快速增长的社区!Linkerd托管在GitHub上,我们在Slack、Twitter和邮件列表上都有一个蓬勃发展的社区。来一起玩吧!

点击【阅读原文】阅读网站原文。

扫描二维码联系我们!


CNCF (Cloud Native Computing Foundation)成立于2015年12月,隶属于Linux Foundation,是非营利性组织。

CNCF(云原生计算基金会)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。我们通过将最前沿的模式民主化,让这些创新为大众所用。请长按以下二维码进行关注。

0 人点赞