CockroachDBをDocker環境上で動かしてみる


はじめに

みなさん、NewSQLをご存知でしょうか?! スケーラビリティーとACID特性があって、SQL言語で操作できるデータベースです。データベースの永遠の課題が解決されたのではと衝撃を受けましたので、今回、NewSQLのひとつであるcockroachDBを、Docker環境上で動かしてみます。

CockroachDBにつきましては、下記をご確認下さい。Cockroachの意味がごきちゃんであるとかは、あえて触れないです。
クリスマス・イブにCockroachDBに負荷をかけてみる

NewSQL登場の背景

非常に簡単にデータベースの歴史を振り返ります。
1977年Oracle Database、1983年IBM DB2に代表されるRDB(=Relational Database)は、スケールアウトしずらいモノリシックな作りになっていました。そのためRDBでは、昨今のビックデータやマイクロサービスの潮流に対応できず、スケーラビリティーを求めてNot Only SQLが登場します。
Not Only SQLは、スケールアウトが容易で高い読み書き性能を持っているのですが、トランザクション機能などのデータの一貫性を求められる処理については不向きでした。Not Only SQLは、一貫性を捨ててスケールアウトを選択したとも言えます。ビッグデータやマイクロサービスがどうこうと言うよりかは、スケーラビリティーとACID特性は、データベースの永遠の課題ではないでしょうか。
その永遠の課題を解決する衝撃のデータベース、NoSQLをベースとして、ACID特性を持って、SQL言語で操作できるNewSQLが登場します。

環境

  • Windows7
  • Vagrant V1.8.6
  • VirtualBox V4.3.10
  • Coreos-alpha V1465.0.0
  • CockroachDB V1.05

1. 事前準備

vagrantとvirtualboxは、各自でご用意下さい。
執筆時点のvagrantの最新版V1.9.8(Windows 64bit版)は、CoreOSのvagrant upが正常に完了しませんでしたので、ご注意下さい。vagrant up以降の返答がなかったです。
その他、下記エラーは、VirtualBoxのデフォルトの仮想マシンフォルダーを変更することで対応しました。

VBoxManage.exe: error: Could not rename the settings file XXX
VBoxManage.exe: error: Details: code E_FAIL (0x80004005) (省略)

- 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の起動

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...
==> core-01: Box 'coreos-alpha' could not be found. Attempting to find and install...
    core-01: Box Provider: virtualbox

- 1.3. Teraterm plugin導入と起動

C:\Users\IBM_ADMIN\vagrant_test\coreos-vagrant>vagrant plugin install vagrant-teraterm
C:\Users\IBM_ADMIN\vagrant_test\coreos-vagrant>vagrant teraterm core-01

- 1.4. CockroachDBのDockerイメージのダウンロード

起動させたTeratermから下記コマンドを実行します。CockroachDBは、執筆時点での最新版V1.0.5を使用します。

core@core-01 ~ $ sudo -s
core-01 core # docker pull cockroachdb/cockroach:v1.0.5
v1.0.5: Pulling from cockroachdb/cockroach
Digest: sha256:9db5df93d2e453ec8c6b78a944a647ade3d63a96f840cb570a0158ea11a5a883
Status: Image is up to date for cockroachdb/cockroach:v1.0.5
core-01 core # docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
cockroachdb/cockroach   v1.0.5              810ca9af6e1b        3 days ago          163MB
core-01 core # docker run --rm cockroachdb/cockroach:v1.0.5 version
Build Tag:    v1.0.5
Build Time:   2017/08/24 17:43:46
Distribution: CCL
Platform:     linux amd64
Go Version:   go1.8.3
C Compiler:   gcc 6.3.0
Build SHA-1:  6255bbf89152218db590c9838976aa8780e4770e

2. ブリッジネットワークの作成

1つのCoreOSインスタンス上に複数のDockerコンテナーを起動し、1つのDockerコンテナー上に1つのCockroachDBを稼働させます。
最初に、複数のDockerコンテナー間で通信するために、roachnetという名前のブリッジネットワークを作成します。

core-01 core # docker network create -d bridge roachnet
64cdee22ed7339edcff501de396e9272ab2592061438e4aae63ddb7ca83b153f
core-01 core # docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
9e236af3f4f2        bridge              bridge              local
c57f06bc5748        host                host                local
4c3bff7d64aa        none                null                local
f2cdc33a677f        roachnet            bridge              local
core-01 core # docker network inspect roachnet
(省略)

3. CockroachDBクラスターの起動

