

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

# 自定义 EMR Serverless 映像
<a name="application-custom-image"></a>

从 Amazon EMR 6.9.0 开始，请使用自定义映像将应用程序依赖项和运行时环境打包到 Amazon EMR Serverless 的单个容器中。这简化了管理工作负载依赖项的方式，并使软件包更具可移植性。自定义 EMR Serverless 映像具有以下优势：
+ 安装并配置针对工作负载优化的软件包。这些软件包无法在 Amazon EMR 运行时环境的公开分发中广泛使用。
+ 将 EMR Serverless 与组织内当前确立的构建、测试和部署流程（包括本地开发和测试）集成。
+ 应用确立的安全流程（如映像扫描），满足组织内的合规性和监管要求。
+ 允许您在应用程序中使用自己的 JDK 和 Python 版本。

EMR Serverless 提供的映像可在您创建自己的映像时作为基础。基础映像提供了映像与 EMR Serverless 交互所需的必要 jar 文件、配置和库。您可以在 [Amazon ECR 公开映像浏览馆](https://gallery.ecr.aws/emr-serverless/)中找到基础映像。使用与您的应用程序类型（Spark 或 Hive）和发行版匹配的映像。例如，如果您在 Amazon EMR 发行版 6.9.0 上创建应用程序，请使用以下映像。


| Type | Image | 
| --- | --- | 
|  Spark  |  `public.ecr.aws/emr-serverless/spark/emr-6.9.0:latest`  | 
|  Hive  |  `public.ecr.aws/emr-serverless/hive/emr-6.9.0:latest`  | 

## 先决条件
<a name="worker-configs"></a>

在创建 EMR Serverless 自定义映像之前，请完成以下先决条件。

1. 创建与启动 EMR 无服务器应用程序相同的 AWS 区域 存储库 Amazon ECR 存储库。要创建 Amazon ECR 私有存储库，请参阅[创建私有存储库](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-create.html)。

1. 要授予用户访问 Amazon ECR 存储库的权限，请向使用该存储库中的映像创建或更新 EMR Serverless 应用程序的用户和角色添加以下策略。

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Sid": "ECRRepositoryListGetPolicy",
         "Effect": "Allow",
         "Action": [
           "ecr:GetDownloadUrlForLayer",
           "ecr:BatchGetImage",
           "ecr:DescribeImages"
         ],
         "Resource": [
           "arn:aws:ecr:*:123456789012:repository/my-repo"
         ]
       }
     ]
   }
   ```

------

   有关 Amazon ECR 基于身份的策略的更多示例，请参阅 [Amazon Elastic Container Registry 基于身份的策略示例](https://docs.aws.amazon.com/AmazonECR/latest/userguide/security_iam_id-based-policy-examples.html)。

## 步骤 1：根据 EMR Serverless 基础映像创建自定义映像
<a name="create-image"></a>

首先，创建一个 [Dockerfile](https://docs.docker.com/engine/reference/builder/)，该文件以 `FROM` 指令开头，要求使用首选基础映像。在 `FROM` 指令之后，包含要对映像进行的任何修改。基础映像会自动将 `USER` 设置为 `hadoop`。此设置不具备您所包含的所有修改的权限。解决方法是，将 `USER` 设置为 `root`，修改映像，然后将 `USER` 重新设置为 `hadoop:hadoop`。要参考常见使用案例的示例，请参阅[在 EMR Serverless 中使用自定义映像](using-custom-images.md)。

```
# Dockerfile
FROM public.ecr.aws/emr-serverless/spark/emr-6.9.0:latest

USER root
# MODIFICATIONS GO HERE

# EMRS runs the image as hadoop
USER hadoop:hadoop
```

创建 Dockerfile 之后，使用以下命令构建映像。

```
# build the docker image
docker build . -t aws-account-id.dkr.ecr.region.amazonaws.com/my-repository[:tag]or[@digest]
```

## 步骤 2：在本地验证映像
<a name="validate"></a>

EMR Serverless 提供了一个离线工具，可静态检查自定义映像，用来验证基本文件、环境变量和正确的映像配置。有关如何安装和运行该工具的信息，请参阅 [Amazon EMR Serverless Image](https://github.com/awslabs/amazon-emr-serverless-image-cli) CLI。 GitHub

安装工具后，运行以下命令验证映像：

```
amazon-emr-serverless-image \
validate-image -r emr-6.9.0 -t spark \
-i aws-account-id.dkr.ecr.region.amazonaws.com/my-repository:tag/@digest
```

输出类似于以下内容。

```
Amazon EMR Serverless - Image CLI
Version: 0.0.1
... Checking if docker cli is installed
... Checking Image Manifest
[INFO] Image ID: 9e2f4359cf5beb466a8a2ed047ab61c9d37786c555655fc122272758f761b41a
[INFO] Created On: 2022-12-02T07:46:42.586249984Z
[INFO] Default User Set to hadoop:hadoop : PASS
[INFO] Working Directory Set to  : PASS
[INFO] Entrypoint Set to /usr/bin/entrypoint.sh : PASS
[INFO] HADOOP_HOME is set with value: /usr/lib/hadoop : PASS
[INFO] HADOOP_LIBEXEC_DIR is set with value: /usr/lib/hadoop/libexec : PASS
[INFO] HADOOP_USER_HOME is set with value: /home/hadoop : PASS
[INFO] HADOOP_YARN_HOME is set with value: /usr/lib/hadoop-yarn : PASS
[INFO] HIVE_HOME is set with value: /usr/lib/hive : PASS
[INFO] JAVA_HOME is set with value: /etc/alternatives/jre : PASS
[INFO] TEZ_HOME is set with value: /usr/lib/tez : PASS
[INFO] YARN_HOME is set with value: /usr/lib/hadoop-yarn : PASS
[INFO] File Structure Test for hadoop-files in /usr/lib/hadoop: PASS
[INFO] File Structure Test for hadoop-jars in /usr/lib/hadoop/lib: PASS
[INFO] File Structure Test for hadoop-yarn-jars in /usr/lib/hadoop-yarn: PASS
[INFO] File Structure Test for hive-bin-files in /usr/bin: PASS
[INFO] File Structure Test for hive-jars in /usr/lib/hive/lib: PASS
[INFO] File Structure Test for java-bin in /etc/alternatives/jre/bin: PASS
[INFO] File Structure Test for tez-jars in /usr/lib/tez: PASS
-----------------------------------------------------------------
Overall Custom Image Validation Succeeded.
-----------------------------------------------------------------
```

## 步骤 3：将映像上传到 Amazon ECR 存储库
<a name="upload-image"></a>

使用以下命令将 Amazon ECR 映像推送到 Amazon ECR 存储库。确保您拥有正确的 IAM 权限，可将映像推送到存储库。有关更多信息，请参阅《Amazon ECR 用户指南》**中的[推送映像](https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-push.html)。

```
# login to ECR repo
aws ecr get-login-password --region region | docker login --username AWS --password-stdin aws-account-id.dkr.ecr.region.amazonaws.com

