生徒も教員も使いやすい！Cloud Run で構築するスケーラブルな JupyterLab 教育環境

## 1. はじめに：クラウド時代の教育環境

データ分析や機械学習の教育現場において、JupyterLab は強力なツールですが、ローカル環境での利用には課題がつきまといます。

生徒や利用者がITに慣れておらず、環境構築が難しかったり、マシンスペックの制限によるパフォーマンスの問題、複数の生徒間でのコラボレーションの難しさなどが、円滑な学習体験を阻害することがあります。

これらの課題を解決するために、クラウドサービスを活用した JupyterLab 環境の構築が注目されています。
特に、Google Cloud の Cloud Run は、フルマネージドでスケーラブルな環境を容易に構築できることから、教育機関にとって魅力的な選択肢となります。

本記事では、Cloud Run を用いて教育向けの JupyterLab 環境を構築する手順を、ステップバイステップで解説します。

さらに、教育現場のニーズを踏まえ、Cloud Run が有力な選択肢となるケースを考察します。

## 2. なぜ Cloud Run なのか？ - 教育機関・企業におけるメリット

Cloud Run は、教育機関だけでなく、企業研修や社内勉強会など、幅広いビジネスシーンにおいても効果的な JupyterLab 環境を提供します。

**教育機関におけるメリット**

- **容易な環境構築**: 学生は複雑なセットアップ作業なしに、Webブラウザからすぐに学習を開始できます。
- **スケーラビリティ**: 学生数の変動にも柔軟に対応でき、大人数の授業でも安定したパフォーマンスを維持できます。
- **コスト効率**: 使用したリソース量に応じた従量課金制のため、予算を抑えながら運用できます。
- **共同作業の促進**: クラウド上で共有された Jupyter Notebook を介して、学生同士、または教員と学生間でのスムーズな共同作業が可能になります。

**企業におけるメリット**

- **研修コストの削減**: 個別環境の構築やメンテナンスが不要になるため、時間とコストを大幅に削減できます。
- **研修の標準化**: 全員が同じ環境で学習するため、スキル習得のバラつきを抑制し、研修効果の向上に繋がります。
- **柔軟なアクセス**: いつでもどこでも、インターネット接続さえあれば学習コンテンツにアクセスできます。
- **最新の環境提供**: 最新のライブラリやツールを常に利用できるため、常に最新のスキルを習得できます。

## 3. Cloud Run を用いた JupyterLab 環境構築手順 - 最もシンプルな方法

Cloud Run で JupyterLab 環境を構築する最もシンプルな方法を解説します。このセクションでは、GitHub から公開されている JupyterLab の Docker イメージを直接利用します。

1. **Google Cloud プロジェクトの作成**: Google Cloud Platform にアクセスし、新しいプロジェクトを作成します。

2. **Cloud Shell の起動**: Google Cloud Console 上部のメニューバーから、Cloud Shell を起動します。

3. **Cloud Run サービスのデプロイ**: 以下のコマンドを実行し、JupyterLab サービスをデプロイします。

   ```bash
   gcloud run deploy jupyterlab \
     --image=us-docker.pkg.dev/cloudrun/container/jupyterlab \
     --platform=managed \
     --region=us-central1 \
     --allow-unauthenticated
   ```

4. **JupyterLab へのアクセス**: デプロイが完了すると、サービスにアクセスするための URL が表示されます。ブラウザでその URL にアクセスすると、JupyterLab が起動します。

**ポイント**:

- この方法は非常にシンプルですが、教材データは含まれていません。
- また、セキュリティ対策は十分ではありません。
- 本番環境では、後のセクションで説明するよりセキュアな方法を採用してください。


## 4. 発展的な構成と詳細な設定

このセクションでは、より実践的なユースケースを想定し、GitHub プライベートリポジトリで管理された教材を JupyterLab 環境で利用できるようにする方法を含めて解説します。

### 4.1. Google Cloud プロジェクトの作成

