2--MyCAT中间件和ansible基础

一、Mycat

1)Mycat介绍

  • 在整个IT系统架构中,数据库是非常重要,通常又是访问压力较大的一个服务,除了在程序开发的本身做优化,如:SQL语句优化、代码优化,数据库的处理本身优化也是非常重要的。主从、热备、分表分库等都是系统发展迟早会遇到的技术问题问题。Mycat是一个广受好评的数据库中间件,已经在很多产品上进行使用了。
  • Mycat是一个开源的分布式数据库系统,是一个实现了MySQL协议的服务器,前端用户可以把它看作是一个数据库代理(类似于Mysql Proxy),用MySQL客户端工具和命令行访问,而其后端可以用MySQL原生协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里。
  • Mycat发展到目前的版本,已经不是一个单纯的MySQL代理了,它的后端可以支持MysQL、sQLServer、Oracle、DB2、PostgreSQL等主流数据库,也支持MongoDB这种新型NoSQL方式的存储,未来还会支持更多类型的存储。而在最终用户看来,无论是那种存储方式,在MyCat里,都是一个传统的数据库表,支持标准的SQL语句进行数据的操作,这样一来,对前端业务系统来说,可以大幅降低开发难度,提升开发速度。

2)Mycat可以简单概况为 

  • 一个彻底开源的,面向企业应用开发的大数据库集群
  • 支持事务、ACID、可以替代MySQL的加强版数据库
  • 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
  • 一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
  • 结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
  • 一个新颖的数据库中间件产品

Mycat官网: http://www.mycat.org.cn 

3)Mycat关键特性

  • 支持SQL92标准
  • 遵守MySQL原生协议,跨语言,跨平台,跨数据库的通用中间件代理
  • 基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluster集群支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster
  • 基于Nio实现,有效管理线程,高并发问题
  • 支持数据的多片自动路由与聚合,支持sum,count,max等常用的聚合函数,支持跨库分页
  • 支持单库内部任意join,支持跨库2表join,甚至基于caltlet的多表join
  • 支持通过全局表,ER关系的分片策略,实现了高效的多表join查询
  • 支持多租户方案
  • 支持分布式事务(弱xa)
  • 支持全局序列号,解决分布式下的主键生成问题
  • 分片规则丰富,插件化开发,易于扩展
  • 强大的web,命令行监控
  • 支持前端作为mysq通用代理,后端JDBC方式支持Oracle、DB2、SQL Server、mongodb、巨杉
  • 支持密码加密
  • 支持服务降级
  • 支持IP白名单
  • 支持SQL黑名单、sql注入攻击拦截
  • 支持分表(1.6)
  • ·集群基于ZooKeeper管理,在线升级,扩容,智能优化,大数据处理(2.0开发版)

 4)为什么要用MyCat

  • 这里要先搞清楚Mycat和MySQL的区别(Mycat的核心作用)。我们可以把上层看作是对下层的抽象,例如操作系统是对各类计算机硬件的抽象。那么我们什么时候需要抽象?假如只有一种硬件的时候,我们需要开发一个操作系统吗?再比如一个项目只需要一个人完成的时候不需要leader,但是当需要几十人完成时,就应该有一个管理者,发挥沟通协调等作用,而这个管理者对于他的上层来说就是对项目组的抽象。
  • 同样的,当我们的应用只需要一台数据库服务器的时候我们并不需要Mycat,而如果你需要分库甚至分表,这时候应用要面对很多个数据库的时候,这个时候就需要对数据库层做一个抽象,来管理这些数据库,而最上面的应用只需要面对一个数据库层的抽象或者说数据库中间件就好了,这就是Mycat的核心作用。所以可以这样理解:数据库是对底层存储文件的抽象,而Mycat是对数据库的抽象。

5)Mycat工作原理

  • Mycat的原理中最重要的一个动词是"拦截"”,它拦截了用户发送过来的SQL语句,首先对sQL语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。

 6)Mycat应用场景

  • 单纯的读写分离,此时配置最为简单,支持读写分离,主从切换
  • 分表分库,对于超过1000万的表进行分片,最大支持1000亿的单表分片
  • 多租户应用,每个应用一个库,但应用程序只连接Mycat,从而不改造程序本身,实现多租户化报表系统,借助于Mycat的分表能力,处理大规模报表的统计
  • 替代Hbase,分析大数据
  • 作为海量数据实时查询的一种简单有效方案,比如100亿条频繁查询的记录需要在3秒内查询出来结果,除了基于主键的查询,还可能存在范围查询或其他属性查询,此时Mycat可能是最简单有效的选择
  • Mycat长期路线图
  • 强化分布式数据库中间件的方面的功能,使之具备丰富的插件、强大的数据库智能优化功能、全面的系统监控能力、以及方便的数据运维工具,实现在线数据扩容、迁移等高级功能
  • ·进一步挺进大数据计算领域,深度结合Spark Stream和Storm等分布式实时流引擎,能够完成快速的巨表关联、排序、分组聚合等OLAP方向的能力,并集成一些热门常用的实时分析算法,让工程师以及DBA们更容易用Mcat实现一些高级数据分析处理功能
  • 不断强化Mycat开源社区的技术水平,吸引更多的IT技术专家,使得Mycat社区成为中国的
  • Apache,并将Mycat推到Apache基金会,成为国内顶尖开源项目,最终能够让一部分志愿者成为专职的Mycat开发者,荣耀跟实力一起提升

 7)Mycat不适合的应用场景

  • 设计使用Mycat时有非分片字段查询,请慎重使用Mycat,可以考虑放弃!
  • 设计使用Mycat时有分页排序,请慎重使用Mycat,可以考虑放弃!
  • 设计使用Mycat时如果要进行表OIN操作,要确保两个表的关联字段具有相同的数据分布,否则请慎重使用Mycat,可以考虑放弃!
  • 设计使用Mycat时如果有分布式事务,得先看是否得保证事务得强一致性,否则请慎重使用Mycat,可以考虑放弃!

8)MyCat的高可用性: 

需要注意:在生产环境中, Mycat节点最好使用双节点,即双机热备环境,防止Mycat这一层出现单点故障.可以使用的高可用集群方式有:

  • Keepalived+Mycat+Mysql
  • Keepalived+LVS+Mycat+Mysql
  • Keepalived+Haproxy+Mycat+Mysql

 9)Mycat安装

1、安装JDK

[root@slave 22:52:21~]# yum -y insta1l java

[root@slave 22:52:21~]# java -version
openjdk version "1.8.0_201"

2、安装Mycat

[root@slave 22:52:21~]# wget http://dl.mycat.org.cn/1.6.7.4/Mycat-server-1.6.7.4-release/Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz

[root@slave 22:54:31~]# mkdir /data/software/ -p

[root@slave 22:56:51~]# tar xvf Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz -C /data/software/

[root@slave 22:57:25~]# cat > /etc/profile.d/mycat_home.sh<<EOF
MYCAT_HOME=/data/software/mycat
export PATH=\${PATH}:\${MYCAT_HOME}/bin
EOF

[root@slave 23:57:30~]# source /etc/profile.d/mycat_home.sh

3、mycat安装目录结构:

  • bin mycat命令,启动、重启、停止等
  • catlet catlet为Mycat的一个扩展功能
  • conf Mycat配置信息,重点关注
  • lib Mycat引用的jar包,Mycat是java开发的
  • logs日志文件,包括Mycat启动的日志和运行的日志. version.txtmycat版本说明

4、logs目录:

  • wrapper.log mycat启动日志
  • mycatlog  mycat详细工作日志

5、Mycat的配置文件都在conf目录里面,这里介绍几个常用的文件:

  • server.xml  Mycat软件本身相关的配置文件,设置账号、参数等
  • schema.xml  Mycat对应的物理数据库和数据库表的配置,读写分离、高可用、分布式策略定制、节点控制
  •  rule.xml  Mycat分片(分库分表)规则配置文件,记录分片规则列表、使用方法等

6、启动和连接

[root@slave 23:15:08~]# mycat start # 启动

# 检查启动日志,确定启动成功
[root@slave 23:16:03~]# grep -w 'startup' /data/software/mycat/logs/wrapper.log

# 连接mycat:
[root@slave 23:16:13~]# mysq1 -uroot -p123456 -h 127.0.0.1 -P8066

 10)MyCAT中间件服务实现读写分离

系统环境

cat /etc/redhat-release 
CentOS Linux release 8.3.2011

(1)架构图如下

 (2)搭建MySQL主从

1、主MySQL配置(IP:192.168.64.10)

[root@master 22:46:42~]# cat /etc/my.cnf

[mysqld]
server-id=10
log_bin

[root@master 22:46:42~]# systemctl enable mariadb && systemctl restart mariadb

[root@master 22:48:39~]# mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 9
Server version: 10.3.28-MariaDB-log MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show master status;
+--------------------+----------+--------------+------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
| mariadb-bin.000001 |      330 |              |                  |
+--------------------+----------+--------------+------------------+
1 row in set (0.000 sec)

MariaDB [(none)]> grant all on *.* to slave@'%' identified by "123456";
Query OK, 0 rows affected (0.001 sec)

MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.000 sec)

MariaDB [(none)]> source hellodb_innodb.sql;  # 导入数据,如果没有,自己随便弄点

MariaDB [mysql]> show databases;
+--------------------+
| Database           |
+--------------------+
| hellodb            |
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
5 rows in set (0.001 sec)

MariaDB [mysql]> use hellodb;
Database changed

MariaDB [hellodb]> show tables;
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes           |
| coc               |
| courses           |
| scores            |
| students          |
| teachers          |
| toc               |
+-------------------+
7 rows in set (0.000 sec)

MariaDB [hellodb]> set global general_log=ON;  # 开启操作日志记录,只是利于检查主从是否生效
Query OK, 0 rows affected (0.000 sec)

MariaDB [hellodb]> show variables like 'gen%';
+------------------+------------+
| Variable_name    | Value      |
+------------------+------------+
| general_log      | ON         |
| general_log_file | master.log |
+------------------+------------+
2 rows in set (0.001 sec)

MariaDB [hellodb]> 

2、从MySQL配置(IP:192.168.64.12)

CHANGE MASTER To MASTER_HOST='192.168.64.10', MASTER_USER='slave', MASTER_PASSwORD='123456', MASTER_LOG_FILE='mariadb-bin.000001', MASTER_LOG_POS=330;

