Docker / Podman 建立MongoDB 副本集群
Docker / Podman 建立MongoDB 副本集群
本文介绍的MongoDB副本集群建立方法只能在Linux系统上使用,其他类Unix系统不适用于此方法。
建立生成Docker-compose.yaml脚本
建立mongoReplSetBuild.sh如下:
#! /bin/bash
:<<'COMMENT'
本脚本用来生成建立Mongo副本集群的docker-compose.yaml或podman-compose.yaml
许阳
2020年12月17日
COMMENT
# 读取容器类型
read_container_type() {
local dt
echo '请输入容器类型:'
echo '1): Docker'
echo '2): Podman'
echo -n '[Docker]:'
read dt
dt=${dt,,}
if [ -z $dt ]; then
c_type=1
else
case $dt in
docker)
c_type=1
;;
podman)
c_type=2
;;
1)
c_type=1
;;
2)
c_type=2
;;
*)
echo '非法输入!'
exit
esac
fi
}
# 读取生成文件要用的文件名
read_file_name() {
local fn
echo -n '请输入文件名[docker-compose.yaml]:'
read fn
if [ -z $fn ]; then
file_name='docker-compose.yaml'
else
ext=`echo $fn | sed -r "s/.*\.(\w*)$/\1/g"`
ext=${ext^^}
if [[ "$ext" =~ "YAML" ]]; then
fn=`echo $fn | sed -r "s/^(\w*)\.\w*$/\1/g"`
fi
file_name=$fn.yaml
fi
}
# 整数转换
conver_number(){
local num_v
if [ -z "$1" ]; then
return
fi
num_v=`echo $1 | sed -rn "s/^([0-9]+)$/\1/gp"`
if [ -z "$num_v" ]; then
echo '非法的整数输入'
else
num_out=$num_v
return $num_v
fi
}
# 读取要生成的副本个数
read_replSet_number() {
local rn
echo -n '请输入副本个数[3]:'
read rn
conver_number $rn
nn=$num_out
if [ -z "$rn" ]; then
replSetNumber=3
elif [ -z "$nn" ]; then
echo '无效的副本个数'
exit
else
replSetNumber=$rn
fi
}
# 读取根用户名
read_root_username() {
local user_name
echo -n '请输入根用户名[root]:'
read user_name
if [ -z "$user_name" ]; then
v_uname='root'
else
v_uname=$user_name
fi
}
# 读取根用户密码
read_root_password() {
local pass_word
echo -e '请输入根用户密码:\c'
while : ;
do
local char=`
stty cbreak -echo
dd if=/dev/tty bs=1 count=1 2>/dev/null
stty -cbreak echo
`
if [ "$char" = "" ]; then
echo
break
fi
v_password="$v_password$char"
echo -n "*"
done
if [ -z "$v_password" ]; then
echo '非法的密码!'
exit
fi
}
# 读取是否需要选举节点
read_arbiter_flag() {
local arf
echo -n '是否需要选举节点(yes|no)[yes]:'
read arf
if [ -z $arf ]; then
v_arf=1
arf=1
fi
arf=${arf,,}
case $arf in
1)
v_arf=1
;;
0)
v_arf=0
;;
y)
v_arf=1
;;
n)
v_arf=0
;;
yes)
v_arf=1
;;
no)
v_arf=0
;;
*)
echo '非法输入!'
exit
esac
}
# 读取数据持久化文件夹前缀
read_data_db() {
local db_path
echo -n '请输入数据文件夹前缀[/opt/mongo/data/db]:'
read db_path
if [ -z "$db_path" ]; then
dbpath='/opt/mongo/data/db'
else
dbpath=$db_path
fi
}
# 读取设定文件夹
read_config_path() {
local configd
echo -n '请输入设定文件夹[/opt/mongo/mongo_key]:'
read configd
if [ -z "$configd" ]; then
cnfpath='/opt/mongo/mongo_key'
else
cnfpath=$configd
fi
}
# 读取密钥文件名
read_key_file(){
local keyf
echo -n '请输入密钥文件名[mongo.key]:'
read keyf
if [ -z "$keyf" ]; then
keyfile='mongo.key'
else
keyfile=$keyf
fi
}
# 读取最高端口号
read_start_port(){
local finalport
echo -n '请输入最高(起始)端口号[30000]:'
read finalport
conver_number $finalport
local tmp=$num_out
if [ -z "$finalport" ]; then
v_port=30000
else
v_port=$tmp
fi
}
read_port_step(){
local step_v
echo -n '请输入端口步长[1]:'
read step_v
conver_number $step_v
local tmpsv=$num_out
if [ -z "$step_v" ]; then
step_num=1
else
step_num=$tmpsv
fi
}
# 生成yaml文件
write_file(){
local start_p=$v_port
local content=`cat<<EOF
version: "$1"
services:
EOF`
local ct=$3
if [ $v_arf -eq 1 ]; then
ct=$(($ct + 1))
fi
for ((fp=0; fp<$ct; fp++))
do
local pp=$(($start_p - $fp * $step_num))
if [ $v_arf -eq 1 ] && [ $fp -eq $3 ]; then
m=`cat<<EOF
mongo_arbiter:
EOF`
else
m=`cat<<EOF
mongo_repl_$fp:
EOF`
fi
m=`cat<<EOF
$m
image: mongo:latest
EOF`
if [ $v_arf -eq 1 ] && [ $fp -eq $3 ]; then
m=`cat<<EOF
$m
container_name: mongo_arbiter
EOF`
else
m=`cat<<EOF
$m
container_name: mongo_replSet$fp
EOF`
fi
if [ $c_type -eq 1 ]; then
m=`cat<<EOF
$m
restart: unless-stopped
EOF`
fi
m=`cat<<EOF
$m
ports:
- $pp:27017
volumes:
- $dbpath$fp:/data/db
- $cnfpath:/data/configdb
environment:
MONGO_INITDB_ROOT_USERNAME: $v_uname
MONGO_INITDB_ROOT_PASSWORD: $v_password
command: 'mongod --auth --keyFile /data/configdb/$keyfile --dbpath /data/db --bind_ip_all --replSet MongoRS --oplogSize 128'
EOF`
if [ $fp -eq 0 ]; then
content=`cat<<EOF
$content
$m
EOF`
else
content=`cat<<EOF
$content
$m
EOF`
fi
done
cat>$2<<EOF
$content
EOF
}
read_container_type
read_file_name
read_replSet_number
read_arbiter_flag
read_root_username
read_root_password
read_data_db
read_config_path
read_key_file
read_start_port
read_port_step
case $c_type in
1)
cc_v=3.3
;;
2)
cc_v=1.0
;;
esac
write_file $cc_v $file_name $replSetNumber $v_arf
Docker 下部署:
拷贝脚本到要部署的机器上
scp mongoReplSetBuild.sh 目标机器:build.sh
登录目标机器,执行脚本
ssh 目标机器
./build.sh
建立相关目录
mkdir -p /opt/mongo/data/db0
mkdir -p /opt/mongo/data/db1
mkdir -p /opt/mongo/data/db2
mkdir -p /opt/mongo/data/db3
mkdir -p /opt/mongo/mongo_key
cd /opt/mongo/mongo_key
openssl rand -base64 700 > mongo.key
chmod 400 mongo.key
cd ~
使用docker-compse启动mongo实例
docker-compose --file mongo.yaml up -d
进入容器【mongo_replSet0】建立集群
docker exec -ti mongo_replSet0 /bin/bash
mongo
use admin
db.auth('root', passwordPrompt())
rs.initiate({
_id: 'MongoRS',
members: [
{ _id: 0, host: '公网地址:30000', priority: 3 },
{ _id: 1, host: '公网地址:29990', priority: 2 },
{ _id: 2, host: '公网地址:29980', priority: 1 },
{ _id: 3, host: '公网地址:29970', arbiterOnly: true },
]
})
完成
Podman下部署
Podman下部署与Docker类似,只是在执行build.sh时选Podman为容器。然后在启动容器时使用下面的命令:
podman-compose -f mongo.yaml -t identity up -d
其他命令与Docker部署一样