MicroK8sでKubeflow 1.0:「導入」と「Jupyterカスタマイズ」


モチベ

『クラウドの力を、自分のマシンでも感じたい。』 完。

先日正式リリースとなった Kubeflow 1.0 が、MicroK8sのアドオンになりました。MicroK8s Release Note

k8sもKubeflowも初学者ですが、以下について残します。

  • インストール
  • Kubeflowから起動できるJupyterサーバーに、カスタムコンテナイメージを使う
    今回は、Jupyter Labで立ち上げます。

環境・バージョン

  • Ubuntu 18.04.4 LTS (Bionic Beaver)
    • Kernel 5.3.0-45-generic
  • MicroK8s v1.18.0

以下は、使ってみて感じた、あくまで主観です。

  • Memory
    16GB以上は欲しい。

  • Storage
    /var をごりごり使う。128GB以上の空きは欲しい。

インストール

MicroK8s

公式ドキュメントを参考に、MicroK8sをインストール。

sudo snap install microk8s --classic --channel=1.18/stable
sudo usermod -a -G microk8s <username>

(Optional) Insecure Registry の設定

カスタムコンテナイメージの格納先に DockerHub など、証明書を気にしなくてよいレジストリを選択する場合、ここは不要。

後半では、オンプレで使えるDocker Registryを使用する。証明書ガン無視なので、insecure-registryの設定を入れます。

  • /var/snap/microk8s/current/args/containerd-template.tomlのpluginセッションに、以下を参考にレジストリのIPアドレス:ポート情報を追加。
/var/snap/microk8s/current/args/containerd-template.toml(抜粋)
[plugins]
  (略)
  [plugins.cri]
    (略)
    [plugins.cri.registry]
      [plugins.cri.registry.mirrors]
        #
        # このセッション内に以下2行追加。この場合、192.168.0.10がオンプレのレジストリ。
        #
        [plugins.cri.registry.mirrors."192.168.0.10:5000"]
          endpoint = ["http://192.168.0.10:5000"]
(略)
  • MicroK8sの再起動
microk8s stop
microk8s start

Kubeflow

MicroK8s v1.18.0のKubeflowアドオンでは、MetalLBが利用されています。
この恩恵で、AmbassadorのExternal IPにMetalLBのIPアドレスがセットされます。

ただし、MetalLBのIPアドレスのレンジが10.64.140.43-10.64.140.49enable.kubeflow.sh にハードコーディングされています。(v1.18.0では?)

ここでは、MetalLBアドオンを先にインストールし、自分の環境に合わせたレンジを先に設定します。

# GPUを利用する場合、必要。
microk8s enable gpu

# MetalLBのインストール。バインドするIPアドレスのレンジを指定。
#  →MicroK8s構築マシンのIPアドレスでバインド。
microk8s enable metallb:192.168.0.15-192.168.0.15

# (任意)Kubeflowアクセス時のFQDN指定。
#     指定しなくても、<External IP>.xip.io が自動設定される。一番ラク。
#     指定ならば、下記注意参照。
export KUBEFLOW_HOSTNAME=miya-kubeflow.localdev

# (任意)ダッシュボードログイン時のパスワードの指定。
export KUBEFLOW_AUTH_PASSWORD=p@ssw0rd

# kubeflowのインストールは、かなり時間がかかるので気長に待つ。ひたすら待つ。
microk8s enable kubeflow

注意

KUBEFLOW_HOSTNAMEに、例のように内部で使うドメインを指定する場合、CoreDNSのForwarderに内部DNSを指定する必要がある。(自分はこれをしないと動かなかった。)

以下やりかた。

  • ConfigMapを編集。
microk8s kubectl -n kube-system edit configmap coredns

forwardに、Google Public DNS(8.8.8.8,8.8.4.4)が二箇所確認できるはずなので、内部DNSを追加ないし、置き換える。

  • Podの再構成。

待っていれば自動で反映されるはず。が、さっとやりたいので。

# CoreDNSのPod名検索
microk8s kubectl get pods -o=name -n kube-system | grep coredns

