さくらのクラウドで、Dockerクラスタ作成とMulti-host networkingを試す

# さくらのクラウド、いつもお世話になっています。

さくらのクラウド、Dockerのホスト動かしたり、検証用途で使わせていただいています。
すぐサーバーが作成でき、使う事ができる。しかも、使った分だけしかお金がかからない。

便利ですね!

実は、11月に「さくら石狩DC見学ツアー」に参加しました。
https://picasablog.wordpress.com/2015/11/19/第4回「さくら石狩dc見学ツアー」に参加しました/

その際に頂いた、さくらのクラウドのクーポンで「Dockerのクラスタを作る」検証をしてみました。

※検証のため、firewallオフ、rootでの操作を行っています。
運用する際には、適切なfirewallの設定、権限の操作でお願いします。

# Docker SwarmでDockerクラスタを作る。

事前に、石狩第１ゾーンに、Ubuntu Server 14.04 3 LTS 64bit (Dockerホスト用)
事前に、石狩第２ゾーンに、Ubuntu Server 14.04 3 LTS 64bit (Dockerホスト用)
事前に、東京第１ゾーンに、CentOS 7.1 64bit (consul用)
のサーバーを作成します。（説明省略）

|ゾーン|ホスト名|IP|
|---|---|---|
|石狩第１ゾーン|docker-host-1|a.a.a.a|
|石狩第２ゾーン|docker-host-2|b.b.b.b|
|東京第１ゾーン|consul|c.c.c.c|

http://kakakikikeke.blogspot.jp/2015/10/centos-consul.html より引用

## consul構築
```bash
[root@consul ~]# systemctl stop firewalld
[root@consul ~]# cd /usr/bin
[root@consul ~]# curl -O https://dl.bintray.com/mitchellh/consul/0.5.2_linux_amd64.zip
[root@consul ~]# unzip 0.5.2_linux_amd64.zip
[root@consul ~]# consul agent -server -bootstrap -client=0.0.0.0 -data-dir /tmp/consul
```

## Dockerホスト構築

公式のインストール方法に従って構築します。（説明省略）
https://docs.docker.com/engine/installation/ubuntulinux/

```bash
# docker run hello-world
```

## Swarmクラスタ構築

こちらも、公式のインストール方法に従って構築します。
https://docs.docker.com/swarm/install-manual/

```bash
# docker pull swarm
```

# Swarm node構築
それぞれのDockerホストで、別ターミナル上で

```bash
# docker daemon -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
```
このコマンドを入力したターミナルには、ログが流れるので、複数ターミナルを開いています。

それぞれのDockerホストで

docker-host-1

```bash
# docker run -d swarm join --addr=a.a.a.a:2375 consul://c.c.c.c:8500/nodes
```

docker-host-2

```bash
# docker run -d swarm join --addr=b.b.b.b:2375 consul://c.c.c.c:8500/nodes
```

# Swarm manager構築

それぞれのDockerホストで

```bash
# docker run -d -p 10000:2375 swarm manage consul://c.c.c.c:8500/nodes
```

# クラスタの情報を見てみる

```bash
# docker -H tcp://localhost:10000 info
Containers: 32
Images: 7
Role: primary
Strategy: spread
Filters: health, port, dependency, affinity, constraint
Nodes: 2
 docker-host-1: a.a.a.a:2375
  └ Status: Healthy
  └ Containers: 16
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.019 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.16.0-28-generic, operatingsystem=Ubuntu 14.04.3 LTS, storagedriver=aufs
 docker-host-2: b.b.b.b:2375
  └ Status: Healthy
  └ Containers: 16
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.019 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.16.0-28-generic, operatingsystem=Ubuntu 14.04.3 LTS, storagedriver=aufs
CPUs: 2
Total Memory: 2.038 GiB
Name: 082f0047225d

```

2つのノードが確認できました。

## コンテナを沢山起動してみる。

コンテナが、どのようにスケジューリングされるかの説明です。（URL先）
https://docs.docker.com/swarm/scheduler/strategy/
今回は、
Strategy: spreadなので、均等にコンテナが配置されるはずです。

試してみます。

