Fedora Atomic Host on EC2 with KubernetesでDockerコンテナのクラスタリング

# はじめに

Redhatが本気でやってそうなので企業内で使うならばProject Atomicが最有力なのではないかなと、Fedora Atomic Hostを使ってEC2上でDockerコンテナのクラスタリングを試してみました。

タイトルはKubernetesと書いていますが、Atomicに入っているCockpitとかも一通り試します。

Project Atomicが何者かは、このスライド「[Docker on RHEL & Project Atomic 入門 - #Dockerjp 4](http://www.slideshare.net/Yuryu/docker-on-project-atomic-docker-meetup-4)」が大変わかりやすいです。

## 試した時点の各ソフトウェアのバージョン

だいぶ前ですが、試したのは**2015年2月17日**なので以下の情報はその日付時点の情報です。

Fedora-Cloud-Atomic-20141203-21.x86_64で`rpm-ostree upgrade`で入った最新バージョンです。

- Kubernetes: 0.7.0
- Cockpit: 0.27
- etcd: 0.4.6
- docker: 1.4.1
- cAdvisor: 0.6.2

最新は以下なので、かなり古い。
まあ日々バージョンアップしているので仕方ないか。

- Kubernetes: 0.10.1
- Cockpit: 0.38
- etcd: 2.0.3
- docker: 1.5.0
- cAdvisor: 0.9.0

今`rpm-ostree upgrade`すると上のより新しいバージョンが入りますし、最新のバージョンも変わっていますが、この記事の内容を試した時点ということでお許し下さい。

# EC2インスタンスのローンチ

RHEL Atomic, CentOS Atomicもありますが、今回は一番開発が早そうなFedora Atomicを使ってみます。

[Fedora Cloud のダウンロード](https://getfedora.org/ja/cloud/download/)の一番下の「Atomic Cloud HVM」から好きなリージョンのAMIを選択。

![スクリーンショット 2015-02-16 14.48.44.png](https://qiita-image-store.s3.amazonaws.com/0/27267/7246e903-66de-894f-f47a-716c268b3ce7.png)

普通にローンチします。
あとでクラスタ組むときに使うので、セキュリティグループには適当な名前をつけておいてください。

![スクリーンショット_2015-02-16_14_49_01.png](https://qiita-image-store.s3.amazonaws.com/0/27267/904f2603-010f-cd29-6a58-3724938ca63d.png)

SSHログインする際のユーザはfedoraです。

```console
$ ssh -i ~/.ssh/key.pem fedora@1.2.3.4
```

Kubernetesなどのバージョンが古いので、パッケージのアップデートをします。

```
$ sudo rpm-ostree upgrade
$ sudo systemctl reboot
```

# Dockerコンテナを動かしてみる

Dockerもちゃんと動いています。

```console
$ systemctl list-units | grep docker   
sys-devices-virtual-net-docker0.device                                                    loaded active plugged   /sys/devices/virtual/net/docker0
sys-subsystem-net-devices-docker0.device                                                  loaded active plugged   /sys/subsystem/net/devices/docker0
docker.service                                                                            loaded active running   Docker Application Container Engine
```

`docker run`してみます。

```console
$ sudo docker run centos /bin/echo "Hello Atomic"
Unable to find image 'centos' locally
Pulling repository centos
dade6cb4530a: Download complete 
511136ea3c5a: Download complete 
5b12ef8fd570: Download complete 
Status: Downloaded newer image for centos:latest
Hello Atomic
```

動きました。

# Cockpitを動かしてみる

[Cockpit](http://cockpit-project.org/)はサーバーおよびDockerコンテナを管理できるWebインターフェースです。
Atomicではデフォルトで動いています。

Cockpitは9090ポートで動くので、セキュリティグループで9090を開けます。

![スクリーンショット 2015-02-16 15.24.00.png](https://qiita-image-store.s3.amazonaws.com/0/27267/2d5be241-82ad-ba02-a9a2-f4f4d7972482.png)

OSのユーザアカウントでログインするので、`root`ユーザにパスワードを設定します。  

```console
$ sudo passwd root
```

`http://1.2.3.4:9090`にアクセス

![スクリーンショット 2015-02-16 15.30.11.png](https://qiita-image-store.s3.amazonaws.com/0/27267/e6afe5ad-720c-291f-d9b8-4e330a5dd151.png)

先ほどパスワードを使ってrootユーザでログインすると、クラスタ内のサーバー一覧が表示されます。

![スクリーンショット 2015-02-16 15.40.06.png](https://qiita-image-store.s3.amazonaws.com/0/27267/a6f23778-e0cb-828f-3c7e-491438405488.png)

各リソースの利用状況を監視できます。

![スクリーンショット 2015-02-16 15.40.13.png](https://qiita-image-store.s3.amazonaws.com/0/27267/5fe63341-8737-73fb-bcad-ab7bc7e281c0.png)

Dockerコンテナ・イメージの管理もできる

![スクリーンショット 2015-02-16 16.08.58.png](https://qiita-image-store.s3.amazonaws.com/0/27267/fd42cf9e-6b9e-8d10-6ab0-fa76aca235c0.png)

Dockerコンテナの管理はかなりいろいろできます。

コンテナの起動・停止
（惜しいことに`docker run`のオプションの指定はできない。）

![スクリーンショット 2015-02-16 22.42.44.png](https://qiita-image-store.s3.amazonaws.com/0/27267/e408c6f9-613c-8ab9-95f1-194b072aec0d.png)

コンテナ毎にシステムリソースの制限を設定

![スクリーンショット 2015-02-16 22.32.49.png](https://qiita-image-store.s3.amazonaws.com/0/27267/4a620021-1cd5-a737-98c9-5e09a06a5edb.png)

Docker Hubからイメージをpull

![スクリーンショット 2015-02-16 22.38.32.png](https://qiita-image-store.s3.amazonaws.com/0/27267/6146f2e2-b4f9-bd84-2c40-ea9a5e449526.png)

他にも「サーバーのターミナルをWebから操作」「全コンテナ合計のCPU・メモリ使用率の参照」「イメージからコンテナの起動」などができます。


# cAdvisorを動かしてみる

cAdvisorはサーバー・コンテナ監視のツールです。デフォルトで起動はしないので、起動します。

```console
$ sudo systemctl start cadvisor
```

動きました。

```console
$ sudo journalctl -f -l -xn -u cadvisor
-- Logs begin at Mon 2015-02-16 13:19:03 UTC. --
Feb 18 02:49:49 ip-172-30-0-246.ec2.internal cadvisor[1331]: I0218 02:49:49.443643    1331 manager.go:77] cAdvisor running in container: "/"
Feb 18 02:49:49 ip-172-30-0-246.ec2.internal cadvisor[1331]: I0218 02:49:49.444400    1331 manager.go:91] Machine: {NumCores:1 MemoryCapacity:1040220160 Filesystems:[{Device:/dev/xvda1 Capacity:198902784}]}
Feb 18 02:49:49 ip-172-30-0-246.ec2.internal cadvisor[1331]: I0218 02:49:49.444749    1331 manager.go:98] Version: {KernelVersion:3.18.6-200.fc21.x86_64 ContainerOsVersion:Fedora 21 (Twenty One) DockerVersion:Unknown CadvisorVersion:0.6.2}
Feb 18 02:49:49 ip-172-30-0-246.ec2.internal cadvisor[1331]: E0218 02:49:49.444973    1331 cadvisor.go:62] Docker registration failed: unable to communicate with docker daemon: dial unix /var/run/docker.sock: no such file or directory.
Feb 18 02:49:49 ip-172-30-0-246.ec2.internal cadvisor[1331]: I0218 02:49:49.445578    1331 factory.go:78] Registering Raw factory
Feb 18 02:49:49 ip-172-30-0-246.ec2.internal cadvisor[1331]: I0218 02:49:49.446156    1331 manager.go:394] Added container: "/" (aliases: [], namespace: "")
Feb 18 02:49:49 ip-172-30-0-246.ec2.internal cadvisor[1331]: I0218 02:49:49.446334    1331 manager.go:131] Starting recovery of all containers
Feb 18 02:49:49 ip-172-30-0-246.ec2.internal cadvisor[1331]: I0218 02:49:49.446922    1331 manager.go:136] Recovery completed
Feb 18 02:49:49 ip-172-30-0-246.ec2.internal cadvisor[1331]: I0218 02:49:49.447805    1331 cadvisor.go:103] Starting cAdvisor version: "0.6.2" on port 4194
Feb 18 02:49:49 ip-172-30-0-246.ec2.internal cadvisor[1331]: I0218 02:49:49.448019    1331 container.go:141] Start housekeeping for container "/"
```

`4194`ポートで動いているので、4194ポートを開けて、`http://<IPアドレス>:4194`にアクセスします。

![スクリーンショット 2015-02-23 1.32.03.png](https://qiita-image-store.s3.amazonaws.com/0/27267/5cbd5009-80d0-d873-d4a3-6e1103c66bbb.png)

サーバーのリソースやDockerコンテナのリソースを見ることができます。
APIもあるので監視の仕組みに使えると思います。
（Dockerコンテナを見ようとするとなぜかエラーになりましたが、とりあえず見なかったことにしました。）

最新バージョン（v0.9.0）だとネットワークやDiskIOの監視もできるようです。（[Releases · google/cadvisor](https://github.com/google/cadvisor/releases)）

なんかCockpitと機能がかぶっていますが、cAdvisorはKubernetesが使っているのでしょうがないですね。

# Kubernetesを動かしてみる

KubernetesはDockerコンテナのクラスタリングツールです。CoreOSのfleetに当たります。

[Testing Kubernetes with an Atomic Host — Project Atomic](http://www.projectatomic.io/blog/2014/11/testing-kubernetes-with-an-atomic-host/)を参考にKubernetesを動かします。

このバージョン（etcd 0.4.6）ではデフォルトの設定ではetcdが起動しないので設定を変更する。
`/etc/etcd/etcd.conf`の`name`のコメントを外す。

```console
$ sudo vi /etc/etcd/etcd.conf
```

```
name = "default-name"
```

Kubernetesはインストール時は動いていないので手動で動かします。

```console
$ sudo su
# for SERVICES in etcd kube-apiserver kube-controller-manager  kube-scheduler docker kube-proxy.service  kubelet.service; do 
         systemctl restart $SERVICES
         systemctl enable $SERVICES
         systemctl status $SERVICES
     done
```

etcdが起動していることを確認します。

```console
$ curl http://localhost:4001/version
etcd 0.4.6
```

Kubernetesのapiserverが起動していることを確認します。

```console
$ curl  http://localhost:8080/version
{
  "major": "0",
  "minor": "7+",
  "gitVersion": "v0.7.0-18-g52e165a4fd720d-dirty",
  "gitCommit": "52e165a4fd720d1703ebc31bd6660e01334227b8",
  "gitTreeState": "dirty"
}
```

まだクラスタは組んでいないのでminionは自分だけです。

```console
$ kubectl get minions
NAME                LABELS
127.0.0.1           <none>
```

Apacheのpodを起動してみます。

```console
$ vi apache.json
```

```json
{
  "id": "fedoraapache",
  "kind": "Pod",
  "apiVersion": "v1beta1",
  "desiredState": {
    "manifest": {
      "version": "v1beta1",
      "id": "fedoraapache",
      "containers": [{
        "name": "fedoraapache",
        "image": "fedora/apache",
        "ports": [{
          "containerPort": 80,
          "hostPort": 80
        }]
      }]
    }
  },
  "labels": {
    "name": "fedoraapache"
  }
}
```

```console
$ kubectl create -f apache.json
I0216 16:00:07.854098    6240 restclient.go:133] Waiting for completion of operation 2
fedoraapache
```

Apacheが動きました。

```console
$ kubectl get pod fedoraapache
NAME                IMAGE(S)            HOST                LABELS              STATUS
fedoraapache        fedora/apache       127.0.0.1/          name=fedoraapache   Running
```

```console
$ curl http://localhost/
Apache
```

# Kubernetesでクラスタ環境を構築

[kubernetes/fedora_manual_config.md at master · GoogleCloudPlatform/kubernetes](https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/getting-started-guides/fedora/fedora_manual_config.md)を参考に手動で設定します。

インスタンスを一台増やして一台をmaster、残りをminionとしてクラスタを組みます。以下の構成とします。

```
fed-master = 172.30.0.246
fed-minion = 172.30.0.43
```

このとき追加したインスタンスは全部同じセキュリティグループに所属させてください。

追加したインスタンスもパッケージを更新します。

```console
$ sudo rpm-ostree upgrade
$ sudo systemctl reboot
```

上の記事ではFedora Atomicでは必要ないと書かれているのですが、同じエラーが出るのでバグ対応します。

```console
$ sudo su
# sed -e "s/docker\.socket/docker\.service/g" /usr/lib/systemd/system/kubelet.service > /etc/systemd/system/kubelet.service
# systemctl daemon-reload
```

全ノードのhostsにサーバーのIPを書きます。（DNSサーバーにホスト名が登録されていれば必要はありません。）

```
$ sudo su
# echo "172.30.0.246 fed-master
172.30.0.43  fed-minion" >> /etc/hosts
```

全ノードの`/etc/kubernetes/config`を以下のように変更します。
`KUBE_ETCD_SERVERS`の設定のみ変更すれば大丈夫なはずです。

```bash
# Comma seperated list of nodes in the etcd cluster
KUBE_ETCD_SERVERS="--etcd_servers=http://fed-master:4001"

# logging to stderr means we get it in the systemd journal
KUBE_LOGTOSTDERR="--logtostderr=true"

# journal message level, 0 is debug
KUBE_LOG_LEVEL="--v=0"

# Should this cluster be allowed to run privleged docker containers
KUBE_ALLOW_PRIV="--allow_privileged=false"
```

同じセキュリティグループ内で全てのTCP通信をOKに設定します。

![スクリーンショット 2015-02-17 14.18.14.png](https://qiita-image-store.s3.amazonaws.com/0/27267/a76aa95e-c3bb-4864-30b7-0908330d1ed0.png)

## masterノードの設定

前に起動したApacheのPodを停止しておきます。

```
$ kubectl delete -f apache.json 
fedoraapache
```

masterノードに不必要なサービスを停止します。

```
$ sudo su
# for SERVICES in kube-proxy kubelet docker; do 
    systemctl stop $SERVICES
    systemctl disable $SERVICES
    systemctl status $SERVICES 
done
```

masterノードの`/etc/kubernetes/apiserver`を以下のように変更します。

```bash
# The address on the local server to listen to.
KUBE_API_ADDRESS="--address=0.0.0.0"

# The port on the local server to listen on.
KUBE_API_PORT="--port=8080"

# How the replication controller and scheduler find the kube-apiserver
KUBE_MASTER="--master=http://fed-master:8080"

# Port minions listen on
KUBELET_PORT="--kubelet_port=10250"

# Address range to use for services
KUBE_SERVICE_ADDRESSES="--portal_net=10.254.0.0/16"

# Add you own!
KUBE_API_ARGS=""
```

masterノードの`/etc/kubernetes/controller-manager`を以下のように変更します。

```bash
# Comma seperated list of minions
KUBELET_ADDRESSES="--machines=fed-minion"
```

masterノードで関連サービスを起動します。

```
$ sudo su
# for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do 
    systemctl restart $SERVICES
    systemctl enable $SERVICES
    systemctl status $SERVICES 
done
```

## minionノードの設定

`/etc/kubernetes/kubelet`を以下のように設定します。

```bash
# The address for the info server to serve on
KUBELET_ADDRESS="--address=0.0.0.0"

# The port for the info server to serve on
KUBELET_PORT="--port=10250"

# You may leave this blank to use the actual hostname
KUBELET_HOSTNAME="--hostname_override=fed-minion"

# Add your own!
KUBELET_ARGS=""
```

必要なサービスを起動します。

```
$ sudo su
# for SERVICES in kube-proxy kubelet docker; do 
    systemctl restart $SERVICES
    systemctl enable $SERVICES
    systemctl status $SERVICES 
done
```

masterノードで以下のコマンドを実行し、fed-minionがクラスタに追加されていることを確認します。

```console
$ kubectl get minions
NAME                LABELS
fed-minion          <none>
```

Apache Podを作成してみます。

```console
$ kubectl create -f apache.json 
fedoraapache
```

ちゃんとfed-minionノードで起動しました。

```console
$ kubectl get pod fedoraapache
NAME                IMAGE(S)            HOST                LABELS              STATUS
fedoraapache        fedora/apache       fed-minion/         name=fedoraapache   Running
```

```console
$ curl http://fed-minion/
Apache
```

クラスタ構成が組めました。

しかし、ここでCockpitを見てもmasterノードしか表示されない。最新のCockpitではKubernetes連携もマルチホスト対応が書かれているので何か違うかもしれない。（[Releases · cockpit-project/cockpit](https://github.com/cockpit-project/cockpit/releases)）

# minionを2つにする

1インスタンス追加します。
上と同じ手順で1インスタンス追加してください。

```
fed-master = 172.30.0.246
fed-minion = 172.30.0.43
fed-minion-2 = 172.30.0.11
```

fed-minion-2の`/etc/hosts`に各ノードのIPを設定します。

```
# echo "172.30.0.246 fed-master
172.30.0.43  fed-minion
172.30.0.11  fed-minion-2" >> /etc/hosts
```

fed-masterとfed-minionの`/etc/hosts`にも以下の設定を追加します。

```
# echo "172.30.0.11  fed-minion-2" >> /etc/hosts
```

fed-masterの`/etc/kubernetes/controller-manager`の以下の箇所にfed-minion-2を追加します。

```bash
KUBELET_ADDRESSES="--machines=fed-minion,fed-minion-2"
```

fed-minion-2の`/etc/kubernetes/config`の`KUBE_ETCD_SERVERS`を以下のように変更します。

```bash
KUBE_ETCD_SERVERS="--etcd_servers=http://fed-master:4001"
```

fed-minion-2の`/etc/kubernetes/kubelet`の以下の２箇所を変更します。

```bash
KUBELET_ADDRESS="--address=0.0.0.0"
```

```bash
KUBELET_HOSTNAME="--hostname_override=fed-minion-2"
```

fed-minion-2の必要なサービスを起動します。

```
$ sudo su
# for SERVICES in kube-proxy kubelet docker; do 
    systemctl restart $SERVICES
    systemctl enable $SERVICES
    systemctl status $SERVICES 
done
```

fed-masterのサービスを再起動します。

```
$ sudo su
# for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do 
    systemctl restart $SERVICES
    systemctl enable $SERVICES
    systemctl status $SERVICES 
done
```

クラスタにfed-minion-2が追加されました。

```console
$ kubectl get minions
NAME                LABELS
fed-minion-2        <none>
fed-minion          <none>
```

# Guestbookサンプルを動かす

再び、[Testing Kubernetes with an Atomic Host — Project Atomic](http://www.projectatomic.io/blog/2014/11/testing-kubernetes-with-an-atomic-host/)を参考に進め、このクラスタ構成でKubernetesに付いている[Guestbookサンプル](https://github.com/GoogleCloudPlatform/kubernetes/tree/v0.7.0/examples/guestbook)を動かします。

GuestbookはPHPとRedisで構成されているデモアプリで、コメントを書き込むとRedisに保存されます。
フロントエンドのコンテナは3つ、Redisのマスターが1つ、読み込み専用のRedisのスレーブが2つという構成です。PHPのアプリは読み込みはスレーブから、書き込みはマスターに行います。

今回はminion２つで試すので、フロントエンドも2つに減らします。以下のような構成です。

![スクリーンショット 2015-02-26 11.17.30.png](https://qiita-image-store.s3.amazonaws.com/0/27267/f2dce5de-7c75-2435-5bcb-0163aeca14fb.png)

[Release v0.7.0 Release Candidate · GoogleCloudPlatform/kubernetes](https://github.com/GoogleCloudPlatform/kubernetes/releases/tag/v0.7.0)からkubernetesのGitリポジトリをダウンロードします。一応インストールされているバージョンと同じv0.7.0にしておきます。
なお、ここからの作業は全てfed-masterノードで行います。

```console
$ curl -L -O https://github.com/GoogleCloudPlatform/kubernetes/releases/download/v0.7.0/kubernetes.tar.gz
$ tar zxvf kubernetes.tar.gz 
$ cd kubernetes/examples/guestbook
```

Redisのマスター`Pod`を起動します。

```console
$ kubectl create -f redis-master.json
```

`get pod redis-master`が`Runing`になるまで待ちます。

```console
$ kubectl get pod redis-master
NAME                IMAGE(S)            HOST                LABELS              STATUS
redis-master        dockerfile/redis    fed-minion/         name=redis-master   Running
```

`redis-master`というラベルのついた`Pod`に通信するサービスを作成します。
Kubernetesの`Service`はコンテナ間通信を仲介するロードバランサーです。コンテナからは環境変数を通してサービスを使うことができます。

```console
$ kubectl create -f redis-master-service.json
```

`Service`が作成されたことを確認します。

```console
$ kubectl get service redis-master        
NAME                LABELS              SELECTOR            IP                  PORT
redis-master        name=redis-master   name=redis-master   10.254.104.212      6379
```

これで全ての`Pod`はredisマスタに`10.254.104.212:6379`でアクセスできるようになります。

Redisマスタは単一の`Pod`でしたが、Redisスレーブは2つの`Pod`を維持するよう設定されています。これは`replicated pod`と呼ばれ、`ReplicationController`が管理します。

以下のコマンドでRedisスレーブを起動します。

```
$ kubectl create -f redis-slave-controller.json
```

`ReplicationContorlller`と`Pod`が2つ起動しています。
Redisスレーブはfed-minionとfed-minion-2の両方で1つずつ動きます。

```console
$ kubectl get replicationController redisSlaveController
NAME                   IMAGE(S)                   SELECTOR            REPLICAS
redisSlaveController   brendanburns/redis-slave   name=redisslave     2
```

```console
$ kubectl get pods -l "name=redisslave"
NAME                                   IMAGE(S)                   HOST                LABELS                              STATUS
36300455-b6a8-11e4-8444-12e8df01b920   brendanburns/redis-slave   fed-minion-2/       name=redisslave,uses=redis-master   Running
3630b03b-b6a8-11e4-8444-12e8df01b920   brendanburns/redis-slave   fed-minion/         name=redisslave,uses=redis-master   Running
```

RedisスレーブのDockerコンテナのコマンドは以下のように環境変数からRedisマスタのホスト名とポート番号を取得するようになっています。これは`redis-masterサービス`で解決されます。

```bash
redis-server --slaveof ${REDIS_MASTER_SERVICE_HOST:-$SERVICE_HOST} $REDIS_MASTER_SERVICE_PORT
```

Redisスレーブ`Pod`が`Running`になったら、Redisスレーブ`Service`を作成します。

```console
$ kubectl create -f redis-slave-service.json
```

```
$ kubectl get service redisslave
NAME                LABELS              SELECTOR            IP                  PORT
redisslave          name=redisslave     name=redisslave     10.254.197.146      6379
```

Redisマスタ`Service`と同じように、どのPod内からもRedisスレーブに`10.254.197.146:6379`でアクセスできるようになります。`Service`がロードバランシングし、2つのPodに透過的にアクセスできます。

最後にフロントエンド`Pod`を作成します。サンプルではフロントエンド`Pod`は3つの`Pod`で構成されているのですが、`minion`が2つしかないので、`frontend-controller.json`の`replicas`を3から2に変更します。

```
    "replicas": 2,
```

最後にフロントエンド`Pod`を作成します。

```console
$ kubectl create -f frontend-controller.json
```

```console
$ kubectl get replicationController frontendController
NAME                 IMAGE(S)                                 SELECTOR            REPLICAS
frontendController   kubernetes/example-guestbook-php-redis   name=frontend       2
```

```console
$ kubectl get pods -l "name=frontend"
NAME                                   IMAGE(S)                                 HOST                LABELS                                       STATUS
b8947bd1-b6ac-11e4-8444-12e8df01b920   kubernetes/example-guestbook-php-redis   fed-minion-2/       name=frontend,uses=redisslave,redis-master   Running
b89561c0-b6ac-11e4-8444-12e8df01b920   kubernetes/example-guestbook-php-redis   fed-minion/         name=frontend,uses=redisslave,redis-master   Running
```

PHPのコードの中では`getenv('REDIS_MASTER_SERVICE_PORT');`のように環境変数からRedisマスタとスレーブのホスト名、ポートを取得しています。詳しくは[guestbook/php-redis/index.php](https://github.com/GoogleCloudPlatform/kubernetes/blob/v0.7.0/examples/guestbook/php-redis/index.php)を見てください。

これで全てのPod, Service, Replication Controllerが起動しました。

```console
$ kubectl get pods
NAME                                   IMAGE(S)                                 HOST                LABELS                                       STATUS
redis-master                           dockerfile/redis                         fed-minion/         name=redis-master                            Running
36300455-b6a8-11e4-8444-12e8df01b920   brendanburns/redis-slave                 fed-minion-2/       name=redisslave,uses=redis-master            Running
3630b03b-b6a8-11e4-8444-12e8df01b920   brendanburns/redis-slave                 fed-minion/         name=redisslave,uses=redis-master            Running
b8947bd1-b6ac-11e4-8444-12e8df01b920   kubernetes/example-guestbook-php-redis   fed-minion-2/       name=frontend,uses=redisslave,redis-master   Running
b89561c0-b6ac-11e4-8444-12e8df01b920   kubernetes/example-guestbook-php-redis   fed-minion/         name=frontend,uses=redisslave,redis-master   Running
```

frontendが起動しているfed-minionからfed-minion-2に8000ポートでアクセスするとGuestbookアプリケーションが動きます。（事前にEC2のセキュリティグループで8000を開けておいてください。）

![スクリーンショット 2015-02-17 23.06.07.png](https://qiita-image-store.s3.amazonaws.com/0/27267/fd039167-04dd-36d9-d322-9cbda9fa251c.png)

# 自動フェイルオーバーを試してみる

fed-minionインスタンスを停止してみる。

```console
$ kubectl get minions
NAME                LABELS
fed-minion-2        <none>
```

`minion`は減った。

```console
$ kubectl get pods
F0217 15:08:54.544116    1605 get.go:75] The requested resource does not exist.
```

あれ。。。
これかな。[kubectl/apiserver problems if minion down · Issue #2951 · GoogleCloudPlatform/kubernetes](https://github.com/GoogleCloudPlatform/kubernetes/issues/2951)

# CoreOSとの比較

### ChromeOS autoupdate vs rpm-ostree

シンプルさと柔軟性のトレードオフという印象
参考：[OSTree: OSイメージとパッケージシステムの間にGitのアプローチを](http://www.slideshare.net/i_yudai/ostree-osgit)

### fleet vs Kubernetes

Atomic同梱のバージョンだとfleetの方が安定している。Kubernetesはバギー。
日々リリースされているので、最新バージョンだともっといいんだろうけど。

けっこう大きな違いだと思うのはmasterサーバーの要不要。
Kubernetesはmasterサーバーが落ちたらコンテナは動いているけど、クラスタ管理機能が使えなくなる。
CoreOSの場合は全サーバーが同じ立場なので、どれが落ちても何も変わらない。
と理解しているが、合っているだろうか。

でも、Kubernetesの方が機能が豊富

- コンテナ間通信はKubernetesのServiceで実現
- Heapsterでクラスタ内コンテナのリソース監視
- fluentd+Elasticsearch+Kibanaによるログ収集・分析

### Cockipit

Cockpit相当の機能はCoreOSにはない。
1ノード完結でDockerを動かす需要がどれほどあるかわからないが、それであればCockpitは十分使えそう。バギーでもなかった。

Kubernetes対応については、Cockpitの0.37でKubernetesプラグインが追加されていたり、さらに開発も進めているようなので期待したい。（今回はAtomicを試しただけなので、最新のCockpitは試していないです。）

# Atomicの感想

デフォルトでKubernetes, etcd, cAdviserが起動せず、DockerとCockpitしか起動していないあたりからも、今のところAtomicは1ノードでのDockerコンテナ管理のためのホストOSとして作られている印象。

Dockerコンテナのクラスタリングは完全にKubernetes任せで、今のところはインストールしといたから後はKubernetesで好きにやってという感じに見える。

まとめると、1ノードなら使える（まあDockerにCockpit付いただけ）、クラスタ構成はまだまだこれからという感想です。

# 参考

- [Testing Kubernetes with an Atomic Host — Project Atomic](http://www.projectatomic.io/blog/2014/11/testing-kubernetes-with-an-atomic-host/)
- [kubernetes/fedora_manual_config.md at v0.7.0 · GoogleCloudPlatform/kubernetes](https://github.com/GoogleCloudPlatform/kubernetes/blob/v0.7.0/docs/getting-started-guides/fedora/fedora_manual_config.md)
- [kubernetes/README.md at v0.7.0 · GoogleCloudPlatform/kubernetes](https://github.com/GoogleCloudPlatform/kubernetes/blob/v0.7.0/examples/guestbook/README.md)
- [kubernetes/cli.md at release-0.8 · GoogleCloudPlatform/kubernetes](https://github.com/GoogleCloudPlatform/kubernetes/blob/release-0.8/docs/cli.md)