Jupyter Notebookはブラウザーを使ってプログラムの対話型実行を実現することが可能なツールです。 いろいろな言語に対応しています。
Pythonで使う場合はpipコマンドで pip3 install jupyter のように実行した後、 jupyter notebook コマンドを実行することで利用できます。その他のインストール方法もあります。
セットアップは比較的簡単ではあるのですが、今回はJupyter NotebookをKubernetesで動かしてしまおうという話です。
必要なもの
Kubernetes
なんらかの方法で構築したKubernetesが必要です。今回はmicrok8sを使う例にしますが、Kubernetesであれば構いません。オプションとしてストレージを提供できると非常に便利です。そういう意味ではk3sとかminikubeとかでもいいと思います。k3sはデフォルトでlocalpathのストレージが使えますし、minikubeもアドオンとして追加すればすぐストレージ割り当てができるためです。
ブラウザー
Firefox、Chrome、Edgeとかを用意します。IE以外を用意してください。私が触った範囲ではSafariでも良さそうです。
Kubernetesの構築
今回はmicrok8sを使った例です。 以下に書かれているように、セットアップします。
コマンドだけ列挙すると次のとおりです。詳細はドキュメントをご覧ください。
$ sudo snap install microk8s --classic --channel=1.18/stable $ sudo usermod -a -G microk8s $USER $ sudo chown -f -R $USER ~/.kube $ su - $USER $ microk8s kubectl get nodes $ alias kubectl='microk8s kubectl' $ microk8s enable dns storage dashboard
YAMLファイルの作成
PVC用のYAMLを作成
次のようなYAMLを作成します。ストレージサイズは適切なものを指定します。
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
app: myclaim
name: myclaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: microk8s-hostpath
Pod用のYAMLを作成
次のようなYAMLを作成します。コンテナーイメージはドキュメントから適切なものを選択して指定してください。違いはインストール済みのモジュールなどの違いです。
---
apiVersion: v1
kind: Service
metadata:
name: jupyter2
labels:
app: jupyter2
spec:
ports:
- port: 80
name: http
targetPort: 8888
selector:
app: jupyter2
type: NodePort
---
apiVersion: v1
kind: Pod
metadata:
name: jupyter2
labels:
app: jupyter2
spec:
containers:
- name: jupyter2
image: jupyter/minimal-notebook
ports:
- containerPort: 8888
protocol: TCP
name: http
volumeMounts:
- mountPath: /jupyter
name: jupyter2
volumes:
- name: jupyter2
persistentVolumeClaim:
claimName: myclaim
KubernetesでJupyter Notebookをデプロイ
作成したYAMLを順に実行します。まずPVC要求をするYAMLを適用して、その後Podを作成します。
$ kubectl apply -f jupyter-storage-pvc.yaml $ kubectl status -f jupyter-storage-pvc.yaml NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE myclaim Bound pvc-8ca320b3-429c-4e68-9eb2-cd5b46ddf766 1Gi RWO microk8s-hostpath 7h35m $ kubectl apply -f jupyter-storage-pod.yaml $ kubectl status -f jupyter-storage-pod.yaml NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/jupyter2 NodePort 10.152.183.238 <none> 80:32583/TCP 7h15m NAME READY STATUS RESTARTS AGE pod/jupyter2 1/1 Running 2 7h15m
Jupyter Notebookにログイン
Jupyter NotebookはNodePortサービスを展開したので、「http://Node IP address:NodePort」でアクセスできます。前の結果から、NodePortは32583であることがわかります。デプロイの度に変わるのでそれが煩わしければYAMLファイルにポート番号を記してください。
アクセスするとログインページが表示されます。ここにトークンキーを入力するとログインできます。

KubernetesクラスターでデプロイしたJupyter Notebookのトークンキーは次の方法で確認できます。
実行例
トークンキーは実際の環境でコマンドを実行して確認してください。
$ kubectl exec -it jupyter2 -- jupyter notebook list Currently running servers: http://0.0.0.0:8888/?token=99d2f53804270cac952c541dedcc124bcc0982a634ba3146 :: /home/jovyan
このトークンキーをログインページで入力するとログインできます。

あとはコードをペタペタ貼り付けて実行することで結果がわかります。

構築したJupyter Notebookについて
2020/08/19現在のイメージは、jovyanはユーザーグループにのみ属しているようです。
notebook_dirが/home/jovyanに設定されており、Jupyter Notebookで作成したデータは /home/jovyan/work に保管されます。
jovyan@jupyter2:~$ id
uid=1000(jovyan) gid=100(users) groups=100(users)
jovyan@jupyter2:~$ cat .local/share/jupyter/runtime/nbserver-6.json
{
"base_url": "/",
"hostname": "0.0.0.0",
"notebook_dir": "/home/jovyan",
"password": false,
"pid": 6,
"port": 8888,
"secure": false,
"token": "99d2f53804270cac952c541dedcc124bcc0982a634ba3146",
"url": "http://0.0.0.0:8888/"
前のYAMLで /jupyter として永続ストレージをマウントしていますので、たまにファイルコピーしておくと
うまく動かなくなったときにPodを消して作り直し、バックアップしたファイルをコピーするだけで元どおりになるので安心です。
バックアップ
$ cp /home/jovyan/work/* /jupyter
復元
$ kubectl apply -f jupyter-storage-pod.yaml $ kubectl exec -it jupyter2 -- bash $ cp /jupyter/* /home/jovyan/work
Kubernetes Dashboardについて
microk8sでアドオンとして追加したKubernetes Dashboardは、以下の方法でアクセスできます。 Kubernetes Proxyを使う方法はちょっと面倒なので、この程度の環境であればLinuxにデスクトップ環境を入れてコンソール内のブラウザーからアクセスすればいいと思います。

今回の例ではLubuntu 20.04.1を使いました。