[root@slave 10:51:01~]# cat /etc/my.cnf
[mysqld]
server-id=12

[root@slave 10:51:09~]# systemctl enable mariadb && systemctl restart mariadb

[root@slave 10:51:31~]# mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 10.3.28-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> CHANGE MASTER To
    -> MASTER_HOST='192.168.64.10',
    -> MASTER_USER='slave', 
    -> MASTER_PASSwORD='123456',
    -> MASTER_LOG_FILE='mariadb-bin.000001',
    -> MASTER_LOG_POS=330;

MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.001 sec)

MariaDB [(none)]> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
                Slave_IO_State: Waiting for master to send event
                   Master_Host: 192.168.64.10
                   Master_User: slave
                   Master_Port: 3306
                 Connect_Retry: 60
               Master_Log_File: mariadb-bin.000001
           Read_Master_Log_Pos: 957
                Relay_Log_File: mariadb-relay-bin.000002
                 Relay_Log_Pos: 1184
         Relay_Master_Log_File: mariadb-bin.000001
              Slave_IO_Running: Yes
             Slave_SQL_Running: Yes
               Replicate_Do_DB: 
           Replicate_Ignore_DB: 
            Replicate_Do_Table: 
        Replicate_Ignore_Table: 
       Replicate_Wild_Do_Table: 
   Replicate_Wild_Ignore_Table: 
                    Last_Errno: 0
                    Last_Error: 
                  Skip_Counter: 0
           Exec_Master_Log_Pos: 957
               Relay_Log_Space: 1495
               Until_Condition: None
                Until_Log_File: 
                 Until_Log_Pos: 0
            Master_SSL_Allowed: No
            Master_SSL_CA_File: 
            Master_SSL_CA_Path: 
               Master_SSL_Cert: 
             Master_SSL_Cipher: 
                Master_SSL_Key: 
         Seconds_Behind_Master: 0
 Master_SSL_Verify_Server_Cert: No
                 Last_IO_Errno: 0
                 Last_IO_Error: 
                Last_SQL_Errno: 0
                Last_SQL_Error: 
   Replicate_Ignore_Server_Ids: 
              Master_Server_Id: 10
                Master_SSL_Crl: 
            Master_SSL_Crlpath: 
                    Using_Gtid: No
                   Gtid_IO_Pos: 
       Replicate_Do_Domain_Ids: 
   Replicate_Ignore_Domain_Ids: 
                 Parallel_Mode: conservative
                     SQL_Delay: 0
           SQL_Remaining_Delay: NULL
       Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
              Slave_DDL_Groups: 4
Slave_Non_Transactional_Groups: 0
    Slave_Transactional_Groups: 0
1 row in set (0.000 sec)


MariaDB [hellodb]> set global general_log=ON;   # 开启操作日志记录,只是利于检查主从是否生效
Query OK, 0 rows affected (0.000 sec)

MariaDB [hellodb]> show variables like 'gen%';
+------------------+-----------+
| Variable_name    | Value     |
+------------------+-----------+
| general_log      | ON        |
| general_log_file | slave.log |
+------------------+-----------+
2 rows in set (0.001 sec)

MariaDB [hellodb]> 

 (3)安装 mycat(192.168.64.11)

 1、安装依赖环境java

yum -y install java

2、安装mycat

[root@mycat 22:52:21~]# wget http://dl.mycat.org.cn/1.6.7.4/Mycat-server-1.6.7.4-release/Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz

[root@mycat 22:54:31~]# mkdir /data/software/ -p

[root@mycat  22:56:51~]# tar xvf Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz -C /data/software/

[root@mycat 22:57:25~]# cat > /etc/profile.d/mycat_home.sh<<EOF
MYCAT_HOME=/data/software/mycat
export PATH=\${PATH}:\${MYCAT_HOME}/bin
EOF

[root@mycat  22:57:30~]# source /etc/profile.d/mycat_home.sh

[root@master 22:57:32~]# mycat
Usage: /data/software/mycat/bin/mycat { console | start | stop | restart | status | dump }

 3、修改schema.xml配置文件

<!DOCTYPE mycat:schema SYSTEM "schema. dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

    <!-- db_name_1是命名标识的第一个数据库,名字自己取,其中hellodb表示后端服务器实际的数据库名称 -->
    <schema name="TESTDB" checkSQLschema="fa1se" sqlMaxLimit="100" dataNode="db_name_1"></schema>
    <dataNode name="db_name_1" dataHost="mysql_host_1" database="hellodb" /> 

    <!-- mysql_host_1是命名标识的第一个数据库连接IP地址,名字自己取 -->
    <dataHost name="mysql_host_1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">

    <!-- 检查后端MySQL是否还存活,心跳检查,也是配置主从 -->
    <heartbeat>select user()</heartbeat>
    <writeHost host="host1" url="192.168.64.10:3306" user="slave" password="123456">
    <readHost host="host2" url="192.168.64.12:3306" user="slave" password="123456"/>

</writeHost>
</dataHost>
</mycat:schema>

4、修改schema.xml配置文件

[root@mycat 21:10:16/data/software/mycat/conf]# cat server.xml 

。。。略

        <user name="root" defaultAccount="true">
                <property name="password">123456</property>
                <property name="schemas">TESTDB</property>
                <property name="defaultSchema">TESTDB</property>
                <!--No MyCAT Database selected 错误前会尝试使用该schema作为schema,不设置则为null,报错 -->

。。。略

5、启动mycat

[root@mycat 09:41:49/data/software/mycat/conf]# mycat start

[root@mycat 09:42:10/data/software/mycat/conf]# grep -w 'startup' /data/software/mycat/logs/wrapper.log
INFO   | jvm 1    | 2021/08/22 09:41:09 | MyCAT Server startup successfully. see logs in logs/mycat.log

[root@mycat 09:45:45/data/software/mycat/conf]# netstat -untpl | grep 8066
tcp6       0      0 :::8066                 :::*                    LISTEN      29103/java

6、模拟客服端连接mycat访问后端mysql读写分离(进行读操作)

[root@client 21:45:03~]# mysql -uroot -p123456 -h192.168.64.11 -P8066
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.29-mycat-1.6.7.4-release-20200105164103 MyCat Server (OpenCloudDB)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB   |
+----------+
1 row in set (0.002 sec)

MySQL [(none)]> use TESTDB;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MySQL [TESTDB]> show tables;
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes           |
| coc               |
| courses           |
| scores            |
| students          |
| teachers          |
| toc               |
+-------------------+
7 rows in set (0.003 sec)

MySQL [TESTDB]>

6、检查结果,刚刚上面一直操作的是读,我们来看看结果

在mysql主服务器(master:192.168.64.10)上执行:show processlist;

并没有看到客服端连接过来的信息

检查日志 :/var/lib/mysql 

在mysql从服务器(slave:192.168.64.12)上执行:show processlist;

我们是能看到客服端连接过来的信息

检查日志 :/var/lib/mysql

 

 7、模拟客服端连接mycat访问后端mysql读写分离(进行写操作)

MySQL [TESTDB]> insert teachers(name,age,gender)values('mo',18,'M');
Query OK, 1 row affected (0.023 sec)

MySQL [TESTDB]> 

 8、检查结果,刚刚上面执行了一条写操作,我们来看看结果

在mysql主服务器(master:192.168.64.10)上检查日志:

在mysql从服务器(master:192.168.64.12)上检查日志: 

因为会从主服务器上复制数据过来,所以是存在着有记录的

 二、MHA实现MySQL的高可用性

1)资源包下载

 manager包

[root@mycat 10:39:17/data/software]# wget https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

node包

[root@mycat 10:39:24/data/software]# wget  https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.centos.noarch.rpm

2)部署架构图

 3)部署环境,由于manager只能用centos7,所以环境全部用centos7,支持MySQL5.7

  • 说明: mha4mysql-manager-0.56-0.el6.noarch.rpm 不支持CentOS 8,只支持CentOS7以下版本
  • 说明: mha4mysql-manager-0.58-0.el7.centos.noarch.rpm ,支持MySQL 5.7 ,但和CentOs8版本上的Mariadb -10.3.17不兼容

 MySQL5.7百度网盘地址下载

链接:https://pan.baidu.com/s/12JXp8r-NU2yzaHSa4d1BSg 
提取码:cmg7

1、在mha(192.168.64.10)的服务器上安装mha4mysql-manager和mha4mysql-node

# 先更新epel源
[root@mha_192.168.64.10 13:13:05~]# yum install epel-release -y

# 下载所需要的rpm包
[root@mha_192.168.64.10 13:13:15~]# wget https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

[root@mha_192.168.64.10 13:13:25~]# wget  https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.centos.noarch.rpm

# 安装
[root@mha_192.168.64.10 13:14:43~]# yum -y install mha4mysql-*

2、其他三个节点(master、slave1、slave2)上安装mha4mysql-node

[root@master_192.168.64.11 13:13:18~]# yum install epel-release -y

[root@master_192.168.64.11 13:13:25~]# wget https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.centos.noarch.rpm

[root@master_192.168.64.11 13:13:48~]# yum -y install mha4mysql-node-0.58-0.el7.centos.noarch.rpm

3、建立所有节点无密登录

[root@mha_192.168.64.10 13:03:27~]# cat /etc/hosts
192.168.64.10 mha
192.168.64.11 master
192.168.64.12 slave1
192.168.64.13 slave2

[root@mha_192.168.64.10 13:03:30~]# ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:JnhuOb7fyIenPTc7gDPWeOjowuh7JKibhrPahkJR/wU root@mha
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|   .   E         |
|  . .   .        |
| .   o   .       |
| .. . + S=       |
|... .o =B +      |
|+. =  =+ = .     |
|*+o +o.oo++ +    |
|O*+o o+o=+oo.+   |
+----[SHA256]-----+

