helmのtillerセットアップと簡易動作確認

# この記事について
簡易検証の必要があり、手元のWindows端末に用意したk8s cluster環境（vagrant）にhelmのtillerをセットアップした手順を整理したものです。（Qiitaで記事を作成する練習もかねてます。）
### 前提
Helm v2.9.1
※検証作業時には2.10はRC版のみだったため2.9.1を利用。
※kubernetes cluster環境はインターネットに接続な構成。

### 参考文献
 - RBACが有効なGKEでHelmを使う
https://www.sambaiz.net/article/160/
 - Helm Documentation - Using Helm
https://docs.helm.sh/using_helm/#example-deploy-tiller-in-a-namespace-restricted-to-deploying-resources-only-in-that-namespace
 - Vagrantで作成したローカルサーバにFTPクライアント(Cyberduck)からログインできないときの解決法
https://qiita.com/noraworld/items/a0fac559d2d6e76d50f8

## 作業概要
 - Githubから落としてきたtarをmaster-nodeにsftp
 - tarを展開してhelmファイルを/usr/local/binに配置
 - クラスターロールバインディングの作成
 - namespaceの作成
 - サービスアカウントの作成
 - Helm init（再実行）
 - Deploymentの確認
 - Helm リポジトリーのupdate
 - stableのリポジトリーからのインストール確認（稼動確認）
 - Helm ls（稼動確認）

