简介
本例简单介绍下如何在多个主机使用docker环境下搭建mairadb集群。只做测试不建议生产中使用。
实现原理:
本例基于severalnines/mariadb镜像制作Mariadb集群,当容器启动后会向etcd注册集群信息,其他容器启动会从etcd获取集群信息(集群名称,运行的容器IP等),从而加入集群。容器之间跨主机的通信则借助flannel来实现。
架构图
架构图3节点上安装跨主机网络,让容器之间可以相互通信,第一个容器启动时向etcd注册自己的集群信息,后面容器启动时从etcd中查找集群信息,并加入集群中去。
环境
主机名 | 机器IP | 系统 | CPU/MEM | Docker版本 |
---|---|---|---|---|
node-1 | 10.0.102.218 | CentOS 7.5 | 4H/16G | 18.06.2-ce |
node-2 | 10.0.102.151 | CentOS 7.5 | 4H/16G | 18.06.2-ce |
node-3 | 10.0.102.162 | CentOS 7.5 | 4H/16G | 18.06.2-ce |
依赖组件
etcd提供服务发现与存放flannel网络信息flannel提供跨主机网络
etcd安装etcd服务,集群都要安装flannel组件(事先关掉docker)
若未装则运行--network=host网络
部署
Docker环境设置
有配置flanneld则需要执行
vim /etc/systemd/system/docker.service中增加下面两条记录
[Service]
EnvironmentFile=/run/docker_opts.env
ExecStart=/usr/bin/dockerd\
--graph=/var/lib/docker --log-level=error $DOCKER_NETWORK_OPTIONS $DOCKER_OPTS
再启动docker
systemctl daemon-reload &&systemctl restart docker
etcd集群
台机器验证集群的可用性,集群信息如下:
机器名 IP地址 角色
node1 10.0.102.218 etcd节点
node2 10.0.102.151 etcd节点
node3 10.0.102.162 etcd节点
运行容器(每个节点都运行)
REGISTRY=k8s.gcr.io/etcd
ETCD_VERSION=3.2.24
TOKEN=my-etcd-token
NAME_1=k8s-node-1
NAME_2=k8s-node-2
NAME_3=k8s-node-3
HOST_1=10.0.102.218
HOST_2=10.0.102.151
HOST_3=10.0.102.162
CLUSTER=${NAME_1}=http://${HOST_1}:2380,${NAME_2}=http://${HOST_2}:2380,${NAME_3}=http://${HOST_3}:2380
DATA_DIR=/var/lib/etcd
# 在节点 node1 上运行:
THIS_NAME=${NAME_1}
THIS_IP=${HOST_1}
docker run -d \
-p 2379:2379 \
-p 2380:2380 \
--volume=${DATA_DIR}:/etcd-data \
--name etcd ${REGISTRY}:${ETCD_VERSION} \
/usr/local/bin/etcd \
--data-dir=/etcd-data --name ${THIS_NAME} \
--initial-advertise-peer-urls http://${THIS_IP}:2380 \
--listen-peer-urls http://0.0.0.0:2380 \
--advertise-client-urls http://${THIS_IP}:2379 \
--listen-client-urls http://0.0.0.0:2379 \
--initial-cluster ${CLUSTER} \
--initial-cluster-state new --initial-cluster-token ${TOKEN}
# 在节点 node2 上运行:
THIS_NAME=${NAME_2}
THIS_IP=${HOST_2}
docker run -d \
-p 2379:2379 \
-p 2380:2380 \
--volume=${DATA_DIR}:/etcd-data \
--name etcd ${REGISTRY}:${ETCD_VERSION} \
/usr/local/bin/etcd \
--data-dir=/etcd-data --name ${THIS_NAME} \
--initial-advertise-peer-urls http://${THIS_IP}:2380 \
--listen-peer-urls http://0.0.0.0:2380 \
--advertise-client-urls http://${THIS_IP}:2379 \
--listen-client-urls http://0.0.0.0:2379 \
--initial-cluster ${CLUSTER} \
--initial-cluster-state existing --initial-cluster-token ${TOKEN}
# 在节点 node3 上运行:
THIS_NAME=${NAME_3}
THIS_IP=${HOST_3}
docker run -d \
-p 2379:2379 \
-p 2380:2380 \
--volume=${DATA_DIR}:/etcd-data \
--name etcd ${REGISTRY}:${ETCD_VERSION} \
/usr/local/bin/etcd \
--data-dir=/etcd-data \
--name ${THIS_NAME} \
--initial-advertise-peer-urls http://${THIS_IP}:2380 \
--listen-peer-urls http://0.0.0.0:2380 \
--advertise-client-urls http://${THIS_IP}:2379 \
--listen-client-urls http://0.0.0.0:2379 \
--initial-cluster ${CLUSTER} \
--initial-cluster-state existing --initial-cluster-token ${TOKEN}
验证集群
#在测试验证节点NFS上,运行另一个etcd容器,
#以便使用其中的etcdctl命令行程序进行验证
REGISTRY=k8s.gcr.io/etcd
ETCD_VERSION=3.2.24
docker run -d \
--name etcd-client ${REGISTRY}:${ETCD_VERSION} \
/usr/local/bin/etcd
#进入容器,查询集群状态
#验证存入数据、读取数据
docker exec etcd-client /bin/sh -c "export ETCDCTL_API=3 && /usr/local/bin/etcdctl --endpoints=http://10.0.102.214:2379,http://10.0.102.175:2379,http://10.0.102.191:2379 --write-out=table member list"
docker exec etcd-client /bin/sh -c "export ETCDCTL_API=3 && /usr/local/bin/etcdctl --endpoints=http://10.0.102.214:2379,http://10.0.102.175:2379,http://10.0.102.191:2379 --write-out=table endpoint status"
docker exec etcd-client /bin/sh -c "export ETCDCTL_API=3 && /usr/local/bin/etcdctl --endpoints=http://10.0.102.214:2379,http://10.0.102.175:2379,http://10.0.102.191:2379 --write-out=table endpoint health"
docker exec etcd-client /bin/sh -c "export ETCDCTL_API=3 && /usr/local/bin/etcdctl --endpoints=http://10.0.102.214:2379,http://10.0.102.175:2379,http://10.0.102.191:2379 put url http://www.sina.com.cn"
docker exec etcd-client /bin/sh -c "export ETCDCTL_API=3 && /usr/local/bin/etcdctl --endpoints=http://10.0.102.214:2379,http://10.0.102.175:2379,http://10.0.102.191:2379 get url"
部署mariadb集群
准备工作
镜像:severalnines/mariadb:10.1
配置文件/etc/my.cnf.d/binlog.cnf
mkdir -p /etc/my.cnf.d/
cat > /etc/my.cnf.d/bin-log.cnf<<EOF
[mysqld]
log-bin = mysql-bin
log_slave_updates = 1
expire_logs_days = 20
server-id = 211
EOF
部署操作
node-1节点
第一个节点:带binlog日志,主机10-0-102-165上操作:
docker run -d -p 3306:3306 --name=galera0_h \
-v /data:/var/lib/mysql -v /etc/my.cnf.d:/etc/my.cnf.d \
-e MYSQL_ROOT_PASSWORD=mypassword \
-e DISCOVERY_SERVICE=10.0.102.215:2379,10.0.102.151:2379,10.0.102.162:2379 \
-e CLUSTER_NAME=my_wsrep_cluster_hp \
-e XTRABACKUP_PASSWORD=mypassword --network=host severalnines/mariadb:10.1
验证
docker ps –a
【见图1】
mysql -uroot -pmypassword -h 10.0.102.215 -e "show status like 'wsrep%';"
【见图2】
binlog日志
【见图3】
1.png
2.png
3.png
node-2节点
第二个节点:非binlog日志
docker run -d -p 3306:3306 --name=galera1_h \
-v /data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=mypassword \
-e DISCOVERY_SERVICE=10.0.102.215:2379,10.0.102.151:2379,10.0.102.162:2379 \
-e CLUSTER_NAME=my_wsrep_cluster_hp \
-e XTRABACKUP_PASSWORD=mypassword --network=host severalnines/mariadb:10.1
docker ps –a
【见图4】
mysql -uroot -pmypassword -h 10.0.102.151 -e "show status like 'wsrep%';"
【见图5】
binlog日志
【见图6】
4.png
5.png
6.png
node-3节点
第三个节点:非binlog日志
docker run -d -p 3306:3306 --name=galera2_h \
-v /data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=mypassword \
-e DISCOVERY_SERVICE=10.0.102.215:2379,10.0.102.151:2379,10.0.102.162:2379 \
-e CLUSTER_NAME=my_wsrep_cluster_hp \
-e XTRABACKUP_PASSWORD=mypassword --network=host severalnines/mariadb:10.1
mysql -uroot -pmypassword -h 10.0.102.162 -e "show status like 'wsrep%';"
【见图7】
binlog日志
【见图8】
8.png
9.png
注意事项
因为容器运行时挂载主机下的/data目录,所以备份与恢复操作较k8s中的操作更简单,在此不再详述,只简单说明下注意事项:
1.如果某个容器挂掉
可以先使用docker start CONTAINER_NAME进行启动,如果启动不成功,这个时候需要重新将node加入集群中,操作步骤如下:
docker stop CONTAINER_NAME
docker rm CONTAINER_NAME
rm -rf /data/
docker run xxx2.容器启动时注意问题:
要按照一定的顺序进行,当docker run第一个容器时,要等容器完全启动起来了再docker run第二个容器,依次类推关闭则执行相反操作,先stop第一个容器,再stop第二个容器,依次类推3.恢复操作注意问题
恢复操作与k8s中mariadb集群相同,需要依次停止,在最后一个节点上执行恢复操作,恢复完成后重新让节点加入集群(节点加入集群前需要先删除本地的/data目录)4.使用docker rm命令会造成集群信息紊乱:
关闭某个节点的mariadb容器时,切记不可执行docker rm –f命令,应该先执行docker stop,然后再执行docker rm命令。补充内容:
使用docker-compose进行部署mariadb-cluster集群
原理与架构均与docker部署相同,在此不再赘述。
一、与上面环境不同点:
1.etcd使用的是集群: 10.0.102.214:2379, 10.0.102.175:2379, 10.0.102.191:2379
原因:测试在之前的etcd中获得不到集群信息,不想在etcd上过多消耗,而且使用etcd集群会更可靠
2.没有使用flannel网络,使用的docker的host网络。
原因:使用docker-compose启动时默认会创建网络,这样三个节点的容器就是在三个网络中,无法通信也就创建不了集群,在docker-compose文件中定义网络为network_mode: host,使用本机IP进行
网友评论