

# 更新 Amazon ECS 容器代理
<a name="ecs-agent-update"></a>

有时，您可能需要更新 Amazon ECS 容器代理以获取错误修正和新功能。更新 Amazon ECS 容器代理不会中断容器实例上正在运行的任务或服务。更新代理的过程各不相同，具体取决于您的容器实例是否通过经 Amazon ECS 优化过的 AMI 或其他操作系统启动。

**注意**  
代理更新不适用于 Windows 容器实例。我们建议您启动新的容器实例来更新您的 Windows 集群中的代理版本。

## 检查 Amazon ECS 容器代理版本
<a name="checking_agent_version"></a>

您可以查看在容器实例上运行的容器代理的版本以确定是否需要更新它。Amazon ECS 控制台中的容器实例视图提供了代理版本。使用以下过程可以检查代理版本。

------
#### [ Amazon ECS console ]

1. 在 [https://console.aws.amazon.com/ecs/v2](https://console.aws.amazon.com/ecs/v2) 打开控制台。

1. 从导航栏中，选择您的外部实例将注册的区域。

1. 在导航窗格中，选择 **集群** 并选择托管外部实例的集群。

1. 在 **Cluster : *name***（集群：名称）页面上，选择 **Infrastructure**（基础设施）选项卡。

1. 在**容器实例**下，注意容器实例的**代理版本**列。如果容器实例未包含最新版本的容器代理，则控制台将通过消息来提醒您并标记已过期的代理版本。

   如果您的代理版本已过期，则可以使用以下过程更新容器代理：
   + 如果您的容器实例正在运行经 Amazon ECS 优化的 AMI，请参阅 [更新经 Amazon ECS 优化的 AMI 上的 Amazon ECS 容器代理](agent-update-ecs-ami.md)。
   + 如果您的容器实例未运行经 Amazon ECS 优化的 AMI，请参阅 [手动更新 Amazon ECS 容器代理（适用于非经 Amazon ECS 优化的 AMI）](manually_update_agent.md)。
**重要**  
要在经 Amazon ECS 优化的 AMI 上从 v1.0.0 之前的版本更新 Amazon ECS代理版本，建议您终止当前容器实例并启动具有最新 AMI 的新实例。使用预览版的任何容器实例都应停用并更换为最新的 AMI。有关更多信息，请参阅 [启动 Amazon ECS Linux 容器实例](launch_container_instance.md)。

------
#### [ Amazon ECS container agent introspection API  ]

您还可以使用 Amazon ECS 容器代理自检 API 从容器实例本身检查代理版本。有关更多信息，请参阅 [Amazon ECS 容器自检](ecs-agent-introspection.md)。

**利用自检 API 检查 Amazon ECS 容器代理运行的是否为最新版本**

1. 通过 SSH 登录到容器实例。

1. 查询自检 API。

   ```
   [ec2-user ~]$ curl -s 127.0.0.1:51678/v1/metadata | python3 -mjson.tool
   ```
**注意**  
自检 API 在 v1.0.0 版本的 Amazon ECS 容器代理中添加了 `Version` 信息。如果在查询自检 API 时 `Version` 不存在，或者自检 API 在您的代理中根本不存在，则表明运行的版本是 v0.0.3 或更早的版本。您应该更新版本。

------

# 更新经 Amazon ECS 优化的 AMI 上的 Amazon ECS 容器代理
<a name="agent-update-ecs-ami"></a>

如果您使用经 Amazon ECS 优化的 AMI，则可通过多种方式获取最新版本的 Amazon ECS 容器代理（按建议的顺序显示）：
+ 终止容器实例并启动最新版本的经 Amazon ECS 优化的 Amazon Linux 2 AMI（手动执行或者通过使用最新的 AMI 更新自动扩缩启动配置来执行）。这将提供全新的容器实例，其中包含最新的经测试和验证的版本的 Amazon Linux、Docker、`ecs-init` 和 Amazon ECS 容器代理。有关更多信息，请参阅 [经 Amazon ECS 优化的 Linux AMI](ecs-optimized_AMI.md)。
+ 使用 SSH 连接到实例，并将 `ecs-init` 程序包（及其依赖项）更新到最新版本。此操作提供了最新的经测试和验证的版本的 Docker 和 `ecs-init`（它们在 Amazon Linux 存储库中提供）以及最新版本的 Amazon ECS 容器代理。有关更多信息，请参阅 [更新经 Amazon ECS 优化过的 AMI 上的 `ecs-init` 程序包](#procedure_update_ecs-init)。
+ 使用 `UpdateContainerAgent` API 操作更新容器代理（通过控制台执行，或者通过 AWS CLI 或 AWS 开发工具包执行）。有关更多信息，请参阅 [使用 `UpdateContainerAgent` API 操作更新 Amazon ECS 容器代理](#agent-update-api)。

**注意**  
代理更新不适用于 Windows 容器实例。我们建议您启动新的容器实例来更新您的 Windows 集群中的代理版本。<a name="procedure_update_ecs-init"></a>

**更新经 Amazon ECS 优化过的 AMI 上的 `ecs-init` 程序包**

1. 通过 SSH 登录到容器实例。

1. 使用以下命令更新 `ecs-init` 包。

   ```
   sudo yum update -y ecs-init
   ```
**注意**  
将立即更新 `ecs-init` 程序包和 Amazon ECS 容器代理。但是，更新版本的 Docker 直至 Docker 进程守护程序重新启动后才会加载。通过重启实例或通过在您的实例上运行以下命令来重新启动：  
经 Amazon ECS 优化的 Amazon ECS Amazon Linux 2 AMI：  

     ```
     sudo systemctl restart docker
     ```
经 Amazon ECS 优化的 Amazon ECS Amazon Linux AMI：  

     ```
     sudo service docker restart && sudo start ecs
     ```

## 使用 `UpdateContainerAgent` API 操作更新 Amazon ECS 容器代理
<a name="agent-update-api"></a>

**重要**  
`UpdateContainerAgent` API 仅在经 Amazon ECS 优化的 AMI 的Linux变体上受支持，但 Amazon ECS 优化的 Amazon Linux 2（arm64）AMI 除外。对于使用经 Amazon ECS 优化的 Amazon Linux 2（arm64）AMI 的容器实例，请更新 `ecs-init` 程序包更新代理。有关运行其他操作系统的容器实例，请参阅[手动更新 Amazon ECS 容器代理（适用于非经 Amazon ECS 优化的 AMI）](manually_update_agent.md)。如果您使用的是 Windows 容器实例，建议您启动新的容器实例以更新 Windows 集群中的代理版本。

`UpdateContainerAgent` API 过程在您请求代理更新时开始（通过控制台执行，或者通过 AWS CLI 或 AWS 开发工具包。Amazon ECS 将对照最新的代理版本检查您当前的代理版本，并检查是否可以更新。如果更新不可用（例如代理已在运行最新版本），则会返回 `NoUpdateAvailableException`。

上面显示的更新过程的各个阶段如下所示：

`PENDING`  
代理更新可用，并且更新过程已开始。

`STAGING`  
代理已开始下载代理更新。如果代理无法下载更新，或者更新的内容不正确或已损坏，代理将发送失败通知，并且更新将变为 `FAILED` 状态。

`STAGED`  
代理下载已完成，且代理内容已经过验证。

`UPDATING`  
`ecs-init` 服务已重新启动，并且选取了新代理版本。如果代理出于某个原因无法重新启动，更新将变为 `FAILED` 状态；否则，代理将向 Amazon ECS 发送更新已完成的信号。

**注意**  
代理更新不适用于 Windows 容器实例。我们建议您启动新的容器实例来更新您的 Windows 集群中的代理版本。

**在控制台中更新经 Amazon ECS 优化的 AMI 上的 Amazon ECS 容器代理**

1. 在 [https://console.aws.amazon.com/ecs/v2](https://console.aws.amazon.com/ecs/v2) 打开控制台。

1. 从导航栏中，选择您的外部实例将注册的区域。

1. 在导航窗格中，选择 **Clusters** 并选择集群。

1. 在 **Cluster : *name***（集群：名称）页面上，选择 **Infrastructure**（基础设施）选项卡。

1. 在**容器实例**下，选择要更新的实例，然后选择**操作**、**更新代理**。

# 手动更新 Amazon ECS 容器代理（适用于非经 Amazon ECS 优化的 AMI）
<a name="manually_update_agent"></a>

有时，您可能需要更新 Amazon ECS 容器代理以获取错误修正和新功能。更新 Amazon ECS 容器代理不会中断容器实例上正在运行的任务或服务。
**注意**  
代理更新不适用于 Windows 容器实例。我们建议您启动新的容器实例来更新您的 Windows 集群中的代理版本。

1. 通过 SSH 登录到容器实例。

1. 检查您的代理是否使用 `ECS_DATADIR` 环境变量保存其状态。

   ```
   ubuntu:~$ docker inspect ecs-agent | grep ECS_DATADIR
   ```

   输出：

   ```
   "ECS_DATADIR=/data",
   ```
**重要**  
如果上一个命令未返回 `ECS_DATADIR` 环境变量，则您在更新代理前必须停止在此容器实例上运行的任何任务。具有 `ECS_DATADIR` 环境变量的较新的代理将保存其状态，您可以在任务运行的同时更新它们，而不会出现问题。

1. 停止 Amazon ECS 容器代理。

   ```
   ubuntu:~$ docker stop ecs-agent
   ```

1. 删除代理容器。

   ```
   ubuntu:~$ docker rm ecs-agent
   ```

1. 确保 `/etc/ecs/ecs.config`中存在 `/etc/ecs` 目录和 Amazon ECS 容器代理配置文件。

   ```
   ubuntu:~$ sudo mkdir -p /etc/ecs && sudo touch /etc/ecs/ecs.config
   ```

1. 编辑 `/etc/ecs/ecs.config` 文件，并确保它至少包含以下变量声明。如果不希望向默认集群注册容器实例，请将 `ECS_CLUSTER` 的值指定为集群名称。

   ```
   ECS_DATADIR=/data
   ECS_ENABLE_TASK_IAM_ROLE=true
   ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=true
   ECS_LOGFILE=/log/ecs-agent.log
   ECS_AVAILABLE_LOGGING_DRIVERS=["json-file","awslogs"]
   ECS_LOGLEVEL=info
   ECS_CLUSTER=default
   ```

   有关这些和其他代理运行时选项的更多信息，请参阅 [Amazon ECS 容器代理配置](ecs-agent-config.md)。
**注意**  
您可以选择将代理环境变量存储在 Amazon S3 中（可在启动时使用 Amazon EC2 用户数据将其下载到容器实例）。建议对敏感信息（如私有存储库的身份验证凭证）采用此方法。有关更多信息，请参阅 [将 Amazon ECS 容器实例配置存储在 Amazon S3 中](ecs-config-s3.md) 和 [在 Amazon ECS 中使用非 AWS 容器映像](private-auth.md)。

1. 从 Amazon Elastic Container Registry Public 拉取最新的 Amazon ECS 容器代理映像。

   ```
   ubuntu:~$ docker pull public.ecr.aws/ecs/amazon-ecs-agent:latest
   ```

   输出：

   ```
   Pulling repository amazon/amazon-ecs-agent
   a5a56a5e13dc: Download complete
   511136ea3c5a: Download complete
   9950b5d678a1: Download complete
   c48ddcf21b63: Download complete
   Status: Image is up to date for amazon/amazon-ecs-agent:latest
   ```

1. 在容器实例上运行最新的 Amazon ECS 容器代理。
**注意**  
使用 Docker 重新启动策略或进程管理器（如 **upstart** 或 **systemd**）将容器代理作为服务或进程守护程序处理，并确保在容器代理退出后重新启动它。经 Amazon ECS 优化的 AMI 使用 `ecs-init` RPM 达到此目的，并且您可以在 GitHub 上查看[此 RPM 的源代码](https://github.com/aws/amazon-ecs-init)。

   以下示例代理运行命令分为若干个单独的行以显示每个选项。有关这些和其他代理运行时选项的更多信息，请参阅 [Amazon ECS 容器代理配置](ecs-agent-config.md)。
**重要**  
运行启用了 SELinux 的操作系统需要在 **docker run** 命令中使用 `--privileged` 选项。此外，对于启用了 SELinux 的容器实例，建议向 `/log` 和 `/data` 卷挂载添加 `:Z` 选项。但是，在运行该命令前，这些卷的主机挂载必须存在，否则会出现 `no such file or directory` 错误。如果您在启用了 SELinux 的容器实例上运行 Amazon ECS 代理时遇到困难，请执行以下操作：  
在容器实例上创建主机卷挂载点。  

     ```
     ubuntu:~$ sudo mkdir -p /var/log/ecs /var/lib/ecs/data
     ```
将 `--privileged` 选项添加到下面的 **docker run** 命令中。
将 `:Z` 选项追加到针对下面的 **docker run** 命令的 `/log` 和 `/data` 容器卷挂载（例如 `--volume=/var/log/ecs/:/log:Z`）。

   ```
   ubuntu:~$ sudo docker run --name ecs-agent \
   --detach=true \
   --restart=on-failure:10 \
   --volume=/var/run:/var/run \
   --volume=/var/log/ecs/:/log \
   --volume=/var/lib/ecs/data:/data \
   --volume=/etc/ecs:/etc/ecs \
   --volume=/etc/ecs:/etc/ecs/pki \
   --net=host \
   --env-file=/etc/ecs/ecs.config \
   amazon/amazon-ecs-agent:latest
   ```
**注意**  
如果您收到一条 `Error response from daemon: Cannot start container` 消息，则可以利用 **sudo docker rm ecs-agent** 命令删除失败的容器并重新尝试运行代理。