Kubernetes1.2使いのエンジニアが1.5(kubeadm)を使って感動した話

この記事は[Kubernetes Advent Calendar 2016](http://qiita.com/advent-calendar/2016/kubernetes)の19日目の記事です。前日はhiyoshiさんの「[kubernetesがサポートする認証方法の全パターンを動かす](http://qiita.com/hiyosi/items/43465d4fc501c2044d01)」でした。

数ヶ月前からKubernetesの環境を触り始めた自分としては、あっという間に1.5がリリースされているKubernetesにただただ驚くばかりです。

そんな1.2時代の知識・経験しかないエンジニアが1.5を触った所感を書きたいと思います。ちなみに1.2を利用していた頃のメモは[こちら](http://qiita.com/kojiisd/items/d3b3b3af77cead2ddbca)に載せています。
＃今回本当に初見で1.5を触っていますので、間違っている箇所などありましたら訂正コメント頂けるとありがたいです。

# 前提
1. kubeadm 1.6系を利用します。Kubernetesは1.5系になります。
2. Master1台、Node1台の構成で一旦動かします。
3. サーバにはAWSのEC2インスタンス（CentOS 7、t2.micro）を利用します。
4. MasterのIPアドレス：```172.17.0.46```　NodeのIPアドレス：```172.17.0.220```

# ゴール
1. kubeadmを使って1.2時代のインストール手順がどの程度簡単になったか確認する
2. 自動化されたことで、注意すべき点は何か、考察する。

# Master側の設定・インストール
## kubeadmのインストール
早速インストールに取り掛かります。が、今回選んだCentOSのインスタンスではリポジトリの追加が必要だったので以下の設定を追加しています。

```/etc/yum.repo.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://yum.kubernetes.io/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
       https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
```
これでインストールを実施します。

```
(master) $ sudo yum --enablerepo=kubernetes install kubeadm
```
で、このまま```sudo kubeadm init```を実施しても色々と怒られるので、まだ準備は続きます。

```
(master) $ sudo systemctl enable kubelet.service
(master) $ sudo setenforce 0

(master) $ sudo yum install docker
(master) $ sudo systemctl start docker
(master) $ sudo systemctl enable docker
```
## kubeadmを利用したKubernetes環境の初期化

ここまで準備ができたらkubeadmコマンドを実行します。

```
(master) $ sudo kubeadm init
```
技術の進歩は素晴らしいもので、、、ここまででバージョン1.2時代に散々苦労した各種Master側の設定が終わってしまいました。証明書の作成もされているようです。

kubeadmの動きは別に解説されている方がいるので、ぜひ[そちら](http://qiita.com/helix_kaz/items/9c4a83532f949d8a94ef)を参照してください。

```
(master) $ sudo kubeadm init
[kubeadm] WARNING: kubeadm is in alpha, please do not use it for production clusters.
[preflight] Running pre-flight checks
[preflight] Starting the kubelet service
[init] Using Kubernetes version: v1.5.1
[tokens] Generated token: "f2288e.8383abeaffe92e46"
[certificates] Generated Certificate Authority key and certificate.
[certificates] Generated API Server key and certificate
[certificates] Generated Service Account signing keys
[certificates] Created keys and certificates in "/etc/kubernetes/pki"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"
[apiclient] Created API client, waiting for the control plane to become ready
[apiclient] All control plane components are healthy after 88.307070 seconds
[apiclient] Waiting for at least one node to register and become ready
[apiclient] First node is ready after 3.502374 seconds
[apiclient] Creating a test deployment
[apiclient] Test deployment succeeded
[token-discovery] Created the kube-discovery deployment, waiting for it to become ready
[token-discovery] kube-discovery is ready after 17.006111 seconds
[addons] Created essential addon: kube-proxy
[addons] Created essential addon: kube-dns

Your Kubernetes master has initialized successfully!

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
    http://kubernetes.io/docs/admin/addons/

You can now join any number of machines by running the following on each node:

$ kubeadm join --token=<token> 172.17.0.46
```
この最後に出てくるtoken付きのjoinコマンドは、この後ノードを追加する際に必要になるコマンドなので、控えておく必要があります。さて、これからアプリ等を複数ノードにデプロイすることを考えた場合、上記にある通りpodnetworkを作成しておく必要があります。

いくつかpodnetworkを作成するためのアドオンがあるようですが、今回は[Weave Net](https://www.weave.works/docs/net/latest/kube-addon/)を選びました。アドオンの一覧は[こちら](http://kubernetes.io/docs/admin/addons/)になります。本当は使い慣れているflannelを選ぼうかと思ったのですが、リンク先のyaml内の設定で、一部CoreOS用っぽいものがあったので、今回は避けました。

```
(master) $ kubectl apply -f https://git.io/weave-kube
```
※ちなみに設定ファイルを見ればわかることですが、これらの設定はkube-systemというネームスペースに作成されていきます。

これで一旦Master側の設定は完了です。```kubectl get nodes```を実行すると、自身がMasterとして認識されているのがわかると思います。この段階で```kubectl get pods --all-namespaces```を実行すると、kube-dnsのPodが大量に生成失敗したかのような状態で表示されることがありますが、podnetwork用のアドオンをインストールすると、kube-dnsのPodがどれか実行される（Running）状態になるはずなので、そうなった後はRunning以外のPodは削除しても大丈夫です。

# Node側の設定
Node側の設定もとても簡単です。まずkubeadmのインストールまでは同じです。

## kubeadmを使ったMasterへのJoin
以下のコマンドでMaster側にJoinします。たったこれだけです。必要なものはJoinコマンドの中で用意してくれるようです。

```
(node) $ sudo kubeadm join --token=<token> 172.17.0.46
```
これでNodeが登録されました。Master側でNodeの確認をすると、追加されたのがわかります。

```
(node) $ kubectl get nodes
NAME              STATUS         AGE
ip-172-17-0-186   Ready          4h
ip-172-17-0-46    Ready,master   5h
```
とても簡単です。ちなみにこれまでの操作で以下のものがインストールされました。1.5おそるべし。

```
(master) $ kubectl get deployment --namespace kube-system
NAME                   DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kube-discovery         1         1         1            1           5h
kube-dns               1         1         1            1           5h
kubernetes-dashboard   1         1         1            1           5h

(master) $ kubectl get daemonset --namespace kube-system
NAME         DESIRED   CURRENT   READY     NODE-SELECTOR   AGE
kube-proxy   2         2         2         <none>          5h
weave-net    2         2         2         <none>          5h

(master) $ kubectl get replicaset --namespace kube-system
NAME                              DESIRED   CURRENT   READY     AGE
dummy-2088944543                  1         1         1         5h
kube-discovery-1769846148         1         1         1         5h
kube-dns-2924299975               1         1         1         5h
kubernetes-dashboard-3095304083   1         1         1         5h

(master)$ kubectl get service --namespace kube-system
NAME                   CLUSTER-IP       EXTERNAL-IP      PORT(S)                       AGE
kube-dns               10.96.0.10       <none>           53/UDP,53/TCP                 5h

(master) $ kubectl get pods --namespace kube-system
NAME                                     READY     STATUS    RESTARTS   AGE
dummy-2088944543-5ql0m                   1/1       Running   0          5h
etcd-ip-172-17-0-46                      1/1       Running   0          5h
kube-apiserver-ip-172-17-0-46            1/1       Running   3          5h
kube-controller-manager-ip-172-17-0-46   1/1       Running   0          5h
kube-discovery-1769846148-x4gf7          1/1       Running   0          5h
kube-dns-2924299975-szlsm                4/4       Running   0          5h
kube-proxy-20vb1                         1/1       Running   0          5h
kube-proxy-zw256                         1/1       Running   0          5h
kube-scheduler-ip-172-17-0-46            1/1       Running   0          5h
weave-net-mjf89                          2/2       Running   0          5h
weave-net-ptprf                          2/2       Running   1          5h
```

# 実運用を踏まえて振り返ってみる
さて、ここまででとても便利なことはわかりましたが、実際使おうと冷静に考えると、いくつか注意が必要そうですね。

現状のインストール方法ですと、

- ネットワークはインターネットにつながることが前提（設定ファイルの中身の調整で何とかなるとは思いますが）
- 細かいアクセス制限は自動で設定される分、最初はかけられない。（というか細かいネットワーク制限の下にkubeadmで初期化すると色々とエラーが起こるんじゃないかな。）
- 証明書は基本的にコマンド実施時作成されるようですが、その更新期限や更新方法は？また証明書なしのアクセスに対応したい場合はkubeadmのコマンドで対応可能な範囲なのでしょうか？

など、実際に自分も見てきた実環境では、エイヤで投入できない可能性がありそうです。このあたりが```kubeadm```コマンドを実行した際に出るメッセージの「これはプロダクション環境では使わないように」に相当するのかと思われます。ある程度カスタマイズした状態でのkubeadmとかできるのか、それともやっぱり一旦デフォルトでインストールしてその後設定ファイルを書き換える必要があるのか、いずれにしても検証が必要そうです。

それでも、1.2とは比べ物にならないくらい始めてみるまでの障壁を下げたkubeadmの今後のアップデートにかなり期待です。

今度は以前1.2環境の際に作成した制限のある環境に、kubeadmを駆使してどうやって簡単に環境を構築するか、試せたらいいな！
＃そう言っている間にkubeadm自体がアップデートされてコマンド一発で実現できるようになることが一番うれしかったりするのですが。