はじめに(前回記事のサマリ)
前回、OKE上にKubeflowを利用して機械学習プラットフォームを構築するという記事を書きました。
これだけだと、単にマネージドKubernetes上に機械学習プラットフォームを構築しただけという形なので、今回の記事ではOKE上のカーネルリソースをローカルのJupyter Notebookから利用するという記事を書いてみたいと思います。
Jupyter Enterprise Gatewayとは
Jupyter Notebookの機能の一つにJupyter Enterprise Gatewayという非常に便利な機能があります。
Jupyter Enterprise Gatewayは、マルチクラスター環境で複数ユーザが利用できるようにするための機能を提供するプラグインです。
後ほど説明しようと思いますが、このJupyter Enterprise Gatewayによって、通常はリモート上のJupyter Notebookで起動するカーネルをWebサーバ上で起動できます。
この際にKubernetesやHadoop YARNなどの分散コンピューティング基盤を利用すると、クラスター全体にカーネルを分散し、同時に接続可能なカーネル数を劇的に向上させることができます。
今回は、OKE上のカーネルに対して、ローカル環境にあるJupyter Notebookから接続してみるということをやってみます。
既存環境の確認
まずは、今の環境を確認していきます。
環境は、前回の記事で構築した状態とします。
念の為、Podを確認しておくと以下のような状態です。(kube-system Namespaceは除外しています)
[opc@kubeflow-client mykubeflow]$ kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
cert-manager cert-manager-7c75b559c4-s7tjm 1/1 Running 0 6m23s
cert-manager cert-manager-cainjector-7f964fd7b5-lvdvc 1/1 Running 0 6m23s
cert-manager cert-manager-webhook-566dd99d6-5wrmg 1/1 Running 1 6m23s
istio-system cluster-local-gateway-5898bc5c74-djc9t 1/1 Running 0 6m37s
istio-system istio-citadel-6dffd79d7-n4cvl 1/1 Running 0 6m47s
istio-system istio-galley-77cb9b44dc-548gl 1/1 Running 0 6m48s
istio-system istio-ingressgateway-7bb77f89b8-k2pnl 1/1 Running 0 6m48s
istio-system istio-nodeagent-59lvb 1/1 Running 0 6m48s
istio-system istio-nodeagent-b5f6m 1/1 Running 0 6m49s
istio-system istio-nodeagent-p2k8f 1/1 Running 0 6m48s
istio-system istio-nodeagent-xtw66 1/1 Running 0 6m48s
istio-system istio-pilot-67d94fc954-vjj8k 2/2 Running 0 6m48s
istio-system istio-policy-546596d4b4-784pl 2/2 Running 1 6m47s
istio-system istio-security-post-install-release-1.3-latest-daily-6bm4w 0/1 Completed 0 6m47s
istio-system istio-sidecar-injector-796b6454d9-fq5gj 1/1 Running 0 6m47s
istio-system istio-telemetry-58f9cd4bf5-qv6tn 2/2 Running 1 6m47s
istio-system prometheus-7c6d764c48-7k5ss 1/1 Running 0 6m48s
knative-serving activator-6c87fcbbb6-jlk6x 1/1 Running 0 4m28s
knative-serving autoscaler-847b9f89dc-7mspk 1/1 Running 0 4m29s
knative-serving controller-55f67c9ddb-q7xk5 1/1 Running 0 4m28s
knative-serving istio-webhook-db664df87-czd2r 1/1 Running 0 4m30s
knative-serving networking-istio-76f8cc7796-rw458 1/1 Running 0 4m29s
knative-serving webhook-6bff77594b-b5rz5 1/1 Running 0 4m30s
kubeflow admission-webhook-bootstrap-stateful-set-0 1/1 Running 2 5m22s
kubeflow admission-webhook-deployment-5cd7dc96f5-x9xls 1/1 Running 1 4m47s
kubeflow application-controller-stateful-set-0 1/1 Running 0 7m4s
kubeflow argo-ui-65df8c7c84-vnz74 1/1 Running 0 4m55s
kubeflow cache-deployer-deployment-5f4979f45-2d5s6 2/2 Running 2 4m55s
kubeflow cache-server-7859fd67f5-w56hs 2/2 Running 0 4m48s
kubeflow centraldashboard-67767584dc-r9wvq 1/1 Running 0 4m54s
kubeflow jupyter-web-app-deployment-8486d5ffff-j76h4 1/1 Running 0 4m54s
kubeflow katib-controller-7fcc95676b-b5qfc 1/1 Running 1 4m54s
kubeflow katib-db-manager-85db457c64-lzprn 1/1 Running 1 4m54s
kubeflow katib-mysql-6c7f7fb869-cd4s2 1/1 Running 0 4m51s
kubeflow katib-ui-65dc4cf6f5-8vw4s 1/1 Running 0 4m53s
kubeflow kfserving-controller-manager-0 2/2 Running 0 4m18s
kubeflow kubeflow-pipelines-profile-controller-797fb44db9-b6dn6 1/1 Running 0 4m53s
kubeflow metacontroller-0 1/1 Running 0 5m22s
kubeflow metadata-db-6dd978c5b-ppdzw 1/1 Running 0 4m53s
kubeflow metadata-envoy-deployment-67bd5954c-6kqqv 1/1 Running 0 4m53s
kubeflow metadata-grpc-deployment-577c67c96f-fmwd2 1/1 Running 1 4m52s
kubeflow metadata-writer-756dbdd478-mbg8z 2/2 Running 0 4m52s
kubeflow minio-54d995c97b-qcv5m 1/1 Running 0 4m52s
kubeflow ml-pipeline-7c56db5db9-s2scf 2/2 Running 1 4m52s
kubeflow ml-pipeline-persistenceagent-d984c9585-4gq6b 2/2 Running 0 4m52s
kubeflow ml-pipeline-scheduledworkflow-5ccf4c9fcc-rzr7c 2/2 Running 0 4m51s
kubeflow ml-pipeline-ui-7ddcd74489-bqp66 2/2 Running 0 4m48s
kubeflow ml-pipeline-viewer-crd-56c68f6c85-z7829 2/2 Running 3 4m51s
kubeflow ml-pipeline-visualizationserver-5b9bd8f6bf-wjww6 2/2 Running 0 4m51s
kubeflow mpi-operator-d5bfb8489-69h7h 1/1 Running 0 4m50s
kubeflow mxnet-operator-7576d697d6-2gvfm 1/1 Running 0 4m50s
kubeflow mysql-74f8f99bc8-hjc7t 2/2 Running 0 4m50s
kubeflow notebook-controller-deployment-5bb6bdbd6d-4ldpf 1/1 Running 0 4m50s
kubeflow profiles-deployment-56bc5d7dcb-2rs8x 2/2 Running 0 4m49s
kubeflow pytorch-operator-847c8d55d8-v5dwn 1/1 Running 0 4m49s
kubeflow seldon-controller-manager-6bf8b45656-46g4m 1/1 Running 0 4m49s
kubeflow spark-operatorsparkoperator-fdfbfd99-qvr2f 1/1 Running 0 5m22s
kubeflow spartakus-volunteer-558f8bfd47-zj66n 1/1 Running 0 4m16s
kubeflow tf-job-operator-58477797f8-27fv8 1/1 Running 0 4m48s
kubeflow workflow-controller-64fd7cffc5-hlx6n 1/1 Running 0 4m48s
この環境にJupyter Enterprise Gatewayをデプロイしていきます。
Jupyter Enterprise Gatewayのデプロイ
Jupyter Enterprise Gatewayのデプロイも非常に簡単です。
以下の1行を叩くだけです。
kubectl apply -f https://raw.githubusercontent.com/jupyter/enterprise_gateway/master/etc/kubernetes/enterprise-gateway.yaml
これでJupyter Enterprise GatewayのデプロイするためのManifestが適用され、以下のようなPodがデプロイされます。
[opc@kubeflow-client mykubeflow]$ kubectl get pod -n enterprise-gateway
NAME READY STATUS RESTARTS AGE
enterprise-gateway-647648f598-qzxxg 1/1 Running 0 8m
kernel-image-puller-8c4zm 1/1 Running 0 7m59s
kernel-image-puller-h9dts 1/1 Running 0 7m59s
kernel-image-puller-qldsr 1/1 Running 0 7m59s
kernel-image-puller-r5nq5 1/1 Running 0 8m
これでJupyter Enterprise Gatewayのデプロイは完了です!
動作確認
それでは動作確認をしていきます。
Jupyter Notebook(Jupyter Lab)のインストール
まず、事前準備を行っていきます。
ローカル端末にJupyter Notebook(Jupyter Lab)がインストールされていない場合は以下のコマンドでインストールしましょう。
(Pythonがインストールされていない場合は、こちらからPython3系をインストールしてください)
pip install jupyterlab
Jupyter Notebook(Jupyter Lab)の起動
インストールが完了したら、以下のコマンドでJupyter Labを起動します。
JUPYTER_GATEWAY_URL=http://<Node IP>:<NodePort> jupyter lab --no-browser
JUPYTER_GATEWAY_URL
に定義するURLはOKE上にデプロイされたJupyter Enterprise GatewayのPodが稼働しているNodeのIPとNodePortです。
例えば、以下のような場合、
[opc@kubeflow-client ~]$ kubectl get pod,svc -n enterprise-gateway -o wide |grep enterprise
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/enterprise-gateway-647648f598-qzxxg 1/1 Running 0 5h13m 10.244.0.18 10.0.10.195 <none> <none>
service/enterprise-gateway NodePort 10.96.8.222 <none> 8888:30567/TCP,8877:31965/TCP 5h13m gateway-selector=enterprise-gateway
このようになります。
JUPYTER_GATEWAY_URL=http:// 10.0.10.195:30567 jupyter lab --no-browser
OKEのクライアント上では、Jupyter Notebookがポート8888で起動しているので、OKEクライアントのポート8888をローカル環境の任意のポートにポートフォワードします。
ローカルのブラウザからhttp://localhost:<ローカル環境の任意のポート>
にアクセスすると以下の画面が起動します。
これで事前準備完了です!
Jupyter NotebookでOKE上のカーネルリソースを使う
いよいよ動作確認本番です。
Notebookには様々な種類がありますが、今回はPython on Kubernetes
を利用してみます。
Python on Kubernetes
をクリックすると、従来のJupyter Notebookが起動します。
このとき、右下の赤枠の部分がIdle
状態になっていれば、無事OKE上のカーネルを利用できています!
ちなみにJupyter Notebook(Jupyter Lab)を起動したOKEクライアント側の標準出力メッセージを見てみると、以下のような内容が出力されています。
[I 2021-08-11 03:41:50.850 ServerApp] Creating new notebook in
[I 2021-08-11 03:41:51.846 ServerApp] Request start kernel: kernel_id=None, path=''
[I 2021-08-11 03:41:55.219 ServerApp] GatewayKernelManager started kernel: 4350a9d2-3def-462a-aed6-bab41664a6cb, args: {'kernel_name': 'python_kubernetes', 'cwd': '/home/opc'}
[I 2021-08-11 03:41:55.684 ServerApp] Connecting to ws://10.0.10.195:30567/api/kernels/4350a9d2-3def-462a-aed6-bab41664a6cb/channels
[I 2021-08-11 03:43:51.895 ServerApp] Saving file at /Untitled.ipynb
先ほど起動時に設定したJUPYTER_GATEWAY_URLを経由してWebSocketで接続していることが確認できます。
これで、ローカル環境からOKEのカーネルリソースを使ってJupyter Notebookを起動することができました!
ローカル環境のスペックを気にすることなく、ガンガン機械学習プロセスを回すことができますね!!
また、これを利用するとローカル環境にGPUを積んでいなくても、OKEのGPUプール(OKEではWorker NodeにGPUインスタンスを利用することが可能)を利用して機械学習を行うこともできるので、夢が広がります!
【おまけ】VSCodeからも動作確認してみる
ここからはおまけです。
先ほどはブラウザでJupyter Notebookを起動しましたが、ここではVSCodeからやってみようと思います。
前提として、VSCodeにPythonおよびJupyterの拡張機能のインストールが必要です。
VSCodeを開いて、コマンドパレットを開き、Jupyter: Specify local or remote Jupyter server for Connections
を入力します。
Specify the URI of an existing server
というメニューが出てくるので、こちらをクリックしてOKEクライアントのJupyter Notebook(Jupyter Lab)を起動時のメッセージ内にある以下の部分をコピーし、貼り付けます。
http://localhost:8888/lab?token=<トークン>
入力すると、VSCodeの再起動が要求されるので、再起動します。
再起動後、Jupyter Notebookが起動するはずです。
ここで、右上にあるカーネルの選択
部分ををクリックすると、先ほどのブラウザで起動した時と同じようなカーネルの種類が選択できるようになっています。
これでVSCode上からJupyter Enterprise Gateway経由でリモートカーネルを利用できます。
まとめ
Kubernetes上にJupyter Enterprise Gatewayをデプロイすると、上記のようにKubernetes上のリソースプールを効率的に利用してローカルで学習プロセスを回すことができます。
特にGPUを利用するような大規模が学習が必要な場合には強力なプラットフォームになります。
従来はアプリケーション基盤として利用しがちなKubernetesですが、このように分散コンピューティングの仕組みとして利用することもできるので、みなさんも試してみてください!
参考資料
- Jupyter Enterprise Gatewayドキュメント