

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 AWS CDK 在 Amazon ECS Anywhere 上为混合工作负载设置 CI/CD 管道和 GitLab
<a name="set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab"></a>

*拉斐尔·奥尔蒂斯，亚马逊 Web Services*

## Summary
<a name="set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab-summary"></a>

Amazon ECS Anywhere 是 Amazon Elastic Container Service (Amazon ECS) 的扩展。它支持将*外部实例*（例如本地服务器或虚拟机 (VM)）注册到 Amazon ECS 集群。该功能有助于降低成本并减轻复杂的本地容器编排和操作。您可以使用 ECS Anywhere 在本地和云环境中部署和运行容器应用程序。它使您的团队无需学习多个域和技能组合，也无需自行管理复杂的软件。

此模式描述了 step-by-step一种使用亚马逊网络服务 (AWS) 云开发套件 (AWS CDK) 堆栈为亚马逊 ECS 集群配置亚马逊 ECS Anywhere 实例的方法。然后，您可以使用 AWS CodePipeline 来设置持续集成和持续部署 (CI/CD) 管道。然后，您将 GitLab 代码存储库复制到 AWS， CodeCommit 并将您的容器化应用程序部署在 Amazon ECS 集群上。

此模式旨在帮助那些使用本地基础设施运行容器应用程序并 GitLab 用于管理应用程序代码库的用户。您可使用 Amazon Web Services Cloud 服务管理这些工作负载，而不会干扰您现有的本地基础设施。

## 先决条件和限制
<a name="set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab-prereqs"></a>

