💐

Ubuntu Server上のMicroK8sにKubeflowとMLflowをインストールする方法

2023/07/05に公開

はじめに

Kubeflow は Google が社内で使っていた MLOps 基盤を OSS として公開したもので、Kubernetes 上で動作させることを前提に開発されている。また、MLflow は Databricks が OSS で開発している機械学習モデル開発の実験管理ツールである。MLflow はサーバーを立てずに動作させることもできるが、MinIO(OSS の S3 互換オブジェクトストレージ)と連携させることで、実験結果をチームで共有することができる。これらのツールを組み合わせると、無料で自分のサーバー上に MLOps 基盤を構築することができる。

この記事では Canonical 社のチュートリアルに従い、Microk8s 上に Kubeflow と MLflow の環境構築を行う。この記事の内容はローカルネットワーク上で実験的に動作させることを想定しており、サーバーにグローバル IP を割り当てて動作させることは前提としていない。その点は注意してほしい。

Kubeflow のインストール

この章では、以下の記事に従い Kubeflow をインストールを行う。記事執筆時点の Kubeflow の最新バージョンは 1.7 である。

https://charmed-kubeflow.io/docs/get-started-with-charmed-kubeflow

はじめに、microk8s をインストールする。

$ sudo snap install microk8s --classic --channel=1.25/stable
$ sudo snap alias microk8s.kubectl kubectl

Kubeflow 1.7 は k8s version 1.24/1.25 上での動作をサポートしている[1]。そのため、今回は microk8s 1.25 をインストールした。

次に、microk8s の addons を有効化する。

$ microk8s enable dns storage hostpath-storage ingress metallb:10.64.140.43-10.64.140.49
$ microk8s enable gpu dashboard

gpu は microk8s 上のコンテナが GPU を認識できるようにするための addon であり、dashboard は microk8s の運用監視用の addon である。

以下のコマンドで dashboard にアクセスできる。

$ microk8s dashboard-proxy

この時、chrome に「この接続はプライバシーが保護されません」と表示することがある。このエラーはthisisunsafeと打つと解決できる[2]

次に juju をインストールする。juju は canonical が開発しているデプロイ自動化ツールであり、k8s やパブリククラウド上に様々なソフトウェアを簡単にインストールできる[3]

sudo snap install juju --classic --channel=2.9/stable

juju v3 以降で bootstrap で microk8s を選択できなくなった。そのため 2.9 を選択する。

以下、コマンドで MicroK8s 上に Kubeflow をインストールすることを宣言できる。

juju bootstrap microk8s
juju add-model kubeflow

実際にデプロイする前に、sysctl.conf の設定を以下のように書き換える。

$ cat /etc/sysctl.conf

fs.inotify.max_user_instances=1280
fs.inotify.max_user_watches=655360

これをしないと Linux の監視ファイル対象の上限に達しコンテナが立ち上がらなくなる[4]

実際にデプロイする。

$ juju deploy kubeflow --trust

kubectl get po -n kubeflowで pods のステータスを確認し、istio 関連でエラーになっていた場合、以下のコマンドで解決する場合がある。

$ juju run --unit istio-pilot/0 -- "export JUJU_DISPATCH_PATH=hooks/config-changed; ./dispatch"

最後に、認証の設定を行う。

$ juju config dex-auth public-url=http://10.64.140.43.nip.io
$ juju config oidc-gatekeeper public-url=http://10.64.140.43.nip.io
$ juju config dex-auth static-username=admin
$ juju config dex-auth static-password=admin

dex は k8s 上で認証を実現する機能である。public-url でアクセスするドメインを指定している。これは、この記事の最後で ingress を設定する際に書き換える。また、dex-auth でユーザー名とパスワードを設定する。admin は Kubeflow から jupyter notebook の pods を立てた時の namespace として用いられる。

これで Kubeflow の構築は完了である。ssh -D 9999 <server>でサーバーに ssh した状態で、ブラウザで socks プロキシとして 127.0.0.1:9999 を設定し、http://10.64.140.43.nip.ioにアクセスすれば Kubeflow が扱える。

MLflow のインストール

この章では、以下の記事に MLflow のインストールを行う。

https://charmed-kubeflow.io/docs/integrate-with-mlflow

以下のコマンドで、MLflow をインストールできる。

$ juju deploy mlflow-server
$ juju deploy charmed-osm-mariadb-k8s mlflow-db

ここで、juju statusで mlflow-server が wait 状態になるのを待つ。その後、以下コマンドで mlflow に kubeflow のデータベース等を関連付ける。

