0%

docker配置mongodb replica set

  1. 通过docker-compose来构建
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
version: '3'
services:
# 这是一个mongod实例的配置
mongo-master:
container_name: mongo-master
image: mongo:4.4.3
environment:
MONGO_INITDB_ROOT_USERNAME: username
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: admin
volumes:
- ./data/db-master:/data/db
- ./data/key_file:/data/configdb/key_file
ports:
- 27017:27017
command: ["mongod", "--bind_ip_all", "--dbpath", "/data/db", "--journal", "--logappend", "--storageEngine", "wiredTiger", "--replSet", "rs", "--oplogSize", "128", "--auth", "--keyFile=/data/configdb/key_file"]
# 然后复制,一共三份配置,分别是主(master)/从(slave)/仲裁(arbiter)
mongo-slave:
container_name: mongo-slave
image: mongo:4.4.3
environment:
MONGO_INITDB_ROOT_USERNAME: username
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: admin
volumes:
- ./data/db-slave:/data/db
- ./data/key_file:/data/configdb/key_file
ports:
- 27017:27017
command: ["mongod", "--bind_ip_all", "--dbpath", "/data/db", "--journal", "--logappend", "--storageEngine", "wiredTiger", "--replSet", "rs", "--oplogSize", "128", "--auth", "--keyFile=/data/configdb/key_file"]
# arbiter
mongo-arbiter:
container_name: mongo-arbiter
image: mongo:4.4.3
environment:
MONGO_INITDB_ROOT_USERNAME: username
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_DATABASE: admin
volumes:
- ./data/db-arbiter:/data/db
- ./data/key_file:/data/configdb/key_file
ports:
- 27017:27017
command: ["mongod", "--bind_ip_all", "--dbpath", "/data/db", "--journal", "--logappend", "--storageEngine", "wiredTiger", "--replSet", "rs", "--oplogSize", "128", "--auth", "--keyFile=/data/configdb/key_file"]

注意:如果使用的是mac系统,因为mac系统是虚拟机的方式,是无法直接mount mongo的/data目录的,因此需要建立named volume方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version: '3'
services:
mongo-master:
# ... 省略
volumes:
- mongodata-master:/data/db
- ./data/key_file:/data/configdb/key_file
# for MacOSX
volumes:
mongodata-master:
driver: local
driver_opts:
o: bind
type: none
device: $PWD/data/db-master
  1. 创建key_file
1
2
openssl rand -base64 756 > key_file
chmod 400 key_file
  1. 运行服务及配置replica set
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
docker-compose up
# 可以看到服务正常运行起来
# 然后通过命令进入到mongo控制台
docker exec -it mongo-master mongo
# 切换到admin
use admin
# 进行授权登录
db.auth({user: 'username', pwd: 'password'})
# 返回 1 代表授权成功,失败的情况会有错误信息
# 授权完成后,配置replica set
# 编写配置信息,因为这是在docker内部,hostname就是服务的名字,因此这里直接写 mongo-master这些就行。
config = {_id:"rs", version:1, members:[{_id:0, host:"mongo-master:27017", priority:5}, {_id:1, host:"mongo-slave:27017", priority:2}, {_id:2, host:"mongo-arbiter:27017", priority:3}]}
# 然后执行 rs.initiate 进行初始化
rs.initiate(config)
# 注意,如果初始化这里返回失败说auth fail什么,就是mongo服务器没有配置好auth参与与keyfile。群集的服务器之间通信,必须要配置好。

到此为止,配置完成。

  1. 使用golang,mongo-drive创建连接
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
func GetMongoClient(dbName string) *mongo.Client {
var uri string
if isDebug {
// debug下,是通过localhost访问replica set,通过参数connect=direct
uri := fmt.Sprintf("mongodb://%s:%s@localhost:27017/%s?connect=direct",
MONGO_USERNAME,
MONGO_PASSWORD,
dbName)
} else {
// 正式环境,MONGO_X_HOST 是服务器HOST或k8s/docker中的hostname。
uri := fmt.Sprintf("mongodb://%s:%s@%s:%s,%s:%s,%s:%s/%s",
MONGO_USERNAME,
MONGO_PASSWORD,
MONGO_1_HOST,
MONGO_1_PORT,
MONGO_2_HOST,
MONGO_2_PORT,
MONGO_3_HOST,
MONGO_3_PORT,
dbName)
}
// 参数
clientOptions := options.Client().ApplyURI(uri)
clientOptions.SetMaxPoolSize(5)
clientOptions.SetAuth(options.Credential{
Username: MONGO_USERNAME,
Password: MONGO_PASSWORD,
})
clientOptions.SetReplicaSet("rs")
// 发起连接
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
client, err := mongo.Connect(ctx, clientOptions)
return client
}