使用 CodeCatalyst 构建多架构容器

作者: 布莱恩·比奇 |

亚马逊云科技 Graviton 处理 器 由 亚马逊云科技 设计,旨在为在 亚马逊弹性计算云(Amazon EC2)中运行的云 工作负载提供最佳的性价比。 Amazon CodeCatalyst 最近增加了对使用由 亚马逊云科技 Graviton 处理器提供支持的按需计算或预配置计算运行工作流程操作的支持。客户现在可以访问高性能的 亚马逊云科技 Graviton 处理器来为 Arm 构建构件或提高其性价比。在这篇文章中,我将向您展示如何使用CodeCatalyst创建可以在amd64和arm64处理器上运行的多架构docker镜像。

背景

容器映像只能在具有与其目标相同的 CPU 架构的系统上运行。例如, amd64 映像在英特尔和 AMD 处理器上运行,而 arm 64 映像在 AWS Grav iton 上运行。请注意,amd64 和 x86_64 经常可以互换使用,在这篇文章中我选择使用 amd64。与其为每种图像类型维护多个存储库,不如将多个架构的变体组合到同一个存储库中。此外,您可以创建清单,描述每种架构要使用哪个映像。这被称为 多架构或多平台 映像。

让我们看一个例子来进一步理解多架构图像。在这张来自 亚马逊弹性容器注册表 (Amazon ECR) 的屏幕截图中 ,我为一个简单的 hello -world 应用程序创建了两个镜像。 其中一张图片被标记为 AMD 架构 的最新 amd64 ,另一张标记为 ARM架构的最新arm64。

此外,我还创建了一个标记为 最新的 图像清单(或者,在 ECR 控制台中创建图像索引)。图像清单是描述每种架构要使用哪张图像的地图。这允许我的用户简单地提取 hello-world: l atest,清单将根据目标平台识别正确的图像。图像清单包含以下清单。

{
  "schemaVersion": 2, 
  "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", 
  "manifests": [ 
    { 
	  "mediaType": "application/vnd.docker.distribution.manifest.v2+json", 
	  "size": 1573, 
	  "digest": "sha256:eccb6dd2c2dbfc9...", 
	  "platform": { 
	    "architecture": "amd64", 
		"os": "linux" 
	  } 
	}, 
	{ 
	  "mediaType": "application/vnd.docker.distribution.manifest.v2+json", 
	  "size": 1573, 
	  "digest": "sha256:c64812837fbd43...", 
	  "platform": { 
	    "architecture": "arm64", 
		"os": "linux" 
	  } 
	}
  ]
} 

现在我已经解释了什么是多架构图像,我将解释如何在CodeCatalyst工作流程中创建一个。 CodeCatalyst 工作流程 是一个自动化程序,描述如何构建、测试和部署您的代码,作为持续集成和持续交付 (CI/CD) 系统的一部分。工作流程定义了在工作流程运行期间要采取的一系列步骤或操作。让我们开始吧。

先决条件

如果您想按照本演练进行操作,则需要:

  • 一个 CodeCatalyst 空间和关联的 亚马逊云科技 账户。
  • 空间中有一个 空的 CodeCatalyst 项目 源代码存储库
  • 关联的 亚马逊云科技 账户 中的 亚马逊 ECR 私有存储库
  • 连接到关联的 亚马逊云科技 账户的 CodeCatalyst 环境

草率排练

在本演练中,我将使用提供静态问候世界页面的 Apache HTTP 服务器创建一个简单的应用程序。工作量无关紧要。我将重点介绍使用 CodeCatalyst 工作流程构建容器镜像的过程。工作流程将构建两个容器镜像,一个用于 amd64,一个用于 arm64。这两个构建任务将在不同的计算架构上并行运行。当两个版本都完成后,工作流程将构建 docker 清单。在这篇文章的最后,我的工作流程将如下所示。

请注意,docker 还提供了一个名为 buildx 的插件,允许您使用单个命令构建多架构映像。在现实世界的应用程序中,工作流程还将在每个架构上构建源代码、运行单元测试等。本文中使用的示例应用程序非常简单,无需构建和测试源代码。现在让我们来看一下示例应用程序。

示例应用程序

最初,空存储库将只有一个 README.md 文件。在这篇文章结束时,我的存储库将看起来像这样。