Dockerコンテナーノード上に、CockroachDBクラスターを起動します。
pullしたCockroachのDockerイメージを指定し、Dockerコンテナーを起動します。
コンテナー名はroach1、コンテナーホスト名はroach1とします。
他と通信するために26257ポート(=CockroachDB用)と8080ポート(=Admin UI用)をフォワードします。
コンテナー上の/cockroach/cockroach-dataを、ホストOS上の${PWD}/cockroach-data/roach1にマウントします。
動かしてみるのが目的ですので、InsecureモードでCockroachDBを起動します。

core-01 core # docker run -d \
--name=roach1 \
--hostname=roach1 \
--net=roachnet \
-p 26257:26257 -p 8080:8080  \
-v "${PWD}/cockroach-data/roach1:/cockroach/cockroach-data"  \
cockroachdb/cockroach:v1.0.5 start --insecure
core-01 core # docker ps
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                                              NAMES
f0129adb1b39        cockroachdb/cockroach:v1.0.5   "/cockroach/cockro..."   11 minutes ago      Up 1 minutes       0.0.0.0:8080->8080/tcp, 0.0.0.0:26257->26257/tcp   roach1
core-01 core # ls ./cockroach-data/roach1/
000003.log  COCKROACHDB_VERSION  CURRENT  IDENTITY  LOCK  MANIFEST-000001  OPTIONS-000005  logs  tmp

4. CockroachDBクラスターにDockerコンテナーノードを追加

3で作成したCockroachDBクラスターに、別のDockerコンテナーノード上(=roach2)のCockroachDBを追加します。
pullしたCockroachのDockerイメージを指定し、Dockerコンテナーを起動します。
コンテナー名はroach2、コンテナーホスト名はroach2とします。
コンテナー上の/cockroach/cockroach-dataを、ホストOS上の${PWD}/cockroach-data/roach2にマウントします。
動かしてみるのが目的ですので、InsecureモードでCockroachDBを起動し、コンテナー名:roach1上のCockroachDBにジョインします。

core-01 core # docker run -d \
--name=roach2 \
--hostname=roach2 \
--net=roachnet \
-v "${PWD}/cockroach-data/roach2:/cockroach/cockroach-data" \
cockroachdb/cockroach:v1.0.5 start --insecure --join=roach1
core-01 core # docker ps
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                                              NAMES
a69f6e032332        cockroachdb/cockroach:v1.0.5   "/cockroach/cockro..."   9 seconds ago       Up 8 seconds        8080/tcp, 26257/tcp                                roach2
f0129adb1b39        cockroachdb/cockroach:v1.0.5   "/cockroach/cockro..."   11 minutes ago      Up 11 minutes       0.0.0.0:8080->8080/tcp, 0.0.0.0:26257->26257/tcp   roach1
core-01 core # ls ./cockroach-data/roach2
000003.log  COCKROACHDB_VERSION  CURRENT  IDENTITY  LOCK  MANIFEST-000001  OPTIONS-000005  logs  tmp

3で作成したCockroachDBクラスターに、さらに別のDockerコンテナーノード上(=roach3)のCockroachDBを追加します。
pullしたCockroachのDockerイメージを指定し、Dockerコンテナーを起動します。
コンテナー名はroach3、コンテナーホスト名はroach3とします。
コンテナー上の/cockroach/cockroach-dataを、ホストOS上の${PWD}/cockroach-data/roach3にマウントします。
動かしてみるのが目的ですので、InsecureモードでCockroachDBを起動し、コンテナー名:roach1上のCockroachDBにジョインします。

core-01 core # docker run -d \
--name=roach3 \
--hostname=roach3 \
--net=roachnet \
-v "${PWD}/cockroach-data/roach3:/cockroach/cockroach-data" \
cockroachdb/cockroach:v1.0.5 start --insecure --join=roach1
core-01 core # docker ps
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                                              NAMES
01fb0b2b1fc1        cockroachdb/cockroach:v1.0.5   "/cockroach/cockro..."   5 seconds ago       Up 4 seconds        8080/tcp, 26257/tcp                                roach3
a69f6e032332        cockroachdb/cockroach:v1.0.5   "/cockroach/cockro..."   3 minutes ago       Up 3 minutes        8080/tcp, 26257/tcp                                roach2
f0129adb1b39        cockroachdb/cockroach:v1.0.5   "/cockroach/cockro..."   14 minutes ago      Up 14 minutes       0.0.0.0:8080->8080/tcp, 0.0.0.0:26257->26257/tcp   roach1
ore-01 core # ls ./cockroach-data/roach3
000003.log  COCKROACHDB_VERSION  CURRENT  IDENTITY  LOCK  MANIFEST-000001  OPTIONS-000005  logs  tmp