[root@mha_192.168.64.10 13:04:31~]# scp -r .ssh master:/root/
The authenticity of host 'master (192.168.64.11)' can't be established.
ECDSA key fingerprint is SHA256:ZWVQ5th7iynhNPKZXujWK5xHRER/eSMTPlSAa5n2n1k.
ECDSA key fingerprint is MD5:2a:b9:ce:23:c7:86:74:c5:9a:75:31:20:bf:80:9e:47.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'master,192.168.64.11' (ECDSA) to the list of known hosts.
root@master's password: 
id_rsa                                                                                     100% 1675     1.1MB/s   00:00    
id_rsa.pub                                                                                 100%  390   440.3KB/s   00:00    
known_hosts                                                                                100%  361   372.8KB/s   00:00    
authorized_keys                                                                            100%  390   393.8KB/s   00:00    
[root@mha_192.168.64.10 13:04:47~]# scp -r .ssh slave1:/root/
The authenticity of host 'slave1 (192.168.64.12)' can't be established.
ECDSA key fingerprint is SHA256:ZWVQ5th7iynhNPKZXujWK5xHRER/eSMTPlSAa5n2n1k.
ECDSA key fingerprint is MD5:2a:b9:ce:23:c7:86:74:c5:9a:75:31:20:bf:80:9e:47.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'slave1,192.168.64.12' (ECDSA) to the list of known hosts.
root@slave1's password: 
id_rsa                                                                                     100% 1675   920.2KB/s   00:00    
id_rsa.pub                                                                                 100%  390   412.3KB/s   00:00    
known_hosts                                                                                100%  543   987.3KB/s   00:00    
authorized_keys                                                                            100%  390   741.8KB/s   00:00    
[root@mha_192.168.64.10 13:04:56~]# scp -r .ssh slave2:/root/
The authenticity of host 'slave2 (192.168.64.13)' can't be established.
ECDSA key fingerprint is SHA256:ZWVQ5th7iynhNPKZXujWK5xHRER/eSMTPlSAa5n2n1k.
ECDSA key fingerprint is MD5:2a:b9:ce:23:c7:86:74:c5:9a:75:31:20:bf:80:9e:47.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'slave2,192.168.64.13' (ECDSA) to the list of known hosts.
root@slave2's password: 
id_rsa                                                                                     100% 1675   864.5KB/s   00:00    
id_rsa.pub                                                                                 100%  390   168.5KB/s   00:00    
known_hosts                                                                                100%  725     1.0MB/s   00:00    
authorized_keys                                                                            100%  390   782.2KB/s   00:00    
[root@mha_192.168.64.10 13:05:03~]# 

4、在管理节点(mha:192.168.64.10)建立配置文件,注意:复制到配置文件里要把注释信息删掉,不然会报错

[root@mha_192.168.64.10 19:26:07~]# cat /etc/mastermha/app1.cnf
[server default]
user=mhauser  # 用于远程连接MySQL所有节点的用户,需要有管理员的权限
password=123456
manager_workdir=/data/mastermha/app1/   # 目录会自动生成,无需手动创建
manager_log=/data/mastermha/app1/manager.log
ssh_user=root  # 用于实现远程ssh基于KEY的连接,访问二进制日志
repl_user=slave  # 主从复制的用户信息
repl_password=123456
ping_interval=1    # 健康性检查的时间间隔
master_ip_failover_script=/usr/local/bin/master_ip_failover  # 切换VIP的per1脚本
report_script=/usr/local/bin/sendmail.sh   # 邮件通知,告警用的
check_repl_delay=0   # 默认如果slave中从库落后主库relaylog超过100M,主库不会选择这个从库为新的master,因为这个从库进行恢复需要很长的时间.通过这个参数,mha触发主从切换的时候会忽略复制的延时,通过check_repl_delay=0这个参数,mha触发主从切换时会忽略复制的延时,对于设置candidate_master=1的从库非常有用,这样确保这个从库一定能成为最新的master
master_binlog_dir=/data/mysq1/   # 指定二进制日志存放的目录,mha4mysq1-manager-0.58必须指定,之前版本不需要指定

[server1]
hostname=192.168.64.11
candidate_master=1

[server2]
hostname=192.168.64.12
candidate_master=1   # 设置为优先候选master,即使不是集群中事件最新的s1ave,也会优先当master

[server3]
hostname=192.168.64.13

5、邮件通知脚本(只在mha安装)

[root@mha_192.168.64.10 19:28:39~]# cat /usr/local/bin/sendmail.sh
echo 'MySQL is down' | mail -s 'MHA warning' 123456789@qq.com
[root@mha_192.168.64.10 19:28:45~]# chmod +x /usr/local/bin/sendmail.sh

6、切换VIP的per1脚本(只在mha安装)

来源地址:原文链接:https://blog.csdn.net/shm19990131/article/details/107423239

[root@mha_192.168.64.10 19:30:13~]# cat /usr/local/bin/master_ip_failover
#!/usr/bin/env perl

#  Copyright (C) 2011 DeNA Co.,Ltd.
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#  Foundation, Inc.,
#  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

## Note: This is a sample script and is not complete. Modify the script based on your environment.

use strict;
use warnings FATAL => 'all';

use Getopt::Long;
use MHA::DBHelper;

my (
  $command,        $ssh_user,         $orig_master_host,
  $orig_master_ip, $orig_master_port, $new_master_host,
  $new_master_ip,  $new_master_port,  $new_master_user,
  $new_master_password
);
my $vip = '192.168.64.100/24';  # 设置virtual IP
my $gateway = '192.168.64.2';   # 网卡gateway IP
my $interface = 'ens32';        # 指定VIP所在网卡
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig $interface:$key Svip;/sbin/arping -I $interface -c 3 -s $vip $gateway >/dev/null 2>&1";
my $ssh_stop_vip = "/sbin/ifconfig $interface:$key down";

GetOptions(
  'command=s'             => \$command,
  'ssh_user=s'            => \$ssh_user,
  'orig_master_host=s'    => \$orig_master_host,
  'orig_master_ip=s'      => \$orig_master_ip,
  'orig_master_port=i'    => \$orig_master_port,
  'new_master_host=s'     => \$new_master_host,
  'new_master_ip=s'       => \$new_master_ip,
  'new_master_port=i'     => \$new_master_port,
  'new_master_user=s'     => \$new_master_user,
  'new_master_password=s' => \$new_master_password,
);

exit &main();

sub main {
  if ( $command eq "stop" || $command eq "stopssh" ) {

    # $orig_master_host, $orig_master_ip, $orig_master_port are passed.
    # If you manage master ip address at global catalog database,
    # invalidate orig_master_ip here.
    my $exit_code = 1;
    eval {

      # updating global catalog, etc
      $exit_code = 0;
    };
    if ($@) {
      warn "Got Error: $@\n";
      exit $exit_code;
    }
    exit $exit_code;
  }
    elsif ( $command eq "start" ) {

        # all arguments are passed.
        # If you manage master ip address at global catalog database,
        # activate new_master_ip here.
        # You can also grant write access (create user, set read_only=0, etc) here.
        my $exit_code = 10;
        eval {
            print "Enabling the VIP - $vip on the new master - $new_master_host \n";
            &start_vip();
            &stop_vip();
            $exit_code = 0;
        };
        if ($@) {
            warn $@;
            exit $exit_code;
        }
        exit $exit_code;
    }
    elsif ( $command eq "status" ) {
        print "Checking the Status of the script.. OK \n";
        `ssh $ssh_user\@$orig_master_host \" $ssh_start_vip \"`;
        exit 0;
    }
    else {
        &usage();
        exit 1;
    }
}


sub start_vip() {
    `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
# A simple system call that disable the VIP on the old_master 
sub stop_vip() {
   `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}


