Rancher で AWS EC2上に Kubernetes クラスタを構築

Rancher(v2.2.3)で AWS EC2上に Kubernetes クラスタ構築のメモ。

#[1] そもそもRancherとは

<img width="179" alt="スクリーンショット 2019-05-27 18.08.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/a02e8a21-cf69-222c-163c-853b553ec846.png">


・Kubernetesクラスタをはじめとした各種OSSの構築・運用を一元的に行える管理ツール
・(米)Rancher Labs社が開発するOSS
・無料のOSS版は全機能利用可能らしく、別途有料のエンタープライズサポートサービスがある。
・2014年に初版リリースされ、当初複数のコンテナオーケストレーションツールをサポートしていたが、2017年のRancer2.0で、k8sベースのマルチクラウド対応特化に生まれ変わった。
・国内でもNTT Com社、LINE社、CyberAgent社、リクルートテクノロジーズ社など多くの企業で導入されてるようです

k8sクラスタ構築のサービスやツールは他にも各種出てます。
例えば本家GCPならGKE、AWSならEKS、PaaS系ならPKS、ツール系ならKubeadmやKOPSなど様々。
そんな中Rancherは、個人的な所感としては「カタログ」機能で、PrometheusやGrafana、Helmのような実運用する上で必要となる周辺のツール群もセットでかつ容易にセットアップして管理できる点が大きな魅力かと感じます。
k8sは様々なツール群のエコシステムでなりなっているので、全部個別にセットアップして管理するのはかなりタフです。
さらに、etcdやk8s masterの冗長化も簡単に組み込める点(HA構成の考慮)も大きな魅力かと思います。


Rancher公式
https://rancher.com/

GitHub
https://github.com/rancher/rancher

参考

https://thinkit.co.jp/article/15816

#[2] とりあえずRancherでk8sクラスタを立てる

##①はじめに

RancherはGUIを有するRancherサーバと、k8sクラスタサーバがあり、今回はRancherサーバ用のEC2と、k8sクラスタ（master/worker兼用の1node構成）用のEC2の計2台で構築。

<img width="462" alt="スクリーンショット 2019-05-27 13.47.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/87573456-b4db-408f-a8c8-cc2a061ee997.png">

基本的にすべてのコンポーネントはdockerコンテナで構築されるので、EC2は基本dockerさえ入っていればOK。
ClusterノードのRancherは、Rancherサーバとやりとりするエージェンドが稼働する。またk8sもhyperkubeでコンテナベースで起動される。

###環境情報

EC2： Amazon Linux2 m5.large
Rancher： version 2.2.3
docker: version 18.06.1-ce


##②Rancherセットアップ

※dockerセットアップ方法は省略

dockerインストール済みインスタンスで下記実行するのみ

```
sudo docker run -d --restart=unless-stopped -p 80:80 -p 443:443 --privileged rancher/rancher
```

参考
https://rancher.com/docs/rancher/v2.x/en/quick-start-guide/deployment/quickstart-manual-setup/#2-install-rancher

ブラウザアクセスすると、Rancher GUI画面にアクセスできる。
初回はadminアカウントが生成されており、パスワードを設定すればログインできる。

<img width="752" alt="スクリーンショット 2019-05-27 13.55.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/0b333cb8-72c2-1da3-7d27-ea4b0d46b91f.png">

<img width="961" alt="スクリーンショット 2019-05-27 13.55.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/7679bbb2-f732-ea27-e559-35faac4e40d1.png">

## adminパスワードを忘れた場合

adminパスワードを忘れた場合はrencherサーバのホスト上で、下記を実行するとリセットされる（ランダムpwdが再発行される）

```
docker exec -ti <rancher server container_id> reset-password
```
https://rancher.com/docs/rancher/v2.x/en/faq/technical/

#③k8sクラスタ作成

ログイン後の画面の「Add Cluster」メニュー

Add Clusterで「Custom」を選択

<img width="881" alt="スクリーンショット 2019-05-27 13.59.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/0f79d2a2-eed6-ae08-acf9-597c72b347bc.png">

クラウドサービスの選択肢もあるので、ゼロの状態からマネージドサービスを活用したクラスタの作成や、新規ノード作成も含めた構築もできるが、
今回のようにホスト（EC2）を立てた状態からのスタートの場合は「Custom」。
オンプレサーバでの構築の場合もおそらく同じ。

<img width="930" alt="スクリーンショット 2019-05-27 14.02.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/0b972381-6179-adc6-bb90-b607efba889f.png">

次にクラスタ名を入れて、k8sバージョンを選択。
さらにオーバーレイネットワークのツールを選択。ざっくり言うと、k8sノード間のコンテナ間通信で仮想ネットワークを構成する機能。
いろいろあるが、Flannelを選択。
最後のCustom ProviderはNoneを選択。

<img width="920" alt="スクリーンショット 2019-05-27 14.05.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/361020d9-ca78-d18c-f2ed-0af713e39327.png">

