＃20 RancherでKubernetesクラスタ構築

本記事は[PostgreSQL on Kubernetes Advent Calendar 2018](https://qiita.com/advent-calendar/2018/postgresonk8s)の20日目です。

25日間の完走めざして頑張っていますが、先日からの検証に詰まっており、19日目の投稿は後ほどとなります。今日はちょっと目先を変えて、Rancherを利用したKubernetes環境の構築について見ていきたいと思います。

# TL;DR

+ Rancherをつかえば複数のKubernetes環境の構築・管理も簡単。
+ Kubernetes Providerの選択には注意、CUSTOMではクラウド関連のAPIは叩けない模様。

**※12/20 さっそく追記
同日に[こちら](https://qiita.com/t_ume/items/9ad3b34a83d40bc1d023)が公開されていました。CUSTOMでもEBSを使うことは出来るようです。良く読んで、後ほど当記事も修正します。**

# Rancherとは
[こちら](https://www.slideshare.net/gchiba/kubernetesrancher-125017022)の資料に詳しいですが、Kubernetesのクラスタを簡単に構築できるツールだと言って良いと思います。（私はKubernetesと同時にRancherに入門したため、実はkubeadmとかminikubeを使ったことはありません。）

今回のPostgreSQL on KubernetesではRancherも含め、以下のような準備をしています。

+ Rancherはv.2.0.6
+ ノードとしてAmazon EC2を1クラスタあたり10台程度準備しておく
+ RancherからKubernetesクラスタを作る際にはCUSTOMを選択

# Rancherからk8sクラスタの構築

## EC2インスタンスの準備
今回の検証ではAmazon EC2上で下記の設定が入った起動テンプレートを事前に準備しました。

+ CentOS Linux release 7.5.1804 ※Marketplaceから
+ docker 17.03.2-ce ※Rancher v2.0.6のインストール要件にあわせて
+ dockerの自動起動を設定済

インスタンスをテンプレートから起動して、dockerのバージョンと自動起動の確認をしておきます。

```terminal:docker&nbsp;versionとsystemctl&nbsp;status
$ sudo docker version
Client:
 Version:      17.03.2-ce
 API version:  1.27
 Go version:   go1.7.5
 Git commit:   f5ec1e2
 Built:        Tue Jun 27 02:21:36 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.03.2-ce
 API version:  1.27 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   f5ec1e2
 Built:        Tue Jun 27 02:21:36 2017
 OS/Arch:      linux/amd64
 Experimental: false

$ sudo systemctl status docker.service
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2018-12-20 01:25:29 UTC; 17min ago
     Docs: https://docs.docker.com
 Main PID: 845 (dockerd)
    Tasks: 20
   Memory: 57.3M
   CGroup: /system.slice/docker.service
           tq 845 /usr/bin/dockerd
           mq3020 docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd...
```

## CUSTOMでk8sクラスタの構築
今回はRancher自身の構築については解説しません。他の記事等を参考にRancherのUIへアクセス可能な環境を前提としていますのでご了承下さい。

ここまででRancherの環境構築が終わり、Kubernetesクラスタ用のEC2インスタンスの起動が終わったら、クラスタ構築を進めていきます。

Rancherで左上の[Global]のタブをクリックし、下記の画面に来たら[Add Cluster]をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/54853/0182d93a-870a-d413-ff04-e5222f288f23.png)

そうすると、以下のようにKubernetes Providerを選択する画面に移りますので、ここで[CUSTOM]を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/54853/e739e4a3-1987-2d71-2cc1-cf158dd3c701.png)

画面下方ではクラスタの名前やKubernetes Version、Network Providerの入力項目があります。ここはお好みで設定して下さい。![image.png](https://qiita-image-store.s3.amazonaws.com/0/54853/fa1bdb2c-1529-1b73-7568-018b34b806db.png)

~~また、ここでCloud Providerで選択ができるようになっていますが、これまで確認したところ、Kubernetes ProviderとCloud Providerで整合性のない状態ではKubernetesクラスタが立ち上がりません。~~

~~例えば、~~

+ ~~Kubernetes ProviderはCUSTOMだが、Cloud ProviderはAmazonにしたい~~

~~などを試しましたが、そもそも以下のノード追加が上手くいきません。CUSTOMの時にはCloud ProviderはNoneにしましょう。~~
[こちら](https://qiita.com/t_ume/items/9ad3b34a83d40bc1d023)によれば、IAMの問題のようです。

## Masterノードの追加
先ほどのクラスタ作成画面を入力して先に進むと、次にクラスタへノードを追加する画面へ移ります。Kubernetesクラスタでは1台以上のetcd、Control Planeが必要ですので、まずはそれを作成します。

下記の画面で[Node Role]の[etcd]と[Control Plane]のチェックを入れると、各ノードごとのdocker runコマンドが生成されますので、コピーアイコンをクリックして、KubernetesのMasterノードにするインスタンスにコマンドを投入して下さい。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/54853/f010dbe3-a69d-8cea-d098-ccf7acc22817.png)

コマンド実行後にコンテナの起動を確認すると、下記のようになっているはずです。

```terminal:Masterノードでのコンテナ起動状況
$ sudo docker ps
CONTAINER ID        IMAGE                                                                                                COMMAND                  CREATED              STATUS              PORTS               NAMES
d5f4c3789314        3571bad91a6b                                                                                         "run.sh"                 22 seconds ago       Up 22 seconds                           k8s_agent_cattle-node-agent-rphqh_cattle-system_732d075e-0400-11e9-8caf-023749fae860_0
37ae796e4dfc        rancher/pause-amd64:3.1                                                                              "/pause"                 22 seconds ago       Up 22 seconds                           k8s_POD_cattle-node-agent-rphqh_cattle-system_732d075e-0400-11e9-8caf-023749fae860_0
0a7a434ff732        rancher/coreos-flannel-cni@sha256:3cf93562b936004cbe13ed7d22d1b13a273ac2b5092f87264eb77ac9c009e47f   "/install-cni.sh"        31 seconds ago       Up 31 seconds                           k8s_install-cni_kube-flannel-86ff2_kube-system_6af851d9-0400-11e9-8caf-023749fae860_0
acd57e7fee2a        rancher/coreos-flannel@sha256:93952a105b4576e8f09ab8c4e00483131b862c24180b0b7d342fb360bbe44f3d       "/opt/bin/flanneld..."   34 seconds ago       Up 33 seconds                           k8s_kube-flannel_kube-flannel-86ff2_kube-system_6af851d9-0400-11e9-8caf-023749fae860_0
0e82ab2ae152        rancher/pause-amd64:3.1                                                                              "/pause"                 36 seconds ago       Up 36 seconds                           k8s_POD_kube-flannel-86ff2_kube-system_6af851d9-0400-11e9-8caf-023749fae860_0
5d6c8baef3cc        rancher/hyperkube:v1.10.5-rancher1                                                                   "/opt/rke/entrypoi..."   45 seconds ago       Up 44 seconds                           kube-proxy
f092442d5e7e        rancher/hyperkube:v1.10.5-rancher1                                                                   "/opt/rke/entrypoi..."   50 seconds ago       Up 50 seconds                           kubelet
aac0a75b6c6b        rancher/hyperkube:v1.10.5-rancher1                                                                   "/opt/rke/entrypoi..."   56 seconds ago       Up 55 seconds                           kube-scheduler
e6f32a34cdf3        rancher/hyperkube:v1.10.5-rancher1                                                                   "/opt/rke/entrypoi..."   About a minute ago   Up About a minute                       kube-controller-manager
38d93b42ab62        rancher/hyperkube:v1.10.5-rancher1                                                                   "/opt/rke/entrypoi..."   About a minute ago   Up About a minute                       kube-apiserver
57f70612020f        rancher/coreos-etcd:v3.1.12                                                                          "/usr/local/bin/et..."   About a minute ago   Up About a minute                       etcd
```

これでetcdとControl Planeは起動しましたが、このままですといずれもシングル構成になります。本来はHA構成でつくったほうが良いですが、今回は割愛します。

## Workerノードの追加
次にクラスタへworkerノードを追加します。

Masterノードと同じ画面で、今度は[Node Role]の[Worker]にチェックを入れて、生成されたdocker runコマンドをWorkerノードにするインスタンスに投入して下さい。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/54853/2419f85f-ef28-6572-99d8-39220612ce0a.png)

これをworkerノードの台数分繰り返せば、Kubernetesクラスタの構築は完了です。

## EBSを使いたいならKubernetes Provider(Amazon EC2)を使おう
ここまで構築した環境で、Rookを利用したPostgreSQL on Kubernetesの検証には問題がありません。しかし、せっかくAmazon EC2を使っているのだから、EBSのボリュームをマウントしたい！となるとこの環境では上手くいきません。

たとえば、以下のようなStorageClassとPersistentVolumeClaimを作ってみます。

```yaml:EBS利用のStorageClassとPersistentVolumeClaim
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: sc-ebs-001
parameters:
  encrypted: "false"
  type: gp2
provisioner: kubernetes.io/aws-ebs
reclaimPolicy: Delete
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: pvc-pg-ebs-sf
  labels:
    app: pg-ebs-sf
spec:
  storageClassName: sc-ebs-001
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi
```

これをRancher v2.0.6のCUSTOMで作成したクラスタにapplyすると以下のようにPVCがPendingとなります。

```terminal
$ kubectl describe pvc pvc-pg-ebs-sf
Name:          pvc-pg-ebs-sf
Namespace:     default
StorageClass:  sc-ebs-001
Status:        Pending
Volume:
Labels:        <none>
Annotations:   field.cattle.io/creatorId=user-4h6wp
               volume.beta.kubernetes.io/storage-provisioner=kubernetes.io/aws-ebs
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:
Access Modes:
Events:
  Type     Reason              Age              From                         Message
  ----     ------              ----             ----                         -------
  Warning  ProvisioningFailed  5s (x7 over 1m)  persistentvolume-controller  Failed to provision volume with StorageClass "sc-ebs-001": Failed to get AWS Cloud Provider. GetCloudProvider returned <nil> instead
```

同じYAMLファイルであっても、Kubernetes ProviderでAmazon EC2、Cloud ProviderでAmazonを選択した環境であれば正常に構築ができます。

~~おそらくEBSに限りませんが、AWSのリソースをそのまま使いたければクラスタ構築時にCUSTOMを選ばないようにしたほうが良いでしょう。~~

# まとめ
今日はちょっと趣向を変えて、RancherによるKubernetes環境の構築をしてみました。その過程でKubernetes ProviderやCloud Providerも色々と試しましたが、明日以降はこれまでのPostgreSQL on Kubernetes(Rook利用）とEBSを利用した構成を比較してみたいと思っています。

よろしくお願いします。