教室での TensorFlow と JupyterHub の使用

このチュートリアルでは、Google Cloud Platform(GCP)の Kubernetes Engine で複数の TensorFlow インスタンスを管理するために JupyterHub を有効にする方法について説明します。

この例では、大学で美術を専攻する学生のグループが DeepDream アルゴリズムでマシン インテリジェンスを使用したデジタル アートワークをレンダリングする実験をしています。Kubernetes Engine、Google Cloud Platform 認証、Cloud Shell を使用し、学生ごとの TensorFlow 環境を JupyterHub を使用して構成します。

TensorFlow は、Google が 2015 年にオープンソース化した機械学習フレームワークです。TensorFlow を使い始める最も簡単な方法の 1 つは、TensorFlow ドキュメントの手順を使用して Docker コンテナを実行することです。Docker イメージが Jupyter ノートブックにバンドルされており、機械学習実験をすばやく稼働させることができます。

Jupyter は、データ サイエンティストが Python やその他のランタイムを使用して実験を構築して実行するための一般的なツールです。また、Jupyter はノートブックのディレクトリを公開します。ノートブックとは、すべてが wiki スタイルのエディタ内で動作する、実行可能コード、埋め込みグラフ、画像、およびテキストのマッシュアップを含む個別のファイルです。Google Datalab Python Package は、Google BigQuery などの Google Cloud Platform のビッグデータ ツールとのさまざまな統合を可能にする Jupyter の機能拡張です。

これらの簡単にアクセス可能な Docker イメージが融合された Jupyter の豊富なオンライン ノートブック エクスペリエンスは、チーム プロジェクト、企業研修、大学の教室に自然に調和します。ただし、複数のインスタンスのプロビジョニングと管理は容易ではありません。ほとんどのシナリオにおいて、1 台のノートパソコンから実行されたスクリプトが CPU とメモリを大量に使用する可能性があるため、学生ごとの Jupyter インスタンスのプロビジョニングが必要になります。また、TensorFlow ランタイムの複雑な特性が専用のコンピューティング リソースの必要性をさらに増大させる可能性があります。

Jupyter の作成者は、複数の Jupyter 環境の管理を可能にする追加のツール JupyterHub を構築しました。このシステムは、個々のユーザーの Jupyter の新しいインスタンスのライフサイクルを管理し、共通のアクセス ゲートウェイに安全な認証を提供します。JupyterHub を有効にすると、ユーザーをより簡単に管理したり、自動的にインスタンスを作成したり、すべての動力源となるコンピューティング リソースをより迅速にプロビジョニングしたりできるようになります。このチュートリアルでは、GitHub 上にある使いやすい自動化スクリプトを使用して、Kubernetes Engine 上にすべてをデプロイするプロセスについて詳しく説明します。

Kubernetes Engine は、Google 独自のオープンソース コンテナ オーケストレーション システムである Kubernetes 上に構築されたマネージド サービスです。Kubernetes Engine を使用すれば、必要な JupyterHub コンポーネントとセキュアな SSL プロキシを実行する Docker コンテナをすばやくプロビジョニングすることができます。新しいユーザーが JupyterHub システムにログインすると、Kubernetes がそのユーザー専用の新しい Jupyter コンテナを自動的に作成するように指示されます。

アーキテクチャ図

この図は、Kubernetes Engine 上の Jupyter コンテナが Datalab や Tensorflow とどのように相互作用するかに関するアーキテクチャ全体を示しています。

アーキテクチャ図

目標

  • Kubernetes Engine 上で Jupyter を使って TensorFlow インスタンスを構成する。
  • JupyterHub でユーザーを管理する。
  • DeepDream アルゴリズムを介してオリジナルのアートワークを生成する。

料金

このチュートリアルでは、以下を含む GCP の課金対象コンポーネントを使用しています。

  • Kubernetes Engine

料金計算ツールを使用すると、想定される利用方法に基づいて費用の見積もりを作成できます。GCP の新規ユーザーは無料トライアルの対象となる可能性があります。

始める前に

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. GCP プロジェクトを選択または作成します。

    プロジェクト セレクタのページに移動

  3. Google Cloud Platform プロジェクトに対して課金が有効になっていることを確認します。 詳しくは、課金を有効にする方法をご覧ください。

  4. 前のステップで選択または作成したプロジェクトに対して Compute Engine API を有効にします。
    Compute Engine API を有効にする

Cloud Shell を介したサンプルコードのクローン化

gke-jupyter-classroom GitHub リポジトリに、すべてのコードと構成が含まれています。すべての初期コマンドを実行するには、Google Cloud Platform Console 内から直接アクセス可能な完全に機能する Linux シェルである Cloud Shell を使用します。

  1. Cloud Shell を起動します。

  2. デフォルトのコンピューティング ゾーンを設定します。Cloud Shell で、次のコマンドを入力します。

    gcloud config set compute/zone us-east1-d

  3. ラボレポジトリのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/gke-jupyter-classroom

  4. 新しいプロジェクト ディレクトリに移動します。

    cd gke-jupyter-classroom
    

ファイル サーバーの起動

Docker コンテナは存続期間が短いため、クラッシュまたは再起動すると、そのローカル ストレージが失われます。Jupyter ノートブックと JupyterHub 構成ファイルが消失する可能性をなくすために、Google Cloud Launcher を使用して Single Node File Server をプロビジョニングします。このサーバーは、単一の Compute Engine 仮想マシン インスタンス上にインストールされたリモート ネットワーク ファイル システム(NFS)です。ファイル サーバーをデプロイしたら、JupyterHub デプロイ用のストレージ ターゲットとしてそのサーバーを使用することができます。

  1. GCP Console を使用して、ファイル サーバーをプロビジョニングします。

    ファイル サーバーのプロビジョニング

  2. ファイル サーバーを起動する GCP プロジェクトを選択します。

  3. ファイル サーバーのディメンションに関する次のパラメータを選択します。

    ディメンション パラメータ / 命令
    デプロイ名 jupyterhub-filer
    ゾーン us-east1-d
    マシンタイプ n1-standard-1
    ストレージ名 data
    SMB 共有の有効化 チェックボックスのオフ
    ストレージ ディスクサイズ 10 GB
    このチュートリアルでは、10 GB のディスクを選択できます。これは、この構成をビッグデータ プロジェクトに使用しない限り、
    高いスループットおよび IOPS が必要ないためです。
  4. [デプロイ] をクリックし、GCP Console が実行中として表示されるまで待ちます。

  5. 新しいマシンの内部 IP アドレスをメモします。以降の手順でこの値が必要になります。この値は、Cloud Shell で次のコマンドを実行して見つけることができます。

    gcloud compute instances list
    

スクリプトと構成の確認

クローン化された GitHub レポジトリを含むディレクトリに移動して、ファイルを一覧表示します。次のファイルとディレクトリに注目してください。

  • gke-jupyter-classroom.sh は、構成をデプロイして、デプロイをカスタマイズするためのいくつかのオプションを提供します。
  • proxy ディレクトリには、汎用の Nginx コンテナ定義と Kubernetes マニフェストの両方が格納されます。Kubernetes マニフェストは Kubernetes ConfigMap ボリュームから nginx.conf ファイルを読み込みます。docker-entrypoint.sh ファイルは、nginx.conf で見つかった環境変数を置き換えます。
  • jupyterhub/custom_manifests ディレクトリには、JupyterHub コンテナが読み込んでユーザーに提供可能ないくつかのサンプル JSON ファイルが格納されています。これらを使用すれば、定義可能な特定の Jupyter インスタンスを選択することができます。これらのサンプル ファイルは、Python スタイルのパラメータ置換を使用して、Kubernetes に送信される前のマニフェストに JupyterHub 変数を挿入します。
  • jupyter ディレクトリには、2 つのコンテナの定義が格納されています。1 つは DeepDream サンプル ノートブックを含むように拡張された基本 TensorFlow Jupyter イメージです。もう 1 つは、Cloud Datalab Python Notebook Extension、Cloud Dataflow SDK for Python、およびいくつかのその他のデータ サイエンス ライブラリを含むように拡張された TensorFlow Jupyter イメージです。

JupyterHub のデプロイ

このセクションでは、GitHub からクローン化したファイルを使用して、必要なすべての構成を作成してデプロイします。gke-jupyter-classroom.sh スクリプトは、すべてをデプロイするプロセスを簡素化しますが、その確認には時間をかける必要があります。このスクリプトは、JupyterHub ポッドや Nginx プロキシポッドに加えて、configmap、シークレット、サービス、SSL 証明書、ファイアウォール ルール、および受信ロードバランサを作成する関数に各手順を分解します。正常に終了すると、スクリプトはブラウザで開くための新しいドメイン名を出力します。スクリプトが使用する DNS サービスは xip.io という名前です。これは、IP アドレスをドメイン名の一部として巧みに使用して、自動的に DNS リクエストをその IP に転送する無料のサービスです。

JupyterHub をデプロイするには:

  1. Cloud Shell から開始して、クローン化された Git レポジトリ ディレクトリ gke-jupyter-classroom に移動し、次のコマンドを実行してスクリプトのすべてのオプションを表示します。

    ./gke-jupyter-classroom.sh -h
    

    コンソールには、スクリプトで使用可能なすべてのアクションが出力されます。これには、ソリューションのデプロイ、ドライランの実行、ソリューション全体の解体、およびソリューションに付属の Docker イメージの構築が含まれます。

  2. 次に、デプロイ アクションを実行して、構成全体を作成します。

    ./gke-jupyter-classroom.sh -v --cluster-name jupytercluster1 --admin-user <your-gmail-address> --filer-ip <your filer ip> --zone <defaults to us-east1-d> --autoscale-nodes 6 deploy
    
  3. スクリプトが OAuth 認証情報の作成を要求するまで待機します。

    #User Action Required: Please follow the instructions to create a Web Application OAuth configuration
    #: use the Cloud Console to access the API Manager credentials section
    #: https://console.cloud.google.com/apis/credentials
    #: use these values origins field:
    https://jhub.10.12.34.56.xip.io callback url:
    https://jhub.10.12.34.56.xip.io/hub/oauth_callback
    

  4. GCP Console で [クライアント ID の作成] ページに移動します。

    [クライアント ID の作成] ページへの移動

  5. Google のログインを受け入れるアプリとして新しいサイトを登録することにより、OAuth クライアント ID をセットアップします。

    1. [アプリケーションの種類] で [ウェブ アプリケーション] を選択します。
    2. [名前] で、クライアント ID 名を入力します。
    3. [制限] で、次のように制限を定義します。
      • [承認済みの JavaScript 生成元] をドメイン名に設定します。
      • [承認済みのリダイレクト URI] をコンソール出力からのコールバック URL に設定します。
    4. [作成] をクリックします。
    5. クライアント ID をコピーして、それを Cloud Shell に入力します。
    6. クライアント シークレットをコピーして、それを Cloud Shell に入力します。
  6. スクリプトが SSL 証明書ファイルを生成するまで待機します。Cloud Shell インスタンスで使用可能なエントロピーに応じてかなりの時間がかかる場合があります。証明書は、認証局によって署名されないため、初めてサイトを訪問したときにブラウザに警告が表示されます。このデモではこの警告を無視しても大丈夫です。信頼された証明書の使用方法については、後述する本番環境デプロイの留意点を参照してください。

    スクリプトが終了したら、新しい JupyterHub サイトの IP と URL を含むメッセージが表示されます。ブラウザで、その URL にアクセスします。

    -----------COMPLETED------------
    Static IP created: 10.12.34.56 using xip.io : https://jhub.10.12.34.56.xip.io
    

JupyterHub へのログイン

これで、ブラウザで新しい JupyterHub サイトにアクセスすることができました。

  1. [Sign in with Google] をクリックして、JupyterHub サイトにログインします。
  2. [Start My Server] をクリックします。
  3. Jupyter イメージを選択します。
    • デフォルトのイメージには、TensorFlow と DeepDream のサンプル ノートブックが含まれています。
    • GCP-Tools イメージを使用すると、TensorFlow と一緒に Datalab と Dataflow SDK を実行することができます。

ユーザーを管理する

JupyterHub で、右上にある [Control Panel] をクリックします。Control Panel を使用すると、ユーザーを作成したり、ユーザー インスタンスを停止または開始したり、ユーザーとそのインスタンスを削除したりできます。

システムの検証

  1. システムで、画面の右上部分にある [アップロード] をクリックしたときに新しいファイルをアップロードできるかどうかをテストします。パソコンから派手なまたは目立つ色の JPG 写真を選択します。ファイル ダイアログで写真を開いたら、そのファイルがファイルリストに表示されるはずです。
  2. その名前をクリックして「input.jpg,」に変更してから、新しいファイルの右側にある [アップロード] をクリックします。deepdream.ipynb ノートブックを選択して起動することにより、Jupyter と TensorFlow のセットアップをテストすることができます。

    Jupyter ファイルリスト

    ノートブックの一番下までスクロール ダウンして、次のように変更します。

    img0 = PIL.Image.open('pilatus800.jpg')
    

    img0 = PIL.Image.open('input.jpg')
    
  3. ノートブック全体を実行するには、上部にある [セル] メニューを開いて、[すべて実行] をクリックします。

  4. スクリプトが終了すると、ノートブックの下部に入力画像のバリエーションが数種類表示されます。

おめでとうございます。マシン インテリジェンスを使用して、Kubernetes Engine クラスタ上に固有のアートワークを正常に作成できました。

本番環境デプロイの留意点

Jupyter インスタンスに割り当てるメモリを増やしたり、独自のドメインまたは証明書を使用したりする場合は、スクリプトをデプロイする前に特定の値を調整する必要があります。

リソースの追加

プロジェクトによっては、1 人のユーザーの Jupyter インスタンスにデフォルトで割り当てられるメモリと CPU の量が少なすぎる場合があります。このような値を調整するために、スクリプトを実行する前に、jupyterhub.yaml.tmp を開いて、KUBESPAWN_CPU_LIMITKUBESPAWN_MEMORY_LIMIT の値を編集することができます。環境がすでに構築されている場合は、Cloud Shell インスタンスの基本ディレクトリで生成された jupyterhub.yaml ファイル内の同じ制限パラメータを変更してから、kubectl delete -f jupyterhub.yamlkubectl apply -f jupyterhub.yaml を実行することができます。いずれの場合も、これらの値を変更することにより、JupyterHub インスタンスが新しい CPU とメモリの制限設定で再作成されます。ユーザーのインスタンスがすでに作成されている場合は、JupyterHub の Control Panel でユーザーを削除してから、再度ユーザーを作成して、再認証することができます。

独自のドメインの使用

独自のパブリック DNS サーバーを所有している場合は、xip.io の代わりに、独自のドメインを使用することができます。JupyterHub のデプロイに記載されている手順に沿って、独自のドメイン名を使用した OAuth 認証情報を作成します。認証情報が作成されたら、トップレベル ドメインを指定するために --domain フラグを指定してデプロイ スクリプトを実行します。このスクリプトは、サイトの構成に jhub.<yourdomain>.com を使用し、一時的なパブリック IP アドレスを作成します。この IP アドレスは、{{console_name_short}} 内の静的 IP に手動で変更できます。DNS サーバーまたは jhub.<yourdomain>.com 内の新しい CNAME をその IP アドレスに登録します。

Google Cloud SSL プロキシの使用

GCP は、サードパーティ製の Nginx プロキシの代わりに使用可能なネイティブな Cloud SSL プロキシ ソリューションを提供しています。この機能は現在ベータ版です。これを使用するには、デプロイ スクリプトを実行するときに --use-ssl-proxy フラグを設定します。

独自の証明書の使用

独自の信頼された証明書を使用する場合は、Let’s Encrypt をご覧ください。* 証明書がすでに存在する場合は、次の手順でデプロイ スクリプトを実行することもできます。

  1. スクリプトを実行する前に、proxy/nginx.conf ファイル内の次の行をコメント解除します。

    #ssl_trusted_certificate /mnt/secure/trusted.crt
    
  2. 証明書ファイルを Cloud Shell インスタンスにコピーします。

    /tmp/tls.crt
    /tmp/tls.key
    /tmp/dhparam.pem
    /tmp/trusted.crt
    

  3. 次の 2 つの追加のフラグを指定してデプロイ スクリプトを実行します。

    --skip-certs --signed-cert

クリーンアップ

このチュートリアルで使用するリソースの GCP アカウントへの課金を回避するには、同じスクリプトを次のオプションを指定して実行します。

./gke-jupyter-classroom.sh --cluster-name jupytercluster1 teardown

このスクリプトは、Kubernetes Engine クラスタを手動で削除するスクリプトを出力します。ファイル サーバーを削除することもできます。

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...