sub usage {
  print
"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}

[root@mha_192.168.64.10 21:22:41~]# chmod +x /usr/local/bin/master_ip_failover

7、安装邮件服务(只在mha安装)

[root@mha_192.168.64.10 22:23:41~]# yum -y install  s-nail

[root@mha_192.168.64.10 22:27:57~]# cat /etc/mail.rc
set from 123456789@qq.com
set smtp=smtp.qq.com
set smtp-auth-user=123456789@qq.com
set smtp-auth-password=123456789  # 授权码,不是QQ密码

# 测试
[root@mha_192.168.64.10 22:31:23~]# sh /usr/local/bin/sendmail.sh

8、在master、slave1、slave2安装mysql5.7

yum -y install numactl gcc gcc-c++
groupadd mysql
useradd -r -s /sbin/nologin -g mysql mysql
tar zxf mysql-5.7.27-linux-glibc2.12-x86_64.tar.gz
mkdir -p /data/software
mv mysql-5.7.27-linux-glibc2.12-x86_64 /data/software/mysql
cd /data/software/mysql
mkdir tmp run log data
touch log/mysql.log
chown mysql:mysql  ../mysql/ -R

cat > /etc/my.cnf <<EOF
根据master、slave1、slave2来配置,详细请看下面
EOF

source /etc/profile
chkconfig --add mysql
chkconfig --level 345 mysql on

service mysql start

source /etc/profile

mysql_pass=$(awk -F 'localhost: ' '$2!="" {print $2}' /data/software/mysql/log/mysql.log)

export MYSQL_PWD=${mysql_pass}

grant_sql="
set password=password('123456');
flush privileges;"

mysql -uroot -e "${grant_sql}" --connect-expired-password

 9、master的mysql配置

[root@master_192.168.64.11 22:53:02~]# cat /etc/my.cnf
[client]
port        = 3306
socket=/data/software/mysql/tmp/mysql.sock

[mysqld]
port        = 3306
socket=/data/software/mysql/tmp/mysql.sock
log-error=/data/software/mysql/log/mysql.log
pid-file=/data/software/mysql/tmp/mysql.pid
datadir=/data/software/mysql/data
skip-external-locking
key_buffer_size = 64M
max_allowed_packet = 1M
table_open_cache = 256
sort_buffer_size = 1M
net_buffer_length = 8K
read_buffer_size = 1M
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 16M
thread_cache_size = 32
query_cache_size = 32M
tmp_table_size = 64M
performance_schema_max_table_instances = 2000

explicit_defaults_for_timestamp = true
max_connections = 500
max_connect_errors = 100
open_files_limit = 65535

log-bin=mysql-bin
binlog_format=mixed
server-id   = 11     # 每台服务器上的id是不同的,以IP结尾做ID,slave1为12,slave2为13
skip_name_resolve=1  # 禁止反向解析
general_log
expire_logs_days = 10
early-plugin-load = ""

default_storage_engine = InnoDB
innodb_file_per_table = 1
innodb_data_home_dir = /data/software/mysql/data
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = /data/software/mysql/data
innodb_buffer_pool_size = 256M
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50

[mysqldump]
quick
max_allowed_packet = 16M

[mysql]
no-auto-rehash

[myisamchk]
key_buffer_size = 64M
sort_buffer_size = 1M
read_buffer_size = 1M
write_buffer_size = 2M

[mysqlhotcopy]
interactive-timeout

[mysqld_safe]
log-error=/data/software/mysql/log/mysql.log
pid-file=/data/software/mysql/tmp/mysql.pid

10、master绑定网卡192.168.64.100的IP地址作为VIP地址:

[root@master_192.168.64.11 07:05:28~]# ifconfig ens32:1 192.168.64.100/24

11、slave1配置

[root@slave1_192.168.64.12 22:58:09~]# cat /etc/my.cnf
[client]
port        = 3306
socket=/data/software/mysql/tmp/mysql.sock

[mysqld]
port        = 3306
socket=/data/software/mysql/tmp/mysql.sock
log-error=/data/software/mysql/log/mysql.log
pid-file=/data/software/mysql/tmp/mysql.pid
datadir=/data/software/mysql/data
skip-external-locking
key_buffer_size = 64M
max_allowed_packet = 1M
table_open_cache = 256
sort_buffer_size = 1M
net_buffer_length = 8K
read_buffer_size = 1M
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 16M
thread_cache_size = 32
query_cache_size = 32M
tmp_table_size = 64M
performance_schema_max_table_instances = 2000

explicit_defaults_for_timestamp = true
max_connections = 500
max_connect_errors = 100
open_files_limit = 65535

log-bin=mysql-bin
binlog_format=mixed
server-id   = 12
read-only
relay_log_purge=0
skip_name_resolve=1  # 禁止反向解析
expire_logs_days = 10
early-plugin-load = ""

default_storage_engine = InnoDB
innodb_file_per_table = 1
innodb_data_home_dir = /data/software/mysql/data
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = /data/software/mysql/data
innodb_buffer_pool_size = 256M
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50

[mysqldump]
quick
max_allowed_packet = 16M

[mysql]
no-auto-rehash

[myisamchk]
key_buffer_size = 64M
sort_buffer_size = 1M
read_buffer_size = 1M
write_buffer_size = 2M

[mysqlhotcopy]
interactive-timeout

[mysqld_safe]
log-error=/data/software/mysql/log/mysql.log
pid-file=/data/software/mysql/tmp/mysql.pid

12、slave2配置

[root@slave2_192.168.64.13 22:58:31~]# cat /etc/my.cnf
[client]
port        = 3306
socket=/data/software/mysql/tmp/mysql.sock

[mysqld]
port        = 3306
socket=/data/software/mysql/tmp/mysql.sock
log-error=/data/software/mysql/log/mysql.log
pid-file=/data/software/mysql/tmp/mysql.pid
datadir=/data/software/mysql/data
skip-external-locking
key_buffer_size = 64M
max_allowed_packet = 1M
table_open_cache = 256
sort_buffer_size = 1M
net_buffer_length = 8K
read_buffer_size = 1M
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 16M
thread_cache_size = 32
query_cache_size = 32M
tmp_table_size = 64M
performance_schema_max_table_instances = 2000

explicit_defaults_for_timestamp = true
max_connections = 500
max_connect_errors = 100
open_files_limit = 65535

log-bin=mysql-bin
binlog_format=mixed
server-id   = 13
read-only
relay_log_purge=0
skip_name_resolve=1  # 禁止反向解析
general_log
expire_logs_days = 10
early-plugin-load = ""

default_storage_engine = InnoDB
innodb_file_per_table = 1
innodb_data_home_dir = /data/software/mysql/data
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = /data/software/mysql/data
innodb_buffer_pool_size = 256M
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50

[mysqldump]
quick
max_allowed_packet = 16M

[mysql]
no-auto-rehash

[myisamchk]
key_buffer_size = 64M
sort_buffer_size = 1M
read_buffer_size = 1M
write_buffer_size = 2M

[mysqlhotcopy]
interactive-timeout

[mysqld_safe]
log-error=/data/software/mysql/log/mysql.log
pid-file=/data/software/mysql/tmp/mysql.pid

13、master创建账号和导入数据

[root@master_192.168.64.11 23:03:12~]# mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 9
Server version: 10.3.31-MariaDB-log MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show master status;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000001 |      329 |              |                  |
+-------------------+----------+--------------+------------------+
1 row in set (0.001 sec)

MariaDB [(none)]> grant all on *.* to mhauser@'%' identified by "123456";
Query OK, 0 rows affected (0.001 sec)

MariaDB [hellodb]> grant all on *.* to slave@'%' identified by "123456";
Query OK, 0 rows affected (0.000 sec)

MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.000 sec)

MariaDB [(none)]> source hellodb_innodb.sql;

14、slave1、slave2执行配置从节点操作

CHANGE MASTER To 
MASTER_HOST='192.168.64.11', 
MASTER_USER='slave', 
MASTER_PASSwORD='123456', 
MASTER_LOG_FILE='master-bin.000001', 
MASTER_LOG_POS=329;
[root@slave1_192.168.64.12 23:03:24~]# mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 9
Server version: 10.3.31-MariaDB-log MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> CHANGE MASTER To 
    -> MASTER_HOST='192.168.64.11', 
    -> MASTER_USER='slave', 
    -> MASTER_PASSwORD='123456', 
    -> MASTER_LOG_FILE='master-bin.000001', 
    -> MASTER_LOG_POS=329;
Query OK, 0 rows affected (0.006 sec)

MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.001 sec)

MariaDB [(none)]> show slave status\G
*************************** 1. row ***************************
                Slave_IO_State: Waiting for master to send event
                   Master_Host: 192.168.64.11
                   Master_User: slave
                   Master_Port: 3306
                 Connect_Retry: 60
               Master_Log_File: master-bin.000001
           Read_Master_Log_Pos: 9551
                Relay_Log_File: slave1-relay-bin.000002
                 Relay_Log_Pos: 9778
         Relay_Master_Log_File: master-bin.000001
              Slave_IO_Running: Yes
             Slave_SQL_Running: Yes


MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| hellodb            |
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
5 rows in set (0.000 sec)

MariaDB [(none)]> use hellodb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [hellodb]> show tables;
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes           |
| coc               |
| courses           |
| scores            |
| students          |
| teachers          |
| toc               |
+-------------------+
7 rows in set (0.000 sec)

MariaDB [hellodb]>

15、检查ssh配置连通是否正常,

提示   All SSH connection tests passed successfully.   则是正常的:

[root@mha_192.168.64.10 23:41:49~]# masterha_check_ssh --conf=/etc/mastermha/app1.cnf
Sun Aug 22 23:41:52 2021 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sun Aug 22 23:41:52 2021 - [info] Reading application default configuration from /etc/mastermha/app1.cnf..
Sun Aug 22 23:41:52 2021 - [info] Reading server configuration from /etc/mastermha/app1.cnf..
Sun Aug 22 23:41:52 2021 - [info] Starting SSH connection tests..
Sun Aug 22 23:41:53 2021 - [debug] 
Sun Aug 22 23:41:52 2021 - [debug]  Connecting via SSH from root@192.168.64.11(192.168.64.11:22) to root@192.168.64.12(192.168.64.12:22)..
Sun Aug 22 23:41:52 2021 - [debug]   ok.
Sun Aug 22 23:41:52 2021 - [debug]  Connecting via SSH from root@192.168.64.11(192.168.64.11:22) to root@192.168.64.13(192.168.64.13:22)..
Sun Aug 22 23:41:52 2021 - [debug]   ok.
Sun Aug 22 23:41:53 2021 - [debug] 
Sun Aug 22 23:41:52 2021 - [debug]  Connecting via SSH from root@192.168.64.12(192.168.64.12:22) to root@192.168.64.11(192.168.64.11:22)..
Sun Aug 22 23:41:52 2021 - [debug]   ok.
Sun Aug 22 23:41:52 2021 - [debug]  Connecting via SSH from root@192.168.64.12(192.168.64.12:22) to root@192.168.64.13(192.168.64.13:22)..
Sun Aug 22 23:41:53 2021 - [debug]   ok.
Sun Aug 22 23:41:54 2021 - [debug] 
Sun Aug 22 23:41:53 2021 - [debug]  Connecting via SSH from root@192.168.64.13(192.168.64.13:22) to root@192.168.64.11(192.168.64.11:22)..
Sun Aug 22 23:41:53 2021 - [debug]   ok.
Sun Aug 22 23:41:53 2021 - [debug]  Connecting via SSH from root@192.168.64.13(192.168.64.13:22) to root@192.168.64.12(192.168.64.12:22)..
Sun Aug 22 23:41:53 2021 - [debug]   ok.
Sun Aug 22 23:41:54 2021 - [info] All SSH connection tests passed successfully.

16、检查MySQL配置连通是否正常

最后提示   MySQL Replication Health is OK.   则是正常的,如果提示  NOT OK!  则不正常。

