使用 Linkerd,Tradeshift 无需停机即可迁移到亚马逊 EKS

作者:安德烈亚斯·林德 | 2023 年 4

这篇文章由Tradeshift的开发运营工程师里卡多·阿马托和亚马逊云科技容器专业解决方案架构师安德烈亚斯·林德共同撰写。

简介

Tradeshift 是一个基于云的业务网络和平台,多年来一直使用自托管 Kubernetes 在 亚马逊云科技 中运行我们的应用程序。2022 年,决定从自托管设置迁移到亚马逊 Elastic Kubernetes 服务 (Am azon EKS ),以减少管理 Kubernetes 本身的运营开销,并允许集中精力为使用该平台的开发人员构建更好的平台。

从自托管的 Kubernetes 集群迁移到 Amazon EKS 可能具有挑战性,具体取决于所使用的策略。传统上,团队需要使用 Amazon EKS 创建新集群,将其 所有 服务以及相关 Kubernetes 对象(例如密钥、ConfigMaps 和 Ingress)部署到这个新集群中,以便相互依赖的服务可以成功地相互通信。然后,成功测试后,他们将流量切换到新集群。这种方法可能需要停机,例如域名系统 (DNS) 生存时间 (TTL) 配置,并且在出现问题时不容易促进回滚。幸运的是,情况不一定是这样。

在这篇文章中,我们将介绍 Tradeshift 如何使用 Linkerd 服务网格及其多集群功能,在不停机的情况下逐步将服务从自托管集群迁移到 Amazon EKS。

问题所在

我们从自托管的 Kubernetes 集群迁移到 Amazon EKS 时面临的最大问题是,传统的迁移方法使用第三方解决方案,如 Velero 和 Druva,可以备份集群的状态,然后将该状态恢复到另一个集群。这种方法不仅需要停机,而且很难测试备份的资源在新集群上是否正常运行。另一个问题是,在出现问题时回滚服务通常并不容易,可能会导致意外停机以及未来出现更多问题。

在开始迁移之前,我们确定了成功迁移的关键业务需求:

  • 无需停机迁移
  • 对服务透明的过渡
  • 可以逐步完成的迁移
  • 如果出现任何问题,可以轻松恢复已迁移的服务

基于这些要求,Tradeshift 的最佳解决方案是将自托管集群和新的 Amazon EKS 集群连接起来并视为单一实体。然后,我们的生产环境成为自托管集群和 Amazon EKS 集群的组合,服务无需更改即可透明地在它们之间进行通信。这使团队能够将其服务逐步迁移到新的 Amazon EKS 集群。此外,有了这样的解决方案,恢复不仅可行,而且很容易实现。

解决方案概述

经过初步研究,我们发现我们需要一个组件来帮助我们促进跨Kubernetes集群的服务间通信,这些功能由服务网格提供,例如 Linkerd和Istio。 Tradeshift 之所以决定使用 Linkerd,是因为与 Istio 更复杂的架构相比,它具有轻量级特性和高效的资源利用率。借助 Linkerd,我们可以更好地了解我们服务的性能,还可以在迁移过程中深入了解我们的服务,以便于发现任何问题。

使用 Linkerd 及其多集群功能,我们能够将自托管的 Kubernetes 集群连接到新的 Amazon EKS 集群,从而确保无缝迁移并满足我们的关键业务需求。这确保了安全迁移到新集群,并且在出现任何问题时,我们能够安全地恢复到以前的解决方案,而无需停机。重要的是,我们的解决方案不需要在迁移过程中对服务本身进行更改,从而进一步将风险和对团队的影响降至最低。

技术细节

既然我们已经制定了迁移到 Amazon EKS 的要求,我们需要做以下事情来实现我们打算做的事情。首先,我们需要连接集群,导出服务,并使用流量分割资源在集群之间路由流量。

为了实现这一点,需要在带有 多集群 和 服务网格接口 (SMI ) 扩展的两个集群 上安装 Linkerd( 文档 )。

连接集群

通过安装 linkerd-multi-cluster 扩展,将在两个集群中创建以下组件:

