Amazon EMR 6.x を使用して Docker で Spark アプリケーションを実行する - Amazon EMR

Amazon EMR 6.x を使用して Docker で Spark アプリケーションを実行する

Amazon EMR 6.0.0 では、Spark アプリケーションで Docker コンテナを使用してライブラリの依存関係を定義できます。クラスター内の各 Amazon EC2 インスタンスに依存関係をインストールする必要はありません。Docker で Spark を実行するには、まず Docker レジストリを設定し、Spark アプリケーションの送信時に追加のパラメータを定義する必要があります。詳細については、「Docker 統合の設定」を参照してください。

アプリケーションが送信されると、YARN は Docker を呼び出して指定された Docker イメージをプルし、Docker コンテナ内で Spark アプリケーションを実行します。これにより、依存関係を簡単に定義して分離できます。結果として、ジョブ実行に必要なライブラリを使用して Amazon EMR クラスター内のインスタンスをブートストラップまたは準備する時間が短縮されます。

Docker で Spark を実行する際の考慮事項

Docker で Spark を実行するときは、次の前提条件を満たす必要があります。

  • docker パッケージと CLI は、コアノードとタスクノードにのみインストールします。

  • Amazon EMR 6.1.0 以降では、次のコマンドを使用してプライマリノードに Docker をインストールすることもできます。

    • sudo yum install -y docker sudo systemctl start docker
  • spark-submit コマンドは、常に Amazon EMR クラスターのプライマリインスタンスから実行します。

  • Docker イメージの解決に使用する Docker レジストリは、分類 API を使用して定義する必要があります。クラスターの起動時に container-executor 分類キーを使用して追加のパラメータを定義します。

    • docker.trusted.registries

    • docker.privileged-containers.registries

  • Docker コンテナで Spark アプリケーションを実行するには、次の設定オプションが必要です。

    • YARN_CONTAINER_RUNTIME_TYPE=docker

    • YARN_CONTAINER_RUNTIME_DOCKER_IMAGE={DOCKER_IMAGE_NAME}

  • Amazon ECR を使用して Docker イメージを取得する場合は、クラスター自体を認証するようにクラスターを設定する必要があります。そのためには、次の設定オプションを使用します。

    • YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG={DOCKER_CLIENT_CONFIG_PATH_ON_HDFS}

  • EMR 6.1.0 以降では、ECR 自動認証機能が有効になっている場合、リストされているコマンド YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG={DOCKER_CLIENT_CONFIG_PATH_ON_HDFS} を使用する必要はありません。

  • Spark で Docker イメージを使用する場合、Docker イメージに Java をインストールする必要があります。

前提条件の詳細については、「Docker 統合の設定」を参照してください。

Docker イメージの作成

Docker イメージを作成するには Dockerfile を使用します。このファイルは、イメージに含めるパッケージと設定を定義します。次に示す 2 つの Dockerfile の例では、PySpark と SparkR を使用しています。

PySpark Dockerfile

この Dockerfile から作成した Docker イメージには、Python 3 と NumPy Python パッケージが含まれます。この Dockerfile では、Amazon Linux 2 と Amazon Corretto JDK 8 を使用します。

FROM amazoncorretto:8 RUN yum -y update RUN yum -y install yum-utils RUN yum -y groupinstall development RUN yum list python3* RUN yum -y install python3 python3-dev python3-pip python3-virtualenv RUN python -V RUN python3 -V ENV PYSPARK_DRIVER_PYTHON python3 ENV PYSPARK_PYTHON python3 RUN pip3 install --upgrade pip RUN pip3 install numpy pandas RUN python3 -c "import numpy as np"

SparkR Dockerfile

この Dockerfile から作成した Docker イメージには、R と randomForest CRAN パッケージが含まれます。この Dockerfile には、Amazon Linux 2 と Amazon Corretto JDK 8 が含まれます。

FROM amazoncorretto:8 RUN java -version RUN yum -y update RUN amazon-linux-extras install R4 RUN yum -y install curl hostname #setup R configs RUN echo "r <- getOption('repos'); r['CRAN'] <- 'http://cran.us.r-project.org'; options(repos = r);" > ~/.Rprofile RUN Rscript -e "install.packages('randomForest')"

Dockerfile の構文の詳細については、Dockerfile リファレンスのドキュメントを参照してください。

Amazon ECR の Docker イメージを使用する

Amazon Elastic Container Registry (Amazon ECR) は、フルマネージド型の Docker コンテナレジストリであり、Docker コンテナイメージの保存、管理、デプロイを容易に行うことができます。Amazon ECR を使用する場合は、ECR のインスタンスを信頼するようにクラスターを設定する必要があります。また、クラスターが Amazon ECR の Docker イメージを使用するように認証を設定する必要があります。詳細については、「Amazon ECR にアクセスするための YARN の設定」を参照してください。

Amazon ECR に保存されているイメージに EMR ホストがアクセスできるようにするには、インスタンスプロファイルに関連付けられた AmazonEC2ContainerRegistryReadOnly ポリシーからのアクセス許可がクラスターに必要です。詳細については、「AmazonEC2ContainerRegistryReadOnly ポリシー」を参照してください。

この例では、Amazon ECR レジストリが信頼されるように、次の追加設定を使用してクラスターを作成する必要があります。123456789123.dkr.ecr.us-east-1.amazonaws.com エンドポイントを、実際の Amazon ECR エンドポイントに置き換えます。

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

Amazon ECR での PySpark の使用

次の例では PySpark Dockerfile を使用します。このファイルは、タグ付けされて Amazon ECR にアップロードされます。Dockerfile がアップロードされたら、PySpark ジョブを実行し、Amazon ECR の Docker イメージを参照できます。

