Skip to content

MySQL Ansible集成

Ansible简介

Ansible是一款开源的自动化工具,用于配置管理、应用部署和任务自动化。它采用无代理架构,通过SSH协议与目标主机通信,具有简单易用、高效可靠的特点。

MySQL与Ansible集成的优势

  • 自动化部署:实现MySQL的一键部署,减少人为错误
  • 配置一致性:确保所有MySQL实例配置统一
  • 批量操作:支持同时管理多个MySQL节点
  • 版本控制:配置文件可纳入版本控制系统
  • 审计追踪:记录所有操作历史,便于审计
  • 跨平台支持:支持多种操作系统和MySQL版本

核心组件

Ansible模块

  • mysql_db:管理MySQL数据库(创建、删除、备份等)
  • mysql_user:管理MySQL用户和权限
  • mysql_variables:管理MySQL系统变量
  • mysql_replication:管理MySQL复制关系
  • mysql_info:收集MySQL实例信息

Ansible角色

  • geerlingguy.mysql:社区广泛使用的MySQL角色,支持多种安装方式
  • database/mysql:企业级MySQL角色,支持复杂配置和高可用

安装与配置

安装Ansible

Ansible支持多种安装方式,以下是在不同操作系统上的安装命令:

bash
# CentOS/RHEL系统使用yum安装
 yum install ansible -y

# Ubuntu/Debian系统使用apt安装
apt-get install ansible -y

# 使用Python包管理器pip安装最新版本
pip install ansible

安装完成后,可以使用ansible --version命令验证安装是否成功,确保Ansible版本符合要求。

配置Ansible

Ansible的配置包括两个主要部分:主配置文件ansible.cfg和主机清单文件。

  1. 编辑ansible.cfg主配置文件

ansible.cfg文件包含Ansible的全局配置,以下是常用配置项:

ini
[defaults]
# 指定主机清单文件位置
inventory = /etc/ansible/hosts
# 远程连接使用的默认用户名
remote_user = root
# 禁用主机密钥检查(生产环境建议启用)
host_key_checking = False
  1. 配置主机清单

主机清单文件用于定义要管理的主机和主机组。以下是一个MySQL服务器主机清单示例:

ini
# 定义MySQL服务器组
[mysql_servers]
# 主机别名 ansible_host=实际IP地址
db1 ansible_host=192.168.1.101
db2 ansible_host=192.168.1.102
db3 ansible_host=192.168.1.103

# 为MySQL服务器组设置变量
[mysql_servers:vars]
# 指定远程Python解释器路径
ansible_python_interpreter=/usr/bin/python3

配置完成后,可以使用ansible all -m ping命令测试与所有主机的连接性。

自动化部署MySQL

使用geerlingguy.mysql角色

geerlingguy.mysql是社区广泛使用的MySQL Ansible角色,支持多种安装方式和配置选项。以下是使用该角色部署MySQL的步骤:

  1. 创建playbook部署脚本
yaml
---
- name: 部署MySQL服务器
  hosts: mysql_servers  # 指定要部署的主机组
  become: yes  # 启用特权升级
  roles:
    - geerlingguy.mysql  # 使用geerlingguy.mysql角色
  vars:
    mysql_root_password: "your_secure_password"  # 设置root密码
    mysql_databases:  # 定义要创建的数据库
      - name: example_db  # 数据库名称
        encoding: utf8mb4  # 字符集
        collation: utf8mb4_unicode_ci  # 排序规则
    mysql_users:  # 定义要创建的用户
      - name: example_user  # 用户名
        password: "user_password"  # 用户密码
        priv: "example_db.*:ALL"  # 授权权限
        host: "%"  # 允许访问的主机
    mysql_bind_address: "0.0.0.0"  # 绑定地址
    mysql_port: 3306  # 端口号
  1. 执行playbook部署

在playbook文件所在目录执行以下命令,启动MySQL自动化部署:

bash
ansible-playbook mysql_deploy.yml

部署完成后,Ansible会自动处理MySQL的安装、配置、数据库和用户创建等所有步骤,无需手动干预。

配置管理

管理MySQL配置文件

yaml
---
- name: 配置MySQL
  hosts: mysql_servers
  become: yes
  tasks:
    - name: 复制MySQL配置文件
      template:
        src: my.cnf.j2
        dest: /etc/mysql/my.cnf
        owner: mysql
        group: mysql
        mode: 0644
      notify:
        - 重启MySQL服务

  handlers:
    - name: 重启MySQL服务
      service:
        name: mysql
        state: restarted

管理MySQL用户和权限

yaml
---
- name: 管理MySQL用户
  hosts: mysql_servers
  become: yes
  tasks:
    - name: 创建MySQL用户
      mysql_user:
        name: app_user
        password: "secure_password"
        priv: "app_db.*:SELECT,INSERT,UPDATE,DELETE"
        host: "192.168.1.%"
        state: present
        login_user: root
        login_password: "root_password"

    - name: 撤销用户权限
      mysql_user:
        name: old_user
        priv: "*.*:ALL"
        state: absent
        login_user: root
        login_password: "root_password"

数据库管理

创建和管理数据库

