IDCFクラウドのDebian JessieでMulti-Host Docker Networking - Part 4: Couchbase Serverをスケールしてみる

　JSONベースでドキュメント指向のデータベースでスケールする[Couchbase Server](http://www.couchbase.com/)のように、最初からスケールする設計のNoSQLを選択した方がRDBMSよりも適しているケースが増えていると思います。今回はIDCFクラウドにDockerのMulti-host networkを構築したのでCouchbaseもセットアップしてみます。

## このシリーズ

* [IDCFクラウドのDebian JessieでMulti-Host Docker Networking - Part 1: Overlayネットワークの作成](http://qiita.com/masato/items/6a1fa797b6c25d4c5745)
* [IDCFクラウドのDebian JessieでMulti-Host Docker Networking - Part 2: Docker Swarmクラスタの作成](http://qiita.com/masato/items/a047798e48ccc1e56eb8)
* [IDCFクラウドのDebian JessieでMulti-Host Docker Networking - Part 3: OverlayネットワークとDocker SwarmとDocker ComposeでRethinkDBをスケールさせる](http://qiita.com/masato/items/bd3d50b31f16a00eac47)
* [IDCFクラウドのDebian JessieでMulti-Host Docker Networking - Part 4: Couchbase Serverをスケールしてみる](http://qiita.com/masato/items/0be8b7da012f1180c281)

## Multi-host network

　Docker 1.9から採用されたMulti-host networkとDocker Swarmのセットアップは[IDCFクラウドのDebian JessieでMulti-Host Docker Networking - Part 2: Docker Swarmクラスタの作成](http://qiita.com/masato/items/a047798e48ccc1e56eb8)を参考にしてください。


## 仮想マシン

　Swarmクラスタは以下の仮想マシンで構成しています。

|Dockerホストのhostname|Dockerホストのeth0| Docker Swarm |
|:--|:--|:--|
|minion-1|10.3.0.101| Swarm Manager/Agent |
|minion-2|10.3.0.102| Swarm Agent |
|minion-3|10.3.0.103| Swarm Agent |

## docker-compose.yml

　Docker Swarmに参加しているノードでDockcer Composeのディレクトリを作成します。どこでも構いませんが今回は`minion-1 (10.3.0.101)`の仮想マシンで作業します。デフォルトではこのディレクトリ名がDockerネットワーク名として自動的に作成されます。

```bash
$ mkdir ~/couch
$ cd !$
```

　Dockerイメージは公式の[couchbase](https://hub.docker.com/_/couchbase/)を使います。[ライセンス](http://www.couchbase.com/jp/couchbase-server/editions)についてはEnterprise版でも以下の条件で無償で使うことができるのでDockerイメージもEnterprise版にします。

>非商用利用では無制限のノード、商用利用2ノードまで無償で利用

　docker-compose.ymlを作成します。`couchbase`サービスはDocker ComposeとDocker Swarmを使ってスケールさせるコンテナです。anti-affinityを設定して同じDockerホストでは起動を避けるようにします。`proxy`サービスもCouchbase Server クラスタに参加しますが、DockerホストにマップしてパブリックIPアドレスから管理画面などを操作できるように公開します。

```yaml:~/couch/docker-compose.yml
couchbase:
  image: couchbase:enterprise
  environment:
    - "affinity:container!=couch_couchbase_*"
proxy:
  image: couchbase:enterprise
  environment:
    - constraint:node==minion-3
  ports:
    - 8091:8091
    - 8092:8092
    - 8093:8093
    - 11210:11210
```

## up

　`~/couch`ディレクトリに移動します。`DOCKER_HOST`環境変数にSwarm Manager (10.3.0.101) を指定してupします。`--x-networking`フラグでDocker Composeから[network](https://docs.docker.com/engine/reference/commandline/network_create/)を有効にします。`--x-network-driver=overlay`フラグでOverlayネットワーク[ドライバを指定](https://docs.docker.com/engine/extend/plugins_network/)します。

```bash
$ cd ~/couch
$ export DOCKER_HOST=tcp://10.3.0.101:3333
$ docker-compose \
  --x-networking \
  --x-network-driver=overlay \
  up -d
```

　`minion-1`の仮想マシンで`up`しましたがDocker Swarm環境なので、`minion-3/couch_proxy_1`と`minion-2/couch_couchbase_1`にコンテナが起動しました。

```bash
$ docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                                                                                                     NAMES
4bc37df3ff03        couchbase:enterprise   "/entrypoint.sh couch"   6 seconds ago       Up 4 seconds        10.3.0.103:8091-8093->8091-8093/tcp, 11207/tcp, 11211/tcp, 10.3.0.103:11210->11210/tcp, 18091-18092/tcp   minion-3/couch_proxy_1
5c4f9006df94        couchbase:enterprise   "/entrypoint.sh couch"   8 seconds ago       Up 6 seconds        8091-8093/tcp, 11207/tcp, 11210-11211/tcp, 18091-18092/tcp                                                minion-2/couch_couchbase_1
```

　またMulti-host network構成にしているので異なるDockerホストのコンテナが同じネットワークアドレスにつながっています。

```bash
$ docker inspect --format="{{ .NetworkSettings.Networks.couch.IPAddress }}"  minion-2/couch_couchbase_1
10.0.1.2
$ docker inspect --format="{{ .NetworkSettings.Networks.couch.IPAddress }}"  minion-3/couch_proxy_1
10.0.1.3
```

## Couchbase Server クラスタへのノードの追加

　[RethinkDBの時](http://qiita.com/masato/items/bd3d50b31f16a00eac47)はDocker Composeでscaleさせるとコンテナが自動的にクラスタが追加されたのですがCouchbaseの場合は管理画面かREST APIを使う必要があります。`proxy`サービスのコンテナ自身もCouchbase Server クラスタに参加していますが、パブリックIPアドレスから接続する役割をもたせました。

```yaml:docker-compose.yml
proxy:
  image: couchbase:enterprise
  environment:
    - constraint:node==minion-3
```

　`proxy`サービスのコンテナをブラウザからCouchbaseの管理画面を8091ポートで開きます。

<img width="512" alt="couch-index.png" src="https://qiita-image-store.s3.amazonaws.com/0/43745/a58b62e4-890a-dda9-efa9-9ec00ca05fbe.png">

　初期設定を行います。テスト用にサンプルのバケットを作成してデータを投入しておきます。

<img width="512" alt="couch-beer.png" src="https://qiita-image-store.s3.amazonaws.com/0/43745/0c037603-ea5f-3797-4307-8e2ecd430c48.png">

　Enterprise版を利用しているのでライセンスに同意します。非商用の場合ノードは無制限で利用できます。

<img width="512" alt="couch-agree.png" src="https://qiita-image-store.s3.amazonaws.com/0/43745/4f69a962-017f-60d6-935c-17faa36ac230.png">

　`Server Nodes`タブからノードの追加をします。`minion-2/couch_couchbase_1`コンテナのIPアドレス、10.0.1.2を登録します。

<img width="512" alt="couch-addserver.png" src="https://qiita-image-store.s3.amazonaws.com/0/43745/a0920135-501b-7e1a-2b8a-f28b2cb73270.png">

　`Pending Rebalance`ボタンを押してクラスタのリバランスをします。クラスタにサーバーを追加してデータやRAM、CPU利用の再配置が簡単にできるのがCouchbaseの魅力です。

<img width="512" alt="couch-rebalance.png" src="https://qiita-image-store.s3.amazonaws.com/0/43745/bc0f6605-12c8-579a-114e-544130d528ad.png">


## scale

　Docker Composeを使ってscaleしてみます。`couchbase`サービスを3に変更します。コンテナが2つ追加されました。

```bash
$ docker-compose \
  --x-networking \
  --x-network-driver=overlay \
  scale couchbase=3
Creating and starting 2 ... done
Creating and starting 3 ... done
$ docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                                                                                                     NAMES
d0c34609c697        couchbase:enterprise   "/entrypoint.sh couch"   57 seconds ago      Up 56 seconds       8091-8093/tcp, 11207/tcp, 11210-11211/tcp, 18091-18092/tcp                                                minion-3/couch_couchbase_3
dd3aca431d53        couchbase:enterprise   "/entrypoint.sh couch"   57 seconds ago      Up 56 seconds       8091-8093/tcp, 11207/tcp, 11210-11211/tcp, 18091-18092/tcp                                                minion-1/couch_couchbase_2
4bc37df3ff03        couchbase:enterprise   "/entrypoint.sh couch"   39 minutes ago      Up 39 minutes       10.3.0.103:8091-8093->8091-8093/tcp, 11207/tcp, 11211/tcp, 10.3.0.103:11210->11210/tcp, 18091-18092/tcp   minion-3/couch_proxy_1
5c4f9006df94        couchbase:enterprise   "/entrypoint.sh couch"   39 minutes ago      Up 39 minutes       8091-8093/tcp, 11207/tcp, 11210-11211/tcp, 18091-18092/tcp                                                minion-2/couch_couchbase_1
```

　`minion-1/couch_couchbase_2`と`minion-3/couch_couchbase_3`のコンテナのIPアドレスを確認します。

```bash
$ docker inspect --format="{{ .NetworkSettings.Networks.couch.IPAddress }}"  minion-1/couch_couchbase_2
10.0.1.4
$ docker inspect --format="{{ .NetworkSettings.Networks.couch.IPAddress }}"  minion-3/couch_couchbase_3
10.0.1.5
```

　scaleした2つのコンテナをCouchbase管理画面から先ほどと同様に追加してrebalanceします。サーバーの追加もとても簡単です。


<img width="512" alt="couch-add.png" src="https://qiita-image-store.s3.amazonaws.com/0/43745/7c4d7a98-f4ff-3dd0-578a-22cd4d82277f.png">


　`minion-3`の仮想マシンには`minion-3/couch_proxy_1 (10.0.1.3)`と`minion-3/couch_couchbase_3 (10.0.1.3)`が起動していますが、DockerのMulti-host networkのおかげでこれまでDocker単体では難しかった[Multiple hosts, multiple containers per host](https://hub.docker.com/_/couchbase/)もとても簡単になりました。

```
┌─────────────────────────────────────────┐  ┌─────────────────────────────────────────┐
│            Host OS (Linux)              │  │            Host OS (Linux)              │
│ ┌─────────────────┐ ┌─────────────────┐ │  │ ┌─────────────────┐ ┌─────────────────┐ │
│ │  Container OS   │ │  Container OS   │ │  │ │  Container OS   │ │  Container OS   │ │
│ │    (Ubuntu)     │ │    (Ubuntu)     │ │  │ │    (Ubuntu)     │ │    (Ubuntu)     │ │
│ │  ┌───────────┐  │ │  ┌───────────┐  │ │  │ │  ┌───────────┐  │ │  ┌───────────┐  │ │
│ │  │ Couchbase │  │ │  │ Couchbase │  │ │  │ │  │ Couchbase │  │ │  │ Couchbase │  │ │
│ │  │  Server   │  │ │  │  Server   │  │ │  │ │  │  Server   │  │ │  │  Server   │  │ │
│ │  └───────────┘  │ │  └───────────┘  │ │  │ │  └───────────┘  │ │  └───────────┘  │ │
│ └─────────────────┘ └─────────────────┘ │  │ └─────────────────┘ └─────────────────┘ │
└─────────────────────────────────────────┘  └─────────────────────────────────────────┘
```

　Couchbase Serverクラスタは以下のように構成されました。

|コンテナのhostname|コンテナのIPアドレス|Dockerホスト| DockerホストのIPアドレス |
|:--|:--|:--|:--|
|couch_couchbase_1|10.0.1.2|minion-2|10.3.0.102|
|couch_proxy_1|10.0.1.3|minion-3|10.3.0.103|
|couch_couchbase_2|10.0.1.4|minion-1|10.3.0.101|
|couch_couchbase_3|10.0.1.5|minion-3|10.3.0.103|

## XCDR

　IDCFクラウドの[リージョン](http://www.idcf.jp/words/region.html)は白河の[東日本リージョン](http://www.idcf.jp/datacenter/shirakawa/)と北九州の[西日本リージョン](http://www.idcf.jp/datacenter/asianfrontier/)が選択できます。リージョン間の接続も[簡単にできそう](http://qiita.com/hkajikawaidcf/items/90790a8d5065d1059b3f)なので、Couchbaseの[Cross Datacenter Replication (XCDR)](http://docs.couchbase.com/admin/admin/XDCR/xdcr-intro.html)機能も使ってみたいと思います。