使用自托管式 Jupyter notebook - Amazon EMR

使用自托管式 Jupyter notebook

您可以在 Amazon EC2 实例或您自己的 Amazon EKS 集群上托管和管理 Jupyter 或 JupyterLab notebook 作为自托管式 Jupyter notebook。然后,您可以使用自托管式 Jupyter notebook 运行交互式工作负载。以下各节介绍在 Amazon EKS 集群上设置和部署自托管式 Jupyter notebook 的过程。

创建安全组

在创建交互式端点并运行自托管式 Jupyter 或 JupyterLab notebook 之前,必须创建安全组来控制 Notebook 和交互式端点之间的流量。要使用 Amazon EC2 控制台或 Amazon EC2 SDK 创建安全组,请参阅《Amazon EC2 用户指南》创建安全组的步骤。您应该在要部署 Notebook 服务器的 VPC 中创建安全组。

要按照本指南中的示例进行操作,请使用与 Amazon EKS 集群相同的 VPC。如果您想在与 Amazon EKS 集群 的 VPC 不同的 VPC 中托管 Notebook,则可能需要在这两个 VPC 之间创建对等连接。有关在两个 VPC 之间创建对等连接的步骤,请参阅《Amazon VPC 入门指南》中的创建 VPC 对等连接

您需要安全组的 ID 才能在下一步中创建 Amazon EMR on EKS 交互式端点

创建 Amazon EMR on EKS 交互式端点

为 Notebook 创建安全组后,使用 为虚拟集群创建交互式端点 中的步骤创建交互式端点。您必须提供在 创建安全组 中为 Notebook 创建的安全组 ID。

在以下配置覆盖设置中插入安全 ID 来代替 your-notebook-security-group-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 才能将 Notebook 连接到端点。网关服务器 URL 是私有端点。

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

最初,您的端点处于 CREATING 状态。几分钟后,它会转换到 ACTIVE 状态。端点的状态为 ACTIVE 时即可使用。

记下 aws emr-containers describe-managed-endpoint 命令从活动端点返回的 serverUrl 属性。在部署自托管式 Jupyter 或 JupyterLab notebook 时,需要此 URL 才能将 Notebook 连接到端点。

检索身份验证令牌以连接到交互式端点

要从 Jupyter 或 JupyterLab notebook 连接到交互式端点,必须使用 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。您可以在 describe-managed-endpoint 调用中找到 ARN。

virtualClusterArn

虚拟集群的 ARN。

executionRoleArn

执行角色的 ARN。

durationInSeconds

令牌的有效持续时间(以秒为单位)。默认持续时间为 15 分钟 (900),最大持续时间为 12 小时 (43200)。

region

与端点相同的区域。

输出应与以下示例类似。记下部署自托管式 Jupyter 或 JupyterLab notebook 时将使用的 session-token 值。

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

示例:部署 JupyterLab notebook

完成上述步骤后,您可以尝试此示例过程,使用交互式端点将 JupyterLab notebook 部署到 Amazon EKS 集群中。

  1. 创建命名空间来运行 Notebook 服务器。

  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 的集群,请使用 role 标签标记 Jupyter Pod,如以下示例所示:

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

    Notebook 部署所在的 Kubernetes 命名空间。

    serverUrl

    describe-managed-endpoint 命令在 检索交互式端点的网关服务器 URL 中返回的 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. 将 Pod 规范部署到 Amazon EKS 集群:

    kubectl apply -f notebook.yaml -n namespace

    这将启动已连接到 Amazon EMR on EKS 交互式端点的最小 JupyterLab notebook。等到 Pod 状态变成 RUNNING。您可以使用以下命令检查其状态:

    kubectl get pod jupyter-notebook -n namespace

    Pod 准备就绪时,get pod 命令会返回类似于以下内容的输出:

    NAME READY STATUS RESTARTS AGE jupyter-notebook 1/1 Running 0 46s
  4. 将 Notebook 安全组附加到调度 Notebook 的节点。

    1. 首先,使用 describe pod 命令确定调度 jupyter-notebook 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 Pod,请创建 SecurityGroupPolicy 以应用到带有角色标签的 Jupyter notebook Pod:

      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 notebook。下面是一个示例代码片段,您可以运行它来近似计算 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 notebook 代码的屏幕截图。

删除自托管式 Jupyter notebook

准备好删除自托管式 Notebook 时,也可以删除交互式端点和安全组。按以下顺序执行操作:

  1. 使用以下命令删除 jupyter-notebook Pod:

    kubectl delete pod jupyter-notebook -n namespace
  2. 然后,使用 delete-managed-endpoint 命令删除交互式端点。有关删除交互式端点的步骤,请参阅 删除交互式端点。最初,您的端点处于 TERMINATING 状态。清理完所有资源后,它将转换到 TERMINATED 状态。

  3. 如果您不打算将在 创建安全组 中创建的 Notebook 安全组用于其他 Jupyter notebook 部署,则可以将其删除。有关更多信息,请参阅《Amazon EC2 用户指南》中的删除安全组