セルフホスト型 Jupyter Notebook を使用する - Amazon EMR

セルフホスト型 Jupyter Notebook を使用する

Jupyter または JupyterLab Notebook は、Amazon EC2 インスタンスまたは独自の Amazon EKS クラスターでセルフホスト型 Jupyter Notebook としてホストおよび管理できます。その後、セルフホスト型 Jupyter Notebook でインタラクティブワークロードを実行できます。以下のセクションでは、セルフホスト型 Jupyter Notebook を Amazon EKS クラスターにセットアップしてデプロイするプロセスについて説明します。

セキュリティグループの作成

インタラクティブエンドポイントを作成し、セルフホスト型 Jupyter または JupyterLab ノートブックを実行する前に、ノートブックとインタラクティブエンドポイント間のトラフィックを制御するセキュリティグループを作成する必要があります。Amazon EC2 コンソールまたは Amazon EC2 SDK を使用してセキュリティグループを作成するには、「Amazon EC2 ユーザーガイド」の「セキュリティグループの作成」の手順を参照してください。ノートブックサーバーをデプロイする VPC にセキュリティグループを作成する必要があります。

このガイドの例に従うには、Amazon EKS クラスターと同じ VPC を使用してください。Amazon EKS クラスターの VPC とは異なる VPC でノートブックをホストする場合、これらの 2 つの VPC 間にピアリング接続を作成する必要がある場合があります。2 つの VPC 間にピアリング接続を作成する手順については、「Amazon VPC Getting Started Guide」の「Create a VPC peering connection」を参照してください。

次のステップで EKS での Amazon EMR インタラクティブエンドポイントを作成するには、セキュリティグループの ID が必要です。

EKS での Amazon EMR インタラクティブエンドポイントを作成する

ノートブックのセキュリティグループを作成したら、「仮想クラスターのインタラクティブエンドポイントを作成する」に記載されている手順に従ってインタラクティブエンドポイントを作成します。「セキュリティグループの作成」でノートブック用に作成したセキュリティグループ ID を指定する必要があります。

次の構成オーバーライド設定で、your-notebook-security-group-id の代わりにセキュリティ ID を挿入します。

--configuration-overrides '{ "applicationConfiguration": [ { "classification": "endpoint-configuration", "properties": { "notebook-security-group-id": "your-notebook-security-group-id" } } ], "monitoringConfiguration": { ...'

インタラクティブエンドポイントのゲートウェイサーバー URL を取得する

インタラクティブエンドポイントを作成したら、AWS CLI で describe-managed-endpoint コマンドを使用してゲートウェイサーバーの URL を取得します。この URL は、ノートブックをエンドポイントに接続するために必要です。ゲートウェイサーバー URL はプライベートエンドポイントです。

aws emr-containers describe-managed-endpoint \ --region region \ --virtual-cluster-id virtualClusterId \ --id endpointId

最初、エンドポイントの状態は CREATING です。数分後、ACTIVE 状態に遷移します。エンドポイントが ACTIVE となっていれば、使用準備が完了しています。

serverUrl コマンドがアクティブなエンドポイントから返す aws emr-containers describe-managed-endpoint 属性を書き留めておきます。セルフホスト型 Jupyter または JupyterLab ノートブックをデプロイするときに、ノートブックをエンドポイントに接続するには、この URL が必要です。

認証トークンを取得してインタラクティブエンドポイントに接続します。

Jupyter または JupyterLab ノートブックからインタラクティブエンドポイントに接続するには、GetManagedEndpointSessionCredentials API を使用してセッショントークンを生成する必要があります。このトークンは、インタラクティブエンドポイントサーバーに接続するための認証証明として機能します。

次のコマンドについて、出力例を示してさらに詳しく説明します。

aws emr-containers get-managed-endpoint-session-credentials \ --endpoint-identifier endpointArn \ --virtual-cluster-identifier virtualClusterArn \ --execution-role-arn executionRoleArn \ --credential-type "TOKEN" \ --duration-in-seconds durationInSeconds \ --region region
endpointArn

エンドポイントの ARN。ARN は describe-managed-endpoint 呼び出しの結果で確認できます。

virtualClusterArn

仮想クラスターの ARN。

executionRoleArn

実行ロールの ARN。

durationInSeconds

トークンの有効期間 (秒単位)。デフォルトの有効期間は 15 分 (900) で、最長は 12 時間 (43200) です。

region

エンドポイントと同じリージョン。

出力は次の例のようになります。セルフホスト型 Jupyter または JupyterLab ノートブックをデプロイするときに使用する session-token 値を書き留めておいてください。

{ "id": "credentialsId", "credentials": { "token": "session-token" }, "expiresAt": "2022-07-05T17:49:38Z" }

例: JupyterLab ノートブックをデプロイする