クラスターを起動したら、SSH を使用してコアノードに接続し、次のコマンドを実行して PySpark Dockerfile の例からローカル Docker イメージを構築します。

まず、ディレクトリと Dockerfile を作成します。

mkdir pyspark vi pyspark/Dockerfile

PySpark Dockerfile の内容を貼り付け、次のコマンドを実行して Docker イメージを構築します。

sudo docker build -t local/pyspark-example pyspark/

例の emr-docker-examples ECR リポジトリを作成します。

aws ecr create-repository --repository-name emr-docker-examples

ローカルに構築したイメージにタグを付けて ECR にアップロードし、123456789123.dkr.ecr.us-east-1.amazonaws.com を実際の ECR エンドポイントに置き換えます。

sudo docker tag local/pyspark-example 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example sudo docker push 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example

SSH を使用してプライマリノードに接続し、main.py というファイル名で Python スクリプトを準備します。次の内容を main.py ファイルに貼り付け、保存します。

from pyspark.sql import SparkSession spark = SparkSession.builder.appName("docker-numpy").getOrCreate() sc = spark.sparkContext import numpy as np a = np.arange(15).reshape(3, 5) print(a)

EMR 6.0.0 でジョブを送信するには、Docker イメージの名前を参照します。追加の設定パラメータを定義して、ジョブの実行で必ず Docker がランタイムとして使用されるようにします。Amazon ECR を使用する場合、YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG は Amazon ECR への認証に使用する認証情報が含まれている config.json ファイルを参照する必要があります。

DOCKER_IMAGE_NAME=123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example DOCKER_CLIENT_CONFIG=hdfs:///user/hadoop/config.json spark-submit --master yarn \ --deploy-mode cluster \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG=$DOCKER_CLIENT_CONFIG \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG=$DOCKER_CLIENT_CONFIG \ --num-executors 2 \ main.py -v

EMR 6.1.0 以降でジョブを送信するには、Docker イメージの名前を参照します。ECR 自動認証が有効になっている場合は、次のコマンドを実行します。

DOCKER_IMAGE_NAME=123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:pyspark-example spark-submit --master yarn \ --deploy-mode cluster \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \ --num-executors 2 \ main.py -v

ジョブが完了したら、YARN アプリケーション ID を書き留め、次のコマンドを使用して PySpark ジョブの出力を取得します。

yarn logs --applicationId application_id | grep -C2 '\[\[' LogLength:55 LogContents: [[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14]]

Amazon ECR での SparkR の使用

次の例では、SparkR Dockerfile にタグを付けて ECR にアップロードします。Dockerfile をアップロードすると、SparkR ジョブを実行し、Amazon ECR の Docker イメージを参照できます。

クラスターを起動したら、SSH を使用してコアノードに接続し、次のコマンドを実行して SparkR Dockerfile の例からローカル Docker イメージを構築します。

まず、ディレクトリと Dockerfile を作成します。

mkdir sparkr vi sparkr/Dockerfile

SparkR Dockerfile の内容を貼り付け、次のコマンドを実行して Docker イメージを構築します。

sudo docker build -t local/sparkr-example sparkr/

ローカルに構築したイメージにタグを付けて Amazon ECR にアップロードし、123456789123.dkr.ecr.us-east-1.amazonaws.com を実際の Amazon ECR エンドポイントに置き換えます。

sudo docker tag local/sparkr-example 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example sudo docker push 123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example

SSH を使用してプライマリノードに接続し、sparkR.R というファイル名で R スクリプトを準備します。sparkR.R ファイルに次の内容を貼り付けます。

library(SparkR) sparkR.session(appName = "R with Spark example", sparkConfig = list(spark.some.config.option = "some-value")) sqlContext <- sparkRSQL.init(spark.sparkContext) library(randomForest) # check release notes of randomForest rfNews() sparkR.session.stop()

EMR 6.0.0 でジョブを送信するには、Docker イメージの名前を参照します。追加の設定パラメータを定義して、ジョブの実行で必ず Docker がランタイムとして使用されるようにします。Amazon ECR を使用する場合、YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG は ECR への認証に使用する認証情報が含まれている config.json ファイルを参照する必要があります。

DOCKER_IMAGE_NAME=123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example DOCKER_CLIENT_CONFIG=hdfs:///user/hadoop/config.json spark-submit --master yarn \ --deploy-mode cluster \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG=$DOCKER_CLIENT_CONFIG \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_CLIENT_CONFIG=$DOCKER_CLIENT_CONFIG \ sparkR.R

EMR 6.1.0 以降でジョブを送信するには、Docker イメージの名前を参照します。ECR 自動認証が有効になっている場合は、次のコマンドを実行します。

DOCKER_IMAGE_NAME=123456789123.dkr.ecr.us-east-1.amazonaws.com/emr-docker-examples:sparkr-example spark-submit --master yarn \ --deploy-mode cluster \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \ --conf spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_TYPE=docker \ --conf spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=$DOCKER_IMAGE_NAME \ sparkR.R

ジョブが完了したら、YARN アプリケーション ID を書き留め、次のコマンドを使用して SparkR ジョブの出力を取得します。次の例では、randomForest ライブラリ、インストールされているバージョン、およびリリースノートが利用可能であることを確認するためのテストを含めています。

yarn logs --applicationId application_id | grep -B4 -A10 "Type rfNews" randomForest 4.6-14 Type rfNews() to see new features/changes/bug fixes. Wishlist (formerly TODO): * Implement the new scheme of handling classwt in classification. * Use more compact storage of proximity matrix. * Allow case weights by using the weights in sampling? ======================================================================== Changes in 4.6-14: