BluemixのKubernetesクラスターにDockerHubのTensorFlowイメージをデプロイする

以前にも[BluemixのDockerコンテナ上でTensorFlowを動かす手順](http://qiita.com/takeyan/items/7956ec65e9cca367f8bd)を書いたことがあるのですが、一年も経たないうちに時代遅れの役立たずになってしまいました。
BluemixがKubernetesクラスタ環境の提供を開始し、今後はこれに一本化されるようなので、Kubernetesを前提に全面改訂しました。手順は以下のとおりです。

1. Kubernetesクラスターを作成する
2. CLI環境をセットアップする
3. TensorFlow用Pod定義ファイルを作成する
4. TensorFlowイメージをデプロイする

------

## 1. Kubernetesクラスターを作成する

Bluemixアカウント（トライアルアカウントでOK）はすでに持っている前提で話を進めます。本記事では次のアカウントを使用しています。

+ アカウント名（IBMid）：bmx01@takeyan.xyz
+ 組織名：bmx01
+ スペース名：Dallas

まずBluemixのポータル（https://bluemix.net ）にログインし、カタログのページに移動して、左ペインの全てのカテゴリーから「コンテナー」を選択します。
「Kubernetes Cluster」の方をクリックして、作成画面に入ります。（「Container Registry」タイトルを選択とか言っていますが気にせずに（笑））
<img width="1280" alt="Screen Shot 2017-09-17 at 9.47.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/32083/a3ebbddb-a20c-fe66-b8b8-9e7545275040.png">

作成画面でそのまま「クラスターの作成」をクリックします。クラスター名はデフォルトのmyclusterで構いません。
<img width="1280" alt="Screen Shot 2017-09-17 at 9.49.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/32083/95197f2d-0146-db1c-cafa-da75061f074b.png">

画面が切り替わりますが、まだクラスターは作成中です。
<img width="1280" alt="Screen Shot 2017-09-17 at 9.55.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/32083/5996eff1-e055-0f19-6c26-297825ba1263.png">

Prerequisites以下には、後の手順で使うコマンドが紹介されているので参考にして下さい。
<img width="1280" alt="Screen Shot 2017-09-17 at 9.54.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/32083/b91a3986-8b17-7f4f-19b1-37b57e7f5388.png">

「準備完了」になったら「ワーカー・ノード」のページを開いて、ノードに割り当てられている「パブリックIP」をメモしておいて下さい。ここでは184.172.229.128になっています。TensorFlowのデプロイまで進んだ後、最後にこのIPアドレスにアクセスします。
<img width="1280" alt="Screen Shot 2017-09-17 at 10.19.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/32083/d8cdb1ef-9d4a-a2c6-44c7-5b28b09bdec6.png">

「デプロイ中」が「準備完了」に変わるまで結構時間がかかるようです（経験上は10〜20分程度）。
ここでクラスター作成は「デプロイ中」のまま一旦放置して、Bluemixがクラスターを準備している間にCLIのセットアップに進むことにします。



## 2. CLI環境をセットアップする
### 2-1. Bluemix CLIをインストールする
最新のインストーラーを[こちらのページ](https://clis.ng.bluemix.net/ui/home.html)からダウンロードして実行して下さい。
MacやLinuxユーザーで、ターミナルからコマンド一発でインストールしたい方は以下のコマンドを実行して下さい。

```bash:macOS
sh <(curl -fsSL https://clis.ng.bluemix.net/install/osx)
```

```bash:Linux
sh <(curl -fsSL https://clis.ng.bluemix.net/install/linux)
```

Windowsでもコマンドによるインストールが可能です。手順の詳細は[こちら](https://console.bluemix.net/docs/cli/reference/bluemix_cli/index.html#install_bluemix_cli)を参照して下さい。

### 2-2. コンテナサービス用プラグインをインストールする

Bluemix CLIがインストールできたら、Bluemixのコンテナサービス用プラグインを追加でインストールします。以下のコマンドを実行して下さい（Mac,Linux,Windows共通です）。

```bash
bx plugin install container-service -r Bluemix
bx plugin list
```

以下にWindows環境での実行例を示します。
<img width="1127" alt="Screen Shot 2017-09-14 at 11.05.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/32083/185a609e-3e69-ebdf-ccec-33d34f49b031.png">


手順の詳細は[こちら](https://console.bluemix.net/docs/containers/cs_cli_install.html#cs_cli_install)を参照して下さい。


### 2-3. Kubernetes CLIをインストールする

Kubernetes CLIのインストール手順は[こちらのページ](https://kubernetes.io/docs/tasks/tools/install-kubectl/)に説明があります。
また[こちらのページ](https://console.bluemix.net/docs/containers/cs_cli_install.html#cs_cli_install)のプラグインインストール手順の直後の③④にも説明があります（こちらの方が日本語なのでわかりやすいかも知れません）。
以下はKubernetesのWebサイトのインストール手順説明のページです。該当するOS環境のタブをクリックして手順を確認して下さい。
<img width="1280" alt="Screen Shot 2017-09-14 at 10.12.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/32083/4e016924-b5fe-62b8-f3bf-fca4a0ae593b.png">

MacおよびLinuxの場合はそれぞれターミナルで次のコマンドを実行します。

```bash:macOS
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/darwin/amd64/kubectl
chmod +x ./kubectl 
sudo mv ./kubectl /usr/local/bin/kubectl 
```

```bash:Linux
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
chmod +x ./kubectl 
sudo mv ./kubectl /usr/local/bin/kubectl 
```

Windowsはkubectl.exeファイル（コマンドそのもの）がダウンロードされるので、これをPATHの通っているフォルダに置いて下さい。Bluemix CLIのフォルダ（C:\Program Files\IBM\Bluemix\bin）でもいいと思います。
kubectlを引数なしで実行して、引数の一覧が表示されたらOKです。



### 2-4. kubectlコマンド実行環境をセットアップする

kubectlコマンドで、Bluemix上のKubernetesクラスター環境に接続して操作するための環境をセットアップします。手順は[こちら](https://console.bluemix.net/docs/containers/cs_cli_install.html#cs_cli_install)の「IBM Bluemix Container Service でクラスターに対して kubectl コマンドを実行するように CLI を構成する 」以下を参照して下さい。
Bluemix CLI（bxコマンド）でBluemixにログインして、一連の手順を実行して下さい。以下の例では米国南部リージョンにログインしています。他のリージョンで組織とスペースを作成した場合は、該当リージョンのAPIエンドポイントを指定して下さい。

```bash
bx login -a api.ng.bluemix.net
```

Emailアドレス（Bluemixアカウント名）とパスワードを聞かれるので、適宜応答して下さい。
アカウントの選択の要求には、数字で（おそらく選択肢は1だけだと思いますが）応答して下さい。
ログインしたら次のコマンドでtargetをセットして下さい。

```bash
bx target -o 組織名 -s スペース名
```

ここまでの例を以下に示します。
<img width="979" alt="Screen Shot 2017-09-17 at 10.33.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/32083/29eacea4-4d42-8922-d720-91a0b09b4e93.png">

続いてコンテナサービスの環境をセットアップします。ここでクラスター名は、Bluemixポータル画面でKubernetesクラスターを作成した際のクラスター名です。デフォルトのままならmyclusterです。

```bash
bx cs init
bx cs cluster-config クラスター名
```

bx cs cluster-configコマンドを実行すると、応答としてKUBECONFIG環境変数をセットするコマンドが表示されるので、これをコピペしてそのまま実行します。コマンド内のymlファイル名はKubernetesクラスターによって異なるので、過去に保存したコマンドではなく、必ずその都度bx cs cluster-configコマンドの応答で得られたコマンドを実行して下さい。

```bash:macOS/Linux
export KUBECONFIG=/Users/takey/.bluemix/plugins/container-service/clusters/mycluster/kube-config-・・・
```

```text:Windows
SET KUBECONFIG=C:\Users\takey\.bluemix\plugins\container-service\clusters\mycluster\kube-config-・・・
```

実行後は確認のためkubectl get nodesコマンドを実行します。

```bash
kubectl get nodes
```

ここまでの実行例を以下に示します。
<img width="980" alt="Screen Shot 2017-09-17 at 10.36.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/32083/d8e18e05-3108-c077-ae98-e9f9d0ce3c8c.png">

Kubernetesクラスターの作成がまだ実行中のタイミングでkubectl get nodesコマンドを実行するとエラー応答が返ります。下図のようにBluemixポータル画面で準備完了になってから再実行して下さい。
<img width="1280" alt="Screen Shot 2017-09-17 at 10.48.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/32083/49a997f2-188e-7d45-0b30-42e1b38fe230.png">


## 3. TensorFlow用Pod定義ファイルを作成する

kubernetesクラスタにデプロイするコンテナは、podという単位で管理されます。コンテナをpodで包んでデプロイする感じです。一つのpodに複数のコンテナを含めることもできるようですが、今回はTensorFlowひとつだけのpodを作成します。
podの定義はYAMLという書式で記述してファイルに保管します。
以下にpod定義の例を示します。

```yaml:my-tensor-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: my-tensor-pod
  labels:
    app: my-tensor
spec:
  containers:
    - name: tensorflow
      image: tensorflow/tensorflow:latest
      env:
      - name: PASSWORD
        value: "passw0rd"
```

"image:tensorflow/tensorflow:latest"のところで、DockerHubに公開されているTensorFlowのイメージを呼び出す指定をしています。
TensorFlowを立ち上げてブラウザでアクセスするとまずログイン画面が表示されるのですが、そこで入力するパスワードをあらかじめ決めておきます。
そのための定義がenv:以下の3行です。ここではパスワードとして"passw0rd"という値を入力していますが、安全のため推測しにくいパスワードに置き換えておいて下さい。

定義はテキストファイルに保存します。ここではmy-tensor-pod.ymlというファイルに保存したとして手順を続けます。



## 4. TensorFlowイメージをデプロイする

先に作成したmy-tensor-pod.ymlを使って、まずpodをkubernetesクラスターにデプロイします。続いてpodをサービスとして公開します。
以下の手順を実行します。

```bash
kubectl create -f my-tensor-pod.yml
```

pod "my-tensor-pod" createdという応答が返れば成功です。デプロイされたpodは次のコマンドで確認できます。


```bash
kubectl get pods
```

次にpodをサービスとして公開します。ここではサービス名をmy-tensor-svcとしています。

```bash
kubectl expose pods my-tensor-pod --type=NodePort --port=8888 --name=my-tensor-svc
```

公開されたサービスを確認します。サービスに割り当てられたポート番号が表示されるのでメモしておいて下さい。

```bash
kubectl get services
```

ここまでの実行例を以下に示します。kubectl get podsでREADYの表示が「1/1」になっていたら、podのデプロイが完了している印ですので先に進みましょう。
<img width="979" alt="Screen Shot 2017-09-17 at 10.44.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/32083/b50c8a6b-a1ac-ce7a-fcf6-92cf806d9f22.png">

先に確認したIPアドレス、ポート番号をWebブラウザに入力して（ここではhttp://184.172.229.128:31638 ）、TensorFlow（Jupyter Notebookサーバ）にログインします。ログイン画面が表示されたら、あらかじめpod定義に指定しておいたパスワードを入力して下さい。
<img width="1280" alt="Screen Shot 2017-09-17 at 10.59.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/32083/4245befc-b1b1-6973-743d-e4a0d1c125b7.png">

Jupyter Notebook一覧の画面が表示されたら成功です。
<img width="1280" alt="Screen Shot 2017-09-17 at 10.59.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/32083/43986c3f-29d3-dc75-6895-0763056f527a.png">



これらのJupyter Notebookは、BluemixのData Science Experience（DSX）にインポートして実行することもできます。手順をこちら（http://qiita.com/takeyan/items/83f061ccabeab94ad655 ）で紹介していますので、参考にして下さい。


以上です。