$ juju relate minio mlflow-server
$ juju relate istio-pilot mlflow-server
$ juju relate mlflow-db mlflow-server
$ juju relate mlflow-server admission-webhook

Kubeflow と同様に socks プロキシを設定して、http://10.64.140.43.nip.io/mlflow/にアクセスすれば mlflow にアクセスできる。

MinIO の設定

Charmed Kubeflow には MinIO が含まれている。MinIO の WebUI の管理画面にもアクセスできるようにする。

https://charmed-kubeflow.io/docs/allow-access-minio

以下コマンドでパスワードを設定する。

juju config minio secret-key=<password>

パスワードは 8 文字以上である必要がある。MinIO の管理画面には Ingress を設定するとアクセスできるようになる。

アンインストール方法

上記の手順で失敗した場合は、以下の手順に従ってアンインストールが可能である。

https://charmed-kubeflow.io/docs/uninstall

juju destroy-model kubeflow --yes --destroy-storage --force
juju destroy-controller microk8s-localhost

また、microk8s をリセットしたい場合は、microk8s resetが使える。

Ingress の設定

MicroK8s は Ingress をサポートしている[5]。そのため以下のようにして、Ingress を作成すれば、LAN 内の別のパソコンから Kubeflow や MinIO にアクセス可能である。

kubeflow-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubeflow-ingress
  namespace: kubeflow
spec:
  rules:
  - host: "192.168.0.5.nip.io"
    http:
      paths:
      - pathType: Prefix
        path: /
        backend:
          service:
            name: istio-ingressgateway-workload
            port:
              number: 80
  - host: "minio.192.168.0.5.nip.io"
    http:
      paths:
      - pathType: Prefix
        path: /
        backend:
          service:
            name: minio
            port:
              number: 9001

kubectl apply -f kubeflow-ingress.yamlで Ingress を有効化できる。この後、以下の設定を行う。

$ juju config dex-auth public-url=http://<server ip>.nip.io
$ juju config oidc-gatekeeper public-url=http://<server ip>.nip.io

これで、LAN 内からhttp://<server ip>.nip.ioで Kubeflow にアクセス可能となる。さらに、http://minio.<server ip>.nip.ioで MinIO にアクセス可能である。

MinIO の画面は以下のようになる。

おわりに

MicroK8s 上に Kubeflow と MLflow の環境構築を行った。Canonical 社のエコシステムを使えば簡単に本格的な Kubeflow 環境が作成できることがわかった。MicroK8s は複数ノードにすることも可能[6]であり、NVIDIA DGX にインストールすることも可能[7]であるため、この記事で示したインストール方法はベンチャー企業や大学研究室のオンプレ機械学習環境ぐらいまではスケールすると思う。

また、最近の Canonical 社はデータセンターをパブリッククラウドのような機能を持たせる OSS を積極的に開発している。本格的な環境として、MAAS と Charmed OpenStack と Charmed Kubernetes を組み合わせて基盤を作った上に、Kubeflow などの OSS をデプロイすることも可能である。AI が発展し一般の企業が使うデータ量や計算リソースが今の何倍にも膨れ上がった時、クラウド上のコストがかかる部分をオンプレ回帰させてることになったら、これらを使うことになると思う。

Kubeflow や MLflow の使い方についてはまだわかっていない部分が多い。これらは使いこなせるようになりたい。

関連記事

https://zenn.dev/derbuihan/articles/928ae5f279afbc

https://zenn.dev/derbuihan/articles/cb6b7a84dd6dc0

https://zenn.dev/derbuihan/articles/a1e636d29e1b51

追記

Nvidia Driver をアップデートしたらCan't run container using nvidia-docker - libnvidia-ml.so.1というエラーが出て壊れてしまった。

全てのコンテナを削除し snap remove microk8s を実行して microk8s を削除してリセットしてから、上記のインストールを再実行したら解決した。結局原因はよくわからなかった。microk8s の gpu addon のドキュメント[8]を参考に nvidia-container の設定をすれば治ったのかもしれない。次エラーになったらこのドキュメントを試してみる。

脚注
  1. https://www.kubeflow.org/docs/releases/kubeflow-1.7/ ↩︎

  2. https://qiita.com/TK-C/items/13efa5a45beb6de29134 ↩︎

  3. https://charmhub.io/ ↩︎

  4. https://knowledge.sakura.ad.jp/31502/ ↩︎

  5. https://microk8s.io/docs/addon-ingress ↩︎

  6. https://microk8s.io/docs/clustering ↩︎

  7. https://microk8s.io/docs/nvidia-dgx ↩︎

  8. https://microk8s.io/docs/addon-gpu ↩︎

Discussion