
はじめに
こんにちは。クラウド事業部の山田です。
以前の業務において、Kubernetes上で機械学習ワークフローを構築、実行できる Kubeflow を扱いました。
今回は Windows上の Kubernetes IN Docker (以下、kind) で手軽に構築する方法を検証しました。
なお、実際に学習を行うパイプラインの詳細については省略します。
目次
概要
kind にて Kubenetesマスターとノードの機能を持つコンテナを1つずつ立ち上げ、そのクラスターに kind をインストールします。
Hyper-V上の仮想マシンとは異なりSSH接続やコンソール接続は不要で、ホストOSの Docker Desktop と PowerShell から操作します。
検証
導入
kindのインストール
・必要なパッケージのインストール
・管理者権限でPowerShell起動します。
・Chocolatey(Windowsのパッケージマネージャー)をインストールします。
> Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
⇒ 2.5.1
・必須ツールをインストールします。
> choco install -y docker-desktop kubernetes-cli kustomize git
・パスを手動登録してツールが使用できることを確認する。
> setx PATH "$env:PATH;C:\Program Files\Docker\Docker\resources\bin"
⇒ 2.5.1
> docker --version
⇒ Docker version 28.3.3, build 980b856
> kubectl version --client
⇒ Client Version: v1.34.0
Kustomize Version: v5.7.1
> kustomize version
⇒ v5.5.0
> git --version
⇒ git version 2.51.0.windows.1
・Kindをインストールします。
バージョンの選定
> cd x:\xxx\work
> curl.exe -Lo kind-windows-amd64.exe https://kind.sigs.k8s.io/dl/v0.30.0/kind-windows-amd64
> move .\kind-windows-amd64.exe C:\ProgramData\chocolatey\bin\kind.exe
> kind --version
⇒ kind version 0.30.0
K8sクラスターの構成
・K8sクラスターを構成します。
・yamlファイルを作成します。
> notepad kind-config.yaml
kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane extraPortMappings: - containerPort: 30080 hostPort: 80 protocol: TCP - containerPort: 30443 hostPort: 443 protocol: TCP - role: worker
・クラスターの構成に入ります。
> kind create cluster --name kubeflow --config kind-config.yaml
> kubectl version
⇒ Client Version: v1.34.0
Kustomize Version: v5.7.1
Server Version: v1.34.0
> kubectl get nodes
⇒ NAME STATUS ROLES AGE VERSION
kubeflow-control-plane Ready control-plane 39s v1.34.0
kubeflow-worker Ready
> kubectl get pods -A
⇒ NAME STATUS ROLES AGE VERSION
kube-system ネームスペースの各種Podが "Running" ステータスとなっていること。
Docker Desktop からもマスターとノードのサーバーの役割を持つコンテナを確認できます。

・コンテナの自動起動を無効化します。( Docker Desktop 起動と同時に起動しないようにする。)
> docker inspect -f '{{ .Name }} {{ .HostConfig.RestartPolicy.Name }}' $(docker ps -aq)
⇒ on-failure:異常終了したときは自動的に再起動される。
/kubeflow-control-plane on-failure
/kubeflow-worker on-failure
> docker update --restart=no kubeflow-control-plane
> docker update --restart=no kubeflow-worker
> docker inspect -f '{{ .Name }} {{ .HostConfig.RestartPolicy.Name }}' $(docker ps -aq)
⇒ no:再起動しない。
/kubeflow-control-plane no
/kubeflow-worker no
Kubeflowのインストール
参考)
Deploying Kubeflow Pipelines
バージョンの選定
Kubeflowをインストールします。
> $env:PIPELINE_VERSION=2.16.0
> kubectl apply -k "github.com/kubeflow/pipelines/manifests/kustomize/cluster-scoped-resources?ref=$env:PIPELINE_VERSION"
> kubectl wait --for condition=established --timeout=60s crd/applications.app.k8s.io
> kubectl apply -k "github.com/kubeflow/pipelines/manifests/kustomize/env/platform-agnostic?ref=$env:PIPELINE_VERSION"
> kubectl get pods -A
⇒ NAME STATUS ROLES AGE VERSION
kube-system ネームスペースに加えて kubeflow ネームスペースの各種Podが "Running" ステータスとなっていること。

ダッシュボードの表示
ダッシュボードを表示します。
・ダッシュボード表示の都度、ポートフォワードを設定します。
> kubectl port-forward -n kubeflow svc/ml-pipeline-ui 8080:80
・ブラウザでアクセスします。
http://localhost:8080/

