与其等出事再翻日志,不如每天一分钟巡检:os-health.sh 快速体检 + 九大项巡检详细体检,两个脚本直接抄走
一、部署概述
| 项目 | 值 |
|---|---|
| 环境 | 10.10.10.160 单机(CentOS 7.9 + Train + OVN)实测通过 |
| 使用前提 | 先source /root/keystonerc_admin |
| 建议存放 | 存为/root/osops.sh后chmod +x |
| 巡检日志 | /var/log/openstack-healthcheck.log |
上篇回顾:(五)单机故障排查实录——273 字节镜像坑的完整定位与修复,以及通用排查起手式。
本篇把前五篇的排障经验“反刍”成两个可长期复用的脚本。写脚本的动机很朴素:排查事故时最贵的成本是“想起来该查什么”,巡检脚本的价值就是把这个记忆固化成每天一分钟的例行确认。
二、脚本 1:环境健康检查(os-health.sh,快速体检)
一分钟内回答五个问题:服务在不在?计算服务正常吗?网络 agent 活着吗?资源还够吗?关键资源数量对吗?
bash
#!/bin/bash |
# os-health.sh —— 单机 OpenStack 健康检查 |
source /root/keystonerc_admin |
echo "===== 1) 基础服务 =====" |
for s in httpd mariadb rabbitmq-server ovn-northd ovn-controller neutron-server \ |
openstack-nova-compute openstack-nova-conductor openstack-nova-scheduler \ |
openstack-cinder-volume; do |
st=$(systemctl is-active "$s" 2>/dev/null) |
if [ "$st" = "active" ] || [ "$st" = "unknown" ]; then |
printf " %-32s %s\n" "$s" "$st" # ★unknown = 单元名不存在,不是故障 |
else |
printf " %-32s %s <<< 需检查\n" "$s" "$st" |
fi |
done |
echo " 注:nova-api / glance-api / keystone / placement-api 由 httpd 承载,unknown 属正常" |
echo "===== 2) 计算服务 =====" |
openstack compute service list -f value -c Binary -c State -c Status |
echo "===== 3) 网络 agent(OVN)=====" |
openstack network agent list -f value -c "Agent Type" -c Alive -c State |
echo "===== 4) 资源占用 =====" |
openstack hypervisor stats show # ★用表格输出;多列 -f value 会堆叠难辨 |
free -g | sed -n '2p'; df -h / | tail -1 |
echo "===== 5) 关键资源数量 =====" |
echo " 镜像: $(openstack image list -f value | wc -l) 网络: $(openstack network list -f value | wc -l)" |
脚本里两个 ★ 都是实测踩出来的经验,不是抄来的:
- unknown 不等于故障:
nova-api / glance-api / keystone / placement-api由 httpd 承载(mod_wsgi),systemd 里根本没有这些单元名,is-active返回 unknown。脚本干脆把 active 和 unknown 都视为正常,避免巡检误报。 -f value多列输出会堆叠难辨:openstack hypervisor stats show这种多字段的输出,加一堆-c再用-f value会把所有值竖着堆在一起根本对不上号,直接看表格反而清晰。
三、脚本 2:九大项巡检(详细体检)
作用:输出系统基础信息、MariaDB、RabbitMQ、Keystone、Glance、Nova、Neutron、Cinder、Horizon九大项状态,所有输出同时打屏并落日志(tee -a),方便事后追溯巡检历史。
bash
#!/bin/bash |
# OpenStack Train Health Check Script |
LOGFILE="/var/log/openstack-healthcheck.log" |
echo "==== OpenStack Health Check ($(date)) ====" | tee $LOGFILE |
# ---------- [1] 系统基础信息 ---------- |
echo -e "\n[1] 系统基础信息" | tee -a $LOGFILE |
hostnamectl | tee -a $LOGFILE |
uptime | tee -a $LOGFILE |
chronyc sources | tee -a $LOGFILE 2>/dev/null || echo "chrony not installed" | tee -a $LOGFILE |
# ---------- [2] MariaDB ---------- |
echo -e "\n[2] MariaDB 状态" | tee -a $LOGFILE |
systemctl is-active mariadb | tee -a $LOGFILE |
# ---------- [3] RabbitMQ ---------- |
echo -e "\n[3] RabbitMQ" | tee -a $LOGFILE |
systemctl is-active rabbitmq-server | tee -a $LOGFILE |
rabbitmqctl cluster_status | tee -a $LOGFILE 2>/dev/null |
# ---------- [4] Keystone ---------- |
echo -e "\n[4] Keystone (身份认证)" | tee -a $LOGFILE |
systemctl is-active httpd | tee -a $LOGFILE |
openstack token issue 2>&1 | tee -a $LOGFILE |
# ---------- [5] Glance ---------- |
echo -e "\n[5] Glance (镜像)" | tee -a $LOGFILE |
openstack image list 2>&1 | tee -a $LOGFILE |
# ---------- [6]~[9] Nova / Neutron / Cinder / Horizon ---------- |
# 同样模式:compute service list / network agent list / |
# volume service list / Dashboard HTTP 探测 |
# 完整脚本见文末仓库链接 |
设计要点:
- 每段独立,某一项报错不影响后面各项继续跑
2>&1把报错也收进日志——巡检日志的价值恰恰在于记录“当时报了什么”tee -a追加不覆盖,日志随时间累积成巡检历史,出事后可以翻“最后一次正常是什么时候”
四、巡检判读要点(每一项怎么看)
| 巡检输出 | 判读 | 处置 |
|---|---|---|
| 服务 unknown | 先看是不是 httpd 承载的(正常) | 不是则确认单元名拼写 |
| compute service 有 down | 对应节点的 nova-compute 挂了 | 去该节点tail -f /var/log/nova/nova-compute.log,多为时间/hosts/MQ 连接问题 |
| network agent Alive=False | OVN 通道断了 | systemctl status ovn-controller、检查 ovsdb 连接 |
| token issue 401 | 没 source / 时钟漂移 / Keystone 异常 | 依次 source、chronyc sources、httpd |
| hypervisor vcpus_used 长期 0 | 实例可能没真跑起来 | 回看第(五)篇“真活三连” |
| RabbitMQ cluster_status 异常 | MQ 脑裂/节点掉线 | 优先解决,MQ 是所有组件的血管 |
| 磁盘根分区 >80% | 镜像/日志膨胀 | 清理 Glance 缓存与旧日志 |
五、顺手收录:镜像相关操作速查
巡检之外,日常操作频率最高的是镜像管理,一并整理:
bash
# 常用云镜像下载源(都有现成 qcow2) |
# Cirros: http://download.cirros-cloud.net/ # 超小测试镜像 |
# CentOS: http://cloud.centos.org/centos/7/images/ |
# Ubuntu: https://cloud-images.ubuntu.com/ |
# Rocky: https://dl.rockylinux.org/pub/rocky/9/images/x86_64/ |
# Debian: https://cloud.debian.org/images/cloud/ |
# Fedora: https://download.fedoraproject.org/pub/fedora/linux/releases/ |
# 格式转换(raw 转 qcow2,qcow2 稀疏省空间) |
qemu-img convert -f raw -O qcow2 myserver.img myserver.qcow2 |
# 上传镜像(★image set 不支持 --file,改镜像文件只能删了重建) |
openstack image create "centos7" --file CentOS-7-x86_64-GenericCloud.qcow2 \ |
--disk-format qcow2 --container-format bare --public |
五点五、九大项完整脚本(后四项补全)
第(三)节留了 [6]~[9] 的空白,这里补全,拼起来就是完整的九大项巡检:
bash
# ---------- [6] Nova ---------- |
echo -e "\n[6] Nova (计算)" | tee -a $LOGFILE |
systemctl is-active openstack-nova-compute | tee -a $LOGFILE |
openstack compute service list 2>&1 | tee -a $LOGFILE |
# ---------- [7] Neutron ---------- |
echo -e "\n[7] Neutron (网络)" | tee -a $LOGFILE |
openstack network agent list 2>&1 | tee -a $LOGFILE |
# ---------- [8] Cinder ---------- |
echo -e "\n[8] Cinder (块存储)" | tee -a $LOGFILE |
systemctl is-active openstack-cinder-volume | tee -a $LOGFILE |
openstack volume list 2>&1 | tee -a $LOGFILE |
# ---------- [9] Horizon ---------- |
echo -e "\n[9] Horizon (仪表盘)" | tee -a $LOGFILE |
HTTP=$(curl -s -o /dev/null -w '%{http_code}' http://localhost/dashboard/) |
echo "Dashboard HTTP 状态码:$HTTP" | tee -a $LOGFILE # 302 = 正常 |
echo -e "\n==== 巡检完成 ====" | tee -a $LOGFILE |
判读要点:
[6]里 nova-compute 必须存在且 up,conductor/scheduler 也是;down立即去对应节点查日志[7]关注 Alive 列,False 表示 agent 与 MQ 断连[8]cinder-volume 由 cinder-volume 服务承载(不是 httpd)[9]302 是正常值(跳转登录页),200 反而少见;000/502 才是异常
把这四段接在第(三)节后面,脚本就闭环了——从系统到存储到 Web 入口,一屏看尽全部核心链路。
六、脚本进阶:给巡检加告警阈值
现在的脚本只“报状态”,进阶做法是让它“下判断”——对关键指标设阈值,超标就标红:
bash
# 磁盘使用率超过 80% 则告警(追加到 os-health.sh 末尾) |
USED=$(df --output=pcent / | tail -1 | tr -dc '0-9') |
if [ "$USED" -gt 80 ]; then |
echo " <<< 警告:根分区使用率 ${USED}%,检查镜像缓存与日志" |
fi |
# down 状态的服务自动汇总 |
DOWNS=$(systemctl is-active httpd mariadb rabbitmq-server \ |
openstack-nova-compute openstack-cinder-volume 2>/dev/null \ |
| grep -vc 'active\|unknown') |
echo "down 状态服务数:$DOWNS" |
# token 获取失败则说明 Keystone 异常,直接退出非零(方便接入监控) |
openstack token issue > /dev/null 2>&1 || exit 1 |
exit 1这个细节很关键:脚本有了非零退出码,就能被 Zabbix/Prometheus 的探针直接拉去当采集脚本用。
七、巡检发现的典型问题与处置对照
| 巡检发现 | 隐患 | 处置命令 |
|---|---|---|
/var/lib/glance/images/有小文件 | 坏镜像残留(273 字节坑) | openstack image delete后重传 |
/var/lib/nova/instances/_base/膨胀 | 镜像缓存累积 | 清理已删实例的 base 文件 |
| rabbitmqctl 显示磁盘告警 | MQ 磁盘阈值触发,拒收消息 | 清理日志/调大 disk_free_limit |
| hypervisor running_vms 与 server list 对不上 | 有“幽灵实例” | 对比 virsh list,清理残留 domain |
| chronyc 无 ^* 源 | NTP 源不可达 | 换源或检查网络,★重启后必须复查 |
八、把巡检纳入日常
我的实际用法供参考:
bash
# /etc/cron.d/os-healthcheck —— 每天早上 8 点自动巡检落日志 |
0 8 * * * root /root/osops.sh > /dev/null 2>&1 |
- 手动巡检跑 os-health.sh(快速),出问题再跑九大项(详细)
- 巡检日志保留 90 天,事故复盘时“最后一次正常状态”全靠它
- 巡检脚本的真正价值不是“自动化”,而是把排障经验固化成每天一分钟的例行确认
下篇预告:(七)多节点部署:环境准备与应答文件——单机玩熟了,把 compute 角色拆到另外两台机器上,走向“迷你私有云”。三台机器的“步调一致”是新的挑战。