概要
mongoDBのレプリカセットを構築する際に、docker-composeをつかって、複数のコンテナを立ち上げる方法をまとめます。
docker-composeを使うことで、複数のコンテナの設定の記述と、コンテナ起動、停止が楽にできるため、ローカル環境などで軽くmongoDBのレプリカセットを構築したいときは非常に便利です。
今回は下記構成で1セットのレプリカセットを作ります。
mongod primary secondary合わせて計3コンテナ用意し、それぞれに ホスト環境の30001, 30002, 30003ポートを割り当てます。
primayノードが死んだときに、次のprimaryノードを決定するために必要なarbiterノードを1コンテナ作り、30004ポートを割り当てます。
環境
今回のレプリカセット構築における環境は以下のとおりです。
macOS sierra 10.12.5
docker: 17.03.1-ce
docker-compose 1.11.2
mongoDB 3.4.5
docker-compose.ymlを記述する
さっそく、4つ分のコンテナの設定をdocker-compose.ymlに記述していきます。
ここでは、使用するmongoのdockerイメージはmongo公式のリポジトリのものを使います。
https://hub.docker.com/_/mongo/
docker-compose.yml
version: "3"
services:
mongod001:
container_name: mongors001
image: mongo:3.4.5
command: mongod --replSet rs1 --noprealloc --smallfiles
ports:
- "30001:27017"
mongod002:
container_name: mongors002
image: mongo:3.4.5
command: mongod --replSet rs1 --noprealloc --smallfiles
ports:
- "30002:27017"
mongod003:
container_name: mongors003
image: mongo:3.4.5
command: mongod --replSet rs1 --noprealloc --smallfiles
ports:
- "30003:27017"
mongoa001:
container_name: mongoa001
image: mongo:3.4.5
command: mongod --replSet rs1 --noprealloc --smallfiles
ports:
- "30004:27017"
こんな感じでservices配下に レプリカセット用のmongodノード3台、arbiterノード1台分の記述をしていきます。
imageは mongo:3.4.5と書くことで、前述した公式mongoリポジトリの3.4.5タグのイメージを取ってきます。
mongoのコンテナを立ち上げると、デフォルトでコンテナ内の27017ポートを利用する*1ため、各ノード毎に
“{ホストのポート番号}:27017” と記述してホストのポートと各コンテナ内のポートを紐付けます。
各コンテナのcommandで、実際にコンテナ内で起動するコマンドを記述します。
本稿では、レプリカセットの名前をrs1とします。
docker-composeでコンテナを立ち上げる
docker-composeでコンテナを立ち上げる準備ができたので、実際に立ち上げてみます。
docker-compose upコマンドで、実行しているディレクトリにあるdocker-compose.ymlファイルを読み込み、コンテナを立ち上げていきます。
今回はバックグラウンドで立ち上げるため、docker-compose up の-dオプションを付けます
# バックグラウンドでコンテナ立ち上げ
$ docker-compose up -d
Starting mongors002
Starting mongoa001
Starting mongors001
Starting mongors003
立ち上げ自体はコレだけです。 念のため、正常に立ち上がったか、docker-compose psコマンドで確認してみます。
$ docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------
mongoa001 docker-entrypoint.sh mongo ... Up 0.0.0.0:30004->27017/tcp
mongors001 docker-entrypoint.sh mongo ... Up 0.0.0.0:30001->27017/tcp
mongors002 docker-entrypoint.sh mongo ... Up 0.0.0.0:30002->27017/tcp
mongors003 docker-entrypoint.sh mongo ... Up 0.0.0.0:30003->27017/tcp
指定したとおり、4つのコンテナが正常に上がっているのを確認できました。
ここでStateがUpになっていない場合は、docker-compose logsでエラーを確認して対処します。
各コンテナに紐付けられているポートも30001〜30004まで紐付けられているので、続いてはレプリカセットの設定を進めていきます。
mongoのレプリカセットを初期化する。
早速、起動したmongoコンテナに接続してmongoのレプリカセットの設定を行っていきます。
mongors001 という名前のコンテナに接続するため、 ホストのmongoコマンドを叩いて30001ポートに接続します。
# ホスト(mac)で実行
$ mongo --port 30001
# レプリカセット初期化
> rs.initiate
# ステータス確認
> rs.status()
{
"set" : "rs1",
"date" : ISODate("2017-06-20T15:04:39.227Z"),
"myState" : 1,
"term" : NumberLong(17),
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1497971077, 1),
"t" : NumberLong(17)
},
"appliedOpTime" : {
"ts" : Timestamp(1497971077, 1),
"t" : NumberLong(17)
},
"durableOpTime" : {
"ts" : Timestamp(1497971077, 1),
"t" : NumberLong(17)
}
},
"members" : [
{
"_id" : 0,
"name" : "mongors001:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 24,
"optime" : {
"ts" : Timestamp(1497971077, 1),
"t" : NumberLong(17)
},
"optimeDate" : ISODate("2017-06-20T15:04:37Z"),
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1497971056, 1),
"electionDate" : ISODate("2017-06-20T15:04:16Z"),
"configVersion" : 7,
"self" : true
}
],
"ok" : 1
}
レプリカセットメンバー追加
> rs.add("mongors002:27017")
> rs.add("mongors003:27017")
arbiterメンバ追加
> rs.addArb("mongoa001:27017")
これでレプリカセットの初期化と、secondaryノード、arbiterノードの追加ができました。
細かいところは省きますが、 最後にrs.status()を確認すると下記のようにmembersに各ノードが追加されているのを確認できます。
> rs.status()
{
"set" : "rs1",
"date" : ISODate("2017-06-20T15:07:46.407Z"),
"myState" : 1,
"term" : NumberLong(17),
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1497971258, 1),
"t" : NumberLong(17)
},
"appliedOpTime" : {
"ts" : Timestamp(1497971258, 1),
"t" : NumberLong(17)
},
"durableOpTime" : {
"ts" : Timestamp(1497971258, 1),
"t" : NumberLong(17)
}
},
"members" : [
{
"_id" : 0,
"name" : "mongors001:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 211,
"optime" : {
"ts" : Timestamp(1497971258, 1),
"t" : NumberLong(17)
},
"optimeDate" : ISODate("2017-06-20T15:07:38Z"),
"electionTime" : Timestamp(1497971056, 1),
"electionDate" : ISODate("2017-06-20T15:04:16Z"),
"configVersion" : 11,
"self" : true
},
{
"_id" : 1,
"name" : "mongors002:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 114,
"optime" : {
"ts" : Timestamp(1497971258, 1),
"t" : NumberLong(17)
},
"optimeDurable" : {
"ts" : Timestamp(1497971258, 1),
"t" : NumberLong(17)
},
"optimeDate" : ISODate("2017-06-20T15:07:38Z"),
"optimeDurableDate" : ISODate("2017-06-20T15:07:38Z"),
"lastHeartbeat" : ISODate("2017-06-20T15:07:44.551Z"),
"lastHeartbeatRecv" : ISODate("2017-06-20T15:07:43.562Z"),
"pingMs" : NumberLong(0),
"configVersion" : 11
},
{
"_id" : 2,
"name" : "30002:27017",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2017-06-20T15:07:44.553Z"),
"lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "Invalid argument",
"configVersion" : -1
},
{
"_id" : 3,
"name" : "mongors003:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 74,
"optime" : {
"ts" : Timestamp(1497971258, 1),
"t" : NumberLong(17)
},
"optimeDurable" : {
"ts" : Timestamp(1497971258, 1),
"t" : NumberLong(17)
},
"optimeDate" : ISODate("2017-06-20T15:07:38Z"),
"optimeDurableDate" : ISODate("2017-06-20T15:07:38Z"),
"lastHeartbeat" : ISODate("2017-06-20T15:07:44.551Z"),
"lastHeartbeatRecv" : ISODate("2017-06-20T15:07:43.568Z"),
"pingMs" : NumberLong(0),
"configVersion" : 11
},
{
"_id" : 4,
"name" : "mongoa001:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 7,
"lastHeartbeat" : ISODate("2017-06-20T15:07:44.550Z"),
"lastHeartbeatRecv" : ISODate("2017-06-20T15:07:43.720Z"),
"pingMs" : NumberLong(1),
"configVersion" : 11
}
],
"ok" : 1
}