パイプライン作成の概要
パイプライン作成には下記の準備が必要です。
・Kubeflowから参照できるコンテナイメージ
学習や推論のプログラムを含むコンテナイメージをビルドして利用します。
kind の場合は、ホストOSでビルドして kind にプッシュします。
・パイプライン定義ファイル
下記機能から成り、単一ファイルにまとめることも分割することもできます。
・パイプライン定義:ワークフローを定義します。
例:学習フェーズの後に推論に入る。学習(エポック)を指定回数繰り返す。など
・コンポーネント定義:パイプラインから呼び出されるPodを定義します。
具体的にはパイプライン定義から呼び出される学習Podや推論Podのマニフェストを記載します。
コンテナイメージを登録します。
・ホストOSでコンテナイメージをビルドします。
> cd x:\xxx\work
> docker build -t <イメージ名>:latest -f Dockerfile.txt .
・Kubeflowにおいて latest タグを指定するとインターネットからの参照を優先する場合があるため任意のタグをつけます。
> docker tag <イメージ名>:latest <イメージ名>:1.0
> docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
・・・
<イメージ名> 1.0 2f3ecb164bb3 7 minutes ago 186MB
<イメージ名> latest 2f3ecb164bb3 7 minutes ago 186MB
・・・
・コンテナイメージを Kind にコピーします。
> kind load docker-image <イメージ名>:1.0 --name kubeflow
> docker exec -it kubeflow-worker crictl images
IMAGE TAG IMAGE ID SIZE
・・・
docker.io/library/<イメージ名> 1.0 cd474570c9360 45.4MB
・・・
ホストOSにてパイプライン定義ファイルをコンパイルするための設定を行います。
・Kubeflow Pipelines SDK をインストールします。
インストール済みの Kubeflow に対応するバージョンを指定します。
> kubectl get deployment -n kubeflow -o yaml | Select-String "image:" | Select-String "kfp"
⇒ image: ghcr.io/kubeflow/kfp-api-server:2.14.3
> pip install kfp==2.14.3
> pip show kfp
⇒ Name: kfp
Version: 2.14.3
Summary: Kubeflow Pipelines SDK
~
パイプライン定義ファイルをコンパイルします。
・python xxxx.py
⇒ 上記ファイルで指定した名前の yaml ファイルが出力されます。
基本的なワークフロー実行までの操作
ワークフロー実行のために下記リソースを作成します。
・Experiments:そのワークフローを実行するプロジェクト。(利用者グループごとに作成するなど。)
・Pipeline:ワークフローの設計図。
・Run:Pipelineの実行インスタンス。
Experimentsを登録します。
1) メニュー[Experiments]を開きます。
2) 右上[Create experiments]を開きます。
3) 表示される[New experiment]画面にて、下記設定で Experiment を登録します。
Experiment name:<Experiment名を指定>

Pipelineを登録します。
1) メニュー[Pipelines]を開きます。
2) 右上[Upload pipeline]を開きます。
3) 表示される[New Pipeline]画面にて、下記設定で Pipeline を登録します。
Pipeline:<Pipeline名を指定>
Upload a file:<作成したパイプライン定義ファイルをアップロードします>


Runを開始します。
1) メニュー[Runs]を開きます。
2) 右上[Create run]を開きます。
3) 表示される[Start a new run]画面にて、下記設定で Run を開始します。
Pipeline:<Pipeline名を指定>
Run name:<Run名を指定>
Experiment:<登録したExperimentを指定>
Run Type:One-off は単体の実行、Recurring ではcron形式で時間指定が可能です。
その他、パイプライン定義に含まれるコンポーネント(学習や推論の各フェーズ)が引数を要する場合は、ここで表示されるテキストボックスで指定します。


Runを開始すると下記のようなフローが表示されます。
複数のコンポーネントで構成される場合はそれらが線で接続され、終了したものからアイコンが変化します。

まとめ
Kubeflow のインストールについては、実機や仮想マシンに Kubernetes が導入済みであれば即実施可能であり、特に kind を使用すれば容易です。
一方で、実務でもつまづいたところですが Kubeflow のバージョン違いによりワークフローが動作しないことが多く、すべての環境でバージョンを統一したうえでローカル検証と実機への実装を進める必要があります。