最後に、クラスタを構築するホストサーバ上で実行するためのコマンドを生成する。
Rancherは、Rancherサーバで生成するコマンドを、k8sクラスタに組み込みたいホストサーバで実行するだけで、Rancherエージェントが起動しノードをRancherサーバに登録することで、一元管理可能なk8sクラスタを構築できる便利物。


「Node Option」の「show advanced option」で詳細表示にして、k8sクラスタ用EC2のプライベートIP(Internal Address)を設定する。
Node Roleでは、「etcd」「controll plane」「Worker」すべてにチェックをつける。
各Roleを分離したい場合は、分けてコマンドを生成して実行するだけで、ホスト分散ができるイメージ。

以下のようなコマンドが生成される。
この時、--serverはデフォルトではrancherサーバのグローバルIPが指定されているが、Private IPに手動で変更することも可能。

```
sudo docker run -d 
--privileged 
--restart=unless-stopped 
--net=host 
-v /etc/kubernetes:/etc/kubernetes 
-v /var/run:/var/run rancher/rancher-agent:v2.2.3 
--server https://172.16.0.10 
--token xxxxxxxx 
--ca-checksum xxxxxxxx 
--internal-address 172.16.0.20 
--etcd 
--controlplane 
--worker
```

この画面を表示したまま、このコマンドをk8sクラスタ用EC2で実行し、Rancherサーバが認識すると、

「1 new node has registered」

と表示されるので「Done」を押して完了

クラスタ用のホストサーバ上でdocker psで確認すると以下のようなコンテナが立ち上がっている。

```
a1896a96de66        rancher/hyperkube:v1.13.5-rancher1                "/opt/rke-tools/entr…"   About an hour ago   Up About an hour                        kube-proxy
df7f65730a93        rancher/hyperkube:v1.13.5-rancher1                "/opt/rke-tools/entr…"   About an hour ago   Up About an hour                        kubelet
356dc597c277        rancher/hyperkube:v1.13.5-rancher1                "/opt/rke-tools/entr…"   About an hour ago   Up About an hour                        kube-scheduler
478128e7a70a        rancher/hyperkube:v1.13.5-rancher1                "/opt/rke-tools/entr…"   About an hour ago   Up About an hour                        kube-controller-manager
04577fca9103        rancher/hyperkube:v1.13.5-rancher1                "/opt/rke-tools/entr…"   About an hour ago   Up About an hour                        kube-apiserver
2f0087e09a03        rancher/coreos-etcd:v3.2.24-rancher1              "/usr/local/bin/etcd…"   About an hour ago   Up About an hour                        etcd
747414e88256        rancher/rancher-agent:v2.2.3                      "run.sh --server htt…"   About an hour ago   Up About a minute                       jovial_brahmagupta
5770e05cc24b        rancher/rancher-agent:v2.2.3                      "run.sh --server htt…"   About an hour ago   Up About an hour                        boring_clarke

```

<img width="961" alt="スクリーンショット 2019-05-27 13.55.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/085289b0-510c-ef4d-dce8-1edaa5ac67a0.png">

StateがActiveになればOK

##④k8s動作確認

<img width="955" alt="スクリーンショット 2019-05-27 14.20.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/781fffce-9193-2eb3-4111-368223dbc0d4.png">

クラスタのリソースモニターも標準で確認可能。

<img width="953" alt="スクリーンショット 2019-05-27 14.42.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/369bc396-d168-efd0-66e3-d596e7d9665a.png">

ダッシュボードの「Launch kubectl」もしくは「Kubeconfig File」からdownloadしたconfigを設定したクライアントから、kubectlコマンドを実行できる。

```
$ kubectl get nodes
NAME             STATUS   ROLES                      AGE   VERSION
ip-172-16-0-20   Ready    controlplane,etcd,worker   96m   v1.13.5
```

試しにnginx podを立てる

```
$ kubectl create deployment --image nginx my-nginx
deployment.apps/my-nginx created

$ kubectl get pod 
NAME                        READY   STATUS    RESTARTS   AGE
my-nginx-6cc48cd8db-f4nd6   1/1     Running   0          9s
```

#[3] 機能拡張とカタログ

##モニタリング

煩雑な設定なしに、「Tools」 - 「Monitoring」の設定をenableにするだけで、k8sモニタリングのデファクト「grafana」が利用できる。
Rancherダッシュボードでもサマリー出力されるが、grafanaアイコンで別途grafanaが起動し、詳細モニターを閲覧可能。

<img width="1140" alt="スクリーンショット 2019-05-27 17.56.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/d0f39e57-7155-462d-1aef-22b092134bf1.png">

<img width="1144" alt="スクリーンショット 2019-05-27 17.56.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/64e61a41-4506-4bb0-9809-8c10df79d960.png">

GrafanaでPod単位のリソース消費量も確認できるので便利。

<img width="1027" alt="スクリーンショット 2019-05-28 11.39.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/1e773480-8253-fdd2-de21-0323b84fade4.png">


