Windows10でkubeflowを導入しようとした話


# 1. はじめに
こんにちは。Yahoo! JAPAN 2018年新卒の高木です。
この記事はヤフー株式会社の2018年新卒有志でつくる[Yahoo! JAPAN 18 新卒 Advent Calendar 2018](https://adventar.org/calendars/3388)の19日目の記事です。

前回は[Mako Matsui](https://adventar.org/users/21880)さんによる[3Pタスク分析を少しだけ広めたい](https://qiita.com/matsuk0901/items/ba5b25a6898d046be168)でした。

この記事では、windows10のHyper-V上に[minikube](https://github.com/kubernetes/minikube)にて構築された[kubernetes](https://kubernetes.io/)にkubeflowをインストールして触っていたら「プルリクチャンスがやってきた！」の記事になります。

※この手順は2018/12/10時点での手順を示しています。
※今後のアップデートでこの手順ではできなくなる場合がありますので、ご了承ください。

## 1.1 前提条件
ローカルマシンに以下の環境を用意してあることを前提に進めていきます。
※参考までに、自分はこの順で導入しました。

- Windows10 Pro(64bit)
- Hyper-V
- kubectl
- minikube

## 1.2 kubeflowって？
[kubeflow](https://www.kubeflow.org/)はざっくり言うと[kubernetes](https://kubernetes.io/)(以下k8s)上に簡単に[TensorFlow](https://www.tensorflow.org/?hl=ja)による機械学習用の環境を構築できるものです。[Jupyter](https://jupyter.org/)を複数ユーザーで使えるJupyterHubや学習用の分散環境が簡単に構築できるTensorFlow Training Controller、構築したモデルを運用サーバーなどにデプロイする時に便利な[TensorFlow Serving](https://www.tensorflow.org/serving/)などが用意されています。
一般的に、クラウドベンダーの仮想環境に導入する方法がよく紹介されていますが、今回は自分のWindowsマシンに導入しようと試みました。

# 2. 準備
さて、ここからは準備に入っていきます。作業ディレクトリをあらかじめmkdirなりで準備して作業してください。

## 2.1 ksonnetのインストール
kubectlの導入と同じように、[ksonnet](https://ksonnet.io/)の[最新のバイナリ](https://github.com/ksonnet/ksonnet/releases)(ファイル名にwindows_amd64とついているファイルです　例：ks_0.13.1_windows_amd64.zip)をダウンロードして適当なフォルダに置いたら、環境変数のPathを通すだけです。

## 2.2 ksonnetでサンプルを動かす準備
次にksonnetでkubeflowを準備します。今回はお試しなので、サンプルを動かしてみましょう。作業の前に```minikube start --cpus 4 --memory 8096 --disk-size=40g```にてminikubeを立ち上げておきましょう。立ち上がったら、以下のコマンドを打ち込みます。

```shell
>ks init kubeflow
>cd kubeflow
>ks registry add kubeflow github.com/google/kubeflow/tree/master/kubeflow
>ks registry add kubeflow-git github.com/kubeflow/kubeflow/tree/master/kubeflow
>ks pkg install kubeflow/core
>ks pkg install kubeflow/tf-serving
>ks pkg install kubeflow-git/examples
>ks generate tf-job-simple kfjob --name=kfjob
>kubectl config use-context minikube
>ks env add minikube
```

※```ks pkg install```のところは```ks pkg install kubeflow-git/examples```だけでもよいかもしれないです。
※途中で```～～ 403 API rate limit exceeded for ～～～ [rate reset in 40m13s]```のようなエラーが出たときは、```rate reset **m**s```の時間だけ待つか、個人で発行したGitHubのapiトークンを新規の環境変数```GITHUB_TOKEN```として設定しましょう。

# 3. sampleを動かす
さて、準備ができたので、実際に動かしてみます。

## 3.1 動かして見ると・・・？
```shell
>ks apply minikube -c kfjob
←[31mERROR←[0m find objects: RUNTIME ERROR: open <extvar:__ksonnet/k.libsonnet: The filename, directory name, or volume label syntax is incorrect.
        <extvar:__ksonnet/components>:5:15-35   thunk <k> from <object <anonymous>>
        <extvar:__ksonnet/components>:76:5-6    object <anonymous>
        During manifestation
```

エラーが出力されて動かないので、エラーの内容で調べてみましょう。すると、以下のissueが出てきました。
["ks apply" fails to correctly process paths in Windows shell](https://github.com/ksonnet/ksonnet/issues/382)

そこを確認すると、環境変数まわりのバグか設定ミスが疑われることが関連issueなどから推察されます。実際、[kubeflowのトラブルシューティング](https://www.kubeflow.org/docs/guides/troubleshooting/)にもこのissueのリンクが参考として貼られています。

## 3.2 エラーの原因を探してみる
エラーの場所が表示されているので、実際にその場所を見に行ってみましょう。
エラーでは、```__ksonnet/k.libsonnet```が取得できていないと出ています。
```k.libsonnet```の場所は```<最初の作業ディレクトリ>/kubeflow/lib/ksonnet-lib/v1.10.0/```にあることが確認できるので、覚えておきます。
ここで、起動コマンドをたたくと最初に呼ばれる```kfjob.jsonnet```のエラーが出ている行数の所に着目すると・・・
![kfjob.png](https://qiita-image-store.s3.amazonaws.com/0/136925/c65f4157-655d-e58f-3cf9-6777a83befc3.png)
赤枠真ん中あたりに```k.libsonnet```をimportしている部分があります。ここを先ほどのPathの絶対パスを記述してあげて保存し、再度実行してみると・・・

```bash
>ks apply minikube -c kfjob
←[31mERROR←[0m handle object: patching object from cluster: merging object with existing state: unable to recognize "C:\\Users\\<ユーザー名>\\AppData\\Local\\Temp\\ksonnet-mergepatch756503975": no matches for kind "TFJob" in version "kubeflow.org/v1alpha2"
```
エラー内容が変わりました。
今度はTFJobが```kubeflow.org/v1alpha2```から見つからないような旨のようです。
TFJobについては[公式ドキュメント](https://www.kubeflow.org/docs/guides/components/tftraining/)に説明があります。

ここまでくると環境のenvironmentsやparamsなどの```__ksonnet```配下のファイルパスがすべて疑わしいものとなります。

# 4. 解決策を予想してみる
解決策ですが、windows10のhyper-Vにて構築する際のksonnetのコードの中またはkubeflowのコードで各種パスが正しく設定されるようにkubeflow側の設定コードをたどって変えることで、動く可能性が高いと考えられます。（あくまで推測です）
一応、似たような試みを[このissue](https://github.com/ksonnet/ksonnet/issues/538)でも行われていますが、進展がないようです。

また、同様に都度パスを見直して少しずつ通す王道の方法で解決できるかもしれません。（あくまで推測です）
issueやプルリクを書いてメジャーリリースまでに修正してもらうことを目指したほうがよさそうです。

ここから先は引き続きkubeflowのコミュニティでも議論が続いているようです。

# 5. 結論
結論として、記事作成時点(2018/12/10時点)ではhyper-v上のminikubeにkubeflowをのせて動かすことができませんでした。まだ、記事作成時点ではα版で、v1.0.0のメジャーリリースはされていないので、自己研鑽の一環として本格的に調査してプルリクを投げてみるのもいいかもしれないですね。

また、少し本筋からはそれますが、現状ではBash on WindowsにてLinuxでの構築と同様の方法、つまり[こちらの公式ドキュメント](https://www.kubeflow.org/docs/started/getting-started/)を参考にシェルスクリプトの実行で作成できるようなので、挑戦してみてはいかがでしょうか？

自分はせっかくの機会なので引き続き調査してOSS貢献に挑戦したいと考えています。