追加のカーネルとライブラリをインストールする - Amazon EMR

追加のカーネルとライブラリをインストールする

Amazon EMR で JupyterHub を使用してクラスターを作成すると、Jupyter のデフォルト Python 3 カーネルが、PySpark、Spark カーネル (Sparkmagic 用) と共に Docker コンテナにインストールされます。追加のカーネルをインストールできます。追加のライブラリやパッケージをインストールしてから、適切なシェルにインポートすることもできます。

カーネルをインストールする

カーネルは Docker コンテナ内にインストールされます。これを簡単に行うには、インストールコマンドを使用して bash スクリプトを作成し、マスターノードに保存してから sudo docker exec jupyterhub script_name コマンドで jupyterhub コンテナ内にあるスクリプトを実行します。次の例のスクリプトはカーネルをインストールし、マスターノードでカーネルのライブラリをいくつかインストールすることで、後から Jupyter を使用してライブラリをインポートできるようにします。

#!/bin/bash # Install Python 2 kernel conda create -n py27 python=2.7 anaconda source /opt/conda/envs/py27/bin/activate apt-get update apt-get install -y gcc /opt/conda/envs/py27/bin/python -m pip install --upgrade ipykernel /opt/conda/envs/py27/bin/python -m ipykernel install # Install libraries for Python 2 /opt/conda/envs/py27/bin/pip install paramiko nltk scipy numpy scikit-learn pandas

コンテナ内でカーネルとライブラリをインストールするにはマスターノードへの接続を開き、スクリプトを /etc/jupyter/install_kernels.sh に保存してマスターノードのコマンドラインで次のコマンドを実行します。

sudo docker exec jupyterhub bash /etc/jupyter/install_kernels.sh

ライブラリの使用と追加ライブラリのインストール

Python 3 の機械学習とデータサイエンスライブラリのコアセットは、Amazon EMR の JupyterHub にあらかじめインストールされています。sudo docker exec jupyterhub bash -c "conda list" sudo docker exec jupyterhub bash -c "pip freeze" を使用できます。

Spark ジョブがワーカーノードでライブラリを必要とする場合は、ブートストラップアクションを使用してクラスターの作成時にライブラリをインストールし、スクリプトを実行することを推奨します。ブートストラップアクションは、クラスターの作成時にすべてのクラスターノードで実行され、インストールプロセスが簡素化されます。クラスターを実行してから、コアまたはワーカーノードにライブラリをインストールするとオペレーションが複雑になります。このセクションの Python プログラムの例では、こうしたライブラリのインストール方法を示しています。

このセクションの例のブートストラップアクションと Python プログラムは、Amazon S3 に保存している bash スクリプトを使用してすべてのノードにライブラリをインストールします。

次の例で参照されているスクリプトは、pip を使用して paramiko、nltk、scipy、scikit-learn、pandas (Python 3 カーネル用) をインストールします。

#!/bin/bash sudo python3 -m pip install boto3 paramiko nltk scipy scikit-learn pandas

