

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 如何自訂 Docker 映像檔
<a name="docker-custom-images-steps"></a>

請依照下列步驟來自訂 Amazon EMR on EKS 的 Docker 映像。這些步驟說明如何取得基礎映像、自訂和發佈映像，以及使用映像提交工作負載。
+ [先決條件](#docker-custom-images-prereq)
+ [步驟 1：從 Amazon Elastic Container Registry (Amazon ECR) 中擷取基礎映像](#docker-custom-images-retrieve)
+ [步驟 2：自訂基礎映像](#docker-custom-images-customize)
+ [步驟 3：(選用但不推薦) 驗證自訂映像](#docker-custom-images-validate)
+ [步驟 4：發布自訂映像](#docker-custom-images-publish)
+ [步驟 5：使用自訂映像在 Amazon EMR 中提交 Spark 工作負載](#docker-custom-images-submit)

**注意**  
自訂 Docker 映像時，您可能想要考慮的其他選項是針對互動式端點進行自訂，這是為了確保您擁有所需的相依性，或使用多架構容器映像：  
[為互動端點自訂 Docker 映像檔](docker-custom-images-managed-endpoint.md)
[使用多架構映像](docker-custom-images-multi-architecture.md)

## 先決條件
<a name="docker-custom-images-prereq"></a>
+ 完成 Amazon EMR on EKS 的 [設定 Amazon EMR on EKS](setting-up.md) 步驟。
+ 在您的環境中安裝 Docker。如需詳細資訊，請參閱[獲取 Docker](https://docs.docker.com/get-docker/)。

## 步驟 1：從 Amazon Elastic Container Registry (Amazon ECR) 中擷取基礎映像
<a name="docker-custom-images-retrieve"></a>

基礎映像包含 Amazon EMR 執行期和用於存取其他 AWS 服務的連接器。對於 Amazon EMR 6.9.0 及更高版本，您可從 Amazon ECR 公共映像庫中獲取基礎映像。瀏覽圖庫以尋找映像連結，然後將映像拉到本地工作區。例如，對於 Amazon EMR 7.12.0 版本，以下`docker pull`命令會取得最新的標準基礎映像。您可以將 `emr-7.12.0:latest` 取代為 `emr-7.12.0-spark-rapids:latest`，以擷取具有 Nvidia RAPIDS Accelerator 的映像。也可以將 `emr-7.12.0:latest` 取代為 `emr-7.12.0-java11:latest`，以使用 Java 11 執行期來擷取映像。

```
docker pull public.ecr.aws/emr-on-eks/spark/emr-7.12.0:latest
```

如果想要擷取 Amazon EMR 6.9.0 或更早版本的基礎映像，或者想要從每個區域的 Amazon ECR 登錄檔帳戶中擷取，請使用下列步驟：

1. 選擇基礎映像 URI。映像 URI 遵循此格式，`ECR-registry-account.dkr.ecr.Region.amazonaws.com/spark/container-image-tag`，如下列範例所示。

   ```
   895885662937.dkr.ecr.us-west-2.amazonaws.com/spark/emr-6.6.0:latest
   ```

   若要在您的區域中選擇基礎映像，請參閱 [選取基礎映像 URI 的詳細資訊](docker-custom-images-tag.md)。

1. 登入儲存基礎映像的 Amazon ECR 儲存庫。將 *895885662937* 和 *us-west-2* 取代為您選取的 Amazon ECR 登錄帳戶和 AWS 區域。

   ```
   aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin 895885662937.dkr.ecr.us-west-2.amazonaws.com
   ```

1. 將基礎映像拉入本機工作區。將 *emr-6.6.0:latest* 取代為您選取的容器映像標籤。

   ```
   docker pull 895885662937.dkr.ecr.us-west-2.amazonaws.com/spark/emr-6.6.0:latest
   ```

## 步驟 2：自訂基礎映像
<a name="docker-custom-images-customize"></a>

請依照下列步驟來自訂您從 Amazon ECR 提取的基礎映像。

1. 在您的本機工作區建立新的 `Dockerfile`。

1. 編輯您剛建立的 `Dockerfile`，並新增下列內容。此 `Dockerfile` 使用您從 `895885662937.dkr.ecr.us-west-2.amazonaws.com/spark/emr-6.6.0:latest` 中提取的容器映像。

   ```
   FROM 895885662937.dkr.ecr.us-west-2.amazonaws.com/spark/emr-6.6.0:latest
   USER root
   ### Add customization commands here ####
   USER hadoop:hadoop
   ```

1. 在 `Dockerfile` 中新增命令以自訂基礎映像。例如，新增一個命令來安裝 Python 程式庫，如以下 `Dockerfile` 所示。

   ```
   FROM 895885662937.dkr.ecr.us-west-2.amazonaws.com/spark/emr-6.6.0:latest
   USER root
   RUN pip3 install --upgrade boto3 pandas numpy // For python 3
   USER hadoop:hadoop
   ```

1. 從建立 `Dockerfile` 所在的相同目錄中，執行下列命令以建置 Docker 映像檔。提供 Docker 映像檔的名稱，例如 *emr6.6\$1custom*。

   ```
   docker build -t emr6.6_custom .
   ```

## 步驟 3：(選用但不推薦) 驗證自訂映像
<a name="docker-custom-images-validate"></a>

建議您在發布自訂映像之前先測試它的相容性。您可以使用 [Amazon EMR on EKS 自訂映像檔 CLI](https://github.com/awslabs/amazon-emr-on-eks-custom-image-cli) 來檢查映像是否具有必要的檔案結構和正確的組態，以便在 Amazon EMR on EKS 上執行。

**注意**  
Amazon EMR on EKS 自訂映像 CLI 無法確認您的映像是否沒有錯誤。從基礎映像中移除相依性時，請小心謹慎。

採取下列步驟來驗證自訂映像。

1. 下載並安裝 Amazon EMR on EKS 自訂映像 CLI。如需詳細資訊，請參閱 [Amazon EMR on EKS 自訂映像 CLI 安裝指南](https://github.com/awslabs/amazon-emr-on-eks-custom-image-cli/blob/main/installer/assets/INSTALLATION_GUIDE.md)。

1. 執行下列命令以測試安裝。

   ```
   emr-on-eks-custom-image --version
   ```

   以下顯示輸出範例。

   ```
   Amazon EMR on EKS Custom Image CLI
   Version: x.xx
   ```

1. 執行以下命令來驗證自訂映像。

   ```
   emr-on-eks-custom-image validate-image -i image_name -r release_version [-t image_type]
   ```
   + `-i` 指定需要驗證的本機映像 URI。這可以是映像 URI、您為映像定義的任何名稱或標記。
   + `-r` 指定基礎映像的確切發行版本，例如，`emr-6.6.0-latest`。
   + `-t` 指定映像類型。如果為 Spark 映像，請輸入 `spark`。預設值為 `spark`。目前的 Amazon EMR on EKS 自訂映像 CLI 版本僅支援 Spark 執行期映像。

   如果成功執行命令，且自訂映像符合所有必要的組態和檔案結構，則傳回的輸出會顯示所有測試結果，如下列範例所示。

   ```
   Amazon EMR on EKS Custom Image Test
   Version: x.xx
   ... Checking if docker cli is installed
   ... Checking Image Manifest
   [INFO] Image ID: xxx
   [INFO] Created On: 2021-05-17T20:50:07.986662904Z
   [INFO] Default User Set to hadoop:hadoop : PASS
   [INFO] Working Directory Set to /home/hadoop : PASS
   [INFO] Entrypoint Set to /usr/bin/entrypoint.sh : PASS
   [INFO] SPARK_HOME is set with value: /usr/lib/spark : PASS
   [INFO] JAVA_HOME is set with value: /etc/alternatives/jre : PASS
   [INFO] File Structure Test for spark-jars in /usr/lib/spark/jars: 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 bin-files in /usr/bin: PASS
   ... Start Running Sample Spark Job
   [INFO] Sample Spark Job Test with local:///usr/lib/spark/examples/jars/spark-examples.jar : PASS
   -----------------------------------------------------------------
   Overall Custom Image Validation Succeeded.
   -----------------------------------------------------------------
   ```

   如果自訂映像不符合所需的組態或檔案結構，就會出現錯誤訊息。傳回的輸出會提供有關不正確組態或檔案結構的相關資訊。

## 步驟 4：發布自訂映像
<a name="docker-custom-images-publish"></a>

將新的 Docker 映像檔發布至 Amazon ECR 登錄檔。

1. 執行下列命令以建立用於存放 Docker 映像檔的 Amazon ECR 儲存庫。*為您的儲存庫提供名稱，例如 emr6.6\$1custom\$1repo*。將 *us-west-2* 取代為您的區域。

   ```
   aws ecr create-repository \
       --repository-name emr6.6_custom_repo \
       --image-scanning-configuration scanOnPush=true \
       --region us-west-2
   ```

   如需詳細資訊，請參閱《Amazon ECR 使用者指南》**中的[建立儲存庫](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html#cli-create-repository)。

1. 執行下列命令以驗證預設登錄檔。

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

   如需詳細資訊，請參閱《Amazon ECR 使用者指南》**中的[驗證預設登錄檔](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html#cli-authenticate-registry)。

1. 標記映像並將其發布至您建立的 Amazon ECR 儲存庫。

   標記映像。

   ```
   docker tag emr6.6_custom aws_account_id.dkr.ecr.us-west-2.amazonaws.com/emr6.6_custom_repo
   ```

   推送映像。

   ```
   docker push aws_account_id.dkr.ecr.us-west-2.amazonaws.com/emr6.6_custom_repo
   ```

   如需詳細資訊，請參閱《Amazon ECR 使用者指南》**中的[將映像推送至 Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html#cli-push-image)。

## 步驟 5：使用自訂映像在 Amazon EMR 中提交 Spark 工作負載
<a name="docker-custom-images-submit"></a>

建立並發布自訂映像後，可以使用自訂映像來提交 Amazon EMR on EKS 作業。

首先，建立 start-job-run-request.json 檔案，並指定 `spark.kubernetes.container.image` 參數來參考自訂映像，如下面的 JSON 檔案範例所示。

**注意**  
可以使用 `local://` 結構描述來參考自訂映像中的可用檔案，如下面的 JSON 程式碼片段中的 `entryPoint` 引數所示。也可以使用 `local://` 結構描述來參考應用程式相依性。使用 `local://` 結構描述所參考的所有檔案和相依性必須已存在於自訂映像的指定路徑中。

```
{
    "name": "spark-custom-image", 
    "virtualClusterId": "virtual-cluster-id", 
    "executionRoleArn": "execution-role-arn", 
    "releaseLabel": "emr-6.6.0-latest", 
    "jobDriver": {
      "sparkSubmitJobDriver": {
        "entryPoint": "local:///usr/lib/spark/examples/jars/spark-examples.jar", 
        "entryPointArguments": [
                  "10"
              ],
         "sparkSubmitParameters": "--class org.apache.spark.examples.SparkPi --conf spark.kubernetes.container.image=123456789012.dkr.ecr.us-west-2.amazonaws.com/emr6.6_custom_repo"
       }
    }
}
```

也可以參考具有 `applicationConfiguration` 屬性的自訂映像，如下列範例所示。

```
{
    "name": "spark-custom-image", 
    "virtualClusterId": "virtual-cluster-id", 
    "executionRoleArn": "execution-role-arn", 
    "releaseLabel": "emr-6.6.0-latest", 
    "jobDriver": {
      "sparkSubmitJobDriver": {
        "entryPoint": "local:///usr/lib/spark/examples/jars/spark-examples.jar", 
        "entryPointArguments": [
                  "10"
              ],
         "sparkSubmitParameters": "--class org.apache.spark.examples.SparkPi"
       }
    },
    "configurationOverrides": {
        "applicationConfiguration": [
            {
                "classification": "spark-defaults",
                "properties": {
                    "spark.kubernetes.container.image": "123456789012.dkr.ecr.us-west-2.amazonaws.com/emr6.6_custom_repo"
                }
            }
        ]
    }
}
```

然後執行 `start-job-run` 命令以提交作業。

```
aws emr-containers start-job-run --cli-input-json file://./start-job-run-request.json
```

在上面的 JSON 範例中，請將 *emr-6.6.0-latest* 取代為您的 Amazon EMR 發行版本。強烈建議您使用 `-latest` 發行版本，以確保選取的版本包含最新安全更新。如需有關 Amazon EMR 發行版本和其映像標籤的詳細資訊，請參閱 [選取基礎映像 URI 的詳細資訊](docker-custom-images-tag.md)。

**注意**  
可以使用 `spark.kubernetes.driver.container.image` 和 `spark.kubernetes.executor.container.image` 為驅動程式和執行程式 Pod 指定不同的映像。