Ansible生产调优与故障排查全攻略

一、Ansible 生产调优(Performance & Reliability)

1.1 控制并发与连接池(关键!)

默认 Ansible 是 串行执行,效率极低。生产环境必须调优:

复制代码
# ansible.cfg
[defaults]
# 最大并发主机数(根据控制机资源调整,建议 10~50)
forks = 30

# SSH 连接复用(大幅提升速度)
[ssh_connection]
# 启用 ControlPersist(保持 SSH 连接复用)
ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s
# 禁用 SSH 策略检查(避免首次连接卡住)
control_path = /tmp/ansible-%%r@%%h:%%p
pipelining = True  # 减少 SSH 调用次数(需关闭 requiretty)

前提:目标机 /etc/sudoers禁用 requiretty

复制代码
# 在目标机执行
sed -i 's/^Defaults.*requiretty/#Defaults requiretty/' /etc/sudoers

1.2 使用 async + poll 处理长任务

避免任务超时(如大文件下载、编译):

复制代码
- name: 异步下载大文件(不阻塞)
  command: wget -O /tmp/bigfile.tar.gz https://example.com/bigfile.tar.gz
  async: 3600    # 最大运行时间(秒)
  poll: 0        # 立即返回,不等待
  register: download_job

- name: 等待下载完成
  async_status:
    jid: "{{ download_job.ansible_job_id }}"
  register: job_result
  until: job_result.finished
  retries: 300
  delay: 10

1.3 启用事实缓存(Fact Caching)

避免重复收集 ansible_facts(耗时操作):

复制代码
# ansible.cfg
[defaults]
# 启用事实缓存(使用 JSON 文件)
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_fact_cache
fact_caching_timeout = 86400  # 缓存 24 小时

适用于大规模集群,首次执行后后续 playbook 速度提升 30%+


1.4 限制资源消耗(避免控制机 OOM)

复制代码
# ansible.cfg
[defaults]
# 限制内存使用(通过环境变量)
# 在执行前设置:export ANSIBLE_FORKS=20
# 或使用 systemd 限制控制机资源

建议:Ansible 控制机单独部署,不要与业务混用


二、生产级日志与审计

2.1 完整日志记录

复制代码
# ansible.cfg
[defaults]
log_path = ./logs/ansible-{{ lookup('pipe', 'date +%Y%m%d-%H%M') }}.log

日志包含:时间、主机、任务、状态、变更内容

2.2 启用回调插件(Callback Plugins)

复制代码
# ansible.cfg
[defaults]
# 显示任务耗时(定位慢任务)
callback_whitelist = profile_tasks, timer, mail

# 可选:发送失败邮件(需配置 SMTP)
# [callback_mail]
# smtp_server = smtp.example.com
# ...

2.3 使用 --diff 查看配置变更

复制代码
ansible-playbook site.yml --diff

输出文件内容差异(如配置文件修改),便于审计。


三、常见生产故障 & 排查方法(真实案例)

故障 1:UNREACHABLE! "Failed to connect to the host via ssh"

排查步骤:
复制代码
# 1. 手动测试 SSH
ssh deploy@192.168.1.101

# 2. 检查 SSH 密钥权限
ls -l ~/.ssh/id_rsa        # 应为 600
ls -l ~/.ssh/authorized_keys # 目标机应为 600

# 3. 检查 SELinux(CentOS)
getenforce  # 若为 Enforcing,临时关闭测试
setenforce 0

# 4. 检查防火墙
ansible all -m shell -a "systemctl status firewalld"
修复:
  • 确保 ~/.ssh/config 无冲突配置
  • 控制机与目标机时间同步(NTP)
  • 使用 ansible_ssh_common_args 指定跳板机(如有)

故障 2:MODULE FAILURE: /usr/bin/python: not found

原因:
  • 目标机无 Python 2/3
  • ansible_python_interpreter 路径错误
修复:
复制代码
# hosts.ini
[all:vars]
ansible_python_interpreter=/usr/bin/python3  # Ubuntu 20.04+
# 或
ansible_python_interpreter=/usr/libexec/platform-python  # RHEL 8+

CentOS 8+ 默认无 /usr/bin/python,必须显式指定。


故障 3:sudo: a password is required

原因:
  • deploy 用户无 NOPASSWD 权限
  • /etc/sudoers.d/deploy 权限非 440
