单文件 Ansible Playbook:一键部署 MySQL 5.7 主从集群(CentOS 7)
这个 Playbook 直接在一个文件中完成所有操作,包括:
- 配置 SSH 免密登录(Ansible 控制机到所有节点)。
- 安装 MySQL 5.7(使用官方 Yum 仓库)。
- 配置主从复制(一主二从,GTID 模式)。
- 自动初始化复制关系。
1. Playbook 文件 (deploy_mysql_ha.yml)
---
- name: Configure SSH Key-Based Authentication
hosts: all
tasks:
- name: Generate SSH key on control node (if not exists)
openssh_keypair:
path: ~/.ssh/id_rsa
type: rsa
size: 2048
state: present
- name: Copy public key to all MySQL nodes
authorized_key:
user: "{{ ansible_user | default('root') }}"
state: present
key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
- name: Deploy MySQL 5.7 Master-Slave Cluster
hosts: mysql
become: yes
vars:
mysql_version: "5.7"
mysql_root_password: "Secure@123" # 生产环境请改为复杂密码
mysql_repl_user: "repl_user"
mysql_repl_password: "Repl@123" # 复制账号密码
mysql_master_ip: "{{ hostvars['mysql-master']['ansible_host'] }}"
mysql_slave_ips: "{{ groups['slaves'] | map('extract', hostvars, 'ansible_host') | list }}"
tasks:
# 安装 MySQL 5.7
- name: Add MySQL 5.7 Yum Repository
yum_repository:
name: mysql57-community
description: MySQL 5.7 Community Repository
baseurl: https://repo.mysql.com/yum/mysql-5.7-community/el/7/$basearch/
gpgkey: https://repo.mysql.com/RPM-GPG-KEY-mysql
gpgcheck: yes
enabled: yes
- name: Install MySQL Server
yum:
name: mysql-community-server
state: present
enablerepo: mysql57-community
- name: Start and Enable MySQL Service
service:
name: mysqld
state: started
enabled: yes
- name: Get temporary root password
shell: grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}'
register: mysql_temp_password
ignore_errors: yes # 首次安装可能没有临时密码
- name: Change MySQL root password
mysql_user:
login_user: root
login_password: "{{ mysql_temp_password.stdout | default('') }}"
name: root
password: "{{ mysql_root_password }}"
host: localhost
priv: "*.*:ALL,GRANT"
state: present
when: mysql_temp_password.stdout != ""
# 配置主库
- name: Configure Master my.cnf
template:
src: |
[mysqld]
server-id = 1
log_bin = mysql-bin
binlog_format = ROW
expire_logs_days = 7
sync_binlog = 1
gtid_mode = ON
enforce_gtid_consistency = ON
binlog_group_commit_sync_delay = 100
binlog_group_commit_sync_no_delay_count = 10
dest: /etc/my.cnf
owner: root
group: root
mode: 0644
when: inventory_hostname in groups['master']
# 配置从库
- name: Configure Slave my.cnf
template:
src: |
[mysqld]
server-id = {{ 100 + ansible_hostname.split('-')[-1] | int }}
log_bin = mysql-bin
binlog_format = ROW
gtid_mode = ON
enforce_gtid_consistency = ON
log_slave_updates = ON
read_only = ON
skip_slave_start = 1
relay_log = mysql-relay-bin
dest: /etc/my.cnf
owner: root
group: root
mode: 0644
when: inventory_hostname in groups['slaves']
- name: Restart MySQL to apply config
service:
name: mysqld
state: restarted
# 主库操作:创建复制用户
- name: On Master - Create replication user
mysql_user:
login_user: root
login_password: "{{ mysql_root_password }}"
name: "{{ mysql_repl_user }}"
password: "{{ mysql_repl_password }}"
host: "%"
priv: "REPLICATION SLAVE,REPLICATION CLIENT"
state: present
when: inventory_hostname in groups['master']
# 从库操作:配置主从复制
- name: On Slaves - Configure replication
mysql_query:
login_user: root
login_password: "{{ mysql_root_password }}"
query: |
CHANGE MASTER TO
MASTER_HOST='{{ mysql_master_ip }}',
MASTER_USER='{{ mysql_repl_user }}',
MASTER_PASSWORD='{{ mysql_repl_password }}',
MASTER_AUTO_POSITION=1;
when: inventory_hostname in groups['slaves']
- name: On Slaves - Start replication
mysql_query:
login_user: root
login_password: "{{ mysql_root_password }}"
query: "START SLAVE;"
when: inventory_hostname in groups['slaves']
- name: On Slaves - Check replication status
mysql_query:
login_user: root
login_password: "{{ mysql_root_password }}"
query: "SHOW SLAVE STATUS\G"
register: slave_status
when: inventory_hostname in groups['slaves']2. Inventory 文件 (inventory.ini)
[master]
mysql-master ansible_host=192.168.1.101 # 主库IP
[slaves]
mysql-slave1 ansible_host=192.168.1.102 # 从库1
mysql-slave2 ansible_host=192.168.1.103 # 从库2
[mysql:children]
master
slaves
[mysql:vars]
ansible_user=root # 建议使用 root 或具有 sudo 权限的用户
ansible_ssh_private_key_file=~/.ssh/id_rsa3. 执行 Playbook
# 首次运行前先测试 SSH 连接
ansible all -m ping -i inventory.ini
# 执行 Playbook
ansible-playbook -i inventory.ini deploy_mysql_ha.yml4. 验证主从复制
# 在主库上检查二进制日志状态
mysql -uroot -pSecure@123 -e "SHOW MASTER STATUS\G"
# 在从库上检查复制状态
mysql -uroot -pSecure@123 -e "SHOW SLAVE STATUS\G" | grep -E "Running|Seconds_Behind"关键点解析
SSH 免密登录
- 使用
openssh_keypair模块生成密钥,并通过authorized_key模块分发公钥。
- 使用
MySQL 5.7 安装
- 使用官方 Yum 仓库,避免 CentOS 7 默认仓库的旧版本问题。
GTID 复制
- 主库和从库均启用
gtid_mode=ON,确保数据一致性。
- 主库和从库均启用
自动化主从配置
- 动态获取主库 IP,自动配置从库。
单文件设计
- 所有任务和模板直接嵌入 Playbook,无需额外文件或 Role。
这个 Playbook 可以直接用于生产环境,只需修改 inventory.ini 中的 IP 地址和 mysql_root_password 等变量即可。
作者:严锋 创建时间:2025-10-24 08:22
最后编辑:严锋 更新时间:2025-11-04 14:01
最后编辑:严锋 更新时间:2025-11-04 14:01