## 作業詳細
### Githubから落としてきたtarをmaster-nodeにsftp
GitHub（下記サイト）からLinux用のバイナリーをダウンロードします。（作業時の最新の安定したバージョンが2.9.1であったためこのバージョンを採用しています。）
https://github.com/helm/helm/releases/tag/v2.9.1
Vagrangt上のk8s環境にファイル共有するためには鍵認証を使用しました。（手順は以下を参考にしました。）
[Vagrantで作成したローカルサーバにFTPクライアント(Cyberduck)からログインできないときの解決法
](https://qiita.com/noraworld/items/a0fac559d2d6e76d50f8)

### tarを展開してhelmファイルを/usr/local/binに配置
tarを展開して適切なディレクトリーに配置します。（Helmの公式ガイド通りです。）
> \# tar -zxvf helm-v2.9.1-linux-amd64.tar.gz
> linux-amd64/
> linux-amd64/README.md
> linux-amd64/helm
> linux-amd64/LICENSE
> \#
> \# ls -al linux-amd64/helm
> -rwxr-xr-x 1 root root 30033696 May 15 03:39 linux-amd64/helm
> \# mv linux-amd64/helm /usr/local/bin/helm
> \#

### クラスターロールバインディングの作成
GKEではデフォルトでK8sのRBAC(Role-Based Access Control)が有効になっている([役割ベースのアクセス制御](https://cloud.google.com/kubernetes-engine/docs/role-based-access-control))ため、Tillerインスタンスに権限を与える必要があるそうです。具体的には、"Tiller用にnamespaceを切って、その中では好きにできるRoleと、Tillerが使うServiceAccountを作成し、RoleBindingで紐づける作業"が必要です。（手元のVagrantのk8s clusterでも同様で有効になっていました。）
まず、Roleを追加するため、自分自身にsuper-user相当のcluster-adminroleをbindします。
※上記の解説は[RBACが有効なGKEでHelmを使う](https://www.sambaiz.net/article/160/)を引用しています。

なお、--userの値は~/.kube/configを参照して確認しました。

> \# kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=kubernetes-admin
> clusterrolebinding.rbac.authorization.k8s.io "cluster-admin-binding" created
> \#

### namespaceの作成
helmのtillerでデプロイする際に利用するnamespaceを作成します。以降の作業はここで作成したnamespace名を前提としています。
> \# kubectl create namespace tiller-world
namespace "tiller-world" created
> \#

### サービスアカウントの作成

kubectlコマンドでサービスアカウントtillerの作成を行います。yamlを使ってロール、サービスアカウント、ロールバインディングを一括で作成します。
> \# kubectl create -f tiller-rbac.yaml
> role.rbac.authorization.k8s.io "tiller-manager" created
> serviceaccount "tiller" created
> rolebinding.rbac.authorization.k8s.io "tiller-binding" created
> \# 

K8sのRBACの考え方は以下が参考になります。
[KubernetesのRBACについて](https://qiita.com/sheepland/items/67a5bb9b19d8686f389d)

tiller-rbac.yamlファイルについては[RBACが有効なGKEでHelmを使う](https://www.sambaiz.net/article/160/)の記事のものをそのまま利用させていただきました。

```yaml:tiller-rbac.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: tiller-manager
  namespace: tiller-world
rules:
- apiGroups: ["", "extensions", "apps"]
  resources: ["*"]
  verbs: ["*"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: tiller-world
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: tiller-binding
  namespace: tiller-world
subjects:
- kind: ServiceAccount
  name: tiller
  namespace: tiller-world
roleRef:
  kind: Role
  name: tiller-manager
  apiGroup: rbac.authorization.k8s.io
```
### Helm init（再実行）
先の手順で作成したサービスアカウントとネームスペースを指定してhelm initを実行します。

> \# helm init --service-account tiller --tiller-namespace tiller-world
> $HELM_HOME has been configured at /home/vagrant/.helm.
> Warning: Tiller is already installed in the cluster.
> (Use --client-only to suppress this message, or --upgrade to upgrade Tiller to the current version.)
> Happy Helming!
> \# 

### Deploymentの確認
tillerがデプロイされていることを確認します。
> \#  kubectl get deployment -n tiller-world
> NAME            DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
> tiller-deploy   1         1         1            1           10m
> \#

この時点ではhelmには何もインストールされていません。（当然ですが。）
> \# helm ls --tiller-namespace tiller-world --namespace tiller-world
> \#

### Helm リポジトリーのupdate
リポジトリーをupdateします。（インターネット経由でstableなリポジトリーを参照しているようです。）

> \# helm repo update --tiller-namespace tiller-world
> Hang tight while we grab the latest from your chart repositories...
> ...Skip local chart repository
> ...Successfully got an update from the "stable" chart repository
> Update Complete. ⎈ Happy Helming!⎈
> \#

### stableのリポジトリーからのインストール確認（稼動確認）
稼動確認のためにインストールを実行してみます。
> \# helm install stable/mysql --tiller-namespace tiller-world  --namespace tiller-world

実行例は以下です。

```cmake

# helm install stable/mysql --tiller-namespace tiller-world  --namespace tiller-world
NAME:   harping-kangaroo
LAST DEPLOYED: Mon Jul 30 03:15:40 2018
NAMESPACE: tiller-world
STATUS: DEPLOYED

RESOURCES:
==> v1/PersistentVolumeClaim
NAME                    STATUS   VOLUME  CAPACITY  ACCESS MODES  STORAGECLASS  AGE
harping-kangaroo-mysql  Pending  0s

==> v1/Service
NAME                    TYPE       CLUSTER-IP     EXTERNAL-IP  PORT(S)   AGE
harping-kangaroo-mysql  ClusterIP  10.244.47.175  <none>       3306/TCP  0s

==> v1beta1/Deployment
NAME                    DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
harping-kangaroo-mysql  1        1        1           0          0s

==> v1/Pod(related)
NAME                                     READY  STATUS   RESTARTS  AGE
harping-kangaroo-mysql-7b56488757-vsvk4  0/1    Pending  0         0s

==> v1/Secret
NAME                    TYPE    DATA  AGE
harping-kangaroo-mysql  Opaque  2     0s

==> v1/ConfigMap
NAME                         DATA  AGE
harping-kangaroo-mysql-test  1     0s


NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
harping-kangaroo-mysql.tiller-world.svc.cluster.local

To get your root password run:

    MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace tiller-world harping-kangaroo-mysql -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo)

To connect to your database:

1. Run an Ubuntu pod that you can use as a client:

    kubectl run -i --tty ubuntu --image=ubuntu:16.04 --restart=Never -- bash -il

2. Install the mysql client:

    $ apt-get update && apt-get install mysql-client -y

3. Connect using the mysql cli, then provide your password:
    $ mysql -h harping-kangaroo-mysql -p

To connect to your database directly from outside the K8s cluster:
    MYSQL_HOST=127.0.0.1
    MYSQL_PORT=3306

    # Execute the following commands to route the connection:
    export POD_NAME=$(kubectl get pods --namespace tiller-world -l "app=harping-kangaroo-mysql" -o jsonpath="{.items[0].metadata.name}")
    kubectl port-forward $POD_NAME 3306:3306

    mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}


# 
```


### Helm ls（稼動確認）
helm lsをするとdeployされたchartが表示されます。
> \# helm ls --tiller-namespace tiller-world --namespace tiller-world
> NAME                    REVISION        UPDATED                         STATUS          CHART           NAMESPACE
> harping-kangaroo        1               Mon Jul 30 03:15:40 2018        DEPLOYED        mysql-0.8.2     tiller-world
> \#

tillerが使えるようになりました！