CockroachDBをDocker Swarm環境上で動かし、高可用性と拡張性を試してみた

# はじめに
[CockroachDBをDocker環境上で動かし、サンプルデータベースをselectして、ぎょっとする](http://qiita.com/cyack2002/items/3d6500e0b8ace85cadf0)の続きです。
今回、Container Orchestration Toolを使用して、下図のような高可用性と拡張性に対応できるかを検証してみます。
CockroachDBは、Container Orchestration ToolとしてKubernetesとDocker Swarmをサポートしています。自分の周りではKubernetesの方が人気ですので、あえて不人気のDocker Swarmを採用してみます。CoreOSをgit cloneしてvagrant upすれば、Docker Swarmが導入されていますので、わざわざOrchestration Toolを導入する必要がないって言うことも、選択理由のひとつです。
![6.jpeg](https://qiita-image-store.s3.amazonaws.com/0/199531/7b4e8f9a-4361-b659-30ed-26975cc3af07.jpeg)

# 環境
- Windows7
- Vagrant V1.8.6
- VirtualBox V4.3.10
- Coreos-alpha V1465.0.0
- Docker 17.05.0-ce
- CockroachDB V1.05

# 1. 事前準備
- 1.1. CoreOSのダウンロード
- 

```
C:\Users\IBM_ADMIN>mkdir vagrant_test
C:\Users\IBM_ADMIN>cd vagrant_test
C:\Users\IBM_ADMIN\vagrant_test>git clone https://github.com/coreos/coreos-vagrant/
Cloning into 'coreos-vagrant'...
remote: Counting objects: 448, done.
remote: Total 448 (delta 0), reused 0 (delta 0), pack-reused 448
Receiving objects: 100% (448/448), 110.64 KiB | 75.00 KiB/s, done.
Resolving deltas: 100% (202/202), done.
```

- 1.2. CoreOSの起動
- 

今回、3つのインスタンス(上図のOS部分)が準備しますので、下記のようにVagrantfileを編集します。デフォルトの1024MBでも今回のシナリオでは問題なかったです。
```
$num_instances = 3
```

CoreOSのインスタンスを3つ起動します。vagrant global-statusコマンドを実行し、stateがrunningであることを確認します。

```
C:\Users\IBM_ADMIN\vagrant_test>cd coreos-vagrant
C:\Users\IBM_ADMIN\vagrant_test\coreos-vagrant>vagrant up
Bringing machine 'core-01' up with 'virtualbox' provider...
Bringing machine 'core-02' up with 'virtualbox' provider...
Bringing machine 'core-03' up with 'virtualbox' provider...
(省略)
PS C:\Users\IBM_ADMIN\vagrant_test\coreos-vagrant> vagrant global-status
id       name        provider   state    directory
--------------------------------------------------------------------------------------
81ef246  core-01     virtualbox running  C:/Users/IBM_ADMIN/vagrant_test/coreos-vagrant
2d1bfeb  core-02     virtualbox running  C:/Users/IBM_ADMIN/vagrant_test/coreos-vagrant
ad19b0c  core-03     virtualbox running  C:/Users/IBM_ADMIN/vagrant_test/coreos-vagrant
```

CoreOSのインスタンスにDockerが導入されていることを確認します。

```
C:\Users\IBM_ADMIN\vagrant_test\coreos-vagrant>vagrant teraterm coreos-01
Last login: Sun Sep  3 07:54:18 UTC 2017 from 10.0.2.2 on ssh
Container Linux by CoreOS alpha (1506.0.0)
core@core-01 ~ $ sudo -s
core-01 core # docker version
Client:
 Version:      17.05.0-ce
 API version:  1.29
 Go version:   go1.7.6
 Git commit:   89658be
 Built:        Wed Aug 16 02:57:51 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.05.0-ce
 API version:  1.29 (minimum version 1.12)
 Go version:   go1.7.6
 Git commit:   89658be
 Built:        Wed Aug 16 02:57:51 2017
 OS/Arch:      linux/amd64
 Experimental: false
```

# 2. Docker Swarm環境の設定
- 2.1. Docker Swarmの初期化
-
今回、core-01をDocker Swarm Manager、core-02とcore-03をDocker Swarm workerにします。
Docker Swarm初期化時に、advertise-addrオプションを使用し、CockroachDBクラスターのIPアドレスを指定します。CockroachDBクラスター内で、このインスタンスを指し示すためのIPアドレスです。そのため、ホストOSからもゲストOSからもアクセスできるcore-01のホストオンリーアダプターのIPアドレスにします。

```
core-01 core # docker swarm init --advertise-addr 172.17.8.101
Swarm initialized: current node (iyr5inqklspv4tc4dui3sbo3m) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-3uhm9z5rgw0ln0bb45cvhi3esafnbf7gdd9ucp5972p5qtvpwb-3gy7ctuxxu96c7in1tvg513xm \
    172.17.8.101:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
```

- 2.2. workerノードの作成とDocker Swarmサービスへの追加
-
core-02とcore-03から、2.1にて出力されたコマンドを実行します。その後、core-01からDocker Swarmの設定を確認します。

```
core-02 core # docker swarm join \
--token SWMTKN-1-3uhm9z5rgw0ln0bb45cvhi3esafnbf7gdd9ucp5972p5qtvpwb-3gy7ctuxxu96c7in1tvg513xm \
172.17.8.101:2377
This node joined a swarm as a worker.

core-03 core # docker swarm join \
--token SWMTKN-1-3uhm9z5rgw0ln0bb45cvhi3esafnbf7gdd9ucp5972p5qtvpwb-3gy7ctuxxu96c7in1tvg513xm \
172.17.8.101:2377
This node joined a swarm as a worker.

core-01 core # docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
iyr5inqklspv4tc4dui3sbo3m *   core-01             Ready               Active              Leader
okkfs6rfiqisejpq26mnmlhqa     core-03             Ready               Active
tt48d1r2vc1dyyr5u0z6pqwli     core-02             Ready               Active
```

# 3. オーバーレイネットワークの作成
Docker Swarm環境上で、お互いに通信するためにオーバーレイネットワークを作成します。オーバーレイネットワークの名前は、cockroachとします。Managerノードであるcore-01から実行します。

```
core-01 core # docker network create --driver overlay cockroachdb
kmeqvoq46xcp9fy27m237j7oc
```

Docker上のネットワークの設定を確認します。Driverがoverlayになっています。

```
core-01 core # docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
6e8598ccb3e8        bridge              bridge              local
kmeqvoq46xcp        cockroachdb         overlay             swarm
17e2d6afd695        docker_gwbridge     bridge              local
8e73e890f93a        host                host                local
t8b5yi2ls8nq        ingress             overlay             swarm
5cb170330914        none                null                local
64cdee22ed73        roachnet            bridge              local

core-01 core # docker network inspect cockroachdb
[
    {
        "Name": "cockroachdb",
        "Id": "kmeqvoq46xcp9fy27m237j7oc",
        "Created": "0001-01-01T00:00:00Z",
        "Scope": "swarm",
        "Driver": "overlay",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": []
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "Containers": null,
        "Options": {
            "com.docker.network.driver.overlay.vxlanid_list": "4097"
        },
        "Labels": null
    }
]
```


# 4. CockroachDBクラスターの起動
今回、下図のような構成になります。3つのDocker Swarmサービスを作成し、サービスを削除したり、追加したりしてみます。
![7.png](https://qiita-image-store.s3.amazonaws.com/0/199531/cba98667-3cb4-f6c9-8500-f8382d8ffbce.png)

- 4.1. CockroachDBクラスターのサービス作成
-
Managerノードのcore-01から、CockroachDBクラスターの1つ目のDocker Swarmサービス(=cockroachdb-1)を作成します。

```
docker service create \
--replicas 1 \
--name cockroachdb-1 \
--hostname cockroachdb-1 \
--network cockroachdb \
--mount type=volume,source=cockroachdb-1,target=/cockroach/cockroach-data,volume-driver=local \
--stop-grace-period 60s \
--publish 8080:8080 \
cockroachdb/cockroach:v1.0.5 start \
--logtostderr \
--insecure
```

続いて、Managerノードのcore-01から、CockroachDBクラスターの2つ目のDocker Swarmサービス(=cockroachdb-2)、3つ目のDocker Swarmサービス(=cockroachdb-3)を作成します。

```
core-01 core # docker service create \
--replicas 1 \
--name cockroachdb-2 \
--hostname cockroachdb-2 \
--network cockroachdb \
--mount type=volume,source=cockroachdb-2,target=/cockroach/cockroach-data,volume-driver=local \
--stop-grace-period 60s \
cockroachdb/cockroach:v1.0.5 start \
--join=cockroachdb-1:26257 \
--logtostderr \
--insecure

core-01 core # docker service create \
--replicas 1 \
--name cockroachdb-3 \
--hostname cockroachdb-3 \
--network cockroachdb \
--mount type=volume,source=cockroachdb-3,target=/cockroach/cockroach-data,volume-driver=local \
--stop-grace-period 60s \
cockroachdb/cockroach:v1.0.5 start \
--join=cockroachdb-1:26257 \
--logtostderr \
--insecure

```

作成したDocker Swarmサービスを確認します。

```
core-01 core # docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                          PORTS
aq7m9huz4umv        cockroachdb-2       replicated          1/1                 cockroachdb/cockroach:v1.0.5
liuk7ja6smi3        cockroachdb-3       replicated          1/1                 cockroachdb/cockroach:v1.0.5
ojts2pb17ii5        cockroachdb-1       replicated          1/1                 cockroachdb/cockroach:v1.0.5   *:8080->8080/tcp
```

- 4.2. CockroachDBクラスターのサービス削除
- 
Managerノードのcore-01から、CockroachDBクラスターの1つ目のDocker Swarmサービス(=cockroachdb-1)を削除してみます。その後、削除されたことを確認します。

```
core-01 core # docker service rm cockroachdb-1
cockroachdb-1

core-01 core # docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                          PORTS
aq7m9huz4umv        cockroachdb-2       replicated          1/1                 cockroachdb/cockroach:v1.0.5
liuk7ja6smi3        cockroachdb-3       replicated          1/1                 cockroachdb/cockroach:v1.0.5
```

- 4.3. CockroachDBクラスターのサービス復活
-
再度、CockroachDBクラスターのDocker Swarmサービス(=cockroachdb-1)を作成し、既存のDocker Swarmサービス(=cockroachdb-2)に追加し、復活させます。

```
core-01 core # docker service create \
--replicas 1 \
--name cockroachdb-1 \
--hostname cockroachdb-1 \
--network cockroachdb \
--mount type=volume,source=cockroachdb-1,target=/cockroach/cockroach-data,volume-driver=local \
--stop-grace-period 60s \
--publish 8080:8080 \
cockroachdb/cockroach:v1.0.5 start \
--join=cockroachdb-2:26257 \
--logtostderr \
--insecure
```

# 5. SQL経由でのCockroachDBクラスターの設定確認
CockroachDBクラスタの設定を、Workerノードから確認します。

```
core-02 core # docker ps | grep cockroachdb
2366ee3b63bd        cockroachdb/cockroach:v1.0.5   "/cockroach/cockro..."   14 minutes ago      Up 14 minutes       8080/tcp, 26257/tcp   cockroachdb-2.1.b1n2dil4rfs4qmrted7n3etd2
core-03 core # docker ps | grep cockroachdb
506c8afb2db9        cockroachdb/cockroach:v1.0.5   "/cockroach/cockro..."   11 minutes ago      Up 11 minutes       8080/tcp, 26257/tcp   cockroachdb-3.1.ixjm4myf4lq1imbl21gkj0n3o

core-02 core # docker exec -it 2366ee3b63bd ./cockroach sql --insecure
# Welcome to the cockroach SQL interface.
# All statements must be terminated by a semicolon.
# To exit: CTRL + D.
root@:26257/> CREATE DATABASE insecurenodetest;
CREATE DATABASE
```

# 6. GUI経由でのCockroachDBクラスターのモニタリング
CockroachDBはモニタリング用のAdmin UIが提供されています。Webブラウザから、http://<IPアドレス>:8080/にアクセスします。
![8.jpeg](https://qiita-image-store.s3.amazonaws.com/0/199531/26639757-5f37-645f-5e1d-5f66e208ff32.jpeg)

[Node list]にて、3つのサービスが登録されていることを確認します。
![9.jpeg](https://qiita-image-store.s3.amazonaws.com/0/199531/6b0c8479-3304-be29-8fc7-22d6eb0e8a25.jpeg)

[Database]にて、先程作成したデータベースが登録されていることを確認します。
![10.jpeg](https://qiita-image-store.s3.amazonaws.com/0/199531/ffeef10b-3f63-1abc-bd50-10fad771eb26.jpeg)

# 7. OS(コンテナー)障害の検証
docker killコマンドを使用し、core-02上のCockroachDBが稼働しているコンテナーをkillします。

```
core-02 core # docker ps | grep cockroachdb
2366ee3b63bd        cockroachdb/cockroach:v1.0.5   "/cockroach/cockro..."   About an hour ago   Up About an hour    8080/tcp, 26257/tcp   cockroachdb-2.1.b1n2dil4rfs4qmrted7n3etd2
core-02 core # docker kill 2366ee3b63bd
2366ee3b63bd
core-02 core # docker ps | grep cockroachdb
```

Managerノードのcore-01から、CockroachDBクラスターのDocker Swarmサービスの状態を調査し、cockroachdb-2が復活していることを確認します。Workerノードのcore-02から、CockroachDBクラスターのコンテナーが復活していることを確認します。Docker Swarmによって、OS(コンテナー)障害にも対応できることが確認できます。

```
core-01 core # docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                          PORTS
aq7m9huz4umv        cockroachdb-2       replicated          1/1                 cockroachdb/cockroach:v1.0.5
liuk7ja6smi3        cockroachdb-3       replicated          1/1                 cockroachdb/cockroach:v1.0.5
ww2nj36x8e3i        cockroachdb-1       replicated          1/1                 cockroachdb/cockroach:v1.0.5   *:8080->8080/tcp
core-02 core # docker ps | grep cockroachdb
4280da5ad0a9        cockroachdb/cockroach:v1.0.5   "/cockroach/cockro..."   About a minute ago   Up About a minute   8080/tcp, 26257/tcp   cockroachdb-2.1.dtxkzq5np33uqo0phoflufmad
```

# 8. CockroachDBクラスター拡張の検証

- 8.1. CoreOSの起動
- 
今までは3つのインスタンスが起動していましたが、Vagrantfileを編集し、下図のように4つに増やします。
![12.jpeg](https://qiita-image-store.s3.amazonaws.com/0/199531/689e1f2d-cb9c-9999-d2e8-d0df356f8a5a.jpeg)


```
$num_instances = 4
```

4つ目のCoreOSのインスタンスを起動します。vagrant global-statusコマンドを実行し、stateがrunningであることを確認します。

```
C:\Users\IBM_ADMIN\vagrant_test\coreos-vagrant>vagrant up
Bringing machine 'core-01' up with 'virtualbox' provider...
Bringing machine 'core-02' up with 'virtualbox' provider...
Bringing machine 'core-03' up with 'virtualbox' provider...
Bringing machine 'core-04' up with 'virtualbox' provider...

PS C:\Users\IBM_ADMIN\vagrant_test\coreos-vagrant> vagrant global-status
id       name        provider   state    directory
--------------------------------------------------------------------------------------
81ef246  core-01     virtualbox running  C:/Users/IBM_ADMIN/vagrant_test/coreos-vagrant
2d1bfeb  core-02     virtualbox running  C:/Users/IBM_ADMIN/vagrant_test/coreos-vagrant
ad19b0c  core-03     virtualbox running  C:/Users/IBM_ADMIN/vagrant_test/coreos-vagrant
5472b81  core-04     virtualbox running  C:/Users/IBM_ADMIN/vagrant_test/coreos-vagrant
```

- 8.2. workerノードの作成とDocker Swarmサービスへの追加
-
core-04から、2.1にて出力されたコマンドを実行します。その後、Managerノードのcore-01からDocker Swarmの設定を確認します。

```
core-04 core # docker swarm join \
--token SWMTKN-1-3uhm9z5rgw0ln0bb45cvhi3esafnbf7gdd9ucp5972p5qtvpwb-3gy7ctuxxu96c7in1tvg513xm \
172.17.8.101:2377
This node joined a swarm as a worker.

core-01 core # docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
iyr5inqklspv4tc4dui3sbo3m *   core-01             Ready               Active              Leader
okkfs6rfiqisejpq26mnmlhqa     core-03             Ready               Active
tt48d1r2vc1dyyr5u0z6pqwli     core-02             Ready               Active
w7d58hoc47nbcdgbl7nxxv51o     core-04             Ready               Active
```

Managerノードのcore-01からDocker Swarmサービス(=cockroachdb-4)を作成し、CockroachDBクラスターに追加します。その後、Docker Swarmサービスに、cockroachdb-4が追加されたことを確認します。

```
core-01 core # docker service create \
--replicas 1 \
--name cockroachdb-4 \
--hostname cockroachdb-4 \
--network cockroachdb \
--mount type=volume,source=cockroachdb-4,target=/cockroach/cockroach-data,volume-driver=local \
--stop-grace-period 60s \
cockroachdb/cockroach:v1.0.5 start \
--join=cockroachdb-1:26257 \
--logtostderr \
--insecure

core-01 core # docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                          PORTS
aq7m9huz4umv        cockroachdb-2       replicated          1/1                 cockroachdb/cockroach:v1.0.5
liuk7ja6smi3        cockroachdb-3       replicated          1/1                 cockroachdb/cockroach:v1.0.5
srjwlkil2zvm        cockroachdb-4       replicated          0/1                 cockroachdb/cockroach:v1.0.5
ww2nj36x8e3i        cockroachdb-1       replicated          1/1                 cockroachdb/cockroach:v1.0.5   *:8080->8080/tcp
```

docker serviceコマンドのIDを指定し、どのノードでCockroachDBが稼働しているかを確認します。

```
core-01 core # docker service ps ww2nj36x8e3i
ID                  NAME                  IMAGE                          NODE                DESIRED STATE       CURRENT STATE            ERROR                         PORTS
hap4euhz3yrp        cockroachdb-1.1       cockroachdb/cockroach:v1.0.5   core-01             Running             Running 33 minutes ago           

core-01 core # docker service ps srjwlkil2zvm
ID                  NAME                  IMAGE                          NODE                DESIRED STATE       CURRENT STATE           ERROR                         PORTS
qgwnrn0e2zki        cockroachdb-4.1       cockroachdb/cockroach:v1.0.5   core-04             Running             Running 3 minutes ago
```

# 9. CockroachDBクラスターの停止

最後に、コンテナ名を指定し、Dockerコンテナーを停止します。

```
core-01 core # docker stop cockroachdb-1 cockroachdb-2 cockroachdb-3 cockroachdb-4 
```

# まとめ
今回は、Container Orchestration ToolのDocker Swarmの機能にて、高可用性と拡張性に対応できるかを検証してみました。結果、スモールスタートでビジネスを始めて、ユーザー数の増加に応じてシステムを拡張することが、データベースであっても実現できることが確認できました。また、HWやOS障害が発生しても、自動で障害ノードを切り離し、正常ノードでCockroachDBクラスターを稼働できることも確認できました。(もちろん、パフォーマンス等、もっと検証しなければいけませんが...)

安易ですが、CockroachDBによって、データベースの勢力図が変わる、マイクロサービスがもっと普及するのではないかと予想しています。

今度は、CockroachDBの機能による高可用性と拡張性の検証してみます。



# 参考
[Orchestrate CockroachDB with Kubernetes](https://www.cockroachlabs.com/docs/stable/orchestrate-cockroachdb-with-kubernetes.html)
[Orchestrate CockroachDB with Docker Swarm](https://www.cockroachlabs.com/docs/stable/orchestrate-cockroachdb-with-docker-swarm-insecure.html)
[Qiita:Cockroach関連記事 1.CockroachDBをDocker環境上で動かしてみる](http://qiita.com/cyack2002/items/18d6ad3bdc95eee8fec7)
[Qiita:Cockroach関連記事 2.CockroachDBをDocker環境上で動かし、サンプルデータベースをselectして、ぎょっとする](http://qiita.com/cyack2002/items/3d6500e0b8ace85cadf0)
[Qiita:Cockroach関連記事 4.CockroachDBをDocker環境上で動かし、クラスター内のサービス数を増やし、データをレプリカしてみる
](http://qiita.com/cyack2002/items/6fcbd9a4360e954e4bf9)