如何在自动化运维中快速完成MySQL环境搭建 运维平台数据库环境搭建与脚本联动配置

1次阅读

docker run 一行命令可启动可联动的 mysql 容器实例,需指定端口、root 密码、数据库名、数据卷及配置文件,并设置 bind-address=0.0.0.0;ansible 需 wait_for 端口通+docker exec 查询双重探测就绪;python 脚本应校验 rowcount 并安全调用下游;必须创建 % 用户授权且开启 ip_forward。

如何在自动化运维中快速完成MySQL环境搭建 运维平台数据库环境搭建与脚本联动配置

MySQL 容器化部署:用 docker run 一行命令启动可联动的实例

别折腾源码编译或 deb/rpm 包安装,自动化运维场景下,容器是最快最干净的 MySQL 环境来源。关键不是“能不能跑”,而是“能不能被脚本立刻识别并操作”。

直接运行以下命令即可获得一个带固定端口、预设 root 密码、支持远程连接的基础实例:

docker run -d    --name mysql-prod    -p 3306:3306    -e MYSQL_ROOT_PASSWORD=Abc123!    -e MYSQL_DATABASE=opsdb    -v /data/mysql:/var/lib/mysql    -v $(pwd)/my.cnf:/etc/mysql/my.cnf    --restart=always    mysql:8.0.33
  • MYSQL_DATABASE 必须显式设置,否则脚本调用 mysql -e "USE opsdb" 会失败
  • 挂载 my.cnf 时确保包含 bind-address = 0.0.0.0skip-host-cache,否则 Python 的 pymysql 或 Ansible 的 mysql_db 模块连不上
  • 容器名(--name mysql-prod)要固定,后续脚本用 docker exec mysql-prod mysql ... 直接交互,比查 IP 更稳定

Ansible 脚本如何自动等待 MySQL 就绪并执行建表

刚启动的容器里 MySQL 进程未必已监听 3306,直接执行 SQL 会报 Can't connect to local MySQL server。不能靠 sleep 固定秒数,得用幂等探测。

在 playbook 中插入一个任务块,用 wait_for 等端口通 + command 执行简单查询双重确认:

- name: Wait for MySQL to be ready   wait_for:     host: 127.0.0.1     port: 3306     timeout: 60 <ul><li>name: Verify MySQL accepts queries command: docker exec mysql-prod mysql -uroot -pAbc123! -e "SELECT 1" register: mysql_test until: mysql_test.rc == 0 retries: 10 delay: 3
  • 必须用 docker exec 而非 mysql 命令本地直连,避免依赖宿主机装客户端
  • until/retries 比单纯 wait_for 更可靠——有些镜像启动后端口已通但 mysqld 还没完成初始化
  • 密码写在命令行有日志泄露风险,生产环境应改用 mysql_config_editor 或 Vault 注入 ~/.my.cnf

Python 脚本调用 MySQL 并触发下游任务的最小可行链路

运维平台常需“入库即触发”,比如写入一条采集任务记录后,立刻调用 Celery 或 shell 脚本执行采集。重点在于事务边界清晰、错误不静默。

pymysql 插入后显式检查影响行数,并用 subprocess.run 启动外部命令:

import pymysql import subprocess <p>conn = pymysql.connect( host='127.0.0.1', port=3306, user='root', password='Abc123!', database='opsdb' ) with conn.cursor() as cur: cur.execute("INSERT INTO tasks (host, cmd) VALUES (%s, %s)", ('web01', 'df -h')) if cur.rowcount != 1: raise RuntimeError("Failed to insert task") conn.commit()</p><h1>触发下游</h1><p>result = subprocess.run(['./run_collector.sh', str(cur.lastrowid)], capture_output=True, text=True) if result.returncode != 0: print("Downstream failed:", result.stderr)
  • 务必用 cur.rowcount 校验,避免因唯一键冲突等导致“看似成功实则未写入”
  • subprocess.run 要设 capture_output=True,否则错误直接丢进黑洞
  • 不要在 Python 里拼接 SQL 字符串传参,哪怕参数来自内部变量——防止未来逻辑扩展时引入注入漏洞

权限与网络隔离:为什么脚本总连不上,却查不出原因

最常卡住的地方不是语法或路径,而是 MySQL 默认拒绝 root 从非 localhost 连接,且 Docker 默认网络模式会让宿主机访问容器端口受 iptables 规则干扰。

两个必须做的动作:

  • 容器启动后,进容器执行:mysql -uroot -pAbc123! -e "CREATE USER 'ops'@'%' IDENTIFIED BY 'Xyz456!'; GRANT ALL ON opsdb.* TO 'ops'@'%'; FLUSH PRIVILEGES;"
  • 检查宿主机是否禁用了转发:sysctl net.ipv4.ip_forward 应返回 1;若为 0,临时开启:sudo sysctl -w net.ipv4.ip_forward=1

这两步漏掉任何一项,Connection refusedaccess denied 错误都会让你花半小时翻日志,其实只缺一条授权语句或一个内核参数。

text=ZqhQzanResources