亚马逊AWS官方博客

Global to China 跨国企业 Kubernetes 应用跨境复制和部署方案

背景

很多跨国企业在将他们部署在亚马逊云科技海外区域 Kubernetes 方案复制到北京和宁夏区域的时候,会碰到一些海外镜像仓库访问不稳定的情况,比如共有镜像仓库 Google gcr.io,Red Hat Quay.io 等,又或者需要使用亚马逊云科技海外区域 ECR 存储的镜像。基于这个背景,本文介绍了如何使用亚马逊云科技官网数据传输解决方案结合 Kubernetes Mutating Webhook,端到端地实现从海外镜像库复制镜像到国内,同时在不改变原有 Kubernetes 部署文件的前提下自动更改镜像地址到国内。

解决方案

我们将会使用 DTH(Data Transfer Hub)方案进行镜像传输。DTH 是一个安全,可靠,可扩展和可追踪的数据传输解决方案,提供一致的用户体验,使您可以轻松地创建和管理不同数据类型,从不同的来源到 Amazon Web Service 云原生服务的传输任务。当此解决方案启动后,您可以在几分钟内开始数据传输任务。

在镜像传输完成之后,我们会使用 Kubernetes mutating webhook 的方式来将 Docker 镜像库的地址更新到国内的地址。

架构图

我们在 AWS Global Regions 部署的一套 EKS 应用使用到了 GCR.IO,QUAY.IO 以及 AWS ECR 私有镜像库,我们现在需要将这套发难部署到 AWS China Regions。首先我们需要在 AWS 中国区创建 EKS 集群,之后我们开始部署应用,具体步骤如下——

第一步:通过 CloudFormation 模版部署 DTH 应用

该模版会自动部署和配置一套无服务架构,同时会提供一个 Web 前端,我们通过 Web 页面可以创建 GCR.IO/QUAY.IO 以及 AWS Global ECR 传输到中国区 ECR 的任务,同时我们可以通过 Web 页面实时查看任务传输的状态或者通过配置邮箱来获取任务状态的通知。

第二步:使用 Mutating Webhook 更改镜像地址

这部分使用 Amazon API Gateway 和 AWS Lambda 来设置 HTTP 服务,然后作为 admission webhooks 与 Kubernetes 集成,来接收 admission 请求并动态改变 Kubernetes 资源。这套方案会设置一个 mutating webhook,在 Kubernetes 部署提交到 Kubernetes API 服务器之后并且在它被持久化到 etcd 之前,修改 Kubernetes Pod 中的 docker 镜像路径。

关于 Kubernetes mutating webhook,最有名的用例是 istio sidecar injector,您还可以参考 Kubernetes 文档 或者一些技术博客 来了解 Kubernetes admission 的工作原理。

第三步:使用中国区的 EKS 部署应用

由于配置过 webhook mutating 的功能,EKS 在碰到需要去 GCR.IO/QUAY.IO 所需镜像时,会自动转到配置好的 AWS China ECR 私有镜像库中。

实现步骤

1. Data transfer Hub ECR 跨境传输

1.1 部署 DTH 方案

访问 https://aws.amazon.com/cn/solutions/implementations/data-transfer-hub/,选择在海外 AWS 区域启动方案,如下图。

记录 AdminUsenamer 和密码,以及部署任务完成时的 PortalURL,参考下图:

1.2 创建 DTH 公共镜像传输任务

点击 PortalURL 地址,使用 AdminUsenamer 和密码登录 DTH 应用。

选择 ECR 传输任务,Public Container Registry。

在 Image List 中列出所需要的海外公共镜像。

根据提示填写所有选项,尤其是国内亚马逊云科技账号以及储存的 AK SK 到 Secret Manger 进行使用。

1.3(可选)创建 DTH ECR 镜像跨境传输任务

如果需要从亚马逊云科技海外区域的 ECR 传输镜像到国内 ECR,可以新建 ECR 传输任务,选择 Amazon ECR。

根据要求填写所有信息。

1.4 检查任务传输情况

如果选择了 1.3 所示 Amazon ECR 应该能看到同样的镜像:

如果选择 1.2 共有镜像库,可以看到共有镜像已经被传到国内 ECR,如下图第二项:

2. 部署 Mutating Webhook 方案

2.1 点击 https://github.com/aws-samples/amazon-api-gateway-mutating-webhook-for-k8,根据 Option#2,通过 SAM 脚本创建 Lambda 和 API Gateway。

$ git clone https://github.com/aws-samples/amazon-api-gateway-mutating-webhook-for-k8.git
$ cd amazon-api-gateway-mutating-webhook-for-k8
$ export S3_BUCKET=my_s3_bucket
$ sam package -t sam-template.yaml --s3-bucket ${S3_BUCKET} --output-template-file packaged.yaml
$ sam deploy -t packaged.yaml --stack-name amazon-api-gateway-mutating-webhook-for-k8 --capabilities CAPABILITY_IAM

2.2 更改 Lambda 中的代码指向私有镜像库地址

2.3 更改 Webhook admission 地址到 1 创建的 API Gateway

$ kubectl apply -f mutating-webhook.yaml

方案验证

在不改变部署 YAML 文件的前提下,测试部署镜像拉取地址,大家可以根据在 Lambda 中所做的 Mirror 的匹配进行测试。这里我们选用 metrics-server 进行测试,镜像地址如下:

image: k8s.gcr.io/metrics-server/metrics-server:v0.6.2

根据 metrics-server 链接下载部署文件 components.yaml,无需修改代码,运行 kubectl apply -f components.yaml

使用本方案之前会出现 pull image timeout 的情况,如下所示:

详细信息:

Failed to pull image "k8s.gcr.io/metrics-server/metrics-server:v0.6.2": rpc error: code = Unknown desc = Error response from daemon: Get "https://k8s.gcr.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

使用本方案之后可以看到 pull image 地址已经更改为亚马逊云科技中国区 ECR 地址,并且成功部署,如下图所示:

总结

本文总结了如何通过 Data Transfer Hub 和 Kubernetes Mutating Webhook 的方案来进行共有镜像库的跨境复制,对于在亚马逊云科技部署容器解决方案的用户,可以参考本方案来完成容器镜像的跨境拉取和部署。

本篇作者

丁煜恒

亚马逊云科技解决方案架构师,有 7 年企业数字化转型项目管理和交付经验。目前负责 AWS 海外客户的 landing 中国区的方案设计,实施咨询等相关工作。对计算,存储,安全,DevOps 等领域有丰富的架构设计及实践经验。