🐽

EMR ServerlessをCustom Imageで実行する

2023/03/22に公開

概要

EMR Serverlessの実行環境を自前で作成したdockerイメージに差し替えて、処理を実行する方法をまとめます。

前提

  • ECRにDockerイメージをプッシュし、EMR ServerlessはECRにプッシュしたDokcerイメージをCustomImageとして参照します。
  • Dockerイメージ内にライブラリをインストール他、自前で実装したモジュールをCOPYし、Script locationで指定したファイルから参照できるようにします。
  • ローカル環境のパッケージマネージャーはpoetryを使用します。

ECRの設定

EMRからECRにプッシュしたDockerイメージを参照するため、対象のリポジトリのPermissionを設定する必要があります。

guiから設定する場合、対象のECRを一覧から選択し、アクション(Action)→許可(Permission)を選択します。

ポリシーの編集を選択し、以下のStatementを設定します。
※Conditionの設定で適宜アクセスを許可する EMR Serverless Applicationのarnを設定してください。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Emr Serverless Custom Image Support",
      "Effect": "Allow",
      "Principal": {
        "Service": "emr-serverless.amazonaws.com"
      },
      "Action": [
        "ecr:BatchGetImage",
        "ecr:DescribeImages",
        "ecr:GetDownloadUrlForLayer"
      ]
      "Condition":{
        "StringEquals":{
          "aws:SourceArn": "arn:aws:emr-serverless:region:*******:/applications/test-suzutaku-id"
        }
      }
    }
  ]
}

Dockerファイルの実装

Dockerイメージは公式のイメージをベースにしてカスタマイズします。

以下のURLから、EMR ServerlessのApplicationで指定するRelease versionとArchitectureに合わせてベースイメージを指定します。
https://gallery.ecr.aws/emr-serverless?page=1

デフォルトでインストールされている3系のpythonは3.7と少し古いため、必要に応じてインストールします。

Script locationで実装したモジュールを参照するため、COPYした環境をPYTHONPATHに指定します。

以下を前提としたDockerfileの指定を例として記載します。

  • Release version ・・・ emr-6.9.0
  • Architecture ・・・ arm64
  • Python ・・・ 3.10.10

# Dockerfile
FROM public.ecr.aws/emr-serverless/spark/emr-6.9.0:20221221-arm64 as base

FROM base as build-env
COPY pyproject.toml .
COPY poetry.lock .

RUN pip3 install poetry \
 && /home/hadoop/.local/bin/poetry export --without-hashes --without dev --output requirements.txt

FROM base as runner

USER root
# MODIFICATIONS GO HERE

RUN yum install -y gcc bzip2-devel openssl11 openssl11-devel libffi-devel libssl-dev tar gzip wget make build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev wget
RUN wget https://www.python.org/ftp/python/3.10.10/Python-3.10.10.tgz && \
tar xzf Python-3.10.10.tgz && cd Python-3.10.10 && \
./configure --enable-optimizations && \
make altinstall

COPY ./src ./src
COPY --from=build-env /home/hadoop/requirements.txt .
ENV PYTHONPATH /home/hadoop

RUN pip3.10 install -r requirements.txt

# EMRS will run the image as hadoop
USER hadoop:hadoop

EMR Serverlessの設定

EMR ServerlessのApplicationでCustomImageを指定します。

CustomImageの設定はオプションのため、Application setup optionsをChoose default settingsからChoose custom settingsに変更します。

Custom image settingsを開き、Use the custom image with this applicationを選択状態にして、表示されるImage URI for both Spark drivers and executorsにECRのリポジトリとバージョンを指定します。

Pythonのバージョンを独自でCustomImageにインストールした場合、Jobでpythonの実行コマンドを切り替えてやる必要があります。

Spark propertiesで以下の3つにそれぞれDockerイメージ上のpythonの実行コマンドを指定してください。

  • spark.emr-serverless.driverEnv.PYSPARK_DRIVER_PYTHON
  • serverless.driverEnv.PYSPARK_PYTHON
  • spark.executorEnv.PYSPARK_PYTHON

前述のDockerfileでインストールした3.10.10のpythonを参照する場合は以下のように設定します。

--conf spark.emr-serverless.driverEnv.PYSPARK_DRIVER_PYTHON=/usr/local/bin/python3.10
--conf spark.emr-serverless.driverEnv.PYSPARK_PYTHON=/usr/local/bin/python3.10
--conf spark.executorEnv.PYSPARK_PYTHON=/usr/local/bin/python3.10

まとめ

EMR ServerlessでCustomImageを使用する方法についてまとめました。
気が向いたらterraformの定義のテンプレートなどをgithubで公開しようと思います。

Discussion