[root@mha_192.168.64.10 21:57:09/etc/mastermha]# masterha_check_repl --conf=/etc/mastermha/app1.cnf 
Tue Aug 24 21:57:11 2021 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Tue Aug 24 21:57:11 2021 - [info] Reading application default configuration from /etc/mastermha/app1.cnf..
Tue Aug 24 21:57:11 2021 - [info] Reading server configuration from /etc/mastermha/app1.cnf..
Tue Aug 24 21:57:11 2021 - [info] MHA::MasterMonitor version 0.58.
Tue Aug 24 21:57:12 2021 - [info] GTID failover mode = 0
Tue Aug 24 21:57:12 2021 - [info] Dead Servers:
Tue Aug 24 21:57:12 2021 - [info] Alive Servers:
Tue Aug 24 21:57:12 2021 - [info]   192.168.64.11(192.168.64.11:3306)
Tue Aug 24 21:57:12 2021 - [info]   192.168.64.12(192.168.64.12:3306)
Tue Aug 24 21:57:12 2021 - [info]   192.168.64.13(192.168.64.13:3306)
Tue Aug 24 21:57:12 2021 - [info] Alive Slaves:
Tue Aug 24 21:57:12 2021 - [info]   192.168.64.12(192.168.64.12:3306)  Version=5.7.27-log (oldest major version between slaves) log-bin:enabled
Tue Aug 24 21:57:12 2021 - [info]     Replicating from 192.168.64.11(192.168.64.11:3306)
Tue Aug 24 21:57:12 2021 - [info]     Primary candidate for the new Master (candidate_master is set)
Tue Aug 24 21:57:12 2021 - [info]   192.168.64.13(192.168.64.13:3306)  Version=5.7.27-log (oldest major version between slaves) log-bin:enabled
Tue Aug 24 21:57:12 2021 - [info]     Replicating from 192.168.64.11(192.168.64.11:3306)
Tue Aug 24 21:57:12 2021 - [info] Current Alive Master: 192.168.64.11(192.168.64.11:3306)
Tue Aug 24 21:57:12 2021 - [info] Checking slave configurations..
Tue Aug 24 21:57:12 2021 - [info] Checking replication filtering settings..
Tue Aug 24 21:57:12 2021 - [info]  binlog_do_db= , binlog_ignore_db= 
Tue Aug 24 21:57:12 2021 - [info]  Replication filtering check ok.
Tue Aug 24 21:57:12 2021 - [info] GTID (with auto-pos) is not supported
Tue Aug 24 21:57:12 2021 - [info] Starting SSH connection tests..
Tue Aug 24 21:57:15 2021 - [info] All SSH connection tests passed successfully.
Tue Aug 24 21:57:15 2021 - [info] Checking MHA Node version..
Tue Aug 24 21:57:15 2021 - [info]  Version check ok.
Tue Aug 24 21:57:15 2021 - [info] Checking SSH publickey authentication settings on the current master..
Tue Aug 24 21:57:15 2021 - [info] HealthCheck: SSH to 192.168.64.11 is reachable.
Tue Aug 24 21:57:15 2021 - [info] Master MHA Node version is 0.58.
Tue Aug 24 21:57:15 2021 - [info] Checking recovery script configurations on 192.168.64.11(192.168.64.11:3306)..
Tue Aug 24 21:57:15 2021 - [info]   Executing command: save_binary_logs --command=test --start_pos=4 --binlog_dir=/data/software/mysql/data --output_file=/var/tmp/save_binary_logs_test --manager_version=0.58 --start_file=mysql-bin.000002 
Tue Aug 24 21:57:15 2021 - [info]   Connecting to root@192.168.64.11(192.168.64.11:22).. 
  Creating /var/tmp if not exists..    ok.
  Checking output directory is accessible or not..
   ok.
  Binlog found at /data/software/mysql/data, up to mysql-bin.000002
Tue Aug 24 21:57:15 2021 - [info] Binlog setting check done.
Tue Aug 24 21:57:15 2021 - [info] Checking SSH publickey authentication and checking recovery script configurations on all alive slave servers..
Tue Aug 24 21:57:15 2021 - [info]   Executing command : apply_diff_relay_logs --command=test --slave_user='mhauser' --slave_host=192.168.64.12 --slave_ip=192.168.64.12 --slave_port=3306 --workdir=/var/tmp --target_version=5.7.27-log --manager_version=0.58 --relay_log_info=/data/software/mysql/data/relay-log.info  --relay_dir=/data/software/mysql/data/  --slave_pass=xxx
Tue Aug 24 21:57:15 2021 - [info]   Connecting to root@192.168.64.12(192.168.64.12:22).. 
  Checking slave recovery environment settings..
    Opening /data/software/mysql/data/relay-log.info ... ok.
    Relay log found at /data/software/mysql/data, up to slave1-relay-bin.000002
    Temporary relay log file is /data/software/mysql/data/slave1-relay-bin.000002
    Checking if super_read_only is defined and turned on.. not present or turned off, ignoring.
    Testing mysql connection and privileges..
mysql: [Warning] Using a password on the command line interface can be insecure.
 done.
    Testing mysqlbinlog output.. done.
    Cleaning up test file(s).. done.
Tue Aug 24 21:57:16 2021 - [info]   Executing command : apply_diff_relay_logs --command=test --slave_user='mhauser' --slave_host=192.168.64.13 --slave_ip=192.168.64.13 --slave_port=3306 --workdir=/var/tmp --target_version=5.7.27-log --manager_version=0.58 --relay_log_info=/data/software/mysql/data/relay-log.info  --relay_dir=/data/software/mysql/data/  --slave_pass=xxx
Tue Aug 24 21:57:16 2021 - [info]   Connecting to root@192.168.64.13(192.168.64.13:22).. 
  Checking slave recovery environment settings..
    Opening /data/software/mysql/data/relay-log.info ... ok.
    Relay log found at /data/software/mysql/data, up to slave2-relay-bin.000002
    Temporary relay log file is /data/software/mysql/data/slave2-relay-bin.000002
    Checking if super_read_only is defined and turned on.. not present or turned off, ignoring.
    Testing mysql connection and privileges..
mysql: [Warning] Using a password on the command line interface can be insecure.
 done.
    Testing mysqlbinlog output.. done.
    Cleaning up test file(s).. done.
Tue Aug 24 21:57:16 2021 - [info] Slaves settings check done.
Tue Aug 24 21:57:16 2021 - [info] 
192.168.64.11(192.168.64.11:3306) (current master)
 +--192.168.64.12(192.168.64.12:3306)
 +--192.168.64.13(192.168.64.13:3306)

Tue Aug 24 21:57:16 2021 - [info] Checking replication health on 192.168.64.12..
Tue Aug 24 21:57:16 2021 - [info]  ok.
Tue Aug 24 21:57:16 2021 - [info] Checking replication health on 192.168.64.13..
Tue Aug 24 21:57:16 2021 - [info]  ok.
Tue Aug 24 21:57:16 2021 - [info] Checking master_ip_failover_script status:
Tue Aug 24 21:57:16 2021 - [info]   /usr/local/bin/master_ip_failover --command=status --ssh_user=root --orig_master_host=192.168.64.11 --orig_master_ip=192.168.64.11 --orig_master_port=3306 
Checking the Status of the script.. OK 
Svip: Unknown host
ifconfig: `--help' gives usage information.
Tue Aug 24 21:57:16 2021 - [info]  OK.
Tue Aug 24 21:57:16 2021 - [warning] shutdown_script is not defined.
Tue Aug 24 21:57:16 2021 - [info] Got exit code 0 (Not master dead).

MySQL Replication Health is OK.

17、启动MHA,后台启动

[root@mha_192.168.64.10 22:27:54/etc/mastermha]# nohup masterha_manager --conf=/etc/mastermha/app1.cnf &> /dev/null &
[1] 15392


# 检查MHA状态
[root@mha_192.168.64.10 22:28:03/etc/mastermha]# masterha_check_status --conf=/etc/mastermha/app1.cnf 
app1 (pid:15392) is running(0:PING_OK), master:192.168.64.11

18、测试崩溃master,直接关闭master服务器

[root@master_192.168.64.11 22:46:20~]# init 6
Connection closing...Socket close.

Connection closed by foreign host.

Disconnected from remote host(master) at 22:46:23.

Type `help' to learn how to use Xshell prompt.
[H:\~]$ 

查看MHA日志

tail -f /data/mastermha/app1/manager.log

略略略。。。。


----- Failover Report -----

app1: MySQL Master failover 192.168.64.11(192.168.64.11:3306) to 192.168.64.12(192.168.64.12:3306) succeeded

Master 192.168.64.11(192.168.64.11:3306) is down!

Check MHA Manager logs at mha:/data/mastermha/app1/manager.log for details.

Started automated(non-interactive) failover.
Invalidated master IP address on 192.168.64.11(192.168.64.11:3306)
The latest slave 192.168.64.12(192.168.64.12:3306) has all relay logs for recovery.
Selected 192.168.64.12(192.168.64.12:3306) as a new master.
192.168.64.12(192.168.64.12:3306): OK: Applying all logs succeeded.
192.168.64.12(192.168.64.12:3306): OK: Activated master IP address.
192.168.64.13(192.168.64.13:3306): This host has the latest relay log events.
Generating relay diff files from the latest slave succeeded.
192.168.64.13(192.168.64.13:3306): OK: Applying all logs succeeded. Slave started, replicating from 192.168.64.12(192.168.64.12:3306)
192.168.64.12(192.168.64.12:3306): Resetting slave info succeeded.
Master failover to 192.168.64.12(192.168.64.12:3306) completed successfully.
Tue Aug 24 22:46:51 2021 - [info] Sending mail..

19、MHA是一次性的,如果需要再次运行MHA,需要删除日志文件

[root@mha_192.168.64.10 22:52:58~]# rm -f /data/mastermha/app1/app1.failover.complete 

三、Ansible介绍

官网: https://www.ansible.com/

官方文档: https://docs.ansible.com/

  • Ansible的特性

1、模块化:调用特定的模块完成特定任务,支持自定义模块,可使用任何编程语言写模块

2、Paramiko (python对ssh的实现),PyYAML,Jinja2(模板语言)三个关键模块

3、基于Python语言实现

4、部署简单,基于python和SSH(默认已安装),agentless,无需代理不依赖PKI(无需ssl)

5、安全,基于OpenSSH

6、幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况,此特性非绝对

7、支持playbook编排任务,YAML格式,编排任务,支持丰富的数据结构

8、较强大的多层解决方案role

  • Ansible的组成

 1、组合INVENTORY、API、MODULES、PLUGINS的绿框,为ansible命令工具,其为核心执行工具

2、INVENTORY:Ansible管理主机的清单/etc/anaible/hosts

3、MODULES:Ansible执行命令的功能模块,多数为内置核心模块,也可自定义

4、PLUGINS:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用

5、API:供第三方程序调用的应用程序编程接口

  • Ansible的命令执行来源

1、USER普通用户,即SYSTEM ADMINISTRATOR

2、PLAYBOOKS:任务剧本(任务集),编排定义Ansible任务集的配置文件,由Ansible顺序依次执行,通常是JSON格式的YML文件

3、CMDB(配置管理数据库)API调用

4、PUBLIC/PRIVATE CLOUD API调用

5、USER-> Ansible Playbook ->Ansibile

  • Ansible的注意事项

1、执行ansible的主机一般称为管理端,主控端,中控,master或堡垒机

2、主控端Python版本需要2.6或以上

3、被控端Python版本小于2.4,需要安装python-simplejson

4、被控端如开启SELinux需要安装libselinux-python

5、windows不能做为主控端

  • Ansible的安装

1、官方文档:https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.ht

2、下载地址:Index of /ansible

  • Ansible的相关配置文件

1、/etclansiblelansible.cfg主配置文件,配置ansible工作特性

2、/etclansible/hosts主机清单

3、/etclansible/roles/存放角色的目录

  • ansible的主配置文件:/etc/ansible/ansible.cfg
