背景与目标
人工逐台登录、改配置、查状态,既慢又容易不一致;一台机器配错了,往往要到出故障时才发现。
目标:把日常重复工作沉淀成代码,并且保证重复执行是安全的——跑一次和跑十次结果一样。
架构
- Ansible rolesbaseline · web · redis
- 新服务器账号 · SSH 加固 · 防火墙 · Nginx · Redis
- 重复执行changed=0
- cron每天 09:00
- Python 巡检调用 Prometheus API
- Alertmanager推送通知
- 多阶段构建约 300MB → 15MB
- ComposeNginx · Go · MySQL · Redis
- TerraformDocker provider
关键做法
- 01
Shell 巡检与备份
巡检脚本通过 SSH 批量检查磁盘、内存、负载、关键服务和 MySQL 主从状态,按阈值输出告警,用退出码对接其他自动化。备份脚本带校验和保留策略,用 pipefail 防止"备份失败却留下空文件"。
- 02
Ansible role 交付新机器
把系统初始化、Nginx、Redis 封装成三个 role,使用 Jinja2 模板和分层变量,密码用 Vault 加密;先 --check --diff 预演,再正式执行。
- 03
Python 运维工具
调用 Prometheus HTTP API 生成多主机巡检报告,异常推送到 Alertmanager;用 paramiko + 线程池并发执行命令,单台失败不影响整体;venv + requirements.txt 管理依赖。
- 04
Docker 镜像与编排
多阶段构建、非 root 运行、带健康检查。Compose 用健康检查控制启动顺序,前端 / 后端两个网络隔离数据库,通过 MySQL 参数和容器内存上限在 1GB 内存的主机上稳定运行。
- 05
Terraform 管理容器
用 Docker provider 通过 SSH 管理远端容器,完整练习 plan / apply / destroy、扩容、修改配置和漂移检测。
遇到的问题
Terraform 每次 plan 都显示有差异
- 原因
- memory_swap、log_opts 没在代码里写明,实际值来自 Docker 的 daemon.json
- 解决
- 把实际值写进代码,plan 不再有变化
Compose 扩容后,新副本收不到请求
- 原因
- Nginx 只在启动时解析一次服务名
- 解决
- 重启 Nginx 后请求轮流分到两个副本;生产中可用 resolver 动态解析
Docker 映射的端口绕过了 ufw
- 原因
- Docker 直接写 iptables 规则,先于 ufw 生效
- 解决
- 端口只绑定 127.0.0.1 或内网地址
容器里 nslookup 报 NXDOMAIN,但程序能连上数据库
- 原因
- busybox 的 nslookup 会拼接宿主机的搜索域
- 解决
- 改用 getent hosts,与程序的解析方式一致
结果
- 新服务器一条命令完成交付,重复执行 changed=0
- 每天 9 点自动生成巡检报告,异常直接推送告警
- 应用镜像约 300MB → 15MB,在 1GB 内存主机上稳定运行
- 基础设施变更先 plan 再 apply,配置漂移可被发现