# push the docker image
docker push aws-account-id.dkr.ecr.region.amazonaws.com/my-repository:tag/@digest
```

## 步骤 4：使用自定义映像创建或更新应用程序
<a name="create-app"></a>

根据您想要的 AWS 管理控制台 应用程序启动方式选择 AWS CLI 选项卡或选项卡，然后完成以下步骤。

------
#### [ Console ]

1. [通过 /emr 登录 EMR Studio 控制台。https://console.aws.amazon.com](https://console.aws.amazon.com/emr)导航到您的应用程序，或按照[创建应用程序](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/studio.html#studio-create-app)中的说明创建新的应用程序。

1. 要在创建或更新 EMR Serverless 应用程序时指定自定义映像，请在应用程序设置选项中选择**自定义设置**。

1. 在**自定义映像设置**部分，选择**在此应用程序中使用自定义映像**复选框。

1. 将 Amazon ECR 映像 URI 粘贴到**映像 URI** 字段。EMR Serverless 会将此映像用于应用程序的所有工作线程类型。或者，您可以选择**不同的自定义图像**，然后 URIs 为每种工作人员类型粘贴不同的 Amazon ECR 图像。

------
#### [ CLI ]
+ 使用 `image-configuration` 参数创建应用程序。EMR Serverless 会将此设置应用于所有工作线程类型。

  ```
  aws emr-serverless create-application \
  --release-label emr-6.9.0 \
  --type SPARK \
  --image-configuration '{
      "imageUri": "aws-account-id.dkr.ecr.region.amazonaws.com/my-repository:tag/@digest"
  }'
  ```

  要为每种工作线程类型创建具有不同映像设置的应用程序，请使用 `worker-type-specifications` 参数。

  ```
  aws emr-serverless create-application \
  --release-label emr-6.9.0 \
  --type SPARK \
  --worker-type-specifications '{
      "Driver": {
          "imageConfiguration": {
              "imageUri": "aws-account-id.dkr.ecr.region.amazonaws.com/my-repository:tag/@digest"
          }
      },
      "Executor" : {
          "imageConfiguration": {
              "imageUri": "aws-account-id.dkr.ecr.region.amazonaws.com/my-repository:tag/@digest"
          }
      }
  }'
  ```

  要更新应用程序，请使用 `image-configuration` 参数。EMR Serverless 会将此设置应用于所有工作线程类型。

  ```
  aws emr-serverless update-application \
  --application-id application-id \
  --image-configuration '{
      "imageUri": "aws-account-id.dkr.ecr.region.amazonaws.com/my-repository:tag/@digest"
  }'
  ```

------

## 步骤 5：允许 EMR Serverless 访问自定义映像存储库
<a name="access-repo"></a>

将以下资源策略添加到 Amazon ECR 存储库，以允许 EMR Serverless 服务主体使用来自该存储库的 `get`、`describe` 和 `download` 请求。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "EmrServerlessCustomImageSupport",
      "Effect": "Allow",
      "Action": [
        "ecr:BatchGetImage",
        "ecr:DescribeImages",
        "ecr:GetDownloadUrlForLayer"
      ],
      "Resource": "arn:aws:ecr:*:123456789012:repository/my-repo",
      "Condition": {
        "ArnLike": {
          "aws:SourceArn": "arn:aws:emr-serverless:*:123456789012:/applications/*"
        }
      }
    }
  ]
}
```

------

最佳安全实践是，将 `aws:SourceArn` 条件键添加到存储库策略。IAM 全局条件键 `aws:SourceArn` 可确保 EMR Serverless 仅将存储库用于应用程序 ARN。有关 Amazon ECR 存储库策略的更多信息，请参阅[创建私有存储库](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policies.html)。

## 注意事项和限制
<a name="considerations"></a>

在使用自定义映像时，请注意以下几点：
+ 使用与应用程序类型（Spark 或 Hive）和发行版标签（例如 `emr-6.9.0`）相匹配的正确基础映像。
+ EMR Serverless 会忽略 Docker 文件中的 `[CMD]` 或 `[ENTRYPOINT]` 指令。使用 Docker 文件中的常用指令，如 `[COPY]`、`[RUN]` 和 `[WORKDIR]`。
+ 创建自定义映像时，请不要修改环境变量 `JAVA_HOME`、`SPARK_HOME`、`HIVE_HOME` 和 `TEZ_HOME`。
+ 自定义图像的大小不能超过 10 GB。
+ 如果修改 Amazon EMR 基础映像中的二进制文件或 jar 文件，这可能会导致应用程序或作业启动失败。
+ Amazon ECR 存储库必须与您用于启动 EMR 无服务器应用程序的存储库相同 AWS 区域 。