[defaults]
# inventory = /etc/ansible/hosts       # 主机列表配置文件
# library = /usr/share/my_modules/     # 库文件存放目录
# remote_tmp = $HOME/.ansible/tmp      # 临时py命令文件存放在远程主机目录
# local_tmp = $HOME/.ansible/tmp       # 本机的临时命令执行目录
# forks =5                             # 默认并发数
# sudo_user = root                     # 默认sudo 用户
# ask_sudo_pass = True                 # 每次执行ansible命令是否询问ssh密码
# ask_pass = True
# remote_port = 22
# host_key_checking = False            # 检查对应服务器的host_key,建议取消注释
# log_path=/var/log/ansible.log        # 日志文件,建议启用
# module_name = command                # 默认模块,可以修改为shell模块
  • inventory主机清单

1、ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名

2、默认的inventory file为/etc/ansible/hosts

3、inventory file可以有多个,且也可以通过Dynamic Inventory来动态生成

4、官方文档:How to build your inventory — Ansible Documentation

  • 主机清单文件格式

1、inventory文件遵循INl文件风格,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组中

2、此外,当如若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来标明

3、如果主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机

4、范例:

ntp.magedu.com
[webservers]
www1.magedu.com:2222
www2.magedu.com

[dbservers]
db1.magedu.com
db2.magedu.com
db3.magedu.com

[websrvs]
ww[1:100].example.com

[dbsrvs]
db-[a:f].example.com

[appsrvs]
10.0.0.[1:100]

[test]
10.0.0.8   ansible_connection=local=l    # 指定本地连接,无需ssh配置

# ansible_connection=ssh 需要strictHostKeychecking no
10.0.0.7 ansible_connection=ssh ansible_port=2222 ansible_user=wangansible_password=magedu
10.0.0.6 ansible_connection=ssh ansible_user=root ansible_password=123456
  • Ansible的相关工具

1、/usr/bin/ansible                          主程序,临时命令执行工具

2、/usr/bin/ansible-doc                   查看配置文档,模块功能查看工具,相当于man

3、/usr/bin/ansible-playbook          定制自动化任务,编排剧本工具,相当于脚本,主要用于长期规划好的,大型项目的场景,需要有前期的规划过程

4、/usr/bin/ansible-pull                   远程执行命令的工具

5、usr/bin/ansible-vault                  文件加密工具

6、/usr/bin/ansible-console            基于Console界面与用户交互的执行工具

7、/usr/bin/ansible-galaxy              下载/上传优秀代码或Roles模块的官网平台

四、Ansible常用模块

官网:Module Index — Ansible Documentation

https://docs.ansible.com/ansible/latest/modules/modules_by_category.html

  • ping模块

功能:测试主机的连通性

范例:

[root@server 11:39:51~]# ansible all -m ping
192.168.64.10 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
192.168.64.11 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
192.168.64.12 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
[root@server 11:39:56~]# 
  • Command模块

功能:在远程主机执行命令,此为默认模块,可忽略-m选项

注意:此命令不支持$VARNAME< > |;&等,用shell模块可实现特殊符号实现

范例:

[root@server 11:47:23~]# ansible all -m command -a 'chdir=/root ls -l'
192.168.64.10 | CHANGED | rc=0 >>
总用量 4
-rw-------. 1 root root 1407 3月  13 08:34 anaconda-ks.cfg
192.168.64.11 | CHANGED | rc=0 >>
总用量 4
-rw-------. 1 root root 1407 3月  13 08:34 anaconda-ks.cfg
192.168.64.12 | CHANGED | rc=0 >>
总用量 4
-rw-------. 1 root root 1407 3月  13 08:34 anaconda-ks.cfg
[root@server 11:47:50~]# ansible all -a 'chdir=/root ls -l'
192.168.64.10 | CHANGED | rc=0 >>
总用量 4
-rw-------. 1 root root 1407 3月  13 08:34 anaconda-ks.cfg
192.168.64.11 | CHANGED | rc=0 >>
总用量 4
-rw-------. 1 root root 1407 3月  13 08:34 anaconda-ks.cfg
192.168.64.12 | CHANGED | rc=0 >>
总用量 4
-rw-------. 1 root root 1407 3月  13 08:34 anaconda-ks.cfg
[root@server 11:47:54~]# 
  •  shell模块

功能:和command相似,用shell执行命令,支持各种符号,比如:*,$,>等,它不是默认模块,需要加-m

范例:

[root@server 12:16:19~]# ansible all -m shell -a 'echo $UID'
192.168.64.10 | CHANGED | rc=0 >>
0
192.168.64.11 | CHANGED | rc=0 >>
0
192.168.64.12 | CHANGED | rc=0 >>
0
[root@server 12:16:54~]# 
  • script模块

功能:在远程主机上运行ansible服务器上的脚本(无需执行权限)

范例:

[root@server 12:16:54~]# ansible all -m shell -a 'echo hostname -I > /root/test.sh'
192.168.64.10 | CHANGED | rc=0 >>

192.168.64.11 | CHANGED | rc=0 >>

192.168.64.12 | CHANGED | rc=0 >>

[root@server 12:22:43~]# ansible all -m script -a '/root/test.sh'
192.168.64.10 | CHANGED => {
    "changed": true,
    "rc": 0,
    "stderr": "",
    "stderr_lines": [],
    "stdout": "192.168.64.10 \n",
    "stdout_lines": [
        "192.168.64.10 "
    ]
}
192.168.64.11 | CHANGED => {
    "changed": true,
    "rc": 0,
    "stderr": "Shared connection to 192.168.64.11 closed.\r\n",
    "stderr_lines": [
        "Shared connection to 192.168.64.11 closed."
    ],
    "stdout": "192.168.64.11 \r\n",
    "stdout_lines": [
        "192.168.64.11 "
    ]
}
192.168.64.12 | CHANGED => {
    "changed": true,
    "rc": 0,
    "stderr": "Shared connection to 192.168.64.12 closed.\r\n",
    "stderr_lines": [
        "Shared connection to 192.168.64.12 closed."
    ],
    "stdout": "192.168.64.12 \r\n",
    "stdout_lines": [
        "192.168.64.12 "
    ]
}
[root@server 12:23:13~]# 
  • copy模块

功能:从ansible服务器主控端复制文件到远程主机

注意:如果目标文件已存在,则默认被覆盖;复制目录目录时要注意 '/' ,跟rsync一样;如 /data 表示 /data 整个目录包括 data 本身也复制过去;如 /data/  只复制 /data 目录下的文件和子目录过去

范例:

[root@server 12:45:07~]# mkdir /data
[root@server 12:45:11~]# touch /data/test.txt
[root@server 12:45:18~]# ansible all -m copy -a 'src=/data dest=/test'
192.168.64.10 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "dest": "/test/data/test.txt",
    "gid": 0,
    "group": "root",
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e",
    "mode": "0644",
    "owner": "root",
    "size": 0,
    "src": "/root/.ansible/tmp/ansible-tmp-1630125944.9041228-5084-251443679463658/source",
    "state": "file",
    "uid": 0
}

略略略。。。

[root@server 12:45:46~]# ansible all -m shell -a 'ls -l /test/'
192.168.64.11 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x 2 root root 22 8月  28 12:45 data
192.168.64.12 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x 2 root root 22 8月  28 12:45 data
192.168.64.10 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x 2 root root 22 8月  28 12:45 data
[root@server 12:45:54~]# ansible all -m copy -a 'src=/data/ dest=/test'
192.168.64.10 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "dest": "/test/test.txt",
    "gid": 0,
    "group": "root",
    "md5sum": "d41d8cd98f00b204e9800998ecf8427e",
    "mode": "0644",
    "owner": "root",
    "size": 0,
    "src": "/root/.ansible/tmp/ansible-tmp-1630125962.354739-5224-180881665123159/source",
    "state": "file",
    "uid": 0
}

略略略。。。

[root@server 12:46:03~]# ansible all -m shell -a 'ls -l /test/'
192.168.64.10 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x 2 root root 22 8月  28 12:45 data
-rw-r--r-- 1 root root  0 8月  28 12:46 test.txt
192.168.64.11 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x 2 root root 22 8月  28 12:45 data
-rw-r--r-- 1 root root  0 8月  28 12:46 test.txt
192.168.64.12 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x 2 root root 22 8月  28 12:45 data
-rw-r--r-- 1 root root  0 8月  28 12:46 test.txt
[root@server 12:46:15~]# 
  • fetch模块

功能:从远程主机提取文件至ansible的主控端,copy相反,目前不支持目录

范例:

[root@server 12:50:19~]# ansible all -m fetch -a 'src=/etc/os-release dest=/data'
192.168.64.10 | CHANGED => {
    "changed": true,
    "checksum": "6e35f19e5774acd00f10342edef82a8247674028",
    "dest": "/data/192.168.64.10/etc/os-release",
    "md5sum": "0868a2ea7fc0d17dec85d63f452563d4",
    "remote_checksum": "6e35f19e5774acd00f10342edef82a8247674028",
    "remote_md5sum": null
}
192.168.64.12 | CHANGED => {
    "changed": true,
    "checksum": "6e35f19e5774acd00f10342edef82a8247674028",
    "dest": "/data/192.168.64.12/etc/os-release",
    "md5sum": "0868a2ea7fc0d17dec85d63f452563d4",
    "remote_checksum": "6e35f19e5774acd00f10342edef82a8247674028",
    "remote_md5sum": null
}
192.168.64.11 | CHANGED => {
    "changed": true,
    "checksum": "6e35f19e5774acd00f10342edef82a8247674028",
    "dest": "/data/192.168.64.11/etc/os-release",
    "md5sum": "0868a2ea7fc0d17dec85d63f452563d4",
    "remote_checksum": "6e35f19e5774acd00f10342edef82a8247674028",
    "remote_md5sum": null
}
[root@server 12:51:01~]# tree /data/
/data/
├── 192.168.64.10
│   └── etc
│       └── os-release
├── 192.168.64.11
│   └── etc
│       └── os-release
├── 192.168.64.12
│   └── etc
│       └── os-release
└── test.txt

6 directories, 4 files
[root@server 12:51:11~]# 
  • file模块

功能:设置文件属性,创建软链接等

范例:

