用 ansible 批量检查磁盘使用率需用 df -p 保证格式统一,通过 awk 提取超阈值挂载点;设 threshold 变量、ignore_errors: yes 防中断;避免 register 大文本,改用 failed_when 控制流程。

如何用 Ansible 批量检查服务器磁盘使用率并告警
直接看结果:用 ansible 调 df 命令最轻量,但别直接写 command: df -h —— 输出格式不统一,解析容易翻车。
真实运维中,df 在不同系统(centos 7 vs ubuntu 22.04)里字段顺序可能差一列,-P 参数才是关键:它强制 POSIX 格式,保证“已用百分比”永远在第5列。
- 用
shell: df -P | awk '$5 > 85 {print $1, $5}'提取超阈值的挂载点和使用率 - 把阈值抽成变量:
threshold: 90,避免硬编码 - 加
ignore_errors: yes,否则某台机器df失败会导致整个批次中断 - 别用
register接大段文本再用when判断——性能差,改用failed_when或changed_when控制流程
Python 脚本调用 subprocess 执行 ssh 命令时卡住怎么办
不是网络问题,大概率是 SSH 连接卡在交互式提示(比如密码输入、host key 确认),而 Python 没配超时或非交互模式。
subprocess.run() 默认不会自动处理 SSH 的 stdin/stderr 阻塞,尤其遇到首次连接时的 The authenticity of host 'xxx' can't be verified 提示。
- 必须加
ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5,否则可能等 30 秒才失败 - 用
timeout=10参数传给subprocess.run(),双保险 - 别用
shell=True拼接命令字符串,容易被主机名里的空格或特殊字符搞崩,老实用列表形式:['ssh', '-o', 'StrictHostKeyChecking=no', 'user@host', 'df -P'] - stderr 必须重定向(
stderr=subprocess.PIPE),否则错误输出会直接打到终端,脚本里捕获不到
用 cron + shell 脚本做日志轮转,为什么 /var/log/myapp.log 没删旧文件
常见假象:脚本手动执行正常,放进 cron 就失效。根本原因通常是环境变量缺失或路径不全。
cron 启动的 shell 是 minimal 的,$PATH 只有 /usr/bin:/bin,很多运维习惯用的 logrotate 或自写 find ... -mtime +7 -delete 会因找不到命令或权限不足静默失败。
- 脚本第一行必须写
#!/bin/bash,且所有命令用绝对路径:/usr/bin/find、/bin/rm - 在 crontab 里显式定义 PATH:
PATH=/usr/local/bin:/usr/bin:/bin - 加日志重定向:
2>&1 >> /var/log/rotate.log,不然失败了你根本不知道 - 测试时先用
date和whoami打印上下文,确认运行身份和时间是否符合预期
Ansible playbook 中 use become: yes 却提示 Permission denied
不是密码错了,而是 become_method 默认是 sudo,但目标机没配免密 sudo 权限,或者用户不在 %wheel / %sudo 组里。
更隐蔽的情况是:playbook 里写了 become: yes,但没指定 become_user,结果试图以 root 执行操作,而目标机 root 账户被禁用(PermitRootLogin no)。
- 确认远程用户能无密码运行
sudo -l,至少要有(ALL) NOPASSWD: ALL或对应命令权限 - 显式写
become_user: root,别依赖默认值 - 如果目标机禁用 root,改用
become_user: deploy并确保该用户有对应目录写权限 - 调试时加
-vvv,看 Ansible 实际执行的sudo命令和返回的 stderr
自动化最麻烦的从来不是写逻辑,而是环境差异带来的隐性假设——比如以为所有机器都装了 jq,或默认 shell 都是 bash。每次上线前,拿一台最小权限的测试机,从头跑一遍,比读十遍文档管用。