在本文中,我们将讨论北欧最大的电子产品零售商Elkjøp[1]如何构建一个内部Kubernetes平台,该平台现在成功地托管了200多个生产中的微服务,以提高开发速度——而不影响安全性或可见性。该平台使该组织的托管成本降低了80%左右。
为了获得服务运行状况的可见性和对所有服务到服务的通信进行加密,我们采用了CNCF服务网格项目Linkerd[2]。我们,Henry Hagnäs,Elkjøp云解决方案架构师,以及Fredrik Klingenberg,Aurum AS高级顾问,写了这篇博文与你分享我们采用Linkerd时的想法和考虑。
背景
Elkjøp是北欧最大的电子产品零售商,在挪威、瑞典、芬兰、丹麦拥有超过400家零售店和12,000名员工,并在冰岛、格陵兰岛和法罗群岛拥有专营权。它在所有这些市场也有一个庞大的电子商务存在。
Elkjøp的历史始于1962年。Elkjøp拥有强大的实体零售业务和物流基础设施。在很长一段时间里,IT部门规模很小,主要专注于集成第三方产品和外部开发的解决方案。6年前,当引入微服务来提供系统之间的共享功能时,这种策略开始改变。其中包括电子商务平台和店内销售点系统使用的高级支付API。
事实证明,内部开发的微服务是提高开发速度的一个很好的解决方案,并且很快成为了替代昂贵的企业软件包的首选方案。最初的大约100个微服务托管在个别的Azure Web App,但随着环境的发展,API很快成为销售的中心和唯一方式,我们需要一种新的方法。
经过简短的可行性研究后,Elkjøp团队决定获得挪威IT咨询公司Aurum AS的帮助,帮助Elkjøp构建一个新的、现代化的、面向企业的微服务托管平台。
该平台最终托管了近200个微服务,所有这些服务都进行了升级和调整,以满足Elkjøp客户日益增长的24/7无缝购物体验的需求,无论他们是在线、社交媒体、手机还是实体店。
平台的原则
从一开始,平台就有了明确的目标和原则:
- 第一个平台迭代至少需要与Azure App Service相同的功能,但成本更低,更易于操作。
- 它还需要更易于伸缩(自动或手动),以及集中管理不同的应用程序。
- 迁移工作负载或启动一个新的应用程序之后,开发人员的工作效率应该会提高。
我们还想把横切关注点从库转移到平台上。通过将应用程序部署到平台上,我们需要为开发人员提供一组基本的功能和安全性。换句话说,我们想要拥抱一个更aspect-oriented的模型。我们需要为每个团队提供完全的自主权,同时确保存在防止错误发生的边界。
我们的目标是支持和创建站点可靠性工程(Site Reliability Engineering,SRE),并通过工具和最佳实践,向开发人员更多地考虑运营问题的DevOps文化迈进。
我们需要为开发者提供一个能够给予他们创造性自由的平台,同时为他们提供一个屏障,防止他们犯下代价高昂的错误,如安全性差或在非功能性细节上花费太多时间。正如我们将看到的,Linkerd使这变得容易得多。
没有服务网,没有网络洞察,也没有加密
我们通过容器化和部署我们的应用程序到Kubernetes开始迁移。然而,我们很快意识到我们错过了像Azure App Service这样的PaaS提供的开箱即用的指标和洞察力。此外,由于我们在入口控制器终止了TLS,应用程序之间的所有通信都是未加密的。我们需要引入一些东西来解决这两个问题——这就是服务网格所做的[3]。
我们选择了Linkerd,这是一个轻量级、超高速的CNCF服务网格项目。在高层次上,Linkerd为每个应用程序注入了一个超轻量级的微代理,作为一个边车。代理可以卸载许多横切关注点,比如加密,并提供有价值的指标——这正是我们需要解决的问题。
微代理构成数据平面,而Linkerd的其他组件构成控制平面。Linkerd控制平面有一个API,你可以使用它自己的CLI或仪表板。它还有其他的一些应用,可以帮助发布mTLS的证书,一个代理注入器,可以将代理注入到Kubernetes部署中,还有一个叫做“tap”的应用,它可以设置流来监视代理的实时流量,作为几个例子。
为什么选择了Linkerd?
我们的指导原则之一是引入以最小的复杂性解决特定问题的技术。毕竟,Kubernetes已经够复杂了。从高层次的抽象来看,服务网格的范围从完整的API管理到单个应用程序上的微边车代理。我们倾向于后者。
我们选择Linkerd有几个原因。
Linkerd的代理是用Rust编写的,性能开销很低。在内存和CPU使用方面,它优于其他服务网格[4]。虽然我们不认为Istio的额外性能成本对我们来说会是个问题,但我们还是尽量提高了性能。
此外,我们希望CNCF支持的项目能带来所有的好处。
微软在2019年巴塞罗那Kubecon会议上推出了服务网格接口(SMI)[5]。简而言之,SMI是服务网格可以拥有和实现的接口的开源规范。我们喜欢由一个委员会来评估规范的想法。由于Linkerd实现了SMI,它为我们提供了在未来切换到不同服务网格的灵活性,同时保持相同的接口。
当我们开始实现和使用Linkerd,我们就会发现社区的文档和对问题的回应是首屈一指的。
它易于安装、启动和运行。它自动注入微代理,这意味着平台团队可以标记命名空间,自动将部署部署到服务网格中。开发人员不需要担心Linkerd。如果它们确实需要覆盖默认值,它们可以很容易地使用注释来做到这一点。
指标和我们的SRE方法
使用Linkerd,我们得到默认情况下的Request(请求)、Error(错误)和Duration(持续时间)(RED)指标。开发人员或供应商不需要安装他们的应用程序。如果他们这样做了,偶尔也会有帮助,有了Linkerd,我们得到了最关键的洞察力,给了我们所需要的可观察性。
我们通过让Linkerd在安装期间设置一个内存中的Prometheus[6]服务器和一个内存中的Grafana实例来获取指标。Prometheus是我们选择的度量工具。我们在Prometheus联邦中扩展了这一设置,并使用Thanos[7]获得了长期的留存率。
对网络的信心
如果你操作过复杂的工作负载,那么你可能知道,每当出现问题时,人们往往会责怪网络。Linkerd这样的服务网格提供了详细的遥测技术,减少了根本原因的平均检测时间(MTTD)和平均解决时间(MTTR)。虽然在某些情况下,网络可能确实是问题所在,但它经常成为替罪羊的受害者。而服务网则彻底终结了这一局面。
Linkerd通过在不同的系统中为我们提供必要的网络洞察力迅速解决了许多这些讨论。顺便说一句,问题所在很少是网络。
被Linkerd指标拯救了
随着我们将新的销售后端转移到Kubernetes,我们期望性能测试成为一种形式。后端在Linux服务器上运行良好,那么会出现什么问题呢?令我们惊讶的是,即使是适量的负载,成功率也会下降。我们开始跟踪失败的请求,以使系统健康和稳定。
使用Linkerd指标,我们可以监视TCP连接的数量及其持续时间和失败率,包括入站和出站以及每个应用程序(特别是POS后端)。最终,这些指标使我们发现销售门户应用程序并没有像它应该的那样重用套接字。在没有详细的网络遥测技术的情况下,很难确定SNAT端口是否耗尽。了解了这一点,我们增加了可用的出站端口,并在稍后修复了应用程序。这是一个使用Linkerd减少MTTD和MTTR的完美例子。
服务网格微调
如果这意味着第2天的操作变得太棘手,那么用一个服务网快速建立和启动就没有任何好处。我们需要设置Linkerd成高可用(HA),并对代理资源进行微调。文档很清楚,无论何时接触到社区都得到了快速的回应。从初始设置到HA很容易,通过在Linkerd升级期间设置注释或标记来进行微调。我们对Linkerd消耗的资源如此之少感到惊讶,而且我们还没有经历过它成为瓶颈的情况。
我们已经升级Linkerd多次,没有停机或任何问题。
转向更aspect-oriented的编程模型的一个缺点是,你会非常依赖提供该模型的组件,在我们的例子中是mtl和指标的Linkerd。然而,这并不是一个问题;Linkerd一直坚如磐石。
随着Kubernetes平台在越来越多商店的使用,我们可能会选择使用多个两地三中心冗余集群。因此,很高兴看到Linkerd为此引入了支持。
随着“App Service Replacement”的完成,我们现在也在关注更高级的功能,比如使用Linkerd和Flagger[8]实现流量分割和灰度发布。
Elkjøp的下一步
在撰写本文时,我们正在所有国家推行新的销售点系统。到2021年底,每笔销售额——每年400亿挪威克朗(47亿美元)——都将经历这些新的Kubernetes环境。我们相信Linkerd将帮助我们保持公司的运行,并帮助我们的客户享受惊人的技术。
参考资料
[1]
北欧最大的电子产品零售商Elkjøp: https://www.elkjop.no/
[2]
CNCF服务网格项目Linkerd: https://linkerd.io/
[3]
服务网格所做的: https://buoyant.io/service-mesh-manifesto/
[4]
优于其他服务网格: https://linkerd.io/2019/05/18/linkerd-benchmarks/
[5]
服务网格接口(SMI): https://smi-spec.io/
[6]
Prometheus: https://prometheus.io/
[7]
Thanos: https://thanos.io/
[8]
Flagger: https://github.com/fluxcd/flagger