首先,我将创建名为 index.html 的文件 。我使用了前面显示的 CodeCatalyst 控制台中的 “ 创建文件 ” 按钮。我 的 index.html 文件包含以下内容:

<html>
    <head>
        <title>Hello World!</title>
    </head>
    <body>
        <h1>Hello World!</h1>
        <p>Hello from a multi-architecture container created in CodeCatalyst.</p>
    </body>
</html>

我还将创建一个包含两个命令的 Dockerfil e 第一个命令指示 Docker 从 Apache HTTP 服务器项目映像中构建一个名为 http d 的新 镜像。 值得注意的是,httpd 映像已经支持多种架构,包括 amd64 和 arm64 创建多架构映像时,基础映像还必须支持这些架构。第二个命令只是将上面的 index.html 文件复制到新映像中。我的 Dockerfile 文件包含以下内容。

FROM httpd
COPY ./index.html /usr/local/apache2/htdocs/

示例应用程序的源代码完成后,我可以将注意力转向工作流程。

CI/CD 工作流程

要创建新的工作流程,请 从左侧的导航栏中选择 CI/CD ,然后选择 工作流程 (1) 。 然后,选择 创建工作流程 (2), 保留默认选项,然后选择 创建 (3)

如果工作流编辑器以 YAML 模式打开,请选择 Visual 打开 可视化设计器。现在,我可以开始向工作流程添加操作了。

AMD64 变体的构建动作

首先,我将为 amd64 容器添加一个构建操作。选择 “ + 操作 ” 以打开操作列表。找到 “ 构建 ” 操作并单击 “ + ” 将新的生成操作添加到工作流程中。

在输入选项卡上,创建三个名为 亚马逊云科技_DEFAULT_REGION、IMAGE_REPO_NAME 和 IMAGE_TAG 的变量。 将前两个值设置为等于 Amazon ECR 存储库的区域和**** 名称**.** 将第三个值设置为最新的 amd64。 例如:

现在选择 “ 配置 ” 选项卡并重命名操作 docker_build_amd64 。为您在其中创建 Amazon ECR 存储库 的关联 亚马逊云科技 账户选择 环境 、亚马逊云科技 账户连接 角色 。例如:

然后,将以下代码复制并粘贴到命令行 管理程序命令 中 。这段代码将使用你之前创建的 Dockerfile 来构建镜像。然后,它登录到亚马逊 ECR,最后将新映像推送到 ECR。

- Run: AWS_ACCOUNT_ID=`aws sts get-caller-identity --query "Account" --output text` 
- Run: docker build -t $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG . 
- Run: aws ecr get-login-password | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com 
- Run: docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG

如果您切换回 YAML 视图,则可以看到设计者已将以下操作添加到工作流程定义中。

  docker_build_amd64:
    Identifier: aws/build@v1
    Compute:
      Type: EC2
    Inputs:
      Sources:
        - WorkflowSource
      Variables:
        - Name: AWS_DEFAULT_REGION
          Value: us-west-2
        - Name: IMAGE_REPO_NAME
          Value: hello-world
        - Name: IMAGE_TAG
          Value: latest-amd64
    Environment:
      Name: demo
      Connections:
        - Role: CodeCatalystPreviewDevelopmentAdministrator
          Name: development
    Configuration:
      Steps:
        - Run: AWS_ACCOUNT_ID=`aws sts get-caller-identity --query "Account" --output text`
        - Run: docker build -t $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG .
        - Run: aws ecr get-login-password | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
        - Run: docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG

完成 amd64 图像后,你可以继续前进 arm64 映像。

ARM64 变体的构建动作

为 arm64 容器添加第二个名为 docker_build_arm64 的构建 操作。该配置与之前的操作几乎相同,但有两处细微的更改。 首先,在 “ 输入 ” 选项卡上,我将 IMAGE_TAG 设置为 latest-arm6 4 。

其次,在配置选项卡上,将计算队列更改为 Linux.Arm64.Large。这就是你在 亚马逊云科技 Graviton 上运行操作所需要做的一切。例如:

命令行管理程序命令 与 arm64 编译操作相同。此外,别忘了在配置选项卡 上选择 环境 亚马逊云科技 账户连接 角色 。第二个操作的完整配置如下所示:

  docker_build_arm64:
    Identifier: aws/build@v1
    Compute:
      Type: EC2
      Fleet: Linux.Arm64.Large
    Inputs:
      Sources:
        - WorkflowSource
      Variables:
        - Name: AWS_DEFAULT_REGION
          Value: us-west-2
        - Name: IMAGE_REPO_NAME
          Value: hello-world
        - Name: IMAGE_TAG
          Value: latest-arm64
    Environment:
      Name: demo
      Connections:
        - Role: CodeCatalystPreviewDevelopmentAdministrator
          Name: development
    Configuration:
      Steps:
        - Run: AWS_ACCOUNT_ID=`aws sts get-caller-identity --query "Account" --output text`
        - Run: docker build -t $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG .
        - Run: aws ecr get-login-password | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
        - Run: docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG

现在您已经有了 amd64 和 arm64 映像的构建操作,您只需要创建一个清单文件来描述每种架构要使用哪个映像。

为清单生成操作

工作流程的最后一步是创建 Docker 清单。创建名为 docker _manifest 的第三个生成操作。您希望此操作等待前两个操作完成。因此,从 “ 依赖 对象” 下 拉列表中选择前两项操作,如下所示:

还要配置四个变量。 WS_DEFAULT_REGION 和 IMAGE_RE PO_NAME 与之前的操作相同 。此外, IMAGE_TAG_AMD64 和 IMAGE_TAG_ARM64 包括您在之前的操作中创建的标签

在配置选项卡上,选择 环境 亚马逊云科技 账户连接 角色 , 就像您在之前的操作中所做的那样。然后,复制并粘贴以下 Shell 命令

- Run: AWS_ACCOUNT_ID=`aws sts get-caller-identity --query "Account" --output text`
- Run: aws ecr get-login-password | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
- Run: docker manifest create $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG_ARM64 $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG_AMD64
- Run: docker manifest annotate --arch amd64 $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG_AMD64
- Run: docker manifest annotate --arch arm64 $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG_ARM64
- Run: docker manifest push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME

shell 命令会创建一个清单,然后使用 amd64 和 arm64 的正确映像对其进行注释。最后的动作看起来像这样。

  docker_manifest:
    Identifier: aws/build@v1
    DependsOn:
      - docker_build_arm64
      - docker_build_amd64
    Compute:
      Type: EC2
    Inputs:
      Sources:
        - WorkflowSource
      Variables:
        - Name: AWS_DEFAULT_REGION
          Value: us-west-2
        - Name: IMAGE_REPO_NAME
          Value: hello-world
        - Name: IMAGE_TAG_AMD64
          Value: latest-amd64
        - Name: IMAGE_TAG_ARM64
          Value: latest-arm64
    Environment:
      Name: demo
      Connections:
        - Role: CodeCatalystPreviewDevelopmentAdministrator
          Name: development
    Configuration:
      Steps:
        - Run: AWS_ACCOUNT_ID=`aws sts get-caller-identity --query "Account" --output
            text`
        - Run: aws ecr get-login-password | docker login --username AWS
            --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
        - Run: docker manifest create
            $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME
            $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG_ARM64
            $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG_AMD64
        - Run: docker manifest annotate --arch amd64
            $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME
            $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG_AMD64
        - Run: docker manifest annotate --arch arm64
            $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME
            $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG_ARM64
        - Run: docker manifest push
            $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME

我现在有一个完整的 CI/CD 工作流程,可以为 amd64 和 arm64 创建容器镜像。当我提交更改时,CodeCatalyst将执行我的工作流程,构建图像并推送到ECR。

清理

如果您一直遵循此工作流程,则应删除部署的资源,以免继续产生费用。首先,使用 亚马逊云科技 控制台删除 Amazon ECR 存储库。其次,通过导航到项目设置并选择 “删除项目”,从 CodeCatalyst 中删除该项目。

结论

亚马逊云科技 Graviton 处理器由 亚马逊云科技 定制构建,旨在为云工作负载提供最佳性价比。在这篇文章中,我解释了如何配置CodeCatalyst工作流程操作以在亚马逊云科技 Graviton上运行。我使用CodeCatalyst创建了一个工作流程,该工作流程可以构建一个可以在amd64和arm64架构上运行的多架构容器映像。立即开始在 亚马逊 Cod eCatalyst 中构建您的多架构容器! 你可以在文档中阅读有关CodeCatalyst工作流程的更多信息。


*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。