##ロギング
Rancherが対応しているロギングツール一式。
k8sクラスタの各ノードのログを収集する仕組みを設定できる。

<img width="1133" alt="スクリーンショット 2019-05-27 15.20.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/01f56186-130e-90b6-d0cc-3e2aa8b4a13b.png">


# [4] workerノードの追加

先ほどの1node k8sクラスタにworkerノードを追加する方法。

dockerインストールしたEC2を、同じセグメントに設置して、
先ほど同様にホスト上でコマンドを実行するのみ。
差分は、
--internal-addressオプションが、該当ホストのIPであることと
node roleは、--workerオプションをつける点。

```
sudo docker run -d 
--privileged 
--restart=unless-stopped 
--net=host 
-v /etc/kubernetes:/etc/kubernetes 
-v /var/run:/var/run rancher/rancher-agent:v2.2.3 
--server https://172.16.0.10 
--token xxxxxxxx 
--ca-checksum xxxxxxxx 
--internal-address [追加するノードのIP] 
--worker
```


#[5] はまりどころ

## Case1 : Etcd Cluster is not healthy
クラスタ構築を何度か試したところ、以下のエラーが発生

```
[etcd] Failed to bring up Etcd Plane: [etcd] Etcd Cluster is not healthy
```

どうやらゴミをちゃんと掃除しないといけないらしい。
下記サイトの「Cleaning a Node Manually」の手順を実行し、再度クラスタ作成をしたところエラーは解消。

https://rancher.com/docs/rancher/v2.x/en/cluster-admin/cleaning-cluster-nodes/

## Case2　cattle-cluster-agent CrashLoopBackOff

cattle-cluster-agentとcattle-node-agentというPodが再起動を繰り返す。

```
NAMESPACE       NAME                                                      READY   STATUS             RESTARTS   AGE
cattle-system   cattle-cluster-agent-xxxxx                     0/1     CrashLoopBackOff   40         4h31m
cattle-system   cattle-node-agent-xxxxx                                   1/1     Running            17         98m
cattle-system   cattle-node-agent-xxxxx                                   0/1     CrashLoopBackOff   40         4h31m
```
logを見てみたところ、k8sのノードから、RancherサーバのグローバルIPへの通信でタイムアウトしていた模様。
デフォルトではRancherサーバのグローバルIPが、各種制御のエンドポイントになっている様で、各nodeから443(HTTPS)のアクセス制御を許可する必要がある。

```
$ kubectl -n cattle-system logs cattle-cluster-agent-6fbc6f6b68-68l8l

INFO: Environment: CATTLE_ADDRESS=X.X.X.X CATTLE_CA_CHECKSUM=xxxxx CATTLE_CLUSTER=true CATTLE_INTERNAL_ADDRESS= CATTLE_K8S_MANAGED=true CATTLE_NODE_NAME=cattle-cluster-agent-xxxxx CATTLE_SERVER=https://[RancherサーバのグローバルIP]
INFO: Using resolv.conf: nameserver X.X.X.X search cattle-system.svc.cluster.local svc.cluster.local cluster.local ap-northeast-1.compute.internal options ndots:5
ERROR: https://[RancherサーバのグローバルIP]/ping is not accessible (Failed to connect to [RancherサーバのグローバルIP] port 443: Connection timed out)
```

k8sの各workerから、RancherサーバのグローバルIP（エンドポイント）への443(HTTPS)を許可することで問題解消。

## Case3 : Monitoring API is not ready

Toolsの「Cluster Monitoring Configuration」をenableにしたのに、dashboardで「Monitoring API is not ready」とアラート表示。

Case2同様の原因。同じ対処で問題解消。

## Case4 : kubectl Closed Code: 1006

「Launch kubectl」でRancherのダッシュボード上からkubectlコマンドを実行しようとすると、何の反応もなく、「Closed Code: 1006」などのエラーに。

k8sノードとのコネクションに問題がある。

Case2同様の原因。同じ対処で問題解消。


## Case5 adminユーザのパスワード忘れ

adminユーザパスワードは下記でリセット可能

```
docker exec [RancherサーバのコンテナID] reset-password
```
ランダム文字列のパスワードが出力される

## Case6 Failed to obtain metrics.

<img width="991" alt="スクリーンショット 2019-05-28 11.15.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/49ae21e7-0cb6-db10-c4ab-df7b30cc0b18.png">

prometheusからのメトリクス収集でエラーとなっている模様。
workerで稼働している「k8s_prometheus_prometheus-cluster-monitoring-0_XXX」という名前のコンテナの各logを確認すると、
`context deadline exceeded`とか、
`only allow maximum 512 connections with 5m0s read timeout`とか、
`http: proxy error: context canceled`とか
いろいろ出ていた。

クラスタ再起動や作り直しをした過程のゴミの可能性もあったので
下記手順でホストを掃除し、作り直したところ、とりあえず問題解消。

https://rancher.com/docs/rancher/v2.x/en/cluster-admin/cleaning-cluster-nodes/