1、MySQL的高可性解决方案MHA实战
实验环境:
manager:10.0.0.79 centos 7.9 MHA管理端
master:10.0.0.82 centos 8.1 mysql 5.7
slave1:10.0.0.83 centos 8.1 mysql.5.7
slave2:10.0.0.85 centos 8.1 mysql.5.7
操作步骤
1) 在manager管理节点上安装两个包(不支持CentOS8,只支持CentOS7 以下版本)
下载地址:https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads
先下载两个包
mha4mysql-manager-0.56-0.el6.noarch.rpm
mha4mysql-node-0.56-0.el6.noarch.rpm
#先安装node再安装manager,否则报错
[root@manager ~]#yum install -y mha4mysql-node-0.56-0.el6.noarch.rpm
[root@manager ~]#yum install -y mha4mysql-manager-0.56-0.el6.noarch.rpm
2)在被管理节点安装(支持CentOS 8,7,6)
[root@manager ~]#scp mha4mysql-node-0.56-0.el6.noarch.rpm 10.0.0.82:
[root@manager ~]#scp mha4mysql-node-0.56-0.el6.noarch.rpm 10.0.0.83:
[root@manager ~]#scp mha4mysql-node-0.56-0.el6.noarch.rpm 10.0.0.85:
[root@master ~]#yum install -y mha4mysql-node-0.56-0.el6.noarch.rpm
[root@slave1 ~]#yum install -y mha4mysql-node-0.56-0.el6.noarch.rpm
[root@slave2 ~]#yum install -y mha4mysql-node-0.56-0.el6.noarch.rpm
3)在所有节点实现相互之间ssh key验证
[root@manager ~]#ssh-keygen
[root@manager ~]#ssh-copy-id 10.0.0.79
[root@manager ~]#yum install -y rsync
[root@manager ~]#rsync -av .ssh 10.0.0.82:/root/
[root@manager ~]#rsync -av .ssh 10.0.0.83:/root/
[root@manager ~]#rsync -av .ssh 10.0.0.84:/root/
4)在管理节点建立配置文件
[root@manager ~]#vim /etc/mastermha/app1.cnf
[server default]
user=mhauser #mha管理数据库用户
password=12345678 #mhauser密码
manager_workdir=/data/mastermha/app1/
manager_log=/data/mastermha/app1/manager.log
remote_workdir=/data/mastermha/app1/
master_binlog_dir=/data/mysql/ #二进制日志存储目录
ssh_user=root #远程主机用户
repl_user=repluser #主从复制
repl_password=12345678
ping_interval=1
[server1]
hostname=10.0.0.82
candidate_master=1
[server2]
hostname=10.0.0.83
[server3]
hostname=10.0.0.85
5)master配置
#my.cnf文件
[root@master ~]#cat /etc/my.cnf
[mysqld]
server-id=2
log-bin
datadir=/data/mysql
skip_name_resolve=1
socket=/data/mysql/mysql.sock
log-error=/data/mysql/mysql.log
pid-file=/data/mysql/mysql.pid
general_log=ON
skip_name_resolve=1
[client]
socket=/data/mysql/mysql.sock
#二进制日志位置和主从复制用户,manger的管理用户
mysql> show master logs;
mysql> create user repluser@'10.0.0.%' identified by '12345678';
mysql> grant replication slave on *.* to repluser@'10.0.0.%';
mysql> create user mhauser@'10.0.0.%' identified by '12345678';
mysql> grant all on *.* to mhauser@'10.0.0.%';
6)slave1和slave2,mysql配置
#my.cnf文件
[root@slave2 ~]#cat /etc/my.cnf
[mysqld]
server-id=5 #slave1和slave2不同
log-bin
datadir=/data/mysql
skip_name_resolve=1
socket=/data/mysql/mysql.sock
log-error=/data/mysql/mysql.log
pid-file=/data/mysql/mysql.pid
skip_name_resolve=1
relay_log_purge=0
[client]
socket=/data/mysql/mysql.sock
#添加主服务器信息
[root@slave1 ~]#mysql -uroot -p12345678
mysql> CHANGE MASTER TO MASTER_HOST='10.0.0.82',
-> MASTER_USER='repluser',
-> MASTER_PASSWORD='12345678',
-> MASTER_LOG_FILE='master-bin.000002',
-> MASTER_LOG_POS=615;
mysql> start slave;
mysql> show slave status\G;
7)检查Mha的环境
#主机间连接检查
[root@manager ~]#masterha_check_ssh --conf=/etc/mastermha/app1.cnf
Mon Apr 19 21:52:52 2021 - [info] All SSH connection tests passed successfully.
#mysql配置检查
[root@manager ~]#masterha_check_repl --conf=/etc/mastermha/app1.cnf
MySQL Replication Health is OK.
8)启动MHA
[root@manager ~]#masterha_manager --conf=/etc/mastermha/app1.cnf #前台启动
#后台启动
nohup masterha_manager --conf=/etc/mastermha/app1.cnf &> /dev/null
#查看状态
masterha_check_status --conf=/etc/mastermha/app1.cnf
9)排错日志
[root@manager ~]#tail /data/mastermha/app1/manager.log
10)测试,停止master的mysql服务
[root@master ~]#service mysqld stop;
Shutting down MySQL............ SUCCESS!
[root@manager ~]#tail /data/mastermha/app1/manager.log
...
10.0.0.85(10.0.0.85:3306): OK: Applying all logs succeeded. Slave started, replicating from 10.0.0.83(10.0.0.83:3306)
10.0.0.83(10.0.0.83:3306): Resetting slave info succeeded.
Master failover to 10.0.0.83(10.0.0.83:3306) completed successfully.
2、Ansible常用模块总结
-
Command 模块
功能:在远程主机执行命令,此为默认模块,可忽略-m选项
注意:此命令不支持 $VARNAME < > | ; & 等,用shell模块实现
范例:
ansible websrvs -m command -a 'service vsftpd start'
-
Shell 模块
功能:和command相似,用shell执行命令,比command功能更强一些
注意:调用一些复杂的命令会失败,所以把复杂的命令到脚本中,copy到远程执行
范例:
ansible websrvs -m shell -a 'echo centos | passwd --stdin wang'
-
Script 模块
功能:在远程主机上运行ansible服务器上的脚本(无需执行权限)
范例:
ansible websrvs -m script -a /data/test.sh
-
Copy 模块
功能:从ansible服务器主控端复制文件到远程主机
注意:#如目标存在,默认覆盖,可以指定先备份
范例:
ansible websrvs -m copy -a "src=/root/test1.sh dest=/tmp/test2.sh owner=xiao mode=600 backup=yes"
说明:src:源,dest:目标,owner:所属主,mode:权限,backup:备份
-
Fetch 模块
功能:从远程主机提取文件至ansible的主控端,copy相反,目前不支持目录
范例:
ansible websrvs -m fetch -a 'src=/root/test.sh dest=/data/scripts'
-
File 模块
功能:创建或设置文件、目录属性
范例:
#创建空文件
ansible all -m file -a 'path=/data/test.txt state=touch'
#创建目录
ansible all -m file -a "path=/data/mysql state=directory owner=mysql
#创建软链接
ansible all -m file -a 'src=/data/testfile dest=/data/testfile-link state=link'
-
unarchive 模块
功能:解包解压缩
实现有两种用法:
1、将ansible主机上的压缩包传到远程主机后解压缩至特定目录,设置copy=yes
2、将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no
常见参数:
copy:默认为yes,当copy=yes,拷贝的文件是从ansible主机复制到远程主机上,如果设置为copy=no,会在 远程主机上寻找src源文件
remote_src:和copy功能一样且互斥,yes表示在远程主机,不在ansible主机,no表示文件在ansible主机上
src:源路径,可以是ansible主机上的路径,也可以是远程主机(被管理端或者第三方主机)上的路径,如果是远 程主机上的路径,则需要设置copy=no
dest:远程主机上的目标路径
mode:设置解压缩后的文件权限
范例:将ansible主机中的foo.tar.gz辅导到远程主机并解压,解压后所属主改为xiao,所属组为bin
ansible all -m unarchive -a 'src=/data/foo.tgz dest=/var/lib/foo owner=xiao group=bin'
-
Archive 模块
功能:打包压缩保存在被管理节点
范例:
ansible websrvs -m archive -a 'path=/var/log/ dest=/data/log.tar.bz2 format=bz2 owner=wang mode=0600'
-
Hostname 模块
功能:管理主机名
范例:
ansible 10.0.0.78 -m hostname -a 'name=node18.centos.com'
-
Cron 模块
功能:计划任务管理
支持时间:minute,hour,day,month,weekday
范例:
#创建任务
ansible 10.0.0.8 -m cron -a 'hour=2 minute=30 weekday=1-5 name="backup mysql" job=/root/mysql_backup.sh'
ansible websrvs -m cron -a "minute=*/5 job='/usr/sbin/ntpdate ntp.aliyun.com &>/dev/null' name=Synctime"
#禁用计划任务
ansible websrvs -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.20.0.1 &>/dev/null' name=Synctime disabled=yes"
#启用计划任务
ansible websrvs -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.20.0.1 &>/dev/null' name=Synctime disabled=no"
#删除任务
ansible websrvs -m cron -a "name='backup mysql' state=absent"
-
Yum 模块
功能:管理软件包,只支持RHEL,CentOS,fedora,不支持Ubuntu其它版本
范例:
ansible websrvs -m yum -a 'name=httpd state=present' #安装
ansible websrvs -m yum -a 'name=httpd state=absent' #删除
-
Service 模块
功能:管理服务
范例:
ansible all -m service -a 'name=httpd state=started enabled=yes'
ansible all -m service -a 'name=httpd state=stopped'
ansible all -m service -a 'name=httpd state=reloaded'
ansible all -m service -a 'name=httpd state=restarted'
-
User 模块
功能:管理用户
范例:
#创建用户
ansible all -m user -a 'name=user1 comment="test user" uid=2048 home=/app/user1 group=root'
#remove=yes表示删除用户及家目录等数据,默认remove=no
ansible all -m user -a 'name=nginx state=absent remove=yes'
-
Group 模块
功能:管理组
范例:
#创建组
ansible websrvs -m group -a 'name=nginx gid=88 system=yes'
#删除组
ansible websrvs -m group -a 'name=nginx state=absent'
-
Lineinfile 模块
功能:相当于sed,可以修改文件内容
范例:
ansible all -m lineinfile -a "path=/etc/selinux/config regexp='^SELINUX=' line='SELINUX=disabled'"
-
Replace 模块
功能:该模块有点类似于sed命令,主要也是基于正则进行匹配和替换,建议使用
范例:
ansible all -m replace -a "path=/etc/fstab regexp='^(UUID.*)' replace='#\1'"
ansible all -m replace -a "path=/etc/fstab regexp='^#(.*)' replace='\1'"
-
Setup 模块
功能: setup 模块来收集主机的系统信息,这些 facts 信息可以直接以变量的形式使用,但是如果主机较多, 会影响执行速度,可以使用 gather_facts: no 来禁止 Ansible 收集 facts 信息
范例:
ansible all -m setup #主机全部信息
ansible all -m setup -a "filter=ansible_hostname" #主机名称
ansible all -m setup -a "filter=ansible_memory_mb" #主机内存
ansible all -m setup -a 'filter="ansible_default_ipv4"' #默认IP
ansible 10.0.0.101 -m setup -a 'filter=ansible_all_ipv4_addresses' #所有IP地址
3、Ansible playbook实现httpd源码包批量部署
目标:安装源码安装httpd并修改主机名称nodeIP,index为welcome nodeIP
实验环境:
ansible主机:10.0.0.81
node82:10.0.0.82
node83:10.0.0.83
node84:10.0.0.84
软件包
apr-1.7.0.tar.bz2
apr-util-1.6.1.tar.bz2
httpd-2.4.46.tar.bz2
httpd源码包部署步骤:
1、修改主机名称
2、安装相关包
3、复制apr,apr-util,httpd源码包
4、解压缩apr,apr-util,httpd
5、将apr,apr-util复制到 httpd-2.4.43/srclib/
6、编译安装
7、创建专用用户
8、修改配置文件,指定允许用户
9、配置环境变量
10、配置帮助
11、创建service unit文件
12、修改index.html文件
13、启动httpd和开机启动
相关文件
httpd.service文件
[root@centos8 ~]#cat httpd.service
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)
[Service]
Type=forking
#EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/app/httpd24/bin/apachectl start
#ExecStart=/app/httpd24/bin/httpd $OPTIONS -k start
ExecReload=/app/httpd24/bin/apachectl graceful
#ExecReload=/app/httpd24/bin/httpd $OPTIONS -k graceful
ExecStop=/app/httpd24/bin/apachectl stop
KillSignal=SIGCONT
PrivateTmp=true
[Install]
WantedBy=multi-user.target
批量部署key验证,push_ssh_key.sh
[root@centos8 ~]#cat push_ssh_key.sh
#!/bin/bash
rpm -q sshpass &> /dev/null || yum -y install sshpass
[ -f /root/.ssh/id_rsa ] || ssh-keygen -f /root/.ssh/id_rsa -P ''
export SSHPASS=21561314
while read IP;do
sshpass -e ssh-copy-id -o StrictHostKeyChecking=no $IP
done < hosts.list
key验证主机列表hosts.list
[root@centos8 ~]#cat hosts.list
10.0.0.82
10.0.0.83
10.0.0.84
ansible主机列表
[root@centos8 ~]#cat /etc/ansible/hosts
[test]
10.0.0.82
10.0.0.83
10.0.0.84
anisble批量部署httpd脚本
[root@centos8 ~]#cat install_httpd.yml
---
- hosts: test
remote_user: root
tasks:
- name: change hostname
hostname: name=node{{ ansible_default_ipv4.address.split('.')[-1] }}
- name: install packages
yum: name=gcc,make,pcre-devel,openssl-devel,expat-devel
- name: copy apr
copy: src=/root/apr-1.7.0.tar.bz2 dest=/data/apr-1.7.0.tar.bz2
- name: copy apr-util
copy: src=/root/apr-util-1.6.1.tar.bz2 dest=/data/apr-util-1.6.1.tar.bz2
- name: copy httpd
copy: src=/root/httpd-2.4.46.tar.bz2 dest=/data/httpd-2.4.46.tar.bz2
- name: tar xvf apr
unarchive: src=/data/apr-1.7.0.tar.bz2 dest=/data/ copy=no
- name: tar xvf apr-util
unarchive: src=/data/apr-util-1.6.1.tar.bz2 dest=/data/ copy=no
- name: tar xvf httpd
unarchive: src=/data/httpd-2.4.46.tar.bz2 dest=/data/ copy=no
- name: copy apr to httpd/srclib
shell: /usr/bin/mv /data/apr-1.7.0 /data/httpd-2.4.46/srclib/apr
- name: copy apr-util to srclib
shell: /usr/bin/mv /data/apr-util-1.6.1 /data/httpd-2.4.46/srclib/apr-util
- name: copy configure
copy: src=/root/configure.sh dest=/data/httpd-2.4.46/configure.sh
- name: configure
shell: chdir=/data/httpd-2.4.46/ /bin/bash /data/httpd-2.4.46/configure.sh
- name: make http
shell: chdir=/data/httpd-2.4.46/ make -j 4 && make install
- name: create group
group: name=apache
- name: create user
user: name=apache group=apache shell=/sbin/nologin create_home=no home=/app/httpd24 system=yes
- name: user
replace: path=/app/httpd24/conf/httpd.conf regexp='^User daemon' replace='User apache'
- name: group
replace: path=/app/httpd24/conf/httpd.conf regexp='^Group daemon' replace='Group apache'
- name: create ln
shell: /usr/bin/ln -s /app/http24/bin/* /usr/bin/
- name: service unit
copy: src=/root/httpd.service dest=/usr/lib/systemd/system/httpd.service
- name: create httpd.service
shell: /usr/bin/systemctl daemon-reload
- name: create index
shell: echo "welcome `hostname`" > /app/httpd24/htdocs/index.html
- name: start httpd
service: name=httpd state=started enabled=yes
执行批量部署脚本
[root@centos8 ~]#ansible-playbook install_httpd.yml
查看主机名
[root@centos8 ~]#ansible all -m shell -a 'hostname'
10.0.0.83 | CHANGED | rc=0 >>
node83
10.0.0.82 | CHANGED | rc=0 >>
node82
10.0.0.84 | CHANGED | rc=0 >>
node84
检查httpd是否部署完成并启动成功
[root@centos8 ~]#ansible all -m shell -a 'ss -ntl' #查看80端口是否打开
10.0.0.83 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:111 0.0.0.0:*
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:111 [::]:*
LISTEN 0 128 [::]:22 [::]:*
10.0.0.84 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:111 0.0.0.0:*
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:111 [::]:*
LISTEN 0 128 [::]:22 [::]:*
10.0.0.82 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:111 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:111 [::]:*
LISTEN 0 511 *:80 *:*
LISTEN 0 128 [::]:22 [::]:*
#测试httpd
[root@centos8 ~]#curl 10.0.0.82
welcome node82
[root@centos8 ~]#curl 10.0.0.83
welcome node83
[root@centos8 ~]#curl 10.0.0.84
welcome node84