Helion OpenStackの上にRancherでKubernetesクラスタを構築してみる（その１）

# 概要
OpenStack上でのコンテナ管理といえば[Zun](https://wiki.openstack.org/wiki/Zun)があり、またOpenStackでKubernetesなどのコンテナオーケストレーターの管理といえば[Magnum](https://wiki.openstack.org/wiki/Magnum)がありますが、これらプロジェクトの立ち位置はまだ発展途上であり、プロダクションで採用しているOpenStack環境も少数派なんじゃないかと思います([October2016 User Survey](https://www.openstack.org/assets/survey/October2016SurveyReport.pdf)ではMagnumのProduction採用率は2%でしたね）。HPEのディストリビューションであるHelion OpenStackもMagnumやZunは今のところ採用していません。
とはいえテナントレベルでは流行りのコンテナオーケストレーションを実現したいので、テナント上にプライベートCaaSを作っちゃえばいいわけです。というわけで、Helion OpenStackのテナント上にRancherでKubernetesクラスタを構築してみます。
まあRancherの場合、構築って言ってもDockerイメージを各Host（仮想マシン）で起動すればあとは勝手にやってくれるんですが、せっかくなんで仮想マシンのデプロイにOpenStack Heatを使うところもやってみたいと思います。

# 前提

- 動いているOpenStack環境：
    - ここではHelion OpenStack 4.0 (Mitaka) の環境を使っています
    - イントラネット上にあるプライベートIaaSで、Proxy経由でインターネットにつながります
- OpenStack上のテナント（プロジェクト）
    - ユーザアカウント
    - テナント内プライベートネットワークがひとつ：10.0.0.0/8
    - Glanceに登録された仮想マシンイメージ：ぶっちゃけdockerが動けばなんでもよくて、AtomicとかCoreOSとか使えば手っ取り早いんですが、ここではCentOS7を使ってみます。なければ[ここ](http://docs.openstack.org/image-guide/obtain-images.html)からダウンロードしてGlanceに登録します。

# 作りたいもの
こんな感じ。
![3.PNG](https://qiita-image-store.s3.amazonaws.com/0/103746/d3cd5a33-1118-6a34-c18f-d1e5808318f6.png)
何も考えずに作るとk8sの全ノードにPublic IPを振る感じになりますが、通常イントラネットでは使えるIPアドレスが限られていると思います。なのでFloating IPを3つ使って
- Rancher Serverへのアクセス用
- k8sのLoad Balancer用 x2
とし、コンテナ間の通信はプライベートネットワークを使います。

# 手順

以下OpenStackの操作はコマンドを記載しますが、Horizonのほうが楽な方はそちらで

## 1.ベースイメージの作成

いちいちノード増やすたびにdockerのインストールとかめんどうなので、CentOS7にDockerをインストールしたベースイメージを作っちゃいます

### 1.1 仮想マシンの起動
CentOS7のイメージから仮想マシンインスタンスを起動します。dockerをインストールするだけなのでflavorはsmallとかで適当に

```
$ nova boot --flavor 2 --image <CentOS7のイメージID> --key-name <keypair名> --security-groups <セキュリティーグループID> centos7-docker-base
```
sshで接続して作業したいのでフローティングIPを振ります。

```
$ nova floating-ip-list
$ nova floating-ip-associate centos7-docker-base <Floating IPアドレス>
```

インスタンスが起動したらsshでログインします。

```
$ ssh -i <keyfile> centos@<Floating IP>
```

### 1.2 Dockerのインストール
Dockerをインストールします。

```
$ export http_proxy=http://web-proxy.example.com:8080
$ export https_proxy=http://web-proxy.example.com:8080
$ sudo -E yum -y update
$ sudo -E curl -fsSL https://get.docker.com/ | sh
$ sudo usermod -aG docker centos
$ sudo systemctl enable docker.service
$ sudo systemctl start docker.service
```
dockerサービスの環境変数にHTTP_PROXYが設定されてなきゃいけないので、めんどくさいけど以下設定します。CentOS7ではdockerサービスは`systemctl`で起動されますので、`/etc/systemd/system/docker.service.d/`の下に`*.conf`というファイルを置いておけば起動時にパラメータが読み込まれます。
今回はベースとなる仮想マシンイメージにあらかじめ設定を仕込んでしまいますが、各仮想マシンインスタンス起動時に`cloud-init`スクリプトで設定してもよいです。Heatでデプロイする場合はそのほうがよいかもしれません。

```
$ sudo su
# vi /etc/systemd/system/docker.service.d/20-http-proxy.conf
```

```text:20-http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://web-proxy.example.com:8080"
```

```
# systemctl daemon-reload
# systemctl restart docker
```

### 1.3 Dockerの動作確認

一般ユーザでログインしなおして動作確認

```
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c04b14da8d14: Pull complete
Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.
...
```
dockerサービスにProxyが正しく設定されていないとimageのpullができずエラーになります。

### 1.4 SnapShotの取得
仮想マシンインスタンスをシャットダウンします。
スナップショットを取得します。
```$ nova image-create centos7-docker-base centos7-docker-base-image```


## 2 Rancher+Kubernetesクラスタのセットアップ
### 2.1 ノードの起動
1.で作成したイメージ（スナップショット）をつかって仮想マシンをデプロイします。ここでは5ノード一気にデプロイします。このへんがOpenStackは楽ですね。

```
$ nova boot --image centos7-docker-base-image --min-count 5 --key-name <keypair名> --security-groups <セキュリティグループ名> --flavor 3 rancher-k8s
```
```
$ nova list | grep rancher-k8s
| 526eb62b-a2ba-44ce-8309-f6f400c8468a | rancher-k8s-1 | ACTIVE  | -          | Running     | junichi-private=10.0.0.25                 |
| de77f2dd-d8b0-416a-9277-e1fe97a1a32c | rancher-k8s-2 | ACTIVE  | -          | Running     | junichi-private=10.0.0.26                 |
| 86cefc4d-7ea9-4d83-ae85-5da19ea6f40c | rancher-k8s-3 | ACTIVE  | -          | Running     | junichi-private=10.0.0.27                 |
| 1484ac47-c602-46f2-af3d-24dacaed1f83 | rancher-k8s-4 | ACTIVE  | -          | Running     | junichi-private=10.0.0.28                 |
| 6ec885b6-edc8-4bab-a96b-de1d8d4c668c | rancher-k8s-5 | ACTIVE  | -          | Running     | junichi-private=10.0.0.29                 |
```
### 2.2 Rancher Serverのセットアップ
ここから先は[http://docs.rancher.com/](http://docs.rancher.com/)のドキュメントに書いてある通りです。[zembutsu](http://qiita.com/zembutsu)さんの[こちら](http://qiita.com/zembutsu/items/007617cbb00a0d554c8c)もわかりやすいです。
なので以下、違うところだけ書きます。
 
1台目（rancher-k8s-1）にRancherをインストールします。
まずFloating IPを振ります。

```
$ nova floating-ip-associate rancher-k8s-1 <Floating IPアドレス>
```

sshでログインします。

```
$ ssh -i <keyfile> centos@<Floating IPアドレス>
```

すでに元のイメージにDockerがインストールされていてProxyも設定してあるので、Rancher Serverのインストールはdocker run一発です。

```
$ sudo docker run -d --restart=unless-stopped -p 8080:8080 rancher/server
Unable to find image 'rancher/server:latest' locally
latest: Pulling from rancher/server
96c6a1f3c3b0: Downloading 32.44 MB/65.7 MB
ed40d4bcb313: Download complete
b171f9dbc13b: Download complete
...
```

### 2.3 Kubernetesのセットアップ
rancher-k8s-1に振ったFloating IPのポート8080にブラウザでアクセスします。
EnvironmentでKubernetesを登録します。
最初のHostを登録する際に、Rancher ServerのURLを聞かれますが、クラスタ内の通信はプライベートネットワークを使いたいので、プライベートのIPアドレスで登録します。
![1.PNG](https://qiita-image-store.s3.amazonaws.com/0/103746/e0623aa1-31e7-2361-3819-baaf5dfc002f.png)
あとはホストを登録していきます。ホストの登録はWeb画面の指示に従い、各ノードにsshで入ってコマンドを叩くだけです。

```
$ sudo docker run -e CATTLE_AGENT_IP="10.0.0.27"  -d --privileged -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/rancher:/var/lib/rancher rancher/agent:v1.0.2 http://10.0.0.25:8080/v1/scripts/E0A1E9AE5212FFF56845:1480078800000:57ZANJblcGjSP7tU2740ygNlctw
```

4台目以降のノードにはFloating IPを振らないので、1台目のノードを踏み台とします。そのため1台目のノードにはkeyfileをコピーしておきます。
クラスタの構成が終わるとこんな感じになります（[INFRASTRUCTURE]-[Hosts]）。
![4.PNG](https://qiita-image-store.s3.amazonaws.com/0/103746/d31b1476-84d3-9048-463d-efdee6623f46.png)

続きは次回。