スクリプトを作成したら、Amazon S3 の場所にアップロードします (例: s3://mybucket/install-my-jupyter-libraries.sh)。ブートストラップアクションまたは Python プログラムで使用できるようにするには、Amazon Simple Storage Service User GuideオブジェクトのUploadingで詳細を確認してください。

AWS CLI を使用してクラスターを作成する場合にすべてのノードでライブラリをインストールするためのブートストラップアクションを指定する
  1. 前の例のようなスクリプトを作成し、Amazon S3 の場所に保存します。s3://mybucket/install-my-jupyter-libraries.sh の例を使用します。

  2. JupyterHub でクラスターを作成し、Path の引数 (--bootstrap-actions オプション) を使用して、次の例で表示されているようにスクリプトの場所を指定します。

    注記

    読みやすくするために、Linux 行連続文字 (\) が含まれています。Linux コマンドでは、これらは削除することも、使用することもできます。Windows の場合、削除するか、キャレット (^) に置き換えてください。

    aws emr create-cluster --name="MyJupyterHubCluster" --release-label emr-5.36.1 \ --applications Name=JupyterHub --log-uri s3://MyBucket/MyJupyterClusterLogs \ --use-default-roles --instance-type m5.xlarge --instance-count 2 --ec2-attributes KeyName=MyKeyPair \ --bootstrap-actions Path=s3://mybucket/install-my-jupyter-libraries.sh,Name=InstallJupyterLibs
コンソールを使用してクラスターを作成する場合にすべてのノードでライブラリをインストールするためのブートストラップアクションを指定するには
  1. 新しい Amazon EMR コンソールに移動し、サイドナビゲーションから [古いコンソールに切り替え] を選択します。古いコンソールに切り替えたときの動作の詳細については、「Using the old console」を参照してください。

  2. [Create cluster (クラスターの作成)]、[Go to advanced options (詳細オプションに移動する)] の順に選択します。

  3. アプリケーションの必要に応じて [Software and Steps (ソフトウェアとステップ)] および [Hardware (ハードウェア)] の設定を指定します。

  4. [General Cluster Settings ( (クラスターの全般設定))] 画面で、[Bootstrap Actions (ブートストラップアクション)] を選択します。

  5. [Add bootstrap action (ブートストラップアクションの追加)] で [Custom action (カスタムアクション)]、[Configure and add (設定と追加)] の順に選択します。

  6. [Name] (名前) で、わかりやすい名前を入力します。[Script location] (スクリプトの場所) にスクリプトの Amazon S3 の場所を入力します (この例では、s3://mybucket/install-my-jupyter-libraries.sh を使用)。[Optional arguments (オプションの引数)] は空白のままにして、[Add (追加)] を選択します。

  7. クラスターのその他の設定を指定し、[Next (次へ)] を選択します。

  8. セキュリティ設定を指定し、[Create cluster (クラスターの作成)] を選択します。

例 実行中のクラスターのコアノードにライブラリをインストールする

Jupyter 内からマスターノードでライブラリのインストールを完了すると、実行中のコアノードでライブラリをさまざまな方法でインストールできます。次の例は、ローカルマシンで実行するように書き込まれた Python プログラムを示しています。Python プログラムをローカルで実行すると、AWS Systems Manager の AWS-RunShellScript を使用してサンプルスクリプトを実行します。これは、このセクションですでに表示したクラスターのコアノードでライブラリをインストールするスクリプトです。

import argparse import time import boto3 def install_libraries_on_core_nodes(cluster_id, script_path, emr_client, ssm_client): """ Copies and runs a shell script on the core nodes in the cluster. :param cluster_id: The ID of the cluster. :param script_path: The path to the script, typically an Amazon S3 object URL. :param emr_client: The Boto3 Amazon EMR client. :param ssm_client: The Boto3 AWS Systems Manager client. """ core_nodes = emr_client.list_instances( ClusterId=cluster_id, InstanceGroupTypes=["CORE"] )["Instances"] core_instance_ids = [node["Ec2InstanceId"] for node in core_nodes] print(f"Found core instances: {core_instance_ids}.") commands = [ # Copy the shell script from Amazon S3 to each node instance. f"aws s3 cp {script_path} /home/hadoop", # Run the shell script to install libraries on each node instance. "bash /home/hadoop/install_libraries.sh", ] for command in commands: print(f"Sending '{command}' to core instances...") command_id = ssm_client.send_command( InstanceIds=core_instance_ids, DocumentName="AWS-RunShellScript", Parameters={"commands": [command]}, TimeoutSeconds=3600, )["Command"]["CommandId"] while True: # Verify the previous step succeeded before running the next step. cmd_result = ssm_client.list_commands(CommandId=command_id)["Commands"][0] if cmd_result["StatusDetails"] == "Success": print(f"Command succeeded.") break elif cmd_result["StatusDetails"] in ["Pending", "InProgress"]: print(f"Command status is {cmd_result['StatusDetails']}, waiting...") time.sleep(10) else: print(f"Command status is {cmd_result['StatusDetails']}, quitting.") raise RuntimeError( f"Command {command} failed to run. " f"Details: {cmd_result['StatusDetails']}" ) def main(): parser = argparse.ArgumentParser() parser.add_argument("cluster_id", help="The ID of the cluster.") parser.add_argument("script_path", help="The path to the script in Amazon S3.") args = parser.parse_args() emr_client = boto3.client("emr") ssm_client = boto3.client("ssm") install_libraries_on_core_nodes( args.cluster_id, args.script_path, emr_client, ssm_client ) if __name__ == "__main__": main()