

# 为私有 Docker 映像配置 Amazon ECS 容器实例
<a name="private-auth-container-instances"></a>

Amazon ECS 容器代理可使用基本身份验证对私有注册表进行身份验证。当启用私有注册表身份验证时，您可以在任务定义中使用私有 Docker 映像。只有使用 EC2 的任务才支持此功能。

另一种启用私有注册表身份验证的方法是使用 AWS Secrets Manager 在容器定义中安全地存储并随后引用您的私有注册表凭证。这样，您的任务就可以使用私有存储库中的映像。此方法支持使用 EC2 或 Fargate 的任务。有关更多信息，请参阅 [在 Amazon ECS 中使用非 AWS 容器映像](private-auth.md)。

Amazon ECS 容器代理在启动时将查找两个环境变量：
+ `ECS_ENGINE_AUTH_TYPE`，指定要发送的身份验证数据的类型。
+ `ECS_ENGINE_AUTH_DATA`，包含实际身份验证凭证。

经 Amazon ECS 优化的 AMI 的 Linux 变体在容器实例启动时以及每次服务启动时（使用 **sudo start ecs** 命令）扫描 `/etc/ecs/ecs.config` 文件以查找这些变量。没有经 Amazon ECS 优化的 AMI 应将这些环境变量存储在一个文件中，然后利用 `--env-file path_to_env_file` 选项将其传递到用于启动容器代理的 **docker run** 命令。

**重要**  
我们不建议在实例启动时利用 Amazon EC2 用户数据注入这些身份验证环境变量或利用 `--env` 选项将其传递到 **docker run** 命令。这些方法不适合敏感数据，如身份验证凭证。有关将身份验证凭证安全地添加到容器实例的信息，请参阅[将 Amazon ECS 容器实例配置存储在 Amazon S3 中](ecs-config-s3.md)。

## 身份验证格式
<a name="docker-auth-formats"></a>

私有注册表身份验证有两种可用格式：`dockercfg` 和 `docker`。

**dockercfg 身份验证格式**  
`dockercfg` 格式使用存储在您在运行 **docker login** 命令时创建的配置文件中的身份验证信息。您可以通过在本地系统上运行 **docker login** 并输入注册表用户名、密码和电子邮件地址来创建此文件。您也可以登录到容器实例并运行命令。根据您的 Docker 版本的不同，此文件将以 `~/.dockercfg` 或 `~/.docker/config.json` 的形式保存。

```
cat ~/.docker/config.json
```

输出：

```
{
  "auths": {
    "https://index.docker.io/v1/": {
      "auth": "zq212MzEXAMPLE7o6T25Dk0i"
    }
  }
}
```

**重要**  
较新版本的 Docker 可使用外部 `auths` 对象创建上面所示的配置文件。Amazon ECS 代理仅支持以下格式的 `dockercfg` 身份验证数据，无需 `auths` 对象。如果已安装 **jq** 实用程序，则可以使用以下命令提取此数据：**cat \$1/.docker/config.json \$1 jq .auths**

```
cat ~/.docker/config.json | jq .auths
```

输出：

```
{
  "https://index.docker.io/v1/": {
    "auth": "zq212MzEXAMPLE7o6T25Dk0i",
    "email": "email@example.com"
  }
}
```

在上面的示例中，以下环境变量应添加到 Amazon ECS 容器代理在运行时加载的环境变量文件中（对于经Amazon ECS 优化过的 AMI，该文件为 `/etc/ecs/ecs.config`）。如果不使用经 Amazon ECS 优化的 AMI 并且要利用 **docker run** 手动启动代理，请在启动代理时利用 `--env-file path_to_env_file` 选项指定环境变量文件。

```
ECS_ENGINE_AUTH_TYPE=dockercfg
ECS_ENGINE_AUTH_DATA={"https://index.docker.io/v1/":{"auth":"zq212MzEXAMPLE7o6T25Dk0i","email":"email@example.com"}}
```

您可以使用以下语法配置多个私有注册表：

```
ECS_ENGINE_AUTH_TYPE=dockercfg
ECS_ENGINE_AUTH_DATA={"repo.example-01.com":{"auth":"zq212MzEXAMPLE7o6T25Dk0i","email":"email@example-01.com"},"repo.example-02.com":{"auth":"fQ172MzEXAMPLEoF7225DU0j","email":"email@example-02.com"}}
```

**docker 身份验证格式**  
`docker` 格式使用注册表服务器（代理应向其进行身份验证）的 JSON 表示形式。它还包括注册表需要的身份验证参数（如该账户的用户名、密码和电子邮件地址）。对于 Docker Hub 账户，JSON 表示形式如下所示：

```
{
  "https://index.docker.io/v1/": {
    "username": "my_name",
    "password": "my_password",
    "email": "email@example.com"
  }
}
```

在此示例中，以下环境变量应添加到 Amazon ECS 容器代理在运行时加载的环境变量文件中（对于经 Amazon ECS 优化过的 AMI，该文件为 `/etc/ecs/ecs.config`）。如果不使用经 Amazon ECS 优化过的 AMI 并且要利用 **docker run** 手动启动代理，请在启动代理时利用 `--env-file path_to_env_file` 选项指定环境变量文件。

```
ECS_ENGINE_AUTH_TYPE=docker
ECS_ENGINE_AUTH_DATA={"https://index.docker.io/v1/":{"username":"my_name","password":"my_password","email":"email@example.com"}}
```

您可以使用以下语法配置多个私有注册表：

```
ECS_ENGINE_AUTH_TYPE=docker
ECS_ENGINE_AUTH_DATA={"repo.example-01.com":{"username":"my_name","password":"my_password","email":"email@example-01.com"},"repo.example-02.com":{"username":"another_name","password":"another_password","email":"email@example-02.com"}}
```

## 过程
<a name="enabling-private-registry"></a>

使用以下过程可为容器实例启用私有注册表。

**在经 Amazon ECS 优化的 AMI 中启用私有注册表**

1. 使用 SSH 登录到您的容器实例。

1. 打开 `/etc/ecs/ecs.config` 文件并为注册表和账户添加 `ECS_ENGINE_AUTH_TYPE` 和 `ECS_ENGINE_AUTH_DATA` 值：

   ```
   sudo vi /etc/ecs/ecs.config
   ```

   此示例将对 Docker Hub 用户账户进行身份验证：

   ```
   ECS_ENGINE_AUTH_TYPE=docker
   ECS_ENGINE_AUTH_DATA={"https://index.docker.io/v1/":{"username":"my_name","password":"my_password","email":"email@example.com"}}
   ```

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

   ```
   docker inspect ecs-agent | grep ECS_DATADIR
   ```

   输出：

   ```
   "ECS_DATADIR=/data",
   ```
**重要**  
如果上一个命令未返回 `ECS_DATADIR` 环境变量，则您在停止代理前必须停止在此容器实例上运行的任何任务。使用 `ECS_DATADIR` 环境变量的较新的代理将会保存其状态，您可以在任务运行的过程中停止和启动它们，而不会造成问题。有关更多信息，请参阅 [更新 Amazon ECS 容器代理](ecs-agent-update.md)。

1. 停止 `ecs` 服务：

   ```
   sudo stop ecs
   ```

   输出：

   ```
   ecs stop/waiting
   ```

1. 重新启动 `ecs` 服务。
   + 对于经 Amazon ECS 优化的 Amazon Linux 2 AMI：

     ```
     sudo systemctl restart ecs
     ```
   + 对于经 Amazon ECS 优化的 Amazon Linux AMI：

     ```
     sudo stop ecs && sudo start ecs
     ```

1. （可选）您可以通过查询代理自检 API 操作，验证代理是否正在运行并查看有关新容器实例的一些信息。有关更多信息，请参阅 [Amazon ECS 容器自检](ecs-agent-introspection.md)。

   ```
   curl http://localhost:51678/v1/metadata
   ```