

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

# 配置 Docker 以用于 Amazon EMR 集群
<a name="emr-plan-docker"></a>

亚马逊 EMR 6.x 支持 Hadoop 3，它允许 YARN NodeManager 直接在亚马逊 EMR 集群上或在 Docker 容器内启动容器。Docker 容器提供了自定义执行环境，应用程序代码在其中运行。自定义执行环境与 YARN NodeManager 和其他应用程序的执行环境隔离。

Docker 容器可以包含应用程序使用的特殊库，并且还可以提供不同版本的本机工具和库（如 R 和 Python）。您可以使用熟悉的 Docker 工具，以定义应用程序的库和运行时依赖项。

默认情况下，将 Amazon EMR 6.x 集群配置为允许 YARN 应用程序（如 Spark）使用 Docker 容器运行。要自定义容器配置，请编辑 `yarn-site.xml` 中定义的 Docker 支持选项和 `/etc/hadoop/conf` 目录中提供的 `container-executor.cfg` 文件。有关每个配置选项及其使用方式的详细信息，请参阅[使用 Docker 容器启动应用程序](https://hadoop.apache.org/docs/r3.1.0/hadoop-yarn/hadoop-yarn-site/DockerContainers.html)。

提交任务时，您可以选择使用 Docker。请使用以下变量指定 Docker 运行时和 Docker 镜像。
+ `YARN_CONTAINER_RUNTIME_TYPE=docker`
+ `YARN_CONTAINER_RUNTIME_DOCKER_IMAGE={{{DOCKER_IMAGE_NAME}}}`

您使用 Docker 容器运行 YARN 应用程序时，YARN 会下载您在提交任务时指定的 Docker 镜像。要想让 YARN 解析此 Docker 镜像，必须使用 Docker 注册表进行配置。Docker 注册表的配置选项取决于您使用公有子网还是私有子网来部署集群。

## Docker 注册表
<a name="emr-docker-registries"></a>

Docker 注册表是 Docker 镜像的存储和分配系统。对于 Amazon EMR，我们建议您使用 Amazon ECR，这是一个完全托管式的 Docker 容器注册表，让您能够创建自己的自定义镜像，并在高度可用且可扩展的架构中托管。

**部署注意事项**

Docker 注册表要求从集群中的每个主机进行网络访问。这是因为当您的 YARN 应用程序在集群上运行时，每个主机都会从 Docker 注册表下载镜像。这些网络连接要求可能会限制您对 Docker 注册表的选择，具体取决于您是将 Amazon EMR 集群部署到公有子网还是私有子网。

**公有子网**

当 EMR 集群部署在公有子网中时，运行 YARN 的节点 NodeManager 可以直接访问 Internet 上可用的任何注册表。

**私有子网**

当 EMR 集群部署在私有子网中时，运行 YARN 的节点 NodeManager 无法直接访问互联网。Docker 镜像可以托管在 Amazon ECR 中并通过以下方式进行访问。 Amazon PrivateLink

有关如何在私有子网场景中使用 Amazon PrivateLink 允许访问 Amazon ECR 的更多信息，请参阅[设置 Amazon PrivateLink Amazon ECS 和 Amazon EC](https://www.amazonaws.cn/blogs/compute/setting-up-aws-privatelink-for-amazon-ecs-and-amazon-ecr/) R。

## 配置 Docker 注册表
<a name="emr-docker-hub"></a>

要在 Amazon EMR 中使用 Docker 注册，必须将 Docker 配置为信任要用于解析 Docker 镜像的特定注册表。原定设置的信任注册表是本地（私有）和 centos 注册表。要使用其它公有存储库或 Amazon ECR，您可以使用带有 `container-executor` 分类键的 EMR 分类 API 来覆盖 `/etc/hadoop/conf/container-executor.cfg` 中的 `docker.trusted.registries` 设置。

以下示例演示了如何将集群配置为信任名为 `your-public-repo` 的公有存储库和 ECR 注册表终端节点 `123456789123.dkr.ecr.us-east-1.amazonaws.com`。如果您使用 ECR，请将此终端节点替换为您的特定 ECR 终端节点。

```
[
  {
    "Classification": "container-executor",
    "Configurations": [
        {
            "Classification": "docker",
            "Properties": {
                "docker.trusted.registries": "local,centos,{{your-public-repo}},123456789123.dkr.ecr.us-east-1.amazonaws.com",
                "docker.privileged-containers.registries": "local,centos,your-public-repo,123456789123.dkr.ecr.us-east-1.amazonaws.com"
            }
        }
    ]
  }
]
```

要使用 Amazon Command Line Interface (Amazon CLI) 启动具有此配置的 Amazon EMR 6.0.0 集群，请使用前面的 ontainer-executor JSON 配置的内容创建一个名为`container-executor.json`的文件。然后，使用以下命令启动集群。

```
export KEYPAIR=<{{Name of your Amazon EC2 key-pair}}>
export SUBNET_ID=<{{ID of the subnet to which to deploy the cluster}}>
export INSTANCE_TYPE=<{{Name of the instance type to use}}>
export REGION=<{{Region to which to deploy the cluster}}>

aws emr create-cluster \
    --name "EMR-6.0.0" \
    --region $REGION \
    --release-label emr-6.0.0 \
    --applications Name=Hadoop Name=Spark \
    --service-role EMR_DefaultRole \
    --ec2-attributes KeyName=$KEYPAIR,InstanceProfile=EMR_EC2_DefaultRole,SubnetId=$SUBNET_ID \
    --instance-groups InstanceGroupType=MASTER,InstanceCount=1,InstanceType=$INSTANCE_TYPE InstanceGroupType=CORE,InstanceCount=2,InstanceType=$INSTANCE_TYPE \
    --configuration file://container-executor.json
```

## 将 YARN 配置为访问 Amazon ECR on EMR 6.0.0 及更早版本
<a name="emr-docker-ECR"></a>

如果您是 Amazon ECR 的新用户，请按照 [Amazon ECR 入门](https://docs.amazonaws.cn/AmazonECR/latest/userguide/ECR_GetStarted.html)中的说明进行操作，并验证您是否有权从 Amazon EMR 集群中的每个实例访问 Amazon ECR。

在 EMR 6.0.0 及更早版本上，要使用 Docker 命令访问 Amazon ECR，必须首先生成凭证。要验证 YARN 是否可以从 Amazon ECR 访问镜像，请使用容器环境变量 `YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG` 来传递对您所生成凭证的引用。

在其中一个核心节点上运行以下命令，获取 ECR 账户的登录行。

```
aws ecr get-login --region us-east-1 --no-include-email
```

`get-login` 命令会生成正确的 Docker CLI 命令来运行，以创建凭证。从 `get-login` 复制输出并运行它。

```
sudo docker login -u AWS -p <{{password}}> https://<{{account-id}}>.dkr.ecr.us-east-1.amazonaws.com
```

此命令在 `/root/.docker` 文件夹中生成 `config.json` 文件。将此文件复制到 HDFS，以便提交到集群的任务可以使用它对 Amazon ECR 进行身份验证。

运行以下命令，将 `config.json` 文件复制到您的主目录。

```
mkdir -p ~/.docker
sudo cp /root/.docker/config.json ~/.docker/config.json
sudo chmod 644 ~/.docker/config.json
```

请运行以下将 config.json 放入 HDFS 的命令，以便在集群上运行任务时使用。

```
hadoop fs -put ~/.docker/config.json /user/hadoop/
```

YARN 可以将 ECR 作为 Docker 镜像注册表访问，并在任务执行期间提取容器。

配置 Docker 注册表和 YARN 后，您可以使用 Docker 容器来运行 YARN 应用程序。有关更多信息，请参阅[使用 Amazon EMR 6.0.0 通过 Docker 运行 Spark 应用程序](https://docs.amazonaws.cn/emr/latest/ReleaseGuide/emr-spark-docker.html)。

在 EMR 6.1.0 及更高版本中，您无需手动设置对 Amazon ECR 的身份验证。如果在 `container-executor` 分类键中检测到 Amazon ECR 注册表，将激活 Amazon ECR 自动身份验证功能，并且 YARN 会在您提交带有 ECR 镜像的 Spark 任务时处理身份验证过程。您可以通过在 yarn-site 中检查 `yarn.nodemanager.runtime.linux.docker.ecr-auto-authentication.enabled` 来确认是否启用了自动身份验证。如果 `docker.trusted.registries` 包含 ECR 注册表 URL，将启用自动身份验证，并将 YARN 身份验证设置设置为 `true`。

**对 Amazon ECR 使用自动身份验证的先决条件**
+ EMR 版本 6.1.0 或更高版本
+ 配置中包含的 ECR 注册表与集群位于同一个区域
+ IAM 角色，具有获取授权令牌并提取任何镜像的权限

有关更多信息，请参阅[使用 Amazon ECR 进行设置](https://docs.amazonaws.cn/AmazonECR/latest/userguide/get-set-up-for-amazon-ecr.html)。

**如何启用自动身份验证**

按照 [配置 Docker 注册表](#emr-docker-hub) 将 Amazon ECR 注册表设置为受信任的注册表，并确保 Amazon ECR 存储库和集群位于同一区域。

若要启用此功能（即使未在受信任的注册表中设置 ECR 注册表），请使用配置分类将 `yarn.nodemanager.runtime.linux.docker.ecr-auto-authentication.enabled` 设置为 `true`。

**如何禁用自动身份验证**

默认情况下，如果在受信任的注册表中未检测到 Amazon ECR 注册表，则表明已禁用自动身份验证。

要禁用自动身份验证（即使在受信任的注册表中设置了 Amazon ECR 注册表），请使用配置分类将 `yarn.nodemanager.runtime.linux.docker.ecr-auto-authentication.enabled` 设置为 `false`。

**如何检查是否在集群上启用了自动身份验证**

在主节点上，使用文本编辑器（如 `vi`）来查看文件内容：`vi /etc/hadoop/conf.empty/yarn-site.xml`。检查 `yarn.nodemanager.runtime.linux.docker.ecr-auto-authentication.enabled` 的值。