Google Cloud Console (https://console.cloud.google.com/) にアクセスし、新しいプロジェクトを作成します。

### 4.2. Cloud SDK のインストールと設定

Google Cloud の公式ドキュメント (https://cloud.google.com/sdk/docs/install?hl=ja) に従って、Cloud SDK をインストールし、初期設定を行います。

```bash
# インストール後の設定
$ gcloud init
```

### 4.3. Docker のインストール (任意)

ローカルでイメージをビルドしてテストする場合は、Docker をインストールしておきます。公式ドキュメント (https://docs.docker.com/get-docker/) を参照してください。

### 4.4. Docker イメージの構築

#### 4.4.1 Dockerfile の作成

JupyterLab 環境を定義する Dockerfile を作成します。ここでは、教材リポジトリへのアクセス方法として、SSH 接続とリポジトリコンテンツの Docker イメージへの含め方、2つの方法を紹介します。

##### 方法1: プライベートリポジトリへのSSH接続 (安全性重視)

```dockerfile
FROM python:3.9-slim

# 必要なパッケージをインストール
RUN apt-get update && apt-get install -y git openssh-client
RUN pip install --no-cache-dir jupyterlab pandas numpy matplotlib scikit-learn

# 環境変数を設定
ENV JUPYTER_ENABLE_LAB=yes
EXPOSE 8888

# entrypoint.sh を Dockerfile に組み込む
COPY ./entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

# JupyterLab の起動コマンド
ENTRYPOINT ["/entrypoint.sh"]
CMD ["jupyter", "lab", "--ip=0.0.0.0", "--port=8888", "--no-browser", "--allow-root"]
```

```bash
# entrypoint.sh
#!/bin/bash

echo "Downloading SSH key from Secret Manager..."
gcloud secrets versions access latest --secret="jupyterlab-ssh-key" > /root/.ssh/id_rsa
chmod 600 /root/.ssh/id_rsa

# GitHubのknown_hostsにホストを追加
ssh-keyscan github.com >> /root/.ssh/known_hosts

# リポジトリをクローン
git clone git@github.com:your-username/your-repository.git /app/materials

# JupyterLab を起動
exec "$@"
```

##### 方法2: リポジトリのコンテンツをイメージに含める (簡便性重視)

```dockerfile
FROM python:3.9-slim

# 必要なパッケージをインストール
RUN pip install --no-cache-dir jupyterlab pandas numpy matplotlib scikit-learn

# 環境変数を設定
ENV JUPYTER_ENABLE_LAB=yes
EXPOSE 8888

# リポジトリをクローン (GitHubのアクセストークンが必要な場合は適宜設定)
RUN git clone https://<your-github-token>@github.com/your-username/your-repository.git /app/materials

# JupyterLab の起動コマンド
CMD ["jupyter", "lab", "--ip=0.0.0.0", "--port=8888", "--no-browser", "--allow-root"]
```

#### 4.4.2 SSH鍵ペアの生成 (方法1の場合のみ)

```bash
ssh-keygen -t rsa -b 4096 -C "your_actual_email@example.com"
```
`your_actual_email@example.com`は実際のメールアドレスに置き換えてください。

#### 4.4.3 GitHub への公開鍵登録 (方法1の場合のみ)

生成された公開鍵 (`id_rsa.pub`) の内容を、GitHub リポジトリの設定 > Deploy keys に登録します。

#### 4.4.4 Secret Manager への秘密鍵登録 (方法1の場合のみ)

```bash
# 秘密鍵をSecret Managerに登録
gcloud secrets create jupyterlab-ssh-key --replication-policy="automatic"
gcloud secrets versions add jupyterlab-ssh-key --data-file=id_rsa

# 権限変更
chmod 600 id_rsa
```

#### 4.4.5 イメージのビルドとプッシュ

Dockerfile を作成したら、以下のコマンドを実行して Docker イメージをビルドし、Google Container Registry (GCR) にプッシュします。

```bash
docker build -t us-central1-docker.pkg.dev/YOUR_PROJECT_ID/jupyterlab-on-cloud-run .
docker push us-central1-docker.pkg.dev/YOUR_PROJECT_ID/jupyterlab-on-cloud-run
```

- `YOUR_PROJECT_ID` は実際のプロジェクト ID に置き換えてください。
- `us-central1-docker.pkg.dev` は、選択したリージョンに対応する GCR のホスト名です。

### 4.5. Cloud Run サービスのデプロイ

#### 4.5.1 Cloud Run サービスの作成

GCR にプッシュした Docker イメージを使用して、Cloud Run サービスを作成します。

```bash
# 方法1の場合
gcloud run deploy jupyterlab \
  --image=us-central1-docker.pkg.dev/YOUR_PROJECT_ID/jupyterlab-on-cloud-run \
  --platform=managed \
  --region=YOUR_REGION \
  --allow-unauthenticated \
  --set-secrets=SSH_KEY=jupyterlab-ssh-key:latest

# 方法2の場合
gcloud run deploy jupyterlab \
  --image=us-central1-docker.pkg.dev/YOUR_PROJECT_ID/jupyterlab-on-cloud-run \
  --platform=managed \
  --region=YOUR_REGION \
  --allow-unauthenticated
```

- `jupyterlab` はサービスの名前です。
- `--allow-unauthenticated` は、認証なしでサービスにアクセスできるようにするオプションです。**本番環境では、適切な認証を設定することを強く推奨します。**

#### 4.5.2 デプロイ後の URL の確認

デプロイが完了すると、サービスにアクセスするための URL が表示されます。

```
Service [jupyterlab] revision [jupyterlab-00001-xxx] has been deployed and is serving 100 percent of traffic.
Service URL: https://jupyterlab-xxxxxxxxxx-uc.a.run.app
```

### 4.6. JupyterLab へのアクセスと教材の利用

デプロイした JupyterLab 環境には、Web ブラウザからアクセスできます。前述の手順で表示されたサービス URL にアクセスしてください。`/app/materials` ディレクトリ以下に教材が配置されています。

```mermaid
graph LR
A[学生] -->|Web ブラウザ| B[Cloud Run サービス]
B -->|コンテナ起動| C[JupyterLab]
C --> D[教材データ]
```

### 4.7. セキュリティの強化 - 機密データ保護のために

JupyterLab 環境で機密性の高い教材や企業の内部データを扱う場合、セキュリティ対策は非常に重要です。Cloud Run では、以下の方法を組み合わせることで、強固なセキュリティを実現できます。

- **IAP (Identity-Aware Proxy) によるアクセス制御**: 許可されたユーザーのみにアクセスを制限できます。Google Workspace や Cloud Identity と連携することで、組織内のユーザー管理と統合できます。

    ```bash
    # IAP を有効化
    gcloud run services update jupyterlab --no-allow-unauthenticated

    # メンバーを追加 (オーナーのメールアドレスは適宜変更)
    gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
    --member=user:your-email@example.com \
    --role=roles/iap.httpsResourceAccessor
    ```

- **VPC Service Controls によるデータ保護**: Cloud Run サービスを VPC Service Controls の境界内に配置することで、データの外部への漏洩を防ぎます。

   1. VPC Service Controls の境界を作成し、Cloud Run API を有効化します。
   2. Cloud Run サービスを、作成した境界内にデプロイします。

- **Secret Manager による機密情報の管理**: GitHub のアクセストークンや API キーなどの機密情報は、Secret Manager で安全に管理します。Dockerfile 内で Secret Manager からこれらの情報を読み込むことで、ハードコードを避け、セキュリティリスクを低減できます。

- **HTTPS 接続**: Cloud Run はデフォルトで HTTPS 接続を提供するため、通信は暗号化されます。証明書の管理は Google Cloud が自動的に行うため、特別な設定は不要です。

これらの対策を適切に組み合わせることで、安全な JupyterLab 環境を構築し、機密データへの不正アクセスを防ぎます。

### 4.8. コストの最適化 - 費用を抑えながら運用

Cloud Run は従量課金制であるため、利用状況に応じた最適化を行うことで、費用を抑えながら運用できます。

- **最小インスタンス数の設定**: Cloud Run は、トラフィックがない状態でも、常に一定数のインスタンス (最小インスタンス数) を起動しておくことができます。最小インスタンス数を適切に設定することで、急なアクセス増加にも迅速に対応しつつ、費用を抑えることができます。

   ```bash
   gcloud run deploy jupyterlab \
       --image=us-central1-docker.pkg.dev/YOUR_PROJECT_ID/jupyterlab-on-cloud-run \
       --platform=managed \
       --region=YOUR_REGION \
       --min-instances=1
   ```

- **最大インスタンス数の設定**:  Cloud Run は、トラフィック増加に合わせて自動的にインスタンス数をスケールアウトしますが、最大インスタンス数を設定することで、予期せぬ高負荷によるコスト増加を防ぐことができます。

   ```bash
   gcloud run deploy jupyterlab \
       --image=us-central1-docker.pkg.dev/YOUR_PROJECT_ID/jupyterlab-on-cloud-run \
       --platform=managed \
       --region=YOUR_REGION \
       --max-instances=10
   ```

- **自動スケーリングの利用**: Cloud Run は、デフォルトで自動スケーリングが有効になっています。トラフィック量に応じて自動的にインスタンス数が調整されるため、リソースの無駄を最小限に抑えられます。

- **休止時間の活用**:  利用していない間はインスタンスを自動的に停止する設定も可能です。授業時間外や休講期間中など、利用頻度が低い時間帯にインスタンスを停止することで、費用を効果的に削減できます。

   ```bash
   gcloud run deploy jupyterlab \
       --image=us-central1-docker.pkg.dev/YOUR_PROJECT_ID/jupyterlab-on-cloud-run \
       --platform=managed \
       --region=YOUR_REGION \
       --timeout=15m \
       --no-cpu-idle
   ```


これらの設定を適切に組み合わせることで、Cloud Run の従量課金制のメリットを最大限に活かし、コストを抑えながら JupyterLab 環境を運用できます。

### 4.9. 他の GCP サービスとの連携 -  JupyterLabの可能性をさらに広げる

```mermaid
graph TD
A[JupyterLab on Cloud Run] --> B[BigQuery]
A --> C[Cloud Storage]
A --> D[Vertex AI]
B --> E[大規模データ分析]
C --> F[教材データの保存と共有]
D --> G[機械学習モデルの開発と実験]
```

Cloud Run で構築した JupyterLab 環境は、他の GCP サービスと連携することで、より高度なデータ分析や機械学習の教育・学習環境を実現できます。

- **BigQuery との連携**:  BigQuery は、ペタバイト規模のデータに対して高速な SQL クエリを実行できるデータウェアハウスです。JupyterLab から BigQuery に接続することで、大規模データセットを使ったデータ分析を容易に行えます。

   ```python
   from google.cloud import bigquery

   # BigQuery クライアントのインスタンスを作成
   client = bigquery.Client()

   # クエリを実行
   query_job = client.query("SELECT * FROM `your-project.your_dataset.your_table` LIMIT 10")

   # 結果を取得
   results = query_job.result()

   # 結果を表示
   for row in results:
       print(row)
   ```

- **Cloud Storage との連携**: Cloud Storage は、データの保存、管理、分析に適したオブジェクトストレージです。JupyterLab から Cloud Storage にアクセスすることで、大容量の教材データや学習データの保存、読み込み、共有が容易になります。

   ```python
   from google.cloud import storage

   # Cloud Storage クライアントのインスタンスを作成
   client = storage.Client()

   # バケットを取得
   bucket = client.get_bucket('your-bucket-name')

   # ファイルをアップロード
   blob = bucket.blob('your-file-name')
   blob.upload_from_filename('your-local-file-path')

   # ファイルをダウンロード
   blob = bucket.blob('your-file-name')
   blob.download_to_filename('your-local-file-path')
   ```

- **Vertex AI との連携**: Vertex AI は、機械学習モデルの開発、トレーニング、デプロイを支援する機械学習プラットフォームです。JupyterLab から Vertex AI の機能を利用することで、機械学習モデルの開発や実験を効率的に行えます。

これらの連携により、JupyterLab を単なるデータ分析ツールとしてだけでなく、GCP の各種サービスと組み合わせた、より強力でスケーラブルな教育・学習プラットフォームへと進化させることができます。

### 4.10. CI/CD パイプラインの構築 -  環境構築と教材更新の自動化

CI/CD パイプラインを構築することで、JupyterLab 環境の構築と教材の更新を自動化し、常に最新の状態に保つことができます。

- **Cloud Build を使用した自動ビルド**: GitHub リポジトリにプッシュされた変更をトリガーとして、Cloud Build を使用して Docker イメージの自動ビルドと GCR へのプッシュを行います。

  1. Cloud Build トリガーを作成し、GitHub リポジトリと連携します。
  2. cloudbuild.yaml ファイルを作成し、ビルドとプッシュのステップを定義します。

     ```yaml
     steps:
     - name: 'gcr.io/cloud-builders/docker'
       args: ['build', '-t', 'us-central1-docker.pkg.dev/YOUR_PROJECT_ID/jupyterlab-on-cloud-run', '.']
     - name: 'gcr.io/cloud-builders/docker'
       args: ['push', 'us-central1-docker.pkg.dev/YOUR_PROJECT_ID/jupyterlab-on-cloud-run']
     ```

- **Cloud Run の自動デプロイ**: GCR にプッシュされた新しいイメージを検知して、Cloud Run サービスを自動的に更新します。

  1. Cloud Build トリガーに、デプロイのステップを追加します。

     ```yaml
     steps:
     - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
       entrypoint: 'gcloud'
       args: ['run', 'deploy', 'jupyterlab', '--image', 'us-central1-docker.pkg.dev/YOUR_PROJECT_ID/jupyterlab-on-cloud-run', '--platform', 'managed', '--region', 'YOUR_REGION']
     ```

- **GitOps**:  Git リポジトリを構成管理の唯一の情報源として扱い、環境構築やデプロイを自動化します。Terraform や Ansible などのツールと組み合わせて、インフラストラクチャのコード化を実現します。

  1. Terraform 設定ファイルを作成し、Cloud Run サービスやその他の GCP リソースを定義します。
  2. GitHub Actions や Cloud Build を使用して、Git リポジトリへのプッシュをトリガーに Terraform を実行し、インフラストラクチャを更新します。

CI/CD パイプラインを構築することで、以下のメリットが得られます。

- **環境構築の自動化**:  手動作業を減らすことで、ヒューマンエラーを防止し、環境構築の再現性を高めます。
- **迅速なデプロイ**:  コードの変更を迅速にデプロイすることで、開発のスピードアップに貢献します。
- **最新状態の維持**:  常に最新のコードや教材がデプロイされるため、学習環境の品質を維持できます。

### 4.11. モニタリングとログ分析 -  安定稼働とパフォーマンス改善

JupyterLab 環境の安定稼働とパフォーマンス改善のためには、モニタリングとログ分析が不可欠です。

- **Cloud Monitoring**:  Cloud Monitoring を使用すると、CPU 使用率、メモリ使用量、リクエスト数、レイテンシなどのメトリクスを監視できます。異常を検知した場合にアラートを設定することで、迅速な対応が可能になります。

- **Cloud Logging**:  Cloud Logging には、Cloud Run サービスのログが自動的に収集されます。ログ分析を行うことで、エラーの原因究明やパフォーマンスのボトルネックを特定することができます。

## 5. 様々なプラットフォームとの比較：最適なJupyterLab環境を選ぶ

JupyterLab環境を構築するための選択肢は、GCPだけでも多岐にわたります。加えて、他クラウドサービスやオンプレミスも視野に入れると、その選択肢はさらに広がります。それぞれのメリット・デメリット、そしてユースケースを踏まえて、最適なプラットフォームを見つけ出すことが重要です。

After:
| 特徴 | Vertex AI Workbench | Compute Engine | Google Colaboratory | JupyterHub on Kubernetes | AWS SageMaker | Binder | Cloud Run | PaaS | 独自サーバー |
|---|---|---|---|---|---|---|---|---|---| 
| **料金** | 高 | 中 | 低～中 | 中～高 | 中～高 | 低～中 | 低～中 | 低～中 | 状況による |
| **セットアップ** | 簡単 | 中程度 | 不要 | 複雑 | 中程度 | 簡単 | 簡単 | 中程度 | 複雑 |
| **管理** | フルマネージド | IaaS | フルマネージド |  Kubernetesの知識が必要 | フルマネージド | 限定的 | フルマネージド | プラットフォームによる | 全て自分で管理 |
| **スケーラビリティ** | 高 | 高 | 中 | 高 | 高 | 中 | 高 | プラットフォームによる | 状況による |
| **カスタマイズ性** | 中 | 高 | 低 | 高 | 中 | 低 | 中 | 中 | 高 |
| **セキュリティ** | 高 | 中 | 中 | 高 | 高 | 中 | 高 | プラットフォームによる | 状況による |
| **学習教材の共有** | GCPサービスと連携 | ストレージを接続 | Drive等を利用 | 柔軟な方法を選択可能 | AWSサービスと連携 | Gitリポジトリ | Cloud Storage を利用 | プラットフォームによる | 状況による |
| **おすすめシーン** | 大規模な機械学習、研究 | 柔軟な環境構築、長期利用 | 個人の学習、プロトタイピング | 大規模なチーム、高度なカスタマイズ | 大規模な機械学習、AWS環境 | 簡単な共有、一時的な利用 | 中規模のチーム、バランス重視 | プラットフォームの特性による | 特定のニーズに対応 |

**各プラットフォームの詳細**

* **Vertex AI Workbench**: GCPが提供するフルマネージドの機械学習プラットフォーム。JupyterLab環境もプリセットされており、GPUやTPUも利用可能。ただし、他の選択肢と比べて高価。
* **Compute Engine**: GCPの仮想マシンサービス。OSやソフトウェアを自由に選択し、フルカスタマイズが可能。長期利用する場合や柔軟な環境構築が必要な場合に適している。ただし、サーバー管理などの運用負荷がかかる。
* **Google Colaboratory**: 無料で利用できるクラウドベースのJupyter Notebook環境。GPUも利用可能で、手軽に始められるのが魅力。ただし、カスタマイズ性や実行時間、状態管理に制限がある。
* **JupyterHub on Kubernetes**: Kubernetes上で動作するJupyterHub。ユーザー管理やカスタマイズ性に優れ、スケーラブルな環境を構築可能。ただし、Kubernetesの知識が必要で、環境構築や運用は容易ではない。
* **AWS SageMaker**: AWSの機械学習プラットフォーム。JupyterLab環境も提供され、機械学習に特化した機能が充実。ただし、GCPとの連携は考慮が必要。
* **Binder**: GitHubリポジトリからJupyter環境を簡単に構築・公開できるサービス。環境構築の手間が省け、手軽に共有できる。ただし、カスタマイズ性やスケーラビリティは低い。
* **Cloud Run**: コンテナ化されたアプリケーションを実行するサーバーレスプラットフォーム。JupyterLabも実行可能で、自動スケーリングや従量課金が魅力。バランスの取れた選択肢と言える。
* **その他 (PaaS、独自サーバー)**:  HerokuなどのPaaSや、独自サーバーも選択肢となる。ただし、運用負荷やセキュリティ対策、コストなどを考慮する必要がある。