[root@server 14:57:31~]# ansible all -m shell -a 'ls -l /test'
192.168.64.10 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x 2 root root 22 8月  28 12:45 data
-rw-r--r-- 1 root root  0 8月  28 12:46 test.txt
192.168.64.11 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x 2 root root 22 8月  28 12:45 data
-rw-r--r-- 1 root root  0 8月  28 12:46 test.txt
192.168.64.12 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x 2 root root 22 8月  28 12:45 data
-rw-r--r-- 1 root root  0 8月  28 12:46 test.txt
[root@server 15:08:51~]# ansible all -m file -a  'path=/test/test.txt owner=nobody group=nobody'
192.168.64.10 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "gid": 65534,
    "group": "nobody",
    "mode": "0644",
    "owner": "nobody",
    "path": "/test/test.txt",
    "size": 0,
    "state": "file",
    "uid": 65534
}
192.168.64.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "gid": 65534,
    "group": "nobody",
    "mode": "0644",
    "owner": "nobody",
    "path": "/test/test.txt",
    "size": 0,
    "state": "file",
    "uid": 65534
}
192.168.64.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "gid": 65534,
    "group": "nobody",
    "mode": "0644",
    "owner": "nobody",
    "path": "/test/test.txt",
    "size": 0,
    "state": "file",
    "uid": 65534
}
[root@server 15:12:03~]# ansible all -m shell -a 'ls -l /test'
192.168.64.10 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x 2 root   root   22 8月  28 12:45 data
-rw-r--r-- 1 nobody nobody  0 8月  28 12:46 test.txt
192.168.64.12 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x 2 root   root   22 8月  28 12:45 data
-rw-r--r-- 1 nobody nobody  0 8月  28 12:46 test.txt
192.168.64.11 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x 2 root   root   22 8月  28 12:45 data
-rw-r--r-- 1 nobody nobody  0 8月  28 12:46 test.txt
[root@server 15:12:10~]# 
  • unarchive模块

功能:解包解压缩

实现有两种用法:

1、将ansible主机上的压缩包传到远程主机后解压缩至特定目录,设置copy=yes

2、将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no

常见参数:

copy:默认为yes,当copy=yes,拷贝的文件是从ansible主机复制到远程主机上,如果设置为copy=no,会在远程主机上寻找src源文件

remote_src:和copy功能一样且互斥,yes表示在远程主机,不在ansible主机,no表示文件在ansib1e主机上

src:源路径,可以是ansible主机上的路径,也可以是远程主机(被管理端或者第三方主机)上的路径,如果是远程主机上的路径,则需要设置copy=no

dest:远程主机上的目标路径

mode:设置解压缩后的文件权限

范例:

[root@server 21:45:19~]# tar -zcf data.tar.gz /data/
tar: 从成员名中删除开头的“/”
[root@server 21:45:40~]# ansible all -m shell -a 'ls -l /test/data'
192.168.64.10 | CHANGED | rc=0 >>
总用量 0
-rw-r--r-- 1 root root 0 8月  28 12:45 test.txt
192.168.64.11 | CHANGED | rc=0 >>
总用量 0
-rw-r--r-- 1 root root 0 8月  28 12:45 test.txt
192.168.64.12 | CHANGED | rc=0 >>
总用量 0
-rw-r--r-- 1 root root 0 8月  28 12:45 test.txt
[root@server 21:45:47~]# ansible all -m unarchive -a 'src=/root/data.tar.gz dest=/test/data/ owner=nobody'
192.168.64.10 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "dest": "/test/data/",
    "extract_results": {
        "cmd": [
            "/usr/bin/gtar",
            "--extract",
            "-C",
            "/test/data/",
            "-z",
            "--owner=nobody",
            "-f",
            "/root/.ansible/tmp/ansible-tmp-1630158354.7565894-7394-37836325727783/source"
        ],
        "err": "",
        "out": "",
        "rc": 0
    },
    "gid": 0,
    "group": "root",
    "handler": "TgzArchive",
    "mode": "0755",
    "owner": "root",
    "size": 34,
    "src": "/root/.ansible/tmp/ansible-tmp-1630158354.7565894-7394-37836325727783/source",
    "state": "directory",
    "uid": 0
}

略略略。。。

[root@server 21:45:56~]# ansible all -m shell -a 'ls -l /test/data'
192.168.64.10 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x 5 nobody root 85 8月  28 12:51 data
-rw-r--r-- 1 root   root  0 8月  28 12:45 test.txt
192.168.64.11 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x 5 nobody root 85 8月  28 12:51 data
-rw-r--r-- 1 root   root  0 8月  28 12:45 test.txt
192.168.64.12 | CHANGED | rc=0 >>
总用量 0
drwxr-xr-x 5 nobody root 85 8月  28 12:51 data
-rw-r--r-- 1 root   root  0 8月  28 12:45 test.txt
[root@server 21:46:00~]# 
  • archive模块

功能:打包压缩保存在被管理节点

范例:

[root@server 21:55:12~]# ansible all -m file -a 'path=/data_log state=directory'
192.168.64.10 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "gid": 0,
    "group": "root",
    "mode": "0755",
    "owner": "root",
    "path": "/data_log",
    "size": 6,
    "state": "directory",
    "uid": 0
}
192.168.64.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "gid": 0,
    "group": "root",
    "mode": "0755",
    "owner": "root",
    "path": "/data_log",
    "size": 6,
    "state": "directory",
    "uid": 0
}
192.168.64.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "gid": 0,
    "group": "root",
    "mode": "0755",
    "owner": "root",
    "path": "/data_log",
    "size": 6,
    "state": "directory",
    "uid": 0
}

[root@server 21:56:18~]# ansible all -m shell -a 'ls -l /data_log'
192.168.64.10 | CHANGED | rc=0 >>
总用量 0
192.168.64.12 | CHANGED | rc=0 >>
总用量 0
192.168.64.11 | CHANGED | rc=0 >>
总用量 0
[root@server 21:56:40~]# ansible all -m archive -a 'path=/test/data dest=/data_log/test.tar.gz format=gz owner=bin mode=0644'
192.168.64.10 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "archived": [
        "/test/data/test.txt",
        "/test/data/data/test.txt",
        "/test/data/data/192.168.64.10/etc/os-release",
        "/test/data/data/192.168.64.12/etc/os-release",
        "/test/data/data/192.168.64.11/etc/os-release"
    ],
    "arcroot": "/test/",
    "changed": true,
    "dest": "/data_log/test.tar.gz",
    "expanded_exclude_paths": [],
    "expanded_paths": [
        "/test/data"
    ],
    "gid": 0,
    "group": "root",
    "missing": [],
    "mode": "0644",
    "owner": "bin",
    "size": 519,
    "state": "file",
    "uid": 1
}

略略略。。。

[root@server 21:56:46~]# ansible all -m shell -a 'ls -l /data_log'
192.168.64.10 | CHANGED | rc=0 >>
总用量 4
-rw-r--r-- 1 bin root 519 8月  28 21:56 test.tar.gz
192.168.64.12 | CHANGED | rc=0 >>
总用量 4
-rw-r--r-- 1 bin root 519 8月  28 21:56 test.tar.gz
192.168.64.11 | CHANGED | rc=0 >>
总用量 4
-rw-r--r-- 1 bin root 519 8月  28 21:56 test.tar.gz
[root@server 21:56:51~]# 
  • hostname模块

功能:管理主机名

范例:

[root@server 22:08:22~]# ansible 192.168.64.11 -m shell -a 'hostname'
192.168.64.11 | CHANGED | rc=0 >>
client1
[root@server 22:08:46~]# ansible 192.168.64.11 -m hostname -a 'name=slave-64.11'
192.168.64.11 | CHANGED => {
    "ansible_facts": {
        "ansible_domain": "11",
        "ansible_fqdn": "slave-64.11",
        "ansible_hostname": "slave-64",
        "ansible_nodename": "slave-64.11",
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "name": "slave-64.11"
}
[root@server 22:08:54~]# ansible 192.168.64.11 -m shell -a 'hostname'
192.168.64.11 | CHANGED | rc=0 >>
slave-64.11
  • cron模块

功能:计划任务

支持时间:minute(分),hour(时),day(日),month(月),weekday(周)

  • yum和apt模块

功能:yum管理软件包,只THEL、centos、fedora,不支持ubuntu等其他系统版本

apt模块管理debian相关版本的软件包

范例:

安装:
[root@server 22:09:12~]# ansible all -m yum -a 'name=httpd state=present'

删除:
[root@server 22:23:06~]# ansible all -m yum -a 'name=httpd state=absent'
  • service模块

功能:管理软件服务

范例:

安装httpd服务:
[root@server 22:26:05~]# ansible all -m yum -a 'name=httpd state=present'

启动httpd服务并设置开机自启
[root@server 22:26:12~]# ansible all -m service -a 'name=httpd state=started enabled=yes'
  • group模块

功能:管理组

范例:

添加nginx组
[root@server 23:02:20~]# ansible all -m group -a 'name=nginx gid=1200 system=yes'

删除组
[root@server 23:02:31~]# ansible all -m group -a 'name=nginx state=absent'
  • user模块

功能:管理用户

范例:

先添加nginx组
[root@server 23:03:05~]# ansible all -m group -a 'name=nginx gid=1200 system=yes'

添加nginx用户
[root@server 23:03:08~]# ansible all -m user -a 'name=nginx comment=nginx uid=1200 group=nginx groups="root,daemon" shell=/sbin/nologin system=yes create_home=no home=/data/nginx non_unique=yes'

查看创建的nginx用户
[root@server 23:05:10~]# ansible all -a 'getent passwd nginx'

删除用户,顺便nginx家目录也删除
[root@server 23:05:20~]# ansible all -m user -a 'name=nginx state=absent remove=yes'
  •  lineinfile模块

1、ansible在使用sed进行替换时,经常会遇到需要转义的问题,而且ansible在遇到特殊符号进行替换时,存在问题,无法正常进行替换。其实在ansible自身提供了两个模块:lineinfile模块和replace模块,可以方便的进行替换

2、一般在ansible当中去修改某个文件的单行进行替换的时候需要使用lineinfile模块

3、regexp参数:使用正则表达式匹配对应的行,当替换文本时,如果有多行文本都能被匹配,则只有最后面被匹配到的那行文本才会被替换,当删除文本时,如果有多行文本都能被匹配,这么这些行都会被删除。

4、如果想进行多行匹配进行替换需要使用replace模块

功能:相当于sed,可以修改文件内容

范例:

[root@server 23:21:37~]# ansible all -m shell -a 'grep '^Listen' /etc/httpd/conf/httpd.conf'
192.168.64.10 | CHANGED | rc=0 >>
Listen 80
192.168.64.11 | CHANGED | rc=0 >>
Listen 80
192.168.64.12 | CHANGED | rc=0 >>
Listen 80

[root@server 23:22:34~]# ansible all -m lineinfile -a "path=/etc/httpd/conf/httpd.conf regexp='^Listen' line='Listen 8080'"
192.168.64.10 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "backup": "",
    "changed": true,
    "msg": "line replaced"
}
192.168.64.12 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "backup": "",
    "changed": true,
    "msg": "line replaced"
}
192.168.64.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "backup": "",
    "changed": true,
    "msg": "line replaced"
}