yaml
---
- name: 管理MySQL数据库
  hosts: mysql_servers
  become: yes
  tasks:
    - name: 创建数据库
      mysql_db:
        name: new_db
        encoding: utf8mb4
        collation: utf8mb4_unicode_ci
        state: present
        login_user: root
        login_password: "root_password"

    - name: 备份数据库
      mysql_db:
        name: app_db
        state: dump
        target: /backup/app_db.sql
        login_user: root
        login_password: "root_password"

    - name: 恢复数据库
      mysql_db:
        name: app_db
        state: import
        target: /backup/app_db.sql
        login_user: root
        login_password: "root_password"

复制管理

配置主从复制

yaml
---
- name: 配置MySQL主从复制
  hosts: mysql_servers
  become: yes
  tasks:
    - name: 在主库上创建复制用户
      mysql_user:
        name: repl_user
        password: "repl_password"
        priv: "*.*:REPLICATION SLAVE,REPLICATION CLIENT"
        host: "192.168.1.%"
        state: present
        login_user: root
        login_password: "root_password"
      when: inventory_hostname == "db1"

    - name: 获取主库状态
      mysql_replication:
        mode: getmaster
        login_user: root
        login_password: "root_password"
      register: master_status
      when: inventory_hostname == "db1"

    - name: 配置从库
      mysql_replication:
        mode: changemaster
        master_host: "192.168.1.101"
        master_user: "repl_user"
        master_password: "repl_password"
        master_log_file: "{{ hostvars['db1']['master_status']['File'] }}"
        master_log_pos: "{{ hostvars['db1']['master_status']['Position'] }}"
        login_user: root
        login_password: "root_password"
      when: inventory_hostname != "db1"

    - name: 启动从库复制
      mysql_replication:
        mode: startslave
        login_user: root
        login_password: "root_password"
      when: inventory_hostname != "db1"

监控与维护

收集MySQL信息

yaml
---
- name: 收集MySQL信息
  hosts: mysql_servers
  become: yes
  tasks:
    - name: 获取MySQL状态
      mysql_info:
        login_user: root
        login_password: "root_password"
      register: mysql_status

    - name: 输出MySQL版本
      debug:
        msg: "MySQL版本: {{ mysql_status['version']['version'] }}"

    - name: 输出数据库列表
      debug:
        msg: "数据库列表: {{ mysql_status['databases'] }}"

定期维护任务

yaml
---
- name: MySQL定期维护
  hosts: mysql_servers
  become: yes
  tasks:
    - name: 执行OPTIMIZE TABLE
      mysql_db:
        name: "{{ item }}"
        state: optimize
        login_user: root
        login_password: "root_password"
      loop: "{{ mysql_databases }}"
      when: item != "information_schema" and item != "performance_schema" and item != "sys"

    - name: 执行ANALYZE TABLE
      mysql_db:
        name: "{{ item }}"
        state: analyze
        login_user: root
        login_password: "root_password"
      loop: "{{ mysql_databases }}"
      when: item != "information_schema" and item != "performance_schema" and item != "sys"

最佳实践

安全性

  • 使用Ansible Vault加密敏感信息
  • 遵循最小权限原则
  • 定期更新Ansible和MySQL角色
  • 启用SSH密钥认证

性能优化

  • 使用异步执行长任务
  • 合理设置forks数量
  • 使用本地连接管理大量MySQL实例
  • 缓存facts减少远程调用

版本兼容性

  • 测试不同MySQL版本的兼容性
  • 使用条件语句处理版本差异
  • 保持Ansible版本与MySQL版本的兼容性

常见问题(FAQ)

Q1: Ansible无法连接到MySQL服务器怎么办?

A1: 检查以下几点:

  • 确保SSH连接正常
  • 验证MySQL服务正在运行
  • 检查MySQL用户密码是否正确
  • 确认MySQL允许远程连接
  • 检查防火墙设置

Q2: 如何处理不同版本MySQL的配置差异?

A2: 使用Ansible的条件语句:

yaml
- name: 配置MySQL 8.0
  template:
    src: my.cnf.8.0.j2
    dest: /etc/mysql/my.cnf
  when: mysql_version is version('8.0', '>=')

- name: 配置MySQL 5.7
  template:
    src: my.cnf.5.7.j2
    dest: /etc/mysql/my.cnf
  when: mysql_version is version('5.7', '==')

Q3: 如何加密Ansible中的敏感信息?

A3: 使用Ansible Vault:

bash
# 创建加密文件
ansible-vault create secrets.yml

# 编辑加密文件
ansible-vault edit secrets.yml

# 执行playbook时使用加密文件
ansible-playbook mysql_deploy.yml --ask-vault-pass

Q4: 如何批量执行SQL脚本?

A4: 使用mysql_db模块或shell模块:

yaml
- name: 执行SQL脚本
  mysql_db:
    name: app_db
    state: import
    target: /path/to/script.sql
    login_user: root
    login_password: "root_password"

# 或使用shell模块
- name: 执行SQL脚本
  shell: mysql -u root -p"root_password" app_db < /path/to/script.sql

Q5: 如何管理MySQL集群?

A5: 使用专门的集群管理角色或模块:

  • 对于MySQL Group Replication,使用mysql_replication模块
  • 对于Percona XtraDB Cluster,使用专门的Ansible角色
  • 对于MySQL NDB Cluster,使用ndb_mgm命令结合Ansible