5. CockroachDBクラスターへのSQL実行

ここまでで、1つのCoreOSインスタンス上に3つのDockerコンテナーを起動しています。
各DockerコンテナーにCockroachDBが起動しており、3つのDockerコンテナー間でCockroachDBクラスターが構築されています。
roach1のDockerコンテナーから、SQLを実行します。
データベース名=bank、テーブル名=accounts、データ=id:1/balance:1000.50

core-01 core # docker exec -it roach1 ./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 bank;
CREATE DATABASE
root@:26257/> CREATE TABLE bank.accounts (id INT PRIMARY KEY, balance DECIMAL);
CREATE TABLE
root@:26257/> INSERT INTO bank.accounts VALUES (1, 1000.50);
INSERT 1
root@:26257/> SELECT * FROM bank.accounts;
+----+---------+
| id | balance |
+----+---------+
|  1 | 1000.50 |
+----+---------+
(1 row)
root@:26257/> \q

roach2のDockerコンテナーから、先程設定したCockroachのデータベースに対してselect処理を実行します。

core-01 core # docker exec -it roach2 ./cockroach sql --insecure
# Welcome to the cockroach SQL interface.
# All statements must be terminated by a semicolon.
# To exit: CTRL + D.
root@:26257/> SELECT * FROM bank.accounts;
+----+---------+
| id | balance |
+----+---------+
|  1 | 1000.50 |
+----+---------+
(1 row)
root@:26257/> \q

6. CockroachDBクラスターのモニタリング

CockroachDBはモニタリング用のAdmin UIが提供されています。Webブラウザから、http://(IPアドレス):8080/にアクセスします。
最初に、ネットワーク設定を確認します。

core-01 core # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:49:90:cb brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic eth0
       valid_lft 77124sec preferred_lft 77124sec
    inet6 fe80::a00:27ff:fe49:90cb/64 scope link
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:45:86:4c brd ff:ff:ff:ff:ff:ff
    inet 172.17.8.101/16 brd 172.17.255.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe45:864c/64 scope link
       valid_lft forever preferred_lft forever
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:40:20:4b:65 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever
(省略)
core-01 core # netstat -an | grep 8080
tcp6       0      0 :::8080                 :::*                    LISTEN

Oracle Virtual Boxを起動し、ネットワークの設定を確認します。
該当のCoreOSを選択し、[設定(S)]-[ネットワーク]を選びます。アダプター1とアダプター2の設定を確認します。アダプター2には、[ホストオンリーアダプター]が割り当てられており、ホストOSからゲストOS(CoreOS)に接続可能です。これは、Vagrantfileにて設定されています。

C:\Users\IBM_ADMIN\vagrant_test\coreos-vagrant> cat Vagrantfile
(省略)
      ip = "172.17.8.#{i+100}"
      config.vm.network :private_network, ip: ip
      # This tells Ignition what the IP for eth1 (the host-only adapter) should be
      config.ignition.ip = ip

Webブラウザから、ホストオンリーアダプターのIPアドレスを指定し、http://(IPアドレス):8080/にアクセスします。

Replicas per Nodeにて、roach1からroach2、roach3に自動的にレプリカされていることを確認します。すごいですね。

7. CockroachDBクラスターの停止

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

core-01 core # docker stop roach1 roach2 roach3

まとめ

チュートリアル通りに(Start a Cluster in Docker (Insecure))実施したら、何の問題もなく動いてしまいました。まさにDockerは、"Build Once. Run Anywhere"ですね。今回のように新しいSWを試してみるケースでは最適ではないでしょうか。
また、CockroachDBのスケーラビリティーとSQL言語の操作を実感できたと思います。
その他、今回の環境は下図の左側でした。あるべき姿は、Docker SwarmやKubernetes等のContainer Orchestration Toolを使用し、高可用性や拡張性に対応できるトポロジーになりますので、別の機会に試してみます。

参考

CockroachDB
Install CockroachDB
Start a Cluster in Docker (Insecure)
Orchestrate CockroachDB with Kubernetes
Orchestrate CockroachDB with Docker Swarm
Qiita:Cockroach関連記事 2.CockroachDBをDocker環境上で動かし、サンプルデータベースをselectして、ぎょっとする
Qiita:Cockroach関連記事 3.CockroachDBをDocker Swarm環境上で動かし、高可用性と拡張性を試してみた
Qiita:Cockroach関連記事 4.CockroachDBをDocker環境上で動かし、クラスター内のサービス数を増やし、データをレプリカしてみる