[root@server 23:22:44~]# ansible all -m shell -a 'grep '^Listen' /etc/httpd/conf/httpd.conf'
192.168.64.10 | CHANGED | rc=0 >>
Listen 8080
192.168.64.11 | CHANGED | rc=0 >>
Listen 8080
192.168.64.12 | CHANGED | rc=0 >>
Listen 8080
 
  • replace模块

该模块有点类似于sed命令,主要也是基于正则进行匹配和替换,建议使用

范例:

[root@server 23:34:57~]# cat /etc/fstab 

#
# /etc/fstab
# Created by anaconda on Sat Mar 13 00:29:06 2021
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
/dev/mapper/cl-root     /                       xfs     defaults        0 0
UUID=c72572c5-7e9e-470b-b95d-535233f69ab8 /boot                   xfs     defaults        0 0
/dev/mapper/cl-home     /home                   xfs     defaults        0 0
/dev/mapper/cl-swap     none                    swap    defaults        0 0
[root@server 23:34:58~]# ansible 192.168.64.10 -m replace -a "path=/etc/fstab regexp='^(#.*)' replace='#\1'"
192.168.64.10 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "msg": "10 replacements made"
}
[root@server 23:35:28~]# cat /etc/fstab 

##
## /etc/fstab
## Created by anaconda on Sat Mar 13 00:29:06 2021
##
## Accessible filesystems, by reference, are maintained under '/dev/disk/'.
## See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
##
## After editing this file, run 'systemctl daemon-reload' to update systemd
## units generated from this file.
##
/dev/mapper/cl-root     /                       xfs     defaults        0 0
UUID=c72572c5-7e9e-470b-b95d-535233f69ab8 /boot                   xfs     defaults        0 0
/dev/mapper/cl-home     /home                   xfs     defaults        0 0
/dev/mapper/cl-swap     none                    swap    defaults        0 0
[root@server 23:35:33~]# ansible 192.168.64.10 -m replace -a "path=/etc/fstab regexp='^#(#?.*)' replace='\1'"
192.168.64.10 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "msg": "10 replacements made"
}
[root@server 23:35:40~]# cat /etc/fstab 

#
# /etc/fstab
# Created by anaconda on Sat Mar 13 00:29:06 2021
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
/dev/mapper/cl-root     /                       xfs     defaults        0 0
UUID=c72572c5-7e9e-470b-b95d-535233f69ab8 /boot                   xfs     defaults        0 0
/dev/mapper/cl-home     /home                   xfs     defaults        0 0
/dev/mapper/cl-swap     none                    swap    defaults        0 0
  • setup模块

功能:setup模块来收集主机的系统信息,这些facts 信息可以直接以变量的形式使用,但是如果主机较多,会影响执行速度,可以使用gather_facts:no来禁止Ansible 收集facts信息

1、ansible_all_ipv4_addresses:仅显示ipv4的信息

2、ansible_devices:仅显示磁盘设备信息

3、ansible_distribution:显示是什么系统,例:centos,suse等

4、ansible_distribution_major_version:显示是系统主版本

5、ansible_distribution_version:仅显示系统版本

6、ansible_machine:显示系统类型,例:32位,还是64位

7、ansible_eth0:仅显示eth0的信息

8、ansible_hostname:仅显示主机名

9、ansible_kernel:仅显示内核版本

10、ansible_lvm:显示lvm相关信息

11、ansible_memtotal_mb:显示系统总内存

12、ansible_memfree_mb:显示可用系统内存

13、ansible_memory_mb:详细显示内存情况

14、ansible_swaptotal_mb:显示总的swap内存

15、ansible_swapfree_mb:显示swap内存的可用内存

16、ansible_mounts:显示系统磁盘挂载情况

17、ansible_processor:显示cpu个数(具体显示每个cpu的型号)

18、ansible_processor_vcpus:显示cpu个数(只显示总的个数)

[root@server 23:40:36~]# ansible all -m setup -a 'filter=ansible_processor_vcpus'
192.168.64.10 | SUCCESS => {
    "ansible_facts": {
        "ansible_processor_vcpus": 4,
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false
}
192.168.64.12 | SUCCESS => {
    "ansible_facts": {
        "ansible_processor_vcpus": 4,
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false
}
192.168.64.11 | SUCCESS => {
    "ansible_facts": {
        "ansible_processor_vcpus": 4,
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false
}
[root@server 23:45:49~]# 

五、YAML语言

YAML官方网站:http://www.yaml.org

六、ansible-playbook批量安装httpd,并修改index.html页面

[root@server 10:36:30~]# cat install_httpd.yml 
- hosts: all
  remote_user: root
  gather_facts: no

  tasks:
    - name: install httpd
      yum: name=httpd
    - name: update index.html
      shell: echo welcome $HOSTNAME > /var/www/html/index.html
    - name: start
      service: name=httpd state=started enabled=yes
[root@server 10:36:36~]# ansible-playbook install_httpd.yml 

PLAY [all] ******************************************************************************************************************

TASK [install httpd] ********************************************************************************************************
changed: [192.168.64.11]
changed: [192.168.64.10]
changed: [192.168.64.12]

TASK [update index.html] ****************************************************************************************************
changed: [192.168.64.10]
changed: [192.168.64.11]
changed: [192.168.64.12]

TASK [start] ****************************************************************************************************************
changed: [192.168.64.10]
changed: [192.168.64.12]
changed: [192.168.64.11]

PLAY RECAP ******************************************************************************************************************
192.168.64.10              : ok=3    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.64.11              : ok=3    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
192.168.64.12              : ok=3    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@server 10:36:55~]# curl http://192.168.64.10/index.html
welcome server
[root@server 10:37:44~]# curl http://192.168.64.11/index.html
welcome client1
[root@server 10:37:48~]# curl http://192.168.64.12/index.html
welcome client2
[root@server 10:37:52~]# 

7、redis编译安装

系统:

[root@centos7_192.168.64.132 21:23:39~]# cat /etc/os-release 
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

Redis安装包:redis-6.0.0.tar.gz

编译安装:

[root@centos7_192.168.64.132 21:23:51~]# mkdir /data/software -p
[root@centos7_192.168.64.132 21:23:56~]# rz -E
rz waiting to receive.
[root@centos7_192.168.64.132 21:24:01~]# ll
total 2160
-rw-------. 1 root root    1457 Nov  8  2020 anaconda-ks.cfg
-rw-r--r--  1 root root 2204177 Aug 29 21:15 redis-6.0.0.tar.gz
[root@centos7_192.168.64.132 21:24:04~]# tar zxf redis-6.0.0.tar.gz
[root@centos7_192.168.64.132 21:24:34~]# mv redis-6.0.0 /data/software/redis/
[root@centos7_192.168.64.132 21:24:34~]# cd /data/software/redis/

# 删除旧的yum源
[root@centos7_192.168.64.132 21:27:08/data/software/redis]# rm /etc/yum.repos.d/* -f

# 添加清华源
[root@centos7_192.168.64.132 21:31:19/data/software/redis]# cat /etc/yum.repos.d/CentOS-Base.repo 
# CentOS-Base.repo

[base]
name=CentOS-$releasever - Base
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
 
[updates]
name=CentOS-$releasever - Updates
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
 
[extras]
name=CentOS-$releasever - Extras
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
 
[centosplus]
name=CentOS-$releasever - Plus
baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

[root@centos7_192.168.64.132 21:31:27/data/software/redis]# yum -y install epel-release.noarch

[root@centos7_192.168.64.132 21:32:36/data/software/redis]# yum -y install centos-release-scl gcc gcc-c++

[root@centos7_192.168.64.132 21:34:16/data/software/redis]# yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils

[root@centos7_192.168.64.132 21:34:55/data/software/redis]# scl enable devtoolset-9 bash

[root@centos7_192.168.64.132 21:35:20/data/software/redis]# echo "source /opt/rh/devtoolset-9/enable" >> /etc/profile

[root@centos7_192.168.64.132 21:35:38/data/software/redis]# make install PREFIX=/data/software/redis

[root@centos7_192.168.64.132 21:37:07/data/software/redis]# cat > /data/software/redis/redis.conf <<EOF
bind 127.0.0.1
requirepass OhpJvZPY4Y8rcBKZMe43m5w6WhjJwkFxgKS77YX3EoWS7gAhK
protected-mode yes
tcp-backlog 500
unixsocket /data/software/redis/tmp/redis.sock
timeout 0
daemonize no
supervised auto
pidfile /data/software/redis/run/redis.pid
loglevel notice
logfile "/data/software/redis/log/redis.log"
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data/software/redis/data
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
EOF

[root@centos7_192.168.64.132 21:37:52/data/software/redis]# cd /data/software/redis && mkdir data log tmp

[root@centos7_192.168.64.132 21:37:58/data/software/redis]# /data/software/redis/bin/redis-server /data/software/redis/redis.conf &
[1] 6149

[root@centos7_192.168.64.132 21:38:00/data/software/redis]# cat > /etc/profile.d/redis_home.sh <<EOF
> REDIS_HOME=/data/software/redis
> export PATH=\$PATH:\$REDIS_HOME/bin
> EOF

[root@centos7_192.168.64.132 21:38:06/data/software/redis]# source /etc/profile

[root@centos7_192.168.64.132 21:38:48/data/software/redis]# echo '/data/software/redis/bin/redis-server /data/software/redis/redis.conf &' >> /etc/rc.local 

[root@centos7_192.168.64.132 21:38:58/data/software/redis]# chmod +x /etc/rc.local /etc/rc.d/rc.local

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值