

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用自助託管的 Jupyter 筆記本
<a name="managed-endpoints-self-hosted"></a>

可以在 Amazon EC2 執行個體或您自己的 Amazon EKS 叢集上託管和管理 Jupyter 或 JupyterLab 筆記本，作為*自助託管的 Jupyter 筆記本*。然後，使用自助託管的 Jupyter 筆記本執行互動式工作負載。以下各章節將逐步介紹在 Amazon EKS 叢集上設定和部署自助託管的 Jupyter 筆記本的程序。



**Topics**
+ [建立安全群組](#managed-endpoints-self-hosted-security)
+ [建立 Amazon EMR on EKS 互動端點](#managed-endpoints-self-hosted-create-me)
+ [擷取互動端點的閘道伺服器 URL](#managed-endpoints-self-hosted-gateway)
+ [擷取驗證字符以連接到互動端點](#managed-endpoints-self-hosted-auth)
+ [範例：部署 JupyterLab 筆記本](#managed-endpoints-self-hosted-example)
+ [刪除自助託管的 Jupyter 筆記本](#managed-endpoints-self-hosted-cleanup)

## 建立安全群組
<a name="managed-endpoints-self-hosted-security"></a>

必須先建立安全群組來控制筆記本與互動端點之間的流量，才能建立互動端點並執行自助託管的 Jupyter 或 JupyterLab 筆記本。若要使用 Amazon EC2 主控台或 Amazon EC2 SDK 建立安全群組，請參閱《*Amazon EC2 使用者指南*》中的[建立安全群組](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/working-with-security-groups.html#creating-security-group)中的步驟。應該在要部署筆記本伺服器的 VPC 中建立安全群組。

若要遵循本指南中的範例，請使用與 Amazon EKS 叢集相同的 VPC。如果想要將筆記本託管在與 Amazon EKS 叢集的 VPC 不同的 VPC 中，則可能需要在這兩個 VPC 之間建立對等互連。如需在兩個 VPC 之間建立對等互連的步驟，請參閱《Amazon VPC 入門指南》中的[建立 VPC 對等互連](https://docs.aws.amazon.com/vpc/latest/peering/create-vpc-peering-connection.html)。

您需要安全群組的 ID，才能在下一個步驟中[建立 Amazon EMR on EKS 互動端點](https://docs.aws.amazon.com/)。

## 建立 Amazon EMR on EKS 互動端點
<a name="managed-endpoints-self-hosted-create-me"></a>

為筆記本建立安全群組之後，請使用 [為虛擬叢集建立互動端點](create-managed-endpoint.md) 中提供的步驟建立互動端點。必須提供在 [建立安全群組](#managed-endpoints-self-hosted-security) 中為筆記本建立的安全群組 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
<a name="managed-endpoints-self-hosted-gateway"></a>

建立互動端點後，請使用 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 筆記本](https://docs.aws.amazon.com/)時，需要此 URL 才能將筆記本連接到端點。

## 擷取驗證字符以連接到互動端點
<a name="managed-endpoints-self-hosted-auth"></a>

若要從 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。可以在 `describe-managed-endpoint` 呼叫的結果中尋找 ARN。

**`virtualClusterArn`**  
虛擬叢集的 ARN。

**`executionRoleArn`**  
執行角色的 ARN。

**`durationInSeconds`**  
字符有效的持續時間 (以秒為單位)。預設持續時間為 15 分鐘 (`900`)，最長為 12 小時 (`43200`)。

**`region` **  
與端點相同的區域。

輸出應類似以下範例。請記下您在[部自助託管的 Jupyter 或 JupyterLab 筆記](https://docs.aws.amazon.com/)本時將使用的 `session-token` 值。

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

## 範例：部署 JupyterLab 筆記本
<a name="managed-endpoints-self-hosted-example"></a>

完成上述步驟後，可以嘗試此範例程序，將 JupyterLab 筆記本部署到具有互動端點的 Amazon EKS 叢集中。

1. 建立命名空間，以執行筆記本伺服器。

1. 在本機建立檔案 `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 筆記本部署到僅限 Fargate 的叢集，請使用 `role` 標籤來標記 Jupyter Pod，如下列範例所示：

   ```
   ...
   metadata:
     name: jupyter-notebook
     namespace: default
     labels:
       role: example-role-name-label
   spec:
               ...
   ```  
**`namespace`**  
在其中部署筆記本的 Kubernetes 命名空間。  
**`serverUrl`**  
`describe-managed-endpoint` 命令在 [擷取互動端點的閘道伺服器 URL](#managed-endpoints-self-hosted-gateway) 中傳回的 `serverUrl` 屬性。  
**`session-token`**  
`get-managed-endpoint-session-credentials` 命令在 [擷取驗證字符以連接到互動端點](#managed-endpoints-self-hosted-auth) 中傳回的 `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
             "
   ```

1. 將 Pod 規範部署至 Amazon EKS 叢集。

   ```
   kubectl apply -f notebook.yaml -n namespace
   ```

   這將啟動已連接到 Amazon EMR on EKS 互動端點的最小 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
   ```

1. 將筆記本安全群組附接至排程筆記本所在的節點。

   1. 首先，使用 `describe pod` 命令識別在其中排程 `jupyter-notebook` Pod 的節點。

      ```
      kubectl describe pod jupyter-notebook -n namespace
      ```

   1. 在以下網址開啟 Amazon EKS 主控台：[https://console.aws.amazon.com/eks/home\$1/clusters](https://console.aws.amazon.com/eks/home#/clusters)。

   1. 導覽至 Amazon EKS 叢集的**運算**索引標籤，然後選取 `describe pod` 命令識別的節點。選取節點的執行個體 ID。

   1. 從**動作**功能表中，選取**安全性** > **變更安全群組**，以附接您在 [建立安全群組](#managed-endpoints-self-hosted-security) 中建立的安全群組。

   1. 如果您要在 上部署 Jupyter 筆記本 Pod AWS Fargate，請建立 []() 以套用到具有角色標籤的 Jupyter 筆記本 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
      ```

1. 現在，執行 port-forward，以便您可以在本機存取 JupyterLab 介面：

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

   執行後，導覽至您的本機瀏覽器並造訪 `localhost:8888` 以查看 JupyterLab 介面：  
![\[JupyterLab 開始畫面的螢幕擷取畫面。\]](http://docs.aws.amazon.com/zh_tw/emr/latest/EMR-on-EKS-DevelopmentGuide/images/emr-on-eks-Jupyter-notebook-start.png)

1. 從 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 筆記本程式碼範例的熒幕擷取畫面。\]](http://docs.aws.amazon.com/zh_tw/emr/latest/EMR-on-EKS-DevelopmentGuide/images/emr-on-eks-Jupyter-notebook-scala-program.png)

## 刪除自助託管的 Jupyter 筆記本
<a name="managed-endpoints-self-hosted-cleanup"></a>

當您準備好刪除自助託管的筆記本時，也可以刪除互動端點和安全群組。請依下列順序執行動作：

1. 使用下列命令來刪除 `jupyter-notebook` Pod：

   ```
   kubectl delete pod jupyter-notebook -n namespace
   ```

1. 然後，使用 `delete-managed-endpoint` 命令刪除互動端點。如需有關刪除互動端點的步驟，請參閱 [刪除互動端點](delete-managed-endpoint.md)。最初，您的端點將處於 **TERMINATING** 狀態。清除所有資源後，它會轉換為 **TERMINATED** 狀態。

1. 如果不打算將您在 [建立安全群組](#managed-endpoints-self-hosted-security) 中建立的筆記本安全群組用於其他 Jupyter 筆記本部署，則可以將其刪除。如需詳細資訊，請參閱《Amazon EC2 使用者指南》中的[刪除安全群組](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/working-with-security-groups.html#deleting-security-group)。