**先决条件**
+ 一个有效的 Amazon Web Services account。
+ 在本地基础设施上运行的容器应用程序。
+ 用于管理应用程序代码 GitLab 库的存储库。有关更多信息，请参阅[存储库](https://docs.gitlab.com/ee/user/project/repository/) (GitLab)。
+ 已安装和配置 AWS 命令行界面（AWS CLI）。有关更多信息，请参阅[安装或更新最新版本的 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)（AWS CLI 文档）。
+ AWS CDK Toolkit，已安装并全局配置。有关更多信息，请参阅[安装 AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_install)（AWS CDK 文档）。
+ npm，已为中的 AWS CDK 安装和配置。 TypeScript有关更多信息，请参阅[下载和安装 Node.js 和 npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)（npm 文档）。

**限制**
+ 有关限制和注意事项，请参阅 Amazon ECS 文档中的[外部实例 (Amazon ECS Anywhere)](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-anywhere.html#ecs-anywhere-considerations)。

**产品版本**
+ AWS CDK Toolkit 版本 2.27.0 或更高版本
+ npm 版本 7.20.3 或更高版本
+ Node.js 版本 16.6.1 或更高版本

## 架构
<a name="set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab-architecture"></a>

**目标技术堆栈**
+ AWS CDK
+ AWS CloudFormation
+ AWS CodeBuild
+ AWS CodeCommit
+ AWS CodePipeline
+ Amazon ECS Anywhere
+ Amazon Elastic Container Registry (Amazon ECR)
+ AWS Identity and Access Management (IAM)
+ AWS Systems Manager
+ GitLab 存储库

**目标架构**

![\[设置 Amazon ECS 集群和 CI/CD 管道的架构图。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/b0f35986-a839-4b01-8eb0-4748182ddafc/images/85b8d4d9-3591-4d69-a54b-64aa543498f1.png)


此图表表示此模式中描述的两个主要工作流程，即配置 Amazon ECS 集群和设置设置和部署 CI/CD 管道的 CI/CD 管道，如下所示：

1. **预调配 Amazon ECS 集群**

   1. 当您部署第一个 AWS CDK 堆栈时，它会在 AWS 上创建一个 CloudFormation 堆栈。

   1. 此 CloudFormation 堆栈预配置 Amazon ECS 集群和相关的 AWS 资源。

   1. 要将外部实例注册到 Amazon ECS 集群，您必须在虚拟机上安装 AWS Systems Manager Agent (SSM Agent) 并将该虚拟机注册为 AWS Systems Manager 托管实例。 

   1. 在您的虚拟机上，您还必须安装 Amazon ECS 容器代理和 Docker，以将其注册为 Amazon ECS 集群的外部实例。

   1. 当外部实例注册并配置到 Amazon ECS 集群时，它可以在注册为外部实例的虚拟机上运行多个容器。

   1. Amazon ECS 集群处于活动状态，可通过容器运行应用程序工作负载。Amazon ECS Anywhere 容器实例在本地环境中运行，但与云 Amazon ECS 集群关联。

1. **设置和部署 CI/CD 管道**

   1. 当您部署第二个 AWS CDK 堆栈时，它会在 AWS 上创建另一个 CloudFormation 堆栈。

   1. 此 CloudFormation 堆栈预置管道 CodePipeline 和相关的 AWS 资源。

   1. 您可以将应用程序代码更改推送并合并到本地 GitLab 存储库。 

   1.  GitLab 存储库会自动复制到 CodeCommit 存储库中。

   1. 对 CodeCommit 存储库的更新会自动开始 CodePipeline。 

   1. CodePipeline 从中复制代码 CodeCommit 并创建可部署的 CodeBuild内置应用程序。

   1. CodePipeline 创建 CodeBuild 构建环境的 Docker 镜像并将其推送到 Amazon ECR 存储库。

   1. CodePipeline 启动从 Amazon ECR 存储库中提取容器映像的 CodeDeploy 操作。

   1. CodePipeline 在 Amazon ECS 集群上部署容器映像。

**自动化和扩展**

此模式使用 AWS CDK 作为基础设施即代码（IaC）工具来配置和部署此架构。AWS CDK 可帮助您编排 AWS 资源并设置 Amazon ECS Anywhere 和管道。 CI/CD 

## 工具
<a name="set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab-tools"></a>

**Amazon Web Services**
+ [AWS Cloud Development Kit（AWS CDK）](https://docs.aws.amazon.com/cdk/latest/guide/home.html) 是一个软件开发框架，可帮助您在代码中定义并预调配 AWS 云基础设施。
+ [AWS CodeCommit](https://docs.aws.amazon.com/codecommit/latest/userguide/welcome.html) 是一项版本控制服务，可帮助您私下存储和管理 Git 存储库，而无需管理自己的源代码控制系统。
+ [AWS CodePipeline](https://docs.aws.amazon.com/codepipeline/latest/userguide/welcome.html) 可帮助您快速建模和配置软件发布的不同阶段，并自动执行持续发布软件变更所需的步骤。
+ [AWS 命令行界面（AWS CLI）](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)是一种开源工具，它可帮助您通过命令行 Shell 中的命令与 Amazon Web Services 交互。
+ [Amazon Elastic Container Registry (Amazon ECR)](https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html) 是一项安全、可扩展且可靠的托管容器映像注册表服务。
+ [Amazon Elastic Container Service (Amazon ECS)](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html)是一项快速且可扩展的容器管理服务，可帮助运行、停止和管理集群上的容器。这种模式还使用 [Amazon ECS Anywhere](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-anywhere.html)，它支持向 Amazon ECS 集群注册本地部署服务器或虚拟机。

**其他工具**
+ [Node.js](https://nodejs.org/en/docs/) 是一个事件驱动的 JavaScript 运行时环境，专为构建可扩展的网络应用程序而设计。
+ [npm](https://docs.npmjs.com/about-npm) 是在 Node.js 环境中运行的软件注册表，用于共享或借用软件包以及管理私有软件包的部署。
+ [Vagrant](https://developer.hashicorp.com/vagrant/docs) 是一个开源实用程序，用于构建和维护便携式虚拟软件开发环境。出于演示目的，此模式使用 Vagrant 创建本地虚拟机。

**代码存储库**

此模式的代码可在使用 AWS GitHub [CDK 存储库的 Amazon ECS Anywhere 的 CI/CD 管道](https://github.com/aws-samples/amazon-ecs-anywhere-cicd-pipeline-cdk-sample)中找到。

## 最佳实践
<a name="set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab-best-practices"></a>

部署此模式时，请考虑以下最佳实践：
+ [使用 AWS CDK 开发和部署云基础设施最佳实践](https://docs.aws.amazon.com/cdk/v2/guide/best-practices.html)
+ [使用 AWS CDK 开发云应用程序的最佳实践](https://aws.amazon.com/blogs/devops/best-practices-for-developing-cloud-applications-with-aws-cdk/)（AWS Blog 文章）

## 操作说明
<a name="set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab-epics"></a>

### 验证 AWS CDK 配置
<a name="verify-the-aws-cdk-configuration"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 验证 AWS CDK 版本。 | 通过输入以下命令验证 AWS CDK Toolkit 的版本。<pre>cdk --version</pre>此模式需要版本 2.27.0 或更高版本。如果您拥有早期版本，请按照 [AWS CDK 文档](https://docs.aws.amazon.com/cdk/latest/guide/cli.html)中的说明对其进行更新。 | DevOps 工程师 | 
| 验证 npm 版本。 | 通过输入以下命令验证 npm 的版本。<pre>npm --version</pre>此模式需要版本 7.20.3 或更高版本。如果您拥有早期版本，请按照 [npm 文档](https://docs.npmjs.com/try-the-latest-stable-version-of-npm)中的说明对其进行更新。 | DevOps 工程师 | 
| 设置 AWS 凭证。 | 通过输入 `aws configure` 命令并按照提示进行操作设置凭证。<pre>$aws configure<br />AWS Access Key ID [None]: <your-access-key-ID><br />AWS Secret Access Key [None]: <your-secret-access-key><br />Default region name [None]: <your-Region-name><br />Default output format [None]:</pre> | DevOps 工程师 | 

### 引导 AWS CDK 环境
<a name="bootstrap-the-aws-cdk-environment"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 克隆 AWS CDK 代码存储库。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab.html) | DevOps 工程师 | 
| 引导 环境。 | 输入以下命令，将 CloudFormation 模板部署到您要使用的账户和 AWS 区域。<pre>cdk bootstrap <account-number>/<Region></pre>有关详情，请参阅 AWS CDK 文档中的[引导](https://docs.aws.amazon.com/cdk/latest/guide/bootstrapping.html)。 | DevOps 工程师 | 

### 为 Amazon ECS Anywhere 构建和部署基础设施
<a name="build-and-deploy-the-infrastructure-for-amazon-ecs-anywhere"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 安装软件包依赖关系并编译 TypeScript 文件。 | 通过输入以下命令安装软件包依赖关系并编译 TypeScript 文件。<pre>$cd EcsAnywhereCdk<br />$npm install<br />$npm fund </pre>这些命令安装示例存储库内的所有软件包。有关更多信息，请参阅 npm 文档中的 [npm ci](https://docs.npmjs.com/cli/v7/commands/npm-ci) 和 [npm 安装](https://docs.npmjs.com/cli/v7/commands/npm-install)。如果在输入这些命令时出现任何关于丢失程序包的错误，请参阅此模式的[故障排除](#set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab-troubleshooting)部分。 | DevOps 工程师 | 
| 构建项目。 | 要构建项目代码，请输入以下命令。<pre>npm run build</pre>有关构建和部署项目的更多信息，请参阅 AWS CDK 文档中的[您的第一个 AWS CDK 应用程序](https://docs.aws.amazon.com/cdk/latest/guide/hello_world.html#:~:text=the%20third%20parameter.-,Synthesize%20an%20AWS%20CloudFormation%20template,-Synthesize%20an%20AWS)。 | DevOps 工程师 | 
| 部署 Amazon ECS Anywhere 基础设施堆栈。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab.html) | DevOps 工程师 | 
| 验证堆栈创建和输出。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab.html) | DevOps 工程师 | 

### 设置本地虚拟机
<a name="set-up-an-on-premises-vm"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 设置您的虚拟机。 | 通过从 Vagrantfile 所在的根目录中输入 `vagrant up` 命令来创建 Vagrant 虚拟机。有关更多信息，请参阅 [Vagrant 文档](https://developer.hashicorp.com/vagrant/docs/cli/up)。 | DevOps 工程师 | 
| 将您的虚拟机注册为外部实例。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab.html)[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab.html)这会将您的虚拟机设置为 Amazon ECS Anywhere 外部实例，并将该实例注册至 Amazon ECS 集群。有关更多信息，请参阅 Amazon ECS 文档中的[向集群注册外部实例](https://docs.amazonaws.cn/en_us/AmazonECS/latest/developerguide/ecs-anywhere-registration.html)。如果您遇到任何问题，请参阅[故障排除](#set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab-troubleshooting)部分。 | DevOps 工程师 | 
| 验证 Amazon ECS Anywhere 和外部虚拟机状态。 | 要验证您的虚拟机是否已连接到 Amazon ECS 控制面板并正在运行，请使用以下命令。<pre>$aws ssm describe-instance-information<br />$aws ecs list-container-instances --cluster $CLUSTER_NAME</pre> | DevOps 工程师 | 

### 部署 CI/CD 管道
<a name="deploy-the-ci-cd-pipeline"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 在 CodeCommit 存储库中创建一个分支。 | 通过为存储库创建第一个提交，创建一个`main`在 CodeCommit repo 中命名的分支。您可以按照 AWS 文档[在中创建提交 CodeCommit](https://docs.aws.amazon.com/codecommit/latest/userguide/how-to-create-commit.html#create-first-commit)。以下命令是一个示例。<pre>aws codecommit put-file \<br />  --repository-name EcsAnywhereRepo \<br />  --branch-name main \<br />  --file-path README.md \<br />  --file-content "Test" \<br />  --name "Dev Ops" \<br />  --email "devops@example.com" \<br />  --commit-message "Adding README."</pre> | DevOps 工程师 | 
| 设置存储库镜像。 | 您可以将 GitLab 存储库镜像到外部源或从外部源镜像。您可选择哪个存储库作为源。分支、标签和提交自动同步。在托管应用程序的 GitLab 存储库和存储 CodeCommit 库之间设置推送镜像。有关说明，请参阅[设置从 GitLab 到的推送镜像 CodeCommit](https://docs.gitlab.com/ee/user/project/repository/mirror/push.html#set-up-a-push-mirror-from-gitlab-to-aws-codecommit)（GitLab 文档）。默认情况下，镜像将自动同步存储库。如果要手动更新存储库，请参阅[更新镜像](https://docs.gitlab.com/ee/user/project/repository/mirror/#update-a-mirror)（GitLab 文档）。 | DevOps 工程师 | 
| 部署 CI/CD 管道堆栈。 | 通过输入以下命令部署 `EcsAnywherePipelineStack` 堆栈。<pre>$cdk  deploy EcsAnywherePipelineStack</pre> | DevOps 工程师 | 
| 测试 CI/CD 管道。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab.html) | DevOps 工程师 | 

### 清理
<a name="clean-up"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 清理和删除资源。 | 完成此模式后，应移除您创建的 proof-of-concept资源。要进行清理，请输入以下命令。<pre>$cdk destroy EcsAnywherePipelineStack<br />$cdk destroy EcsAnywhereInfraStack</pre> | DevOps 工程师 | 

## 问题排查
<a name="set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab-troubleshooting"></a>


| 问题 | 解决方案 | 
| --- | --- | 
| 安装程序包依赖项时，出现缺少程序包的错误。 | 输入下列命令之一，解决程序包缺失问题。<pre>$npm ci</pre>或者<pre>$npm install -g @aws-cdk/<package_name></pre> | 
| 在虚拟机上运行 `aws ssm create-activation` 命令时，您将收到以下错误。`An error occurred (ValidationException) when calling the CreateActivation operation: Nonexistent role or missing ssm service principal in trust policy: arn:aws:iam::000000000000:role/EcsAnywhereInstanceRole` | `EcsAnywhereInfraStack` 堆栈尚未完全部署，运行此命令所需 IAM 角色也尚未创建。在 CloudFormation 控制台中检查堆栈状态。状态变为 `CREATE_COMPLETE` 后重试该命令。 | 
| Amazon ECS 运行状况检查返回 `UNHEALTHY`，您会在 Amazon ECS 控制台的集群的**服务**部分看到以下错误。`service EcsAnywhereService was unable to place a task because no container instance met all of its requirements. Reason: No Container Instances were found in your cluster.` | 输入以下命令，在 Vagrant 虚拟机重新启动 Amazon ECS 代理。<pre>$vagrant ssh<br />$sudo systemctl restart ecs<br />$sudo systemctl status ecs</pre> | 

## 相关资源
<a name="set-up-a-ci-cd-pipeline-for-hybrid-workloads-on-amazon-ecs-anywhere-by-using-aws-cdk-and-gitlab-resources"></a>
+ [Amazon ECS Anywhere 营销页面](https://aws.amazon.com/ecs/anywhere/)
+ [Amazon ECS Anywhere 文档](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-anywhere.html#ecs-anywhere-considerations)
+ [Amazon ECS Anywhere 演示](https://www.youtube.com/watch?v=-eud6yUXsJM)（视频）
+ [亚马逊 ECS Anywhere 研讨会示例](https://github.com/aws-samples/aws-ecs-anywhere-workshop-samples) (GitHub)
+ [存储库镜像](https://docs.gitlab.com/ee/user/project/repository/mirror/)（GitLab 文档）