使用自托管式 Jupyter notebook - Amazon EMR
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用自托管式 Jupyter notebook

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

创建安全组

在创建交互式终端节点并运行自托管的 Jupyter 或 JupyterLab 笔记本之前,必须创建一个安全组来控制笔记本和交互式终端节点之间的流量。要使用 Amazon EC2 控制台或 Amazon EC2 软件开发工具包创建安全组,请参阅 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

创建交互式端点后,使用 Amazon 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 或笔记本时,需要此 URL 才能将笔记本电脑连接到终端节点。 JupyterLab

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

要从 Jupyter 或 JupyterLab 笔记本连接到交互式端点,必须使用 API 生成会话令牌。GetManagedEndpointSessionCredentials此令牌作为连接到交互式端点服务器的身份验证证明。

下面的输出示例将更详细地解释以下命令。

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 或笔记本时将使用的session-token值。 JupyterLab

{ "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 的集群,请使用 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

    这将启动一台在 EKS 交互式终端节点上连接到你的 Amazon EMR 的最小 JupyterLab 笔记本电脑。等到 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. 如果您要在上部署 Jupyter 笔记本窗格 Amazon Fargate,请使用角色SecurityGroupPolicy标签创建一个应用于 Jupyter 笔记本窗格:

      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()
    中 Scala 笔记本示例代码的屏幕截图。 JupyterLab

删除自托管式 Jupyter notebook

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

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

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

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