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を使いました。