dble+mysql+keeplived
mysql01(172.28.8.65)
mysql02(172.28.8.61)
dble01(172.28.8.62)
dble02(172.28.8.63)
keeplived01(172.28.8.62)
keeplived02(172.28.8.63)
docker pull mysql:5.7
创建文件夹(两个容器不要共用文件夹)
mkdir /usr/local/mysql
cd mysql/
mkdir conf data
在conf下创建docker.cnf
vim /usr/local/mysql/conf/docker.cnf
添加
[mysqld]
server-id=1
log-bin=master-bin #只是读写,就只要主库配置即可.如果要做主从切换,那么主库和从库都需要开启.
skip-host-cache
skip-name-resolve
collation-server = utf8_unicode_ci
init-connect='SET NAMES utf8'
character-set-server = utf8
[mysql]
default-character-set=utf8
[client]
default-character-set=utf8
[mysqld]
server-id=2
log-bin=master-bin
skip-host-cache
skip-name-resolve
collation-server = utf8_unicode_ci
init-connect='SET NAMES utf8'
character-set-server = utf8
[mysql]
default-character-set=utf8
[client]
default-character-set=utf8
systemctl disable firewalld
docker run --name mysqlmastertwo -p 3306:3306 -p 33060:33060 -v /usr/local/mysql/conf:/etc/mysql/conf.d -v /usr/local/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --privileged=true -d mysql:5.7
docker run --name mysqlslave -p 3307:3306 -p 33070:33060 -v /usr/local/mysql2/conf:/etc/mysql/conf.d -v /usr/local/mysql2/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --privileged=true -d mysql:5.7
docker run --name mysqlpart1 -p 3308:3306 -p 33080:33060 -v /data/db_group/part_data/conf:/etc/mysql/conf.d -v /data/db_group/part_data/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --privileged=true -d mysql:5.7
docker run --name mysqlpart1 -p 3309:3306 -p 33090:33060 -v /data/db_group/part2_data/conf:/etc/mysql/conf.d -v /data/db_group/part2_data/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --privileged=true -d mysql:5.7
进入mysql容器
docker exec -it mysqlmaster /bin/bash
启动mysql
mysql -uroot -proot
创建slave用户
create user 'hzero'@'%' identified by 'hzero';
授权
grant replication slave on *.* to 'hzero'@'%';
刷新权限
flush privileges;
查看状态
show master status;
show master status\G
mysql> show master status\G;
*************************** 1. row ***************************
File: master-bin.000004
Position: 154
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
进入mysql容器
docker exec -it mysqlmastertwo /bin/bash
启动mysql
mysql -uroot -proot
执行主从
change master to master_host='172.28.8.61',master_port=3306,master_user='hzero',master_password='hzero',master_log_file='master-bin.000003',master_log_pos=745;
开启复制
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
查看主从是否成功
show slave status \G;
停止
stop slave;
show slave status \G;
截图
在写库创建一条记录
读库自动同步
注意:由于是主主架构,刚才的步骤,两台机器互换角色,再配置一次,保证两台机器可以相互同步
1、安装python-pip
yum -y install epel-release
yum -y install python-pip
2、安装docker-compose
pip install docker-compose
待安装完成后,执行查询版本的命令,即可安装docker-compose
docker-compose version
创建docker-compose.yml
version: '2'
services:
dble-server:
image: actiontech/dble:latest
container_name: dble-server
hostname: dble-server
privileged: true
stdin_open: true
tty: true
volumes:
- ./config/:/opt/dble/extra/
ports:
- "8066:8066"
- "9066:9066"
在对应目录下执行
docker-compose up -d
docker exec -it DBLE容器ID /bin/bash
yum -y install passwd openssl openssh-server openssh-clients
# 创建 /var/run/sshd/目录,要不然sshd服务启动会报错
mkdir /var/run/sshd/
# 编辑sshd的配置文件/etc/ssh/sshd_config,将其中的UsePAM yes改为UsePAM no
sed -i "s/UsePAM.*/UsePAM no/g" /etc/ssh/sshd_config
# 7.创建公私密钥,输入命令后,直接按两次enter键确认就行了
ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key
#8.完成上述几步后,可以开启ssh服务了(&表示后台启动)
/usr/sbin/sshd -D &
# 9.此时使用命令ps -ef | grep sshd 便可以看到效果
#10.查询22端口是否处于监听状态
yum -y install lsof
lsof -i:22
# 11.修改root密码
.
#12.测试
#输入命令ssh localhost,然后输入之前设置的root密码
#13.如何配置外部客户端访问docker里的centos7.4容器
docker ps -a
#提交容器成为新的镜像,例如叫做sshd_centos7.4,输入
docker commit 容器ID sshd_dble:0.0.1
#启动这个镜像的容器,并映射本地的一个闲置的端口(例如15000)到容器的22端口,并启动容器的sshd(只要端口不冲突可以同时启动多个容器,如下图)
docker run -d -p 15000:22 -p 8066:8066 -p 9066:9066 sshd_dble:0.0.1 /usr/sbin/sshd -D
#现在打开新的终端,输入ssh root@宿主机IP地址 -p 15000,如果能连接成功,会要求输入密码的,输入刚才passwd命令设置的root账户密码就可以进入容器的终端了
#如果连接失败,请检查防火墙是否未开放该端口。
finalShell连接容器
新建文件夹/data/dockerfile
cd /data/dockerfile
from sshd_dble:0.0.1
MAINTAINER pigic from hand-china.com([email protected])
WORKDIR /
ADD run.sh /run.sh
RUN chmod 777 /*.sh
EXPOSE 8066
EXPOSE 9066
EXPOSE 22
ENTRYPOINT ["/run.sh"]
#!/bin/bash
/opt/dble/bin/docker_init_start.sh
/usr/sbin/sshd -D
docker build -t sshd_dble:0.0.2 .
docker run -d -p 15000:22 -p 8066:8066 -p 9066:9066 sshd_dble:0.0.2
进入容器
cd /opt/dble/conf
修改server.xml和schema.xml
<dble:server xmlns:dble="http://dble.cloud/" version="2.0">
<system>
<property name="serverPort">8066property>
<property name="managerPort">9066property>
<property name="sequnceHandlerType">2property>
<property name="serverBacklog">2048property>
<property name="checkTableConsistency">0property>
<property name="checkTableConsistencyPeriod">60000property>
<property name="dataNodeIdleCheckPeriod">300000property>
<property name="dataNodeHeartbeatPeriod">10000property>
<property name="processorCheckPeriod">1000property>
<property name="sqlExecuteTimeout">300property>
<property name="idleTimeout">1800000property>
<property name="recordTxn">0property>
<property name="xaSessionCheckPeriod">1000property>
<property name="xaLogCleanPeriod">1000property>
<property name="useJoinStrategy">trueproperty>
<property name="nestLoopConnSize">4property>
<property name="nestLoopRowsSize">2000property>
<property name="otherMemSize">4property>
<property name="orderMemSize">4property>
<property name="joinMemSize">4property>
<property name="bufferPoolChunkSize">4096property>
<property name="bufferPoolPageNumber">256property>
<property name="bufferPoolPageSize">2097152property>
<property name="useSqlStat">0property>
<property name="enableSlowLog">0property>
<property name="flushSlowLogPeriod">1property>
<property name="flushSlowLogSize">1000property>
<property name="sqlSlowTime">100property>
system>
<user name="man1">
<property name="password">654321property>
<property name="manager">trueproperty>
user>
<user name="hzero">
<property name="password">bHaxWqczzmUSil0/mziGTukB+pqPC7NM3E/Qqstd1GT90OQLX9APJLT0toyHEtwr/X3S72LPe98CDe66oN098Q==property>
<property name="usingDecrypt">1property>
<property name="schemas">hzero_platformproperty>
user>
dble:server>
<?xml version="1.0"?>
<!--
~ Copyright (C) 2016-2019 ActionTech.
~ License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher.
-->
<!DOCTYPE dble:schema SYSTEM "schema.dtd">
<dble:schema xmlns:dble="http://dble.cloud/" version="2.0">
<!-- schema testdb route to database named dn1 in backend-mysql1 -->
<schema name="hzero_platform" dataNode="dn1">
</schema>
<dataNode name="dn1" dataHost="backend-mysql" database="hzero_platform"/>
<dataHost name="backend-mysql" maxCon="1000" minCon="10" balance="2" switchType="1" slaveThreshold="100">
<heartbeat>show slave status</heartbeat>
<writeHost host="MySQLA" url="172.28.8.65:3306" user="hzero" password="hzero">
</writeHost>
<writeHost host="MySQLB" url="172.28.8.61:3306" user="hzero" password="hzero">
</writeHost>
</dataHost>
</dble:schema>
生成工具:/opt/dble/bin/encrypt.sh
修改/opt/dble/bin/encrypt.sh
#!/bin/sh
#set HOME
CURR_DIR=`pwd`
cd `dirname "$0"`/..
APP_HOME=`pwd`
cd $CURR_DIR
if [ -z "$APP_HOME" ] ; then
echo
echo "Error: APP_HOME environment variable is not defined correctly."
echo
exit 1
fi
#============run encrypt
input=$1
PASSWORD=${input/password=/""}
RUN_CMD="/bin/java -cp $APP_HOME/lib/dble*.jar com.actiontech.dble.util.DecryptUtil $PASSWORD"
echo "/bin/java -cp $APP_HOME/lib/dble*.jar com.actiontech.dble.util.DecryptUtil password=******"
eval $RUN_CMD
EXIT_STATUS=$?
exit $EXIT_STATUS
#==============================================================================
生成密码:
0:{用户名}:{密码}
例如:
[root@8086449c1aec bin]# ./encrypt.sh 0:hzero:hzero
/bin/java -cp /opt/dble/lib/dble*.jar com.actiontech.dble.util.DecryptUtil password=******
bHaxWqczzmUSil0/mziGTukB+pqPC7NM3E/Qqstd1GT90OQLX9APJLT0toyHEtwr/X3S72LPe98CDe66oN098Q==
#!/bin/sh
echo "dble init&start in docker"
sh /opt/dble/bin/dble start
sh /opt/dble/bin/wait-for-it.sh 127.0.0.1:8066
echo "dble init finish"
/bin/bash
cd /opt/dble/bin
./docker_init_start.sh
同理在dble02(172.28.8.63)相同配置方式。
至此DBLE和Mysql都搭建好了,测试一下
1.类似于主机备机,本身不具备负载均衡,只能生效一台机器,当且仅当主机器宕机后,才会切换其它机器。
2.自身提供虚拟IP地址,用户只需要关注虚拟IP地址,通过虚拟VIP去访问应用,底层会根据物理机器情况,选择可用机器。
例如有3台机器(01,02,03),我们设置了
01作为主机器,优先级为110
02作为从机器,优先级为100
03作为从机器,优先级为90
当用户配置完keeplived后,会提供一个虚拟VIP假设为04
用户只需访问04,实际每次请求都会走到01去,永远到01,直到01发生意外宕机,此时再访问04,请求会分发到02,同样一直走02,直到02也宕机,才会走03。如果01某个时间经过运维人员修复,恢复运行,因为优先级最高,此时访问04,请求会优先分发到刚恢复的01机器。
原理是这样,下面介绍具体使用,我们以172.28.8.62为例,搭建一份完整案例。172.28.8.63同理
yum install -y keepalived
cd /etc/keepalived
! Configuration File for keepalived
global_defs {
notification_email {
[email protected]
[email protected]
}
notification_email_from [email protected]
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id MYCAT_HA
}
vrrp_script chk_mysql_port { #检测mysql服务是否在运行。有很多方式,比如进程,用脚本检测等等
script "/opt/chk_mysql.sh" #这里通过脚本监测
interval 2 #脚本执行间隔,每2s检测一次
weight -5 #脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -5
fall 2 #检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间)
rise 1 #检测1次成功就算成功。但不修改优先级
}
vrrp_instance VI_1 {
state MASTER
interface ens192
virtual_router_id 51 #路由器标识,MASTER和BACKUP必须是一致的
priority 101 #定义优先级,数字越大,优先级越高,在同一个vrrp_instance下,MASTER的优先级必须大于BACKUP的优先级。这样MASTER故障恢复后,就可以将VIP资源再次抢回来
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.28.8.112/24
}
track_script {
chk_mysql_port
}
}
virtual_server 172.28.8.112 8066 {
delay_loop 6
protocol TCP
real_server 172.28.8.63 8066 {
notify_down "kill -9 $(cat /var/run/keepalived.pid)"
TCP_CHECK {
connect_port 8066
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
其他BACKUP从机器后面这样修改keepalived.conf(注意:针对其他从机器的keeplived)
! Configuration File for keepalived
global_defs {
notification_email {
[email protected]
[email protected]
}
notification_email_from [email protected]
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id MYCAT_HA
}
vrrp_script chk_mysql_port { #检测mysql服务是否在运行。有很多方式,比如进程,用脚本检测等等
script "/opt/chk_mysql.sh" #这里通过脚本监测
interval 2 #脚本执行间隔,每2s检测一次
weight -5 #脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -5
fall 2 #检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间)
rise 1 #检测1次成功就算成功。但不修改优先级
}
vrrp_instance VI_1 {
state BACKUP
interface ens192
virtual_router_id 51 #路由器标识,MASTER和BACKUP必须是一致的
priority 99 #定义优先级,数字越大,优先级越高,在同一个vrrp_instance下,MASTER的优先级必须大于BACKUP的优先级。这样MASTER故障恢复后,就可以将VIP资源再次抢回来
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.28.8.112/24
}
track_script {
chk_mysql_port
}
}
virtual_server 172.28.8.112 8066 {
delay_loop 6
protocol TCP
real_server 172.28.8.62 8066 {
notify_down "kill -9 $(cat /var/run/keepalived.pid)"
TCP_CHECK {
connect_port 8066
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
作用:检测8066端口是否还被使用,即dble是否宕机,如果宕机,当前节点keeplived自杀,强制停止,让其他节点keeplived生效,进行抢占VIP
#!/bin/bash
counter=$(netstat -na|grep "LISTEN"|grep "8066"|wc -l)
if [ "${counter}" -eq 0 ]; then
systemctl stop keepalived.service
fi
service keepalived start
关闭keepalived服务
systemctl stop keepalived.service
# 配置开机自启动
systemctl enable keepalived
#查看服务启动情况:
ps -aux |grep keepalived
#查看启动日志:
journalctl -xe
#查看keepalived日志,实时查看最后100行keepalived日志
tail -100f /var/log/messages
另一台机器同理配置,keepalived.conf配置参考上面提供的(BACKUP从机器配置修改keepalived.conf)。
至此高可用集群搭建完毕
cat /var/run/keepalived.pid