# Podを消して、Deployを強制。
microk8s kubectl delete -n kube-system <Pod名>

確認

  • 正常にインストールが終了すると、こんな感じの文章が出力される。
Congratulations, Kubeflow is now available.

The dashboard is available at http://<KUBEFLOW_HOSTNAMEで設定したやつ>/
    Username: admin
    Password: <KUBEFLOW_AUTH_PASSWORD>で設定したやつ

To see these values again, run:
    microk8s juju config dex-auth static-username
    microk8s juju config dex-auth static-password

To tear down Kubeflow and associated infrastructure, run:
   microk8s disable kubeflow
  • コンテナが正常に上がっているか確認。
microk8s kubectl -n kubeflow get all

# kubectlが異常に遅いとき →下の「kubectlがやたらと重い」参照

# Ambassadorに注目すると、External IPがセットされているはず。
# NAME                    TYPE           CLUSTER-IP       EXTERNAL-IP    PORT(S)             AGE
# service/ambassador      LoadBalancer   10.152.183.147   192.168.0.15   80:30617/TCP        14h
  • ブラウザに設定したホスト名でアクセスし、ダッシュボードを表示&ログイン。 インストール完了。

kubectlがやたらと重い

${HOME}/.kube の所有者がrootになっている場合、sudoなしでkubectlを利用すると遅くなることがあるみたい。所有者をユーザにする。

自作イメージでJupyter NoteBook立ち上げ

tl; dr

公式ドキュメント - Create a Custom Jupyter Image の起動コマンド使えば、自作コンテナイメージ作れる。

以降でやること

  • カスタムしたコンテナイメージの作成。
  • レジストリへ登録。
  • 登録したイメージでの、Notebook Sever立ち上げ。

DockerFile作成

以下のDockerFileを利用。

  • Point
    • 永続Volumeは、/home/jovyan にマウントされる
    • CMDの引数部は、Create a Custom Jupyter Imageのドキュメントをそのまま使えばいい。
JupyterLabのカスタムイメージ
FROM tensorflow/tensorflow:2.1.0-gpu-py3-jupyter

MAINTAINER miya_sh

WORKDIR /home/jovyan
RUN pip3 install --no-cache-dir jupyterlab && mv /tf /home/jovyan/

RUN useradd -m -s /bin/bash jovyan
USER jovyan

ENV NB_PREFIX /
CMD ["bash", "-c", "jupyter lab --notebook-dir=/home/jovyan --ip=0.0.0.0 --no-browser --allow-root --port=8888 --NotebookApp.token='' --NotebookApp.password='' --NotebookApp.allow_origin='*' --NotebookApp.base_url=${NB_PREFIX}"]

レジストリへPush

DockerHubなど好きなレジストリにイメージを登録。

ここでは、オンプレで使えるDocker Registryを使う。

# 別マシン(ここでは 192.168.0.10)にレジストリを作る
docker run --rm -d -p 5000:5000 -v ${PWD}/images:/var/lib/registry registry

# 先ほどのDockerFileをビルド&プッシュ
docker build -t 192.168.0.10:5000/kubeflow-jupyter/tensorflow:2.1.0-gpu .
docker push 192.168.0.10:5000/kubeflow-jupyter/tensorflow:2.1.0-gpu

Notebook Sever立ち上げ

公式ドキュメントにあるように、ナビゲーションからサーバ作成を行う。

  • 作ったイメージを指定する。

  • GPUを使う場合、ベンダー(nvidia.com/gpuamd.com/gpu)および個数をExtra Resourcesに指定する。
    例){"nvidia.com/gpu": "1"}

  • LAUNCHで作成。初回はイメージPullのため時間がかかる。

  • CONNECTで無事Jupyter Labとつながれば、ほっと一息。
    念の為、TensorFlowのバージョンとか、GPU見えているか確認。

    学習まで試す用に→TensorFlow 2.0 公式チュートリアル


MicroK8sのマルチノードで、散らばってるGPUが活用できないか、シームレスな学習環境を作れるか試してみたい・・・