Diagram showing components in Kubernetes namespace linkerd-multicluster.

  • 网关 :这是从外部进入集群的入口。这是建立链接后其他 Linkerd 集群与之通信的内容。
  • 服务镜像 :建立链接后,此组件将连接到远程集群,并与其 Kubernetes 应用程序编程接口 (API) 进行通信以监视要导出的服务。
  • 服务账户 :需要能够在两个集群关联时创建所需的资源,例如 Kubernetes 服务。

如果您使用 官方文档 ,使用 Linkerd 命令行界面 (CLI) 或 Helm ,则默认情况下会安装网关。此组件使用服务类型 LoadBalancer 公开,它允许启用了 mTLS 的任何地方 (0.0.0.0/0) 的入站流量使用 Linkerd 信任锚来验证请求。

要将我们的两个集群连接在一起,我们需要在它们之间创建链接。Linkerd 多集群中的链接是单向的,因此我们需要在两个集群之间的每个方向上创建一个链接。我们通过使用 Linkerd CLI 工具为每个集群生成正确的 Kubernetes 清单,然后将其应用到目标集群来实现这一点。请注意我们在下面的命令 中 如何使用 eks 和 le gacy 来引用要处理的集群。

我们想将我们的传统(自托管)集群连接到新的 Amazon EKS 集群,因此我们将运行:

linkerd --context=legacy multicluster link --cluster-name legacy |
  kubectl --context=eks apply -f -

由于链接是单向的,因此还需要创建反向链接:

linkerd --context=eks multicluster link --cluster

完成此操作后,将创建服务镜像和服务帐户,集群可以一起使用。

正在验证连接

我们需要做的第一件事是检查是否可以在两个集群上找到多集群网关,以及服务是否已公开。我们在亚马逊 EKS 集群上确认:

linkerd multicluster gateways --context eks
CLUSTER  ALIVE    NUM_SVC  LATENCY_P50  LATENCY_P95  LATENCY_P99
eks      True           0          3ms          8ms         10ms
legacy   True         409          2ms          8ms          9ms

如我们所见, 旧版多集群网关配置 正确,其上的 409 服务现在可以从 Amazon EKS 集群中发现和访问。我们现在也这样做,但要从传统集群中确认 Amazon EKS 也在与传统集群共享其服务:

linkerd multicluster gateways --context legacy
CLUSTER  ALIVE    NUM_SVC  LATENCY_P50  LATENCY_NP95  LATENCY_P99
eks      True          51          3ms          8ms         10ms
legacy   True           0          2ms          8ms          9ms

这显示了如何在传统集群上正确设置 Amazon EKS 集群,以及传统集群中已公开了 51 项服务。有了这些信息,我们知道两个集群都已正确连接。

我们导出的服务保留原始名称,并自动将其相应集群的名称添加为后缀,格式为 -。这就是我们的服务在亚马逊 EKS 中的显示方式:

kubectl get svc | grep "legacy"
serviceA-legacy                                         ClusterIP      10.32.227.124   <none>                                                                 80/TCP                                26h
serviceB-legacy                                          ClusterIP      10.32.198.18    <none>                                                                 80/TCP                                26h

如果 服务 A 通常与服务 B 通信 ,而 服务 B 服务 C 通信 ,则 服务 C 将迁移到新的 Amazon EKS 集群,如下图所示:

Diagram showing inter-cluster connectivity

正如我们所见,所有服务都是使用链接代理进行网格化和通信的,该代理以 sidecar 的形式运行。当 服务 B 向在 Amazon EKS 集群上运行的 服务 C 发送请求时,该请求会自动路由到在 Amazon EKS 集群上运行的多集群网关。然后,它会自动将流量路由到 服务 C 。网关是集群的唯一入口点,需要根据您的流量进行扩展。此组件可能会使用水平 Pod 自动缩放器。

导出服务

现在集群已经实现了双向链接,我们可以开始在它们之间导出服务了。导出服务是专门用于链接多集群的术语,是指从一个集群与另一个集群共享服务。欲了解更多信息,请参阅 官方文档 。对于此次迁移,我们假设所有服务都需要迁移,因此我们将公开 Amazon EKS 集群上的所有传统服务,反之亦然。为此,我们修改了 链接 资源。我们可以使用以下命令列出所有链接:

kubectl get link -n linkerd-multicluster

此命令列出了连接群集时创建的链接。找到链接后,您可以对其进行修改,以便按如下方式导出所有服务:

selector:
    matchExpressions:
    - key: mirror.linkerd.io/mirrored-service
      operator: DoesNotExist

这可确保导出所有未镜像的服务,因为我们希望避免无限循环。

使用 TrafficSplit 资源使迁移变得透明

我们的集群现在相互连接,这允许彼此远程访问彼此的服务。为了无缝迁移我们的服务,我们必须确保传统集群上的服务仍然可以连接到 Amazon EKS 上的服务,反之亦然,并且我们可以在对配置进行最少更改的情况下在集群之间切换每项服务流量。

我们利用服务网格接口 (SMI) T rafficSplit 资源 来实现我们的目标,如下代码所示:

apiVersion: split.smi-spec.io/v1alpha2
kind: TrafficSplit
metadata:
  name: serviceA
  namespace: default
spec:
  service: serviceA.default.svc.cluster.local
  backends:
  - service: serviceA-eks
    weight: 0
  - service: serviceA
    weight: 100

如果我们将上述内容部署到传统集群,则此配置将应用于所有 linkerd-sidecar 容器,这会导致流量在 100% 的时间内被发送到 Service A。将 Servic eA 部署到 Amazon EKS 并对服务进行了镜像后, Servicea- EKS 便可用,如下所示。

Diagram illustrating how the TrafficSplit resource allows us to shift traffic between clusters

现在,我们可以通过更改以下内容简单地更改权重,从而将所有流量发送到在 Amazon EKS 上运行的服务:

backends:
  - service: serviceA-eks
    weight: 100
  - service: serviceA
    weight: 0

这可确保调用 ServiceA 的传统服务以透明的方式将流量 发送到 Servicea-eks 。无需对旧集群进行进一步更改。在 Amazon EKS 集群上,我们需要确保 T rafficSplit 将所有流量路由到本地 ServiceA ,如以下配置所示:

backends:
  - service: serviceA-legacy
    weight: 0
  - service: serviceA
    weight: 100

下图说明了这个解决方案:

这样,该服务迁移到亚马逊 EKS,其他依赖于 ServiceA 的 服务 只需在 Amazon E KS 集群上访问该服务即可。如果出现错误或需要再次使用传统服务,我们只需更改值,使传统集群使用 ServiceA,而 Amazon EK S 集群使用 Service a-legacy 提供 100% 的流量。要实现此目的,只需反向执行上述步骤,然后使用 kubectl 将资源应用 于 两个 集群即可。

将单项服务迁移到 Amazon EKS 集群现已完成!为了完成向 Amazon EKS 的迁移,我们对每项服务重复相同的流程,直到所有服务都在 Amazon EKS 上运行。一旦出现这种情况,就可以安全地关闭和删除自托管(即旧版)集群。

结论

在这篇文章中,我们讨论了如何使用 Linkerd 的多集群功能,Tradeshift 能够将其服务从自托管集群无缝迁移到 Amazon EKS。将两个 Kubernetes 集群(自托管集群和 Amazon EKS)连接在一起,在不停机的情况下将服务从一个集群迁移到另一个集群,同时知道在出现任何问题时进行恢复非常简单明了,这让我们高枕无忧。

从自托管集群迁移到 Amazon EKS 似乎是一项艰巨的任务,如果您没有做好准备,也可能如此。您可以按照本文中显示的详细信息来缓解任何问题,以确保以可管理、高效和安全的方式进行迁移。

要了解有关 Amazon EKS 的更多信息 、查看 文档 或浏览 EKS 研讨会 ,要了解有关 Linkerd 的更多信息,可以在这里找到文档 。

Headshot of Ricardo Amato

Ricardo Amato,Tradeshift

Ricardo目前在Tradeshift担任开发运营工程师,专门设计和实施云解决方案。他对 DevOps 充满热情,并将自己的职业生涯建立在实施最先进的解决方案的基础上。他不断有动力突破该领域可能性的界限。