```bash
# docker -H tcp://localhost:10000 ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
```

このコマンドを10回入力

```bash
# docker -H tcp://localhost:10000 run -itd ubuntu /bin/bash
```

```bash
# docker -H tcp://localhost:10000 ps
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
94248b8d581e        ubuntu              "/bin/bash"         53 seconds ago       Up 52 seconds                           docker-host-2/serene_goldberg
14756426159c        ubuntu              "/bin/bash"         About a minute ago   Up About a minute                       docker-host-1/lonely_brown
648aacfd52cc        ubuntu              "/bin/bash"         About a minute ago   Up About a minute                       docker-host-2/sharp_kowalevski
5e252ac1cd66        ubuntu              "/bin/bash"         About a minute ago   Up About a minute                       docker-host-1/condescending_engelbart
75ef8b2e8489        ubuntu              "/bin/bash"         About a minute ago   Up About a minute                       docker-host-2/sad_liskov
90bd7d46fe05        ubuntu              "/bin/bash"         About a minute ago   Up About a minute                       docker-host-1/cocky_wright
64d4378d3552        ubuntu              "/bin/bash"         About a minute ago   Up About a minute                       docker-host-2/angry_archimedes
dcaeb7fd8bbc        ubuntu              "/bin/bash"         About a minute ago   Up About a minute                       docker-host-1/stoic_jang
c8e476c8faac        ubuntu              "/bin/bash"         About a minute ago   Up About a minute                       docker-host-1/agitated_curie
264b7a389a79        ubuntu              "/bin/bash"         About a minute ago   Up About a minute                       docker-host-2/sharp_hypatia
```

それぞれのノードに5つずつコンテナが配置されました。

# Multi-host networkingでDockerホストを跨ぐネットワークを作る。

先程は、クラスタを作りました、しかし、ノード間のコンテナ同士は同じネットワークではありません。
そこで、別ノード間（別ホスト）でもコンテナ同士が同じネットワークに繋がるようにします。

https://docs.docker.com/engine/userguide/networking/get-started-overlay/
Multi-host networkingを利用するには、Linux Kernelが3.16以上でないと利用できません。

それぞれのDockerホストでカーネルをアップデートします。

http://www.neko6.info/archives/1874 より引用

```bash
# apt-get install linux-image-3.16.0-28-generic linux-headers-3.16.0-28
```

https://github.com/docker/docker/issues/14026 より引用

```bash
# apt-get -y update
# apt-get -y upgrade
# apt-get -y dist-upgrade
# apt-get -y install aufs-tools openjdk-7-jre curl wget git vim make php-pear \
php5-dev php5-curl python mc gawk ssh grep sudo htop nmon mysql-client php5-cli \
sqlite3 sysstat sysdig linux-headers-$(uname -r) lxc bsdtar
# apt-get -y install linux-image-extra-$(uname -r)
# modprobe aufs
# apt-get clean
# reboot
```

先ほど同様、それぞれのDockerホストで別ターミナルを開いて

```bash
# docker daemon --cluster-advertise=eth0:2376 --cluster-store=consul://c.c.c.c:8500/nodes -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
```

docker-host-1

```bash
# docker run -d swarm join --addr=a.a.a.a:2375 consul://c.c.c.c:8500/nodes
```

docker-host-2

```bash
# docker run -d swarm join --addr=b.b.b.b:2375 consul://c.c.c.c:8500/nodes
```

それぞれのDockerホストで

```bash
# docker run -d -p 10000:2375 swarm manage consul://c.c.c.c:8500/nodes
```

どちらかのホストで

```bash
# docker network create --driver overlay my-net
```

それぞれのDockerホストで

```bash
# docker -H tcp://localhost:10000 run --net=my-net -i -t ubuntu /bin/bash
```

立ち上がったコンテナは、10.0.0.* のIPが割り振られます。

立ち上がったコンテナ同士をpingを実行すると、ネットワークが繋がっている事を確認できます。


# 感想
クラスタというと、結構難しいのかなと思っていましたが、
swarmをpullしてノードであったり、マネージャーが組めるのはすごく楽だなと思いました。

HA構成も組めるようですので、組んでみたいと思います。