Kubernetesの環境構築とguestbookの実行


Kubernetesの検証環境を作るため、VirtualBoxのVMにKubernetesのクラスターを構築する。

## 環境
* OS X El Capitan
* VirtualBox 5.0.8
* Vagrant 1.7.4
* Kubernetes 1.1.1

## 構築手順

最新版は[公式レポジトリ](https://github.com/kubernetes/kubernetes/releases)にある。ここではバージョン1.1.1で進める

```console:
$ wget https://github.com/kubernetes/kubernetes/releases/download/v1.1.1/kubernetes.tar.gz
$ tar zxvf kubernetes.tar.gz
```

Kubernetesの自動構築スクリプトが`./cluster/kube-up.sh`にあるが、デフォルトの構築場所がGCE(Google Compute Engine)になっているため、vagrantに変更し、Minionの数も指定しておく

```console:
$ cd kubernetes
$ export KUBERNETES_PROVIDER=vagrant # vagrantを利用してvirtualbox上に構築
$ export NUM_MINIONS=2 # Minionの数
$ cluster/kube-up.sh # しばらくまつ
...
Done, listing cluster services:

Kubernetes master is running at https://10.245.1.2
Heapster is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/heapster
KubeDNS is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/kube-dns
KubeUI is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/kube-ui
Grafana is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana
InfluxDB is running at https://10.245.1.2/api/v1/proxy/namespaces/kube-system/services/monitoring-influxdb
```

環境構築が終わったら、`kubectl`コマンドが動作することを確認する

```
$ cluster/kubectl.sh get pods # まだ何もない
NAME      READY     STATUS    RESTARTS   AGE
$ cluster/kubectl.sh get services
NAME         CLUSTER_IP   EXTERNAL_IP   PORT(S)   SELECTOR   AGE
kubernetes   10.247.0.1   <none>        443/TCP   <none>     8m
```

## Guestbookの実行

kubernetes/examplesフォルダにあるサンプルプログラムguestbookを実行する

### Redis Masterの追加

```
$ cluster/kubectl.sh create -f examples/guestbook/redis-master-controller.yaml
replicationcontroller "redis-master-controller" created
$ cluster/kubectl.sh create -f examples/guestbook/redis-master-service.yaml
service "redis-master" created
$ cluster/kubectl.sh get rc
CONTROLLER     CONTAINER(S)   IMAGE(S)   SELECTOR            REPLICAS   AGE
redis-master   master         redis      name=redis-master   1          4m
$ cluster/kubectl.sh get pods
NAME                 READY     STATUS    RESTARTS   AGE
redis-master-svui5   1/1       Running   0          4m
$ cluster/kubectl.sh get services
NAME           CLUSTER_IP       EXTERNAL_IP   PORT(S)    SELECTOR            AGE
kubernetes     10.247.0.1       <none>        443/TCP    <none>              10h
redis-master   10.247.189.209   <none>        6379/TCP   name=redis-master   20s
```

### Redis Slaveの追加

```
$ cluster/kubectl.sh create -f examples/guestbook/redis-slave-controller.yaml
replicationcontroller "redis-slave" created
$ cluster/kubectl.sh create -f examples/guestbook/redis-slave-service.yaml
service "redis-slave" created
$ cluster/kubectl.sh get rc
CONTROLLER     CONTAINER(S)   IMAGE(S)                                 SELECTOR            REPLICAS   AGE
redis-master   master         redis                                    name=redis-master   1          7m
redis-slave    worker         gcr.io/google_samples/gb-redisslave:v1   name=redis-slave    2          59s
$ cluster/kubectl.sh get pods
NAME                 READY     STATUS    RESTARTS   AGE
redis-master-svui5   1/1       Running   0          8m
redis-slave-67g25    1/1       Running   0          1m
redis-slave-vsuge    1/1       Running   0          1m
$ cluster/kubectl.sh get services
NAME           CLUSTER_IP       EXTERNAL_IP   PORT(S)    SELECTOR            AGE
kubernetes     10.247.0.1       <none>        443/TCP    <none>              10h
redis-master   10.247.189.209   <none>        6379/TCP   name=redis-master   2m
redis-slave    10.247.105.127   <none>        6379/TCP   name=redis-slave    1m
```

### Frontendの追加

Frontendを追加する際に、Minionの中だけでなくホストマシンMacからアクセスできるように`NodePort`を設定する

```
$ vi examples/guestbook/frontend-service.yaml
# 下記のように2行追加する
apiVersion: v1
kind: Service
metadata:
  name: frontend
  labels:
    name: frontend
spec:
  # if your cluster supports it, uncomment the following to automatically create
  # an external load-balanced IP for the frontend service.
  # type: LoadBalancer
  type: NodePort # ADD
  ports:
    # the port that this service should serve on
    - port: 80
      nodePort: 30301 # ADD
  selector:
    name: frontend
$ cluster/kubectl.sh create -f examples/guestbook/frontend-controller.yaml
replicationcontroller "frontend" created
$ cluster/kubectl.sh create -f examples/guestbook/frontend-service.yaml
You have exposed your service on an external port on all nodes in your
cluster.  If you want to expose this service to the external internet, you may
need to set up firewall rules for the service port(s) (tcp:30301) to serve traffic.

See http://releases.k8s.io/release-1.1/docs/user-guide/services-firewalls.md for more details.
service "frontend" created
$ cluster/kubectl.sh get rc
CONTROLLER     CONTAINER(S)   IMAGE(S)                                 SELECTOR            REPLICAS   AGE
frontend       php-redis      gcr.io/google_samples/gb-frontend:v3     name=frontend       3          1m
redis-master   master         redis                                    name=redis-master   1          14m
redis-slave    worker         gcr.io/google_samples/gb-redisslave:v1   name=redis-slave    2          7m
$ cluster/kubectl.sh get pods
NAME                 READY     STATUS    RESTARTS   AGE
frontend-b8fay       1/1       Running   0          3m
frontend-en9xd       1/1       Running   0          3m
frontend-fu8mh       1/1       Running   0          3m
redis-master-svui5   1/1       Running   0          16m
redis-slave-67g25    1/1       Running   0          9m
redis-slave-vsuge    1/1       Running   0          9m
$ cluster/kubectl.sh get services
NAME           CLUSTER_IP       EXTERNAL_IP   PORT(S)    SELECTOR            AGE
frontend       10.247.5.231     nodes         80/TCP     name=frontend       55s
kubernetes     10.247.0.1       <none>        443/TCP    <none>              11h
redis-master   10.247.189.209   <none>        6379/TCP   name=redis-master   8m
redis-slave    10.247.105.127   <none>        6379/TCP   name=redis-slave    7m
```

### テスト

`kubectl get nodes`でMinionのIPアドレスを調べ、ホストマシンのブラウザで「http://[下記コマンドで調べたMinionのIPアドレス]:30301」にアクセスする

```
$ cluster/kubectl.sh get nodes
NAME         LABELS                              STATUS    AGE
10.245.1.3   kubernetes.io/hostname=10.245.1.3   Ready     11h
10.245.1.4   kubernetes.io/hostname=10.245.1.4   Ready     10h
```

下記のような画面が表示され、コメントが投稿できたら完成

![guestbook.png](https://qiita-image-store.s3.amazonaws.com/0/27509/b8e90c7e-472b-39cc-9d65-49a696c4dd7d.png "guestbook.png")