

# 创建容器映像以在 Amazon ECS 上使用
<a name="create-container-image"></a>

Amazon ECS 在任务定义中使用 Docker 映像来启动容器。Docker 技术为您提供了在容器中构建、运行、测试和部署分布式应用程序的工具。

Amazon ECS 将容器化应用程序调度到容器实例或 AWS Fargate 上。容器化应用程序将打包为容器映像。此示例为 Web 服务器创建容器映像。

您可以创建第一个 Docker 映像，然后将该映像推送到 Amazon ECR（容器注册表），以便在 Amazon ECS 任务定义中使用。此演练假定您已基本了解 Docker 是什么及其工作方式。有关 Docker 的更多信息，请参阅[什么是 Docker？](https://aws.amazon.com/docker/)和 [Docker 文档](https://docs.docker.com/get-started/docker-overview/)。

## 先决条件
<a name="create-container-image-prerequisites"></a>

在您开始之前，确保您满足以下先决条件。
+ 确保您已完成 Amazon ECR 设置步骤。有关更多信息，请参阅《Amazon Elastic Container Registry 用户指南》**中的 [Moving an image through its lifecycle in Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html)。
+ 您的用户具有访问和使用 Amazon ECR 服务所需的 IAM 权限。有关更多信息，请参阅 [Amazon ECR 托管策略](https://docs.aws.amazon.com/AmazonECR/latest/userguide/security-iam-awsmanpol.html)。
+ 您已安装 Docker。有关 Amazon Linux 2023 的 Docker 安装步骤，请参阅[在 AL2023 上安装 Docker](#create-container-image-install-docker)。对于所有其他操作系统，请参阅 [Docker 桌面概述](https://docs.docker.com/desktop/)中的 Docker 文档。
+ 您已经安装并配置 AWS CLI。有关更多信息，请参阅《AWS Command Line Interface 用户指南》**中的[安装或更新到最新版本的 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

如果您没有或不需要本地开发环境，并且更喜欢使用 Amazon EC2 实例来使用 Docker，我们将提供以下步骤来使用 Amazon Linux 2023 启动 Amazon EC2 实例并安装 Docker Engine 和 Docker CLI。

### 在 AL2023 上安装 Docker
<a name="create-container-image-install-docker"></a>

Docker 适用于许多不同的操作系统，包括大多数现代 Linux 分发版（如 Ubuntu）甚至 MacOS 和 Windows。有关如何在特定的操作系统上安装 Docker 的更多信息，请转到 [Docker 安装指南](https://docs.docker.com/engine/installation/#installation)。

您无需本地开发系统即可使用 Docker。如果您已在使用 Amazon EC2，则可启动 Amazon Linux 2023 实例并安装 Docker 以开始使用。

如果您已安装 Docker，请跳到[创建 Docker 映像](#create-container-image-create-image)。

**使用 Amazon Linux 2023 AMI 在 Amazon EC2 实例上安装 Docker**

1. 使用最新版 Amazon Linux 2023 AMI 启动实例。有关更多信息，请参阅《Amazon EC2 用户指南》中的[使用控制台中的启动实例向导来启动 EC2 实例](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-launch-instance-wizard.html)**。

1. 连接到您的实例。有关更多信息，请参阅《Amazon EC2 用户指南》**中的[连接到您的 EC2 实例](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/connect.html)。

1. 更新实例上已安装的程序包和程序包缓存。

   ```
   sudo yum update -y
   ```

1. 安装最新的 Docker Community Edition 程序包。

   ```
   sudo yum install docker
   ```

1. 启动 Docker 服务。

   ```
   sudo service docker start
   ```

1. 将 `ec2-user` 添加到 `docker` 组，以便您能够执行 Docker 命令，而无需使用 `sudo`。

   ```
   sudo usermod -a -G docker ec2-user
   ```

1. 退出，再重新登录以接受新的 `docker` 组权限。您可以关闭当前的 SSH 终端窗口并在新终端窗口中重新连接到实例，完成这一过程。您的新 SSH 会话将具有相应的 `docker` 组权限。

1. 验证 `ec2-user` 是否能在没有 `sudo` 的情况下运行 Docker 命令。

   ```
   docker info
   ```
**注意**  
在某些情况下，您可能需要重新启动实例，以便为 `ec2-user` 提供访问 Docker 进程守护程序的权限。如果您看到以下错误，请尝试重启您的实例：  

   ```
   Cannot connect to the Docker daemon. Is the docker daemon running on this host?
   ```

## 创建 Docker 映像
<a name="create-container-image-create-image"></a>

Amazon ECS 任务定义使用容器映像启动集群中容器实例上的容器。在本节中，您将创建简单 Web 应用程序的 Docker 映像，并在本地系统或 Amazon EC2 实例上测试此映像，然后将此映像推送至 Amazon ECR 容器注册表，以便能够在 Amazon ECS 任务定义中使用它。

**创建简单 Web 应用程序的 Docker 映像**

1. 创建名为 `Dockerfile` 的文件。Dockerfile 是一个清单文件，描述了用于 Docker 映像的基本映像以及要安装的项目以及在此项目上运行的内容。有关 Dockerfile 的更多信息，请转到 [Dockerfile 参考](https://docs.docker.com/reference/dockerfile/)。

   ```
   touch Dockerfile
   ```

1. 编辑您刚刚创建的 `Dockerfile` 并添加以下内容。

   ```
   FROM public.ecr.aws/amazonlinux/amazonlinux:latest
   
   # Update installed packages and install Apache
   RUN yum update -y && \
    yum install -y httpd
   
   # Write hello world message
   RUN echo 'Hello World!' > /var/www/html/index.html
   
   # Configure Apache
   RUN echo 'mkdir -p /var/run/httpd' >> /root/run_apache.sh && \
    echo 'mkdir -p /var/lock/httpd' >> /root/run_apache.sh && \
    echo '/usr/sbin/httpd -D FOREGROUND' >> /root/run_apache.sh && \
    chmod 755 /root/run_apache.sh
   
   EXPOSE 80
   
   CMD /root/run_apache.sh
   ```

   此 Dockerfile 使用 Amazon ECR Public 上托管的 Amazon Linux 2023 公有映像。`RUN` 指令更新包缓存，安装一些适用于 Web 服务器的软件包，然后将“Hello World\$1” 内容写入 Web 服务器的文档根目录。`EXPOSE` 指令指的是容器的端口 80 为正在侦听的端口，`CMD` 指令启动 Web 服务器。

1. <a name="sample-docker-build-step"></a>从您的 Dockerfile 生成 Docker 映像。
**注意**  
Docker 的某些版本可能需要在以下命令中使用 Dockerfile 完整路径，而不是所示的相对路径。  
如果在 [Apple Silicon](https://support.apple.com/en-gb/116943) 等基于 ARM 的系统上运行该命令，请使用 --platform 选项“--platform linux/amd64”。

   ```
   docker build -t hello-world .
   ```

1. 列出容器映像。

   ```
   docker images --filter reference=hello-world
   ```

   输出：

   ```
   REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
   hello-world         latest              e9ffedc8c286        4 minutes ago       194MB
   ```

1. 运行新构建的映像。`-p 80:80` 选项将容器上公开的端口 80 映射到主机系统上的端口 80。

   ```
   docker run -t -i -p 80:80 hello-world
   ```
**注意**  
来自 Apache Web 服务器的输出将显示在终端窗口中。您可以忽略“`Could not reliably determine the fully qualified domain name`”消息。

1. 打开浏览器并指向正在运行 Docker 并托管您的容器的服务器。
   + 如果您使用的是 EC2 实例，这将是服务器的 **Public DNS** 值，此值与您用于通过 SSH 连接到实例的地址相同。确保实例的安全组允许端口 80 上的入站流量。
   + 如果您正在本地运行 Docker，可将您的浏览器指向 [http://localhost/](http://localhost/)。

   您应看到一个显示“Hello World\$1”语句的 网页。

1. 通过键入 **Ctrl \$1 c** 来停止 Docker 容器。

## 将映像推送到 Amazon Elastic Container Registry
<a name="create-container-image-push-ecr"></a>

Amazon ECR 是 AWS 托管的映像注册表服务。您可以使用 Docker CLI 在 Amazon ECR 存储库中推送、拉取和托管映像。有关 Amazon ECR 产品详细信息、特色客户案例研究和常见问题解答，请参阅 [Amazon Elastic Container Registry 产品详细信息页面](https://aws.amazon.com/ecr)。

**标记映像并将其推送至 Amazon ECR**

1. 创建用于存储您的 `hello-world` 映像的 Amazon ECR 存储库。在输出中记下 `repositoryUri`。

   将 `region` 替换为您的 AWS 区域，例如 `us-east-1`。

   ```
   aws ecr create-repository --repository-name hello-repository --region region
   ```

   输出：

   ```
   {
       "repository": {
           "registryId": "aws_account_id",
           "repositoryName": "hello-repository",
           "repositoryArn": "arn:aws:ecr:region:aws_account_id:repository/hello-repository",
           "createdAt": 1505337806.0,
           "repositoryUri": "aws_account_id.dkr.ecr.region.amazonaws.com/hello-repository"
       }
   }
   ```

1. 使用上一步中的 `repositoryUri` 值标记 `hello-world` 映像。

   ```
   docker tag hello-world aws_account_id.dkr.ecr.region.amazonaws.com/hello-repository
   ```

1. 运行 **aws ecr get-login-password** 命令。指定要对其进行身份验证的注册表 URI。有关更多信息，请参阅 *Amazon Elastic Container Registry 用户指南*中的[注册表身份验证](https://docs.aws.amazon.com/AmazonECR/latest/userguide/Registries.html#registry_auth)。

   ```
   aws ecr get-login-password --region region | docker login --username AWS --password-stdin aws_account_id.dkr.ecr.region.amazonaws.com
   ```

   输出：

   ```
   Login Succeeded
   ```
**重要**  
如果收到错误，请安装或更新到最新版本的 AWS CLI。有关更多信息，请参阅《AWS Command Line Interface 用户指南》**中的[安装或更新到最新版本的 AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

1. 使用上一步中的 `repositoryUri` 值将映像推送至 Amazon ECR。

   ```
   docker push aws_account_id.dkr.ecr.region.amazonaws.com/hello-repository
   ```

## 清理
<a name="create-container-image-cleanup"></a>

要继续创建 Amazon ECS 任务定义并使用容器映像启动任务，请跳至 [后续步骤](#create-container-image-next-steps)。完成试验 Amazon ECR 映像后，您可以删除存储库，从而无需为映像存储付费。

```
aws ecr delete-repository --repository-name hello-repository --region region --force
```

## 后续步骤
<a name="create-container-image-next-steps"></a>

您的任务定义需要任务执行角色。有关更多信息，请参阅 [Amazon ECS 任务执行 IAM 角色](task_execution_IAM_role.md)。

在创建容器映像并将其推送到 Amazon ECR 后，您可以在任务定义中使用该映像。有关更多信息，请参阅以下任一文档：
+ [了解如何为 Fargate 创建 Amazon ECS Linux 任务](getting-started-fargate.md)
+ [了解如何为 Fargate 创建 Amazon ECS Windows 任务](Windows_fargate-getting_started.md)
+ [使用 AWS CLI 为 Fargate 创建 Amazon ECS Linux 任务](ECS_AWSCLI_Fargate.md)