使用自托管式 Jupyter notebook - Amazon EMR

使用自托管式 Jupyter notebook

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

创建安全组

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

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

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

创建 Amazon EMR on EKS 交互式端点

为笔记本创建安全组后,使用 为虚拟集群创建交互式端点 中的步骤创建交互式端点。您必须提供在 创建安全组 中为笔记本创建的安全组 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 才能将笔记本连接到端点。网关服务器 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 才能将笔记本连接到端点。

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

要从 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. 创建命名空间来运行笔记本服务器。

  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

    笔记本部署所在的 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. 将笔记本安全组附加到调度笔记本的节点。

    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

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

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

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

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