告别手动rpm!用Ansible在银河麒麟V10集群里批量部署MySQL 8.0
在国产化操作系统浪潮中,银河麒麟V10凭借其安全稳定的特性,正逐步成为企业级基础设施的新选择。当面对数十台甚至上百台服务器需要部署MySQL数据库时,传统的手动安装方式不仅效率低下,更难以保证配置的一致性。本文将带你体验如何通过Ansible实现一键式自动化部署,让繁琐的rpm安装流程成为历史。
1. 为什么选择Ansible进行批量部署
在国产化环境中部署MySQL 8.0,通常会遇到三个典型痛点:系统依赖冲突、安装流程复杂、多节点配置一致性难以保证。手动操作不仅需要逐台登录服务器,还要重复执行相同的命令序列,既容易出错又耗费时间。
Ansible的核心优势在于:
- 无代理架构:通过SSH直接管理节点,无需在目标机器安装额外服务
- 幂等性设计:Playbook可重复执行且结果一致
- 声明式语法:用YAML描述最终状态而非具体步骤
对比传统部署方式:
| 对比维度 | 手动rpm安装 | Ansible自动化部署 |
|---|---|---|
| 10节点耗时 | 约2小时 | 15分钟 |
| 配置一致性 | 依赖人工检查 | 剧本保证 |
| 回滚难度 | 复杂 | 版本控制简单 |
| 可审计性 | 操作记录分散 | 完整执行日志 |
提示:银河麒麟V10基于CentOS 8开发,但部分系统路径和软件包命名存在差异,需要特别处理
2. 环境准备与前置检查
2.1 配置Ansible控制节点
首先确保控制机已安装Ansible 2.9+版本,并配置对麒麟节点的SSH免密访问:
# 安装Ansible yum install -y ansible # 生成SSH密钥对 ssh-keygen -t rsa -b 4096 # 批量分发公钥 for ip in $(cat hosts); do ssh-copy-id -i ~/.ssh/id_rsa.pub root@$ip done创建主机清单文件inventory.ini,按功能分组管理服务器:
[db_servers] node[1:10].example.com ansible_user=root [db_servers:vars] ansible_ssh_private_key_file=~/.ssh/id_rsa2.2 编写系统检查Playbook
创建precheck.yml验证目标系统环境:
- name: Verify Kylin V10 environment hosts: db_servers tasks: - name: Check OS version command: cat /etc/os-release register: os_info changed_when: false - name: Validate architecture assert: that: ansible_architecture == 'x86_64' fail_msg: "仅支持x86_64架构" - name: Check existing MySQL packages shell: rpm -qa | grep -E 'mysql|mariadb' register: conflict_pkgs ignore_errors: yes - name: Report conflicts debug: msg: "需要移除冲突包: {{ conflict_pkgs.stdout_lines }}" when: conflict_pkgs.stdout != ""执行预检查并保存报告:
ansible-playbook -i inventory.ini precheck.yml --tags precheck3. 自动化部署Playbook设计
3.1 核心任务分解
完整的部署流程应包含以下阶段:
- 环境清理:移除冲突的MariaDB组件
- 软件包分发:传输MySQL RPM包到各节点
- 顺序安装:解决rpm依赖关系
- 服务配置:初始化数据库和安全加固
- 验证测试:确保服务可用性
3.2 主Playbook实现
创建deploy_mysql.yml文件:
- name: Deploy MySQL 8.0 on Kylin V10 hosts: db_servers vars: mysql_version: 8.0.33 install_dir: /opt/mysql tasks: - name: Remove conflict packages yum: name: "{{ item }}" state: absent loop: - mariadb-connector-c - mariadb-server - mariadb-common - name: Create installation directory file: path: "{{ install_dir }}" state: directory mode: 0755 - name: Upload RPM bundle unarchive: src: /path/to/local/mysql-{{ mysql_version }}-1.el8.x86_64.rpm-bundle.tar dest: "{{ install_dir }}" remote_src: no - name: Install dependencies yum: name: [libaio, net-tools, perl-Data-Dumper] state: present - name: Install MySQL components command: > rpm -ivh {{ install_dir }}/mysql-community-{{ item }}-{{ mysql_version }}-1.el8.x86_64.rpm loop: - common - client-plugins - libs - client - icu-data-files - server args: creates: /usr/sbin/mysqld - name: Initialize MySQL shell: | chown -R mysql:mysql /var/lib/mysql systemctl start mysqld temp_pass=$(grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}') mysql -u root -p"$temp_pass" --connect-expired-password \ -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ new_root_password }}'; CREATE USER '{{ admin_user }}'@'%' IDENTIFIED BY '{{ admin_password }}'; GRANT ALL PRIVILEGES ON *.* TO '{{ admin_user }}'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES;" args: executable: /bin/bash no_log: true # 保护密码不输出到日志 when: not mysql_initialized.stat.exists - name: Enable service systemd: name: mysqld enabled: yes state: started注意:实际使用时应将密码变量通过Ansible Vault加密存储
4. 高级配置与优化技巧
4.1 安全加固方案
在tasks中添加安全配置任务:
- name: Apply security hardening template: src: templates/my.cnf.j2 dest: /etc/my.cnf owner: root group: root mode: 0644 notify: restart mysql - name: Remove test databases mysql_query: login_user: root login_password: "{{ new_root_password }}" query: "DROP DATABASE IF EXISTS test"示例模板templates/my.cnf.j2:
[mysqld] # 基础安全配置 skip-name-resolve = ON local-infile = OFF symbolic-links = OFF # 性能优化 innodb_buffer_pool_size = {{ ansible_memtotal_mb * 0.6 }}M max_connections = 5004.2 多版本控制策略
使用Ansible Collections管理不同MySQL版本:
ansible-galaxy collection install community.mysql创建版本化的Playbook结构:
mysql-deploy/ ├── vars/ │ ├── 8.0.yml │ └── 5.7.yml ├── templates/ │ └── my.cnf.j2 └── deploy.yml通过--extra-vars指定版本:
ansible-playbook deploy.yml -e "@vars/8.0.yml"5. 验证与故障排查
5.1 自动化测试方案
添加验证任务:
- name: Verify MySQL installation block: - name: Check service status command: systemctl is-active mysqld register: service_status changed_when: false - name: Test connection mysql_query: login_user: "{{ admin_user }}" login_password: "{{ admin_password }}" query: "SELECT VERSION()" register: mysql_version - name: Show summary debug: msg: | MySQL {{ mysql_version.results[0].data[0]['VERSION()'] }} 已成功部署 服务状态: {{ service_status.stdout }} 监听端口: 33065.2 常见问题处理
依赖冲突解决:
- name: Handle libssl conflict yum: name: openssl-libs state: latest when: "'libssl.so.10()(64bit)' in rpm_install_errors"磁盘空间检查:
- name: Validate disk space assert: that: - ansible_facts['devices']['vda']['size'] > 50 fail_msg: "根分区需要至少50GB空间"通过ansible-playbook --step可以交互式执行每个任务,便于调试复杂场景。对于大规模部署,建议结合Tower或AWX提供可视化管理和审计功能。