上記のステップを完了したら、このサンプル手順を試して、インタラクティブエンドポイントを使用して JupyterLab ノートブックを Amazon EKS クラスターにデプロイできます。

  1. ノートブックサーバーを実行する名前空間を作成します。

  2. notebook.yaml というファイルを次の内容でローカルに作成します。ファイルの内容は次のとおりです。

    apiVersion: v1 kind: Pod metadata: name: jupyter-notebook namespace: namespace spec: containers: - name: minimal-notebook image: jupyter/all-spark-notebook:lab-3.1.4 # open source image ports: - containerPort: 8888 command: ["start-notebook.sh"] args: ["--LabApp.token=''"] env: - name: JUPYTER_ENABLE_LAB value: "yes" - name: KERNEL_LAUNCH_TIMEOUT value: "400" - name: JUPYTER_GATEWAY_URL value: "serverUrl" - name: JUPYTER_GATEWAY_VALIDATE_CERT value: "false" - name: JUPYTER_GATEWAY_AUTH_TOKEN value: "session-token"

    Jupyter Notebook を Fargate 専用クラスターにデプロイする場合は、次の例のように Jupyter ポッドに role ラベルを付けます。

    ... metadata: name: jupyter-notebook namespace: default labels: role: example-role-name-label spec: ...
    namespace

    ノートブックをデプロイする Kubernetes 名前空間。

    serverUrl

    インタラクティブエンドポイントのゲートウェイサーバー URL を取得する describe-managed-endpoint コマンドが返した serverUrl 属性。

    session-token

    認証トークンを取得してインタラクティブエンドポイントに接続します。get-managed-endpoint-session-credentials コマンドが返した session-token 属性。

    KERNEL_LAUNCH_TIMEOUT

    インタラクティブエンドポイントが、カーネルが RUNNING 状態になるのを待つ時間 (秒単位)。カーネル起動タイムアウトを適切な値 (最大 400 秒) に設定して、カーネルの起動が完了するまで十分な時間を確保します。

    KERNEL_EXTRA_SPARK_OPTS

    オプションで、Spark カーネルに追加の Spark 構成を渡すことができます。以下の例のように、この環境変数に Spark 設定プロパティとして値を設定します。

    - name: KERNEL_EXTRA_SPARK_OPTS value: "--conf spark.driver.cores=2 --conf spark.driver.memory=2G --conf spark.executor.instances=2 --conf spark.executor.cores=2 --conf spark.executor.memory=2G --conf spark.dynamicAllocation.enabled=true --conf spark.dynamicAllocation.shuffleTracking.enabled=true --conf spark.dynamicAllocation.minExecutors=1 --conf spark.dynamicAllocation.maxExecutors=5 --conf spark.dynamicAllocation.initialExecutors=1 "
  3. Amazon EKS クラスターにポッドの仕様をデプロイします。

    kubectl apply -f notebook.yaml -n namespace

    これにより、EKS での Amazon EMR インタラクティブエンドポイントに接続された最小限の JupyterLab ノートブックが起動します。ポッドが RUNNING になるまでお待ちください。次のコマンドを使用して、ポッドのステータスを確認します。

    kubectl get pod jupyter-notebook -n namespace

    ポッドの準備が整うと、get pod コマンドは次のような出力を返します。

    NAME READY STATUS RESTARTS AGE jupyter-notebook 1/1 Running 0 46s
  4. ノートブックセキュリティグループを、ノートブックがスケジュールされているノードにアタッチします。

    1. まず、jupyter-notebook ポッドがスケジュールされているノードを describe pod コマンドで特定します。

      kubectl describe pod jupyter-notebook -n namespace
    2. Amazon EKS コンソール (https://console.aws.amazon.com/eks/home#/clusters) を開きます。

    3. Amazon EKS クラスターの [コンピューティング] タブに移動し、describe pod コマンドで特定したノードを選択します。ノードのインスタンス ID を選択します。

    4. [アクション] メニューから [セキュリティ] > [セキュリティグループを変更] を選択し、セキュリティグループの作成 で作成したセキュリティグループをアタッチします。

    5. AWS Fargate で Jupyter Notebook ポッドをデプロイする場合は、ロールラベルを付けた Jupyter Notebook ポッドに適用する SecurityGroupPolicy を作成します。

      cat >my-security-group-policy.yaml <<EOF apiVersion: vpcresources.k8s.aws/v1beta1 kind: SecurityGroupPolicy metadata: name: example-security-group-policy-name namespace: default spec: podSelector: matchLabels: role: example-role-name-label securityGroups: groupIds: - your-notebook-security-group-id EOF
  5. 次に、ポート転送して JupyterLab インターフェイスにローカルにアクセスできるようにします。

    kubectl port-forward jupyter-notebook 8888:8888 -n namespace

    それが実行したら、ローカルブラウザに移動し、localhost:8888 にアクセスして JupyterLab インターフェイスを確認してください。

    JupyterLab のスタート画面のスクリーンショット。
  6. JupyterLab から、新しい Scala ノートブックを作成します。Pi の値を概算するために実行できるサンプルコードスニペットを次に示します。

    import scala.math.random import org.apache.spark.sql.SparkSession /** Computes an approximation to pi */ val session = SparkSession .builder .appName("Spark Pi") .getOrCreate() val slices = 2 // avoid overflow val n = math.min(100000L * slices, Int.MaxValue).toInt val count = session.sparkContext .parallelize(1 until n, slices) .map { i => val x = random * 2 - 1 val y = random * 2 - 1 if (x*x + y*y <= 1) 1 else 0 }.reduce(_ + _) println(s"Pi is roughly ${4.0 * count / (n - 1)}") session.stop()
    JupyterLab の Scala ノートブックコードの例のスクリーンショット。

セルフホスト型 Jupyter Notebook を削除する

セルフホスト型ノートブックを削除する準備ができたら、インタラクティブエンドポイントとセキュリティグループも削除できます。次の順番でアクションを実行します。

  1. 次のコマンドを使用して、jupyter-notebook ポッドを削除します。

    kubectl delete pod jupyter-notebook -n namespace
  2. 次に、delete-managed-endpoint コマンドを使用してインタラクティブエンドポイントを削除します。インタラクティブエンドポイントを削除する手順については、「インタラクティブエンドポイントを削除する」を参照してください。最初、エンドポイントは TERMINATING 状態になります。すべてのリソースがクリーンアップされると、TERMINATED 状態に移行します。

  3. セキュリティグループの作成 で作成したノートブックセキュリティグループを他の Jupyter Notebook デプロイに使用する予定がない場合は、削除できます。詳細については、「Amazon EC2 User Guide」の「Delete a security group」を参照してください。