Helmで最新のJupyterHub(0.8-b6bdb73)をMinikubeにデプロイする
以前、マルチユーザ機械学習環境をJupyterHubとKubernetesで構築で構築していたJupyterHubはGKE(Google Kubernetes Engine)にデプロイしていて、ローカル開発環境ではJupyterHubのかわりに、普通のJupyter Notebookを動かしていました。JupyterHubはHubやNotebookの部分をカスタマイズしていることもあり、Jupyter Notebookを動かすのは実際の本番環境と異なっており、開発がしんどくなってきたので、今回、Minikubeを使ってJupyterHubをローカル開発環境上に構築しました。
HubやNotebookを独自にビルドしてGCR(Google Container Registry)などにpushしてから利用する場合、Helmの最新安定版の0.7.0
では対応できなかったので記事をかいている現在最新の0.8-b6bdb73
を利用して構築しました。
JupyterHub(0.8-b6bdb73)をMinikubeにデプロイする
JupyterHubでGCRにおいてあるDockerイメージを使わない場合は、MinikubeがDockerイメージを取得する際のGCRの設定をする必要がないので簡単です。(この場合は、JupyterHubのHelmチャートのバージョンが0.7.0
でも動かすことができます。)
まずMinikubeを立ち上げます。Kubernetesで使うVMの、Diskサイズ40GB、メモリ8GB、CPUの数6を指定していますが、ここらへんはローカルのマシンの状況に応じて変えてください。あまりリソースが少ないとJupyterHubのほかにPodを立ち上げたときにリソース不足でPodが立ち上がらなくなるので調整してください。
minikube start --disk-size 40g --memory 8192 --cpus 6
しばらくするとMinikubeが立ち上がるので、IngressのAdd-onを有効にします。JupyterHubをそのままデプロイしてもServiceのLoad BalancerがMinikubeだと機能しないのでIngressを通してJupyterHubにアクセスします。
minikube addons enable ingress
Ingressを通してアクセスするドメインの設定をしておきます。今回はjupyterhub.example.com
というドメインを仮に/etc/hosts
に登録しますが、各自すきなドメインとしてください。ただし、*.dev
のようなドメインの場合、ChromeがHSTSをきかせてHTTPSにリダイレクトされてこまるのでそれを避けるようなドメインにしてください。
# MinikubeのIPを取得する
minikube ip
# /etc/hostsに登録する。以下は例
192.168.99.100 jupyterhub.example.com
次にHelmをMinikubeのKubernetes側にインストールします。Helmのバージョンが低いとJupyterHubのデプロイがうまくいかないときがあるので、最新にしておきます(今回はv2.12.3
)
helm init --service-account tiller --wait
次にJupyterHubをHelmでインストールします(Setting up JupyterHubが参考になります)。まずは設定ファイルをつくります。secretTokenとcookieSecretはよしなに設定してください。singleuserはデフォルトで10GBのディスク容量でユーザごとのディスクを作成するのですが、そんなには必要ないので2GBとしています。proxyのserviceはIngressを使うのでNodePort
を指定しています。
proxy:
secretToken: xxx
service:
type: NodePort
hub:
cookieSecret: yyy
singleuser:
storage:
capacity: 2Gi
dynamic:
storageClass: standard
prePuller:
hook:
enabled: true
cull:
enabled: false
次に、最新のJupyterHubのHelmファイルを取得します。JupyterHubの最新のHelmチャートはJupyterHub and BinderHub Helm charts for Kubernetesにあるので、そこからダウンロードします。今回は、jupyterhub-0.8-b6bdb73.tgz
をダウンロードして、解凍しました。解凍したフォルダをjupyterhub
とします。
HelmでJupyterHubをデプロイするには以下のようにします。ネットワークの環境によっては結構時間がかかるので完了するまでしばらく待ちます。
helm upgrade --install jhub ./jupyterhub --values values.yaml --timeout 1800
デプロイしたらkubectl get pod
などで正しくPodが作成されているか確かめます。
最後に、Ingressの設定をします。設定ファイルは以下です。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
spec:
backend:
serviceName: proxy-public
servicePort: 80
MinikubeのKubernetesに適用します。
kubectl config use-context minikube
kubectl apply -f ingress.yaml
これで、http://jupyterhub.example.com
にアクセスすればJupyterHubにただしくアクセスできます。
GCRにある独自ビルドしたHubやNotebookのイメージを利用してデプロイする
GCRにあるDockerイメージをHubやNotebookのイメージとして使った場合の手順を説明します。HubやNotebookのイメージの作成自体はとくに特別なことはありませんが、HubのベースイメージはJupyterのHelmチャートと合わせる必要があります。今回はFROM jupyterhub/k8s-hub:80a76ac
としました。
今回は、以下のGCRのアドレスのイメージを使用するものとします。
- Hub: gcr.io/example/jupyter-hub-minikube:1.0.0
- Notebook: gcr.io/example/jupyter-singleuser-minikube:1.0.0
MinikubeからGCRのDockerイメージを取得するにはJupyterのHelmチャートのvalues.yaml
のhub.imagePullSecret
とsingleuser.imagePullSecret
にGCRのサービスアカウントを登録します。GCRのやりかたについてはJupyterHubのHelmチャートに詳しくかいてあります。以下は今回使うvalues.yaml
のimagePullSecret設定
の一部です。
hub:
image:
name: gcr.io/example/jupyter-hub-minikube
tag: 1.0.0
imagePullSecret:
enabled: true
registry: gcr.io
username: _json_key
password: |-
{
...
}
...
singleuser:
image:
name: gcr.io/example/jupyter-singleuser-minikube
tag: 1.0.0
imagePullSecret:
enabled: true
registry: gcr.io
username: _json_key
password: |-
{
...
}
あとは先程と同じようにHelmでJupyterHubをデプロイします。これで独自にビルドしたDockerイメージをMinikube上のJupyterHubでうごかせました。
helm upgrade --install jhub ./jupyterhub --values values.yaml --timeout 1800
まとめ
JupyterHubを、最新のHelmチャートを使ってMinikubeでデプロイする手順を説明しました。
最新のバージョン(0.8-b6bdb73)で、imagePullSecret
を使えば、GCRにあるDockerイメージもHubやNotebookとして使うことができます。
初めて、Minikubeを使いましたがなかなか使えそうです。これでローカルでの開発もはかどりそうですね。