排查:
复制代码
# 在目标机执行
sudo -l -U deploy  # 查看 deploy 的 sudo 权限
ls -l /etc/sudoers.d/deploy  # 必须是 -r--r-----
修复:
复制代码
echo "deploy ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/deploy
sudo chmod 440 /etc/sudoers.d/deploy

故障 4:Handler 未触发

常见原因:
  • 任务状态为 ok(未变更),Handler 不触发
  • Playbook 中未定义 handlers 区域
修复:
  • 确保任务使用 template/copy 等可能变更的模块
  • 使用 --force-handlers 强制执行(调试用)

故障 5:幂等性失效(每次执行都 changed)

典型场景:
  • 使用 shell/command 模块执行非幂等命令
  • 未使用 creates/removes 参数
修复示例:
复制代码
- name: 启动脚本(幂等)
  command: /opt/app/start.sh
  args:
    creates: /var/run/app.pid  # 文件存在则跳过

原则:优先使用 Ansible 内置模块 (如 systemdpackage),避免 shell


四、安全加固(生产必备)

4.1 禁用 root 远程登录(已做)

4.2 使用 Ansible Vault 加密敏感变量

复制代码
# 创建加密变量文件
ansible-vault create group_vars/all/vault.yml

# 内容示例:
db_password: "s3cr3t!"

# 执行时解密
ansible-playbook site.yml --ask-vault-pass

建议:Vault 密码由团队共享(如 HashiCorp Vault 或 1Password)

4.3 限制 playbook 权限

复制代码
# 在 playbook 开头限制
- hosts: web
  become: yes
  become_user: root  # 明确提权目标
  vars:
    ansible_ssh_user: deploy

五、监控与告警集成

5.1 失败自动告警(邮件/钉钉/企业微信)

使用 callback 插件或在 CI/CD 中判断退出码:

复制代码
ansible-playbook site.yml
if [ $? -ne 0 ]; then
  curl -X POST https://oapi.dingtalk.com/robot/send?access_token=xxx \
       -H 'Content-Type: application/json' \
       -d '{"msgtype": "text", "text": {"content": "Ansible 部署失败!"}}'
fi

5.2 与 Prometheus 集成

  • 使用 ansible-exporter 暴露指标
  • 或在 playbook 结尾上报状态到 Pushgateway

六、测试与验证(CI/CD 流程)

6.1 使用 Molecule 测试 Role

复制代码
pip install molecule[docker]
molecule init role nginx
molecule test

6.2 预演模式(Dry Run)

复制代码
ansible-playbook site.yml --check --diff

注意:--checkshell/command 无效,仅模拟。


七、生产 Checklist

项目 是否完成
使用普通用户 + sudo NOPASSWD
SSH 密钥认证 + 禁用密码登录
forks 并发调优
启用 pipeliningControlPersist
日志记录 + 回调插件
敏感信息使用 Vault 加密
所有任务幂等
Handler 正确触发
多环境变量分离(dev/staging/prod)
故障自动告警

推荐工具链

  • 日志分析 :ELK 收集 ansible.log
  • 版本管理 :Git + Tag(如 v1.2.0-prod
  • CI/CD:GitLab CI / Jenkins 执行 playbook
  • 配置备份 :定期备份 /etc 到 S3(使用 Ansible 自动化)

建议
永远不要在生产环境直接运行未经测试的 playbook

先在 staging 环境验证,再通过 CI/CD 流水线发布。

相关推荐
有毒的教程7 小时前
Ansible批量操作自动化完整教程:批量部署服务、配置同步、软件更新实战
运维·自动化·ansible
Hy行者勇哥5 天前
用Cursor智能编写Ansible/Terraform脚本,打通CI/CD链路
ci/cd·ansible·terraform
芷栀夏7 天前
飞牛NAS怎么部署Immich?家庭照片自动备份与远程访问教程
服务器·nginx·ansible
悠然南风18 天前
Ansible常见模块总结及LDAP Role 编写与调试
ansible
祺风挽楠1 个月前
ansible编辑
网络·ansible
芳心粽伙饭1 个月前
Ansible课后作业
ansible
烁3471 个月前
Ansible初识
ansible
烁3471 个月前
Ansible安装部署调试
ansible
烁3471 个月前
Ansible命令
ansible
小义_1 个月前
【Ansible】(三)基础配置与连接设置
云原生·ansible