vCenter 6.0 这套环境跑了也有年头了某天早上监控直接告警vSphere Web Client 能登录但主机、虚拟机清单死活刷不出来集群层面一片空白。登进 vCSA 一看VMware Inventory Service 状态是 Stoppped用 service-control 拉起来没几分钟又挂反复几次典型故障现场。但这问题背后其实藏着一整条因果链——磁盘被写满、日志文件暴涨、数据库起不来、Inventory Service 依赖数据库却连不上最后才表现为服务起不来。这篇文章就把这条链路完整拆开从排查思路、根因分析、实操清理到避坑记录把你可能遇到的情况都覆盖到位。先说结论Inventory Service 起不来通常不是它自己“生病”而是外部依赖出了问题。在 vCenter 6.0 的 vCSA 环境里这个服务的依赖链相当长——vPostgres 数据库、SSO/LDAP 组件、vmon 服务管理框架哪一环掉链子它都会启动失败。而磁盘满这个“大前提”会让数据库中所有组件一连串崩溃你看到 Inventory Service 起不来只是冰山一角。1. 故障现象与排查链路1.1 现场症状服务停了界面空了这套环境是 vCenter Server Appliance 6.0 的版本客户端普遍用的是 Web Client。故障发生时最直观的感受是登录没问题认证能通过但进入主页后主机清单、虚拟机清单全部加载不出来左侧导航树直接空白或者一直转圈。尝试对某个集群点右键刷新会提示“Inventory Service 无法连接”之类的报错。用命令行会有更直接的证据。在 vCSA 的 shell 里执行service-control --status --all输出中 vmware-inventoryservice 这一项的状态就是 stopped右边的注释可能写着 failed。这时候如果强行启动service-control --start vmware-inventoryservice命令本身会立刻回报成功但等个几秒到十几秒再查状态又变回 stopped。这种“起来了又躺下”的行为模式基本可以断定是启动过程中某个前置条件不满足服务进程在初始化阶段就退出而不是被外部 kill。很多人到这里就一头扎进 Inventory Service 本身的日志里翻来翻去结果只看到一堆数据库连接失败的报错然后开始怀疑数据库密码、怀疑账户权限方向越搞越偏。我当时的习惯是先看系统层级的资源再看服务层级的日志最后才碰服务本体的配置文件。顺序反了排查效率会成倍下降。1.2 顺着日志找根因不是服务本身是磁盘如果一上来就盯 Inventory Service 的日志你会看到类似这样的内容ERROR [BackgroundInventoryManager] Failed to connect to database java.sql.SQLException: FATAL: terminating connection due to administrator command或者Caused by: org.postgresql.util.PSQLException: Connection refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.数据库连接被拒绝第一反应是 vPostgres 挂了。然后你去看 vPostgres 的状态会发现它确实起不来。再翻 vPostgres 的日志里面写着“No space left on device”或者类似的磁盘空间耗尽报错。真相到此基本浮出水面磁盘满 — vPostgres 写不了数据 — Inventory Service 连不上数据库 — 启动失败。这个因果链在排障过程里非常骗人因为每个环节都像独立故障你逐个修过去会发现修完一个又冒出来另一个。我建议在收到任何关于“服务起不来”的工单时第一时间先执行df -h把根分区、/storage/archive、/storage/log 这些常见的挂载点都看一遍再用du -sh /var/log/vmware/* | sort -rh | head -20直接列出日志目录下占用空间最大的前 20 个项目。这两条命令二十秒内就能帮你判断是不是“磁盘空间问题引发的次生灾害”避免在不该深挖的方向上浪费大半天。2. 为什么磁盘满了Inventory Service 就起不来2.1 Inventory Service 的启动依赖链先说 Inventory Service 在 vCenter 6.0 架构里的位置。它就是负责资源清单管理的服务——收集 vCenter 中所有主机、虚拟机、集群、数据存储、网络的关系信息并提供给 Web Client 等客户端做展示和检索。这个服务的数据持久化依赖 vPostgresPostgreSQL 的 VMware 发行版启动阶段会初始化数据库连接池、加载场景、恢复缓存数据。也就是说数据库不可用的是致命的。整个启动链路大致是这样的vmon 服务管理框架先启动vmware-vmonvmon 依赖 vpostgresvCenter 6.0 中数据库服务名可能是 vmware-vpostgresvpostgres 正常起来以后vmon 再拉起 inventoryserviceinventoryservice 启动时尝试连接 vPostgres连接成功后还要和 SSOVMware Directory Service做 token 交换验证全部通过后服务才进入稳定运行状态Web Client 才能正常拉取清单数据磁盘满之后vPostgres 无法创建 WAL 日志、无法写临时表空间、无法扩展数据文件整个数据库服务直接异常退出。数据库挂掉Inventory Service 哪怕代码逻辑没问题也会因为连不上后端存储而反复启动失败。除此之外SSO 组件在磁盘满时也经常出问题它的 ldap 数据文件写不进去服务同样会僵掉。最终呈现出来的就是一连串服务全部异常。所以看 Inventory Service 起不来的问题至少要同时检查同一个故障时间里 vpostgres 和 vmafdSSO 服务的状态。不是它们的配置有问题而是它们共同处于一个“存储空间枯竭”的恶劣环境里。2.2 vCSA 6.0 的日志膨胀机制磁盘为什么会被写满这得从 vCSA 6.0 的日志机制讲起。vCSA 6.0 是一个基于 Photon OS精简版 Linux的虚拟机设备系统盘默认较小日志挂载点独立在 /storage/log 下。这里管得松一点日积月累就会出事。vCSA 6.0 的主要日志成分包括日志路径服务膨胀原因/var/log/vmware/vpx/vpxd.logvCenter Server 主服务任务、事件、告警记录多错误栈打满/var/log/vmware/inventory-service/inventory-service.logInventory Service连不上数据库时疯狂打错误日志死循环式刷屏/var/log/vmware/vws/vws.logWeb Service会话信息、客户端请求记录/var/log/vmware/vmafd/vmafd.logSSO 认证认证失败时单条日志并不大但数量巨大/var/log/vmware/rhttpproxy/rhttpproxy.log反向代理HTTP 访问日志累计非常快这里面最典型的一种恶性循环是Inventory Service 连不上数据库后日志模块会把每次失败的连接尝试、堆栈信息全部写进 inventory-service.log日志大小迅速攀升。磁盘空间进一步缩紧vPostgres 更起不来于是日志继续暴涨。直到整个 /storage/log 分区被写满连 vmon 自己的状态文件都写不进去那时你会看到更诡异的现象——服务控制命令都开始卡顿。另外vCSA 6.0 默认的日志轮转策略并不激进。logrotate 虽然有配置但切割周期、保留份数都偏保守如果 vSphere 环境里事件量比较大、任务量比较重同时存在某些组件频繁报错两周到一个月之间日志就能把分区吃干抹净。加上很多人不会定期登录 vCSA 去检查空间水位最终故障就是突然爆发的。3. 磁盘清理与日志轮转处理实操3.1 安全清理日志的正确姿势先强调一个非常关键的底层认知在 Linux 上如果一个日志文件正在被进程写入你用 rm 删除掉这个文件磁盘空间并不会立刻释放。这是因为进程仍然持有该文件的文件句柄file descriptor内核不会释放对应的数据块直到句柄关闭。你 df 看空间还是满的但 ls 看文件已经不见了这种“幽灵占用”是运维排障里最典型的陷阱。正确做法是先确认哪些进程占用了被删除的文件。用lsof L1或者定位到具体路径lsof /var/log/vmware/vpx/vpxd.log如果文件显示为 deleted 但仍被进程持有可以对对应进程执行 reload 或重启或者用truncate主动将文件清零: /var/log/vmware/vpx/vpxd.log或truncate -s 0 /var/log/vmware/vpx/vpxd.log这样做既能释放空间又不影响进程继续写日志实际运维中比 rm 安全得多。接下来就是按空间占用逐个“拆弹”。我当时最常用的流程# 1. 看整体空间水位 df -h # 2. 定位 /storage/log 或 / 分区中占用最高的目录 du -xsh /* 2/dev/null | sort -rh | head -20 du -xsh /var/log/vmware/* 2/dev/null | sort -rh | head -20 # 3. 找出超过几百 MB 的日志文件 find /var/log/vmware -type f -size 200M -exec ls -lh {} \; # 4. 清理已被日志轮转保留的压缩旧文件 find /var/log/vmware -name *.gz -mtime 7 -delete最后一个命令需要特别说明一下日志轮转机制会把旧日志压缩成 .gz 文件保留 N 份。如果空间捉急删掉 mtime 超过 7 天的压缩旧日志通常是安全的不会影响正在运行的进程。但对于还没压缩的原始日志文件尽量先 truncate 而不是直接删。直接删了会引发句柄问题而且如果服务配置里对日志文件权限、属主有严格校验服务重启时还可能因为文件不存在而重新初始化行为不可控。还有一种情况journald 的 systemd 日志占用。vCSA 6.0 里 journal 也会积累大量开机日志和服务日志。压缩归档清完之后空间还不够再考虑清理 journaljournalctl --vacuum-size200M这个命令会把 journal 总大小压缩到 200MB 左右对系统服务和 vmon 日志影响很小但能快速释放空间。3.2 扩容方向与日志轮转配置调整清理完日志之后空间会好一阵子但这只是“治标”。如果环境里长期有日志增长速度超过轮转速度的情况一定要做两件事。首先是调整日志轮转策略。vCSA 6.0 上 logrotate 的配置分散在 /etc/logrotate.d/ 下面vpxd 等服务的日志轮转配置在各组件的配置目录里。可以手动调整的最大保留份数和切割周期。比如你希望 vpxd.log 每 100MB 就轮转一次可以新增配置/var/log/vmware/vpx/vpxd.log { size 100M rotate 7 copytruncate compress missingok notifempty }其中copytruncate是日志轮转里最友好的选项它会先复制当前日志内容到轮转文件再立即清空原文件整个过程不影响进程的写入句柄不需要重启服务。没有这个参数的话logrotate 会 rename 文件再重建新文件有些服务如果持有旧句柄日志就会写到已删除的文件里造成“日志还在涨但文件看不到”的迷惑现象。其次是给 vCSA 加磁盘。vCSA 6.0 支持通过 vSphere Web Client 给虚拟机加硬盘然后在客户机操作系统里创建分区、扩容 LVM。这个操作要谨慎尤其是在生产环境。如果 vCSA 本身的存储布局是 LVM那可以通过lvextend和resize2fs来扩展逻辑卷如果分区是普通分区扩展起来会更麻烦可能需要重建分区表有数据风险。稳妥的做法是给 vCSA 新增一块数据盘把 /storage/log 迁移过去或者挂载到新的扩容目录但这涉及修改 fstab 和服务路径操作复杂度高建议在维护窗口内由有经验的人执行。我的实际经验是空间清理只是应急最终答案还是控制日志产生量和加大存储容量双管齐下。只清不控过几周又会打回原样。3.3 让 Inventory Service 恢复正常启动空间清理完成、磁盘水位降下来以后恢复 Inventory Service 的顺序也有讲究。别上来就直接 start inventoryservice要先确认依赖项是否就绪。推荐顺序# 1. 确认 vpostgres 状态如果没起先启动 service-control --status --all | grep -E vpostgres|vmafd|inventory # 2. 如果 vpostgres 是 stopped启动它 service-control --start vmware-vpostgres # 3. 等十几秒确认稳定在 running service-control --status vmware-vpostgres # 4. 再启动 inventory service service-control --start vmware-inventoryservice # 5. 间隔几秒后复查状态也可以看日志确认是否成功连接数据库 tail -50 /var/log/vmware/inventory-service/inventory-service.log如果 vPostgres 启动时一直失败大概率是数据文件本身有问题在磁盘写满时强杀数据库极容易导致数据文件不一致。这时候要先看日志tail -100 /var/log/vmware/vpostgres/postgresql.log如果确实出现数据库内部错误或者数据文件损坏提示可能需要 vPostgres 做单用户模式检查或恢复。实在不行还有一招保留数据文件重新初始化数据库实例但这对生产环境影响巨大属于最后手段必须在充分评估后执行。Inventory Service 启动成功后再回到 Web Client 刷新页面主机、虚拟机清单应该能恢复正常加载。如果还是空白的把 vmon 也重启一遍service-control --restart --all全量重启 vCSA 里的所有受管服务适合在业务低峰执行能让各个服务重新建立彼此之间的连接会话很多“逻辑上的残留问题”都会被冲掉。4. 常见问题与踩坑实录4.1 日志文件句柄导致的“删了但空间没释放”这个坑我在真实现场踩过两三次必须单独拎出来讲。当时的操作是发现 /storage/log 满先du -sh /var/log/vmware/*定位到大文件然后直接rm -f /var/log/vmware/vpx/vpxd.log。执行完之后再 df -h 一看空间竟然一点都没释放。当时还以为是文件太多删除慢又等了半天依旧满。排查后才发现原因就是进程持有已删除文件的句柄。vpxd 还在运行它一直往那个已删除的 inode 里写数据。解决办法只能找到持有者然后重启服务或者对文件做 truncate 清空。这个小知识点处置得当的话能省下大量误判和无效等待时间。强烈建议运维同行养成习惯日志文件一般不动 rm优先 truncate。4.2 Inventory Service 反复启动失败的几种诱因除了磁盘满Inventory Service 起不来的原因还有几类在排查时要逐一排除:诱因典型表现快速判断方法vPostgres 数据文件损坏数据库服务起不来或频繁闪断查看 postgresql.log搜索 unexpected 或 could not open file证书过期或时间偏差Inventory Service 在 SSO 校验阶段失败查看 vmafd.log搜索 certificate 或 time 相关报错数据库连接池配置错误Inventory Service 日志一直打连接超时检查 /etc/vmware-sso 和 inventory-service 的 db.properties 配置文件服务间顺序错乱vmon 启动时多个服务同时抢资源重启 vmon 后再按依赖顺序启动端口被占用或防火墙规则异常TCP 连接被拒绝netstat 检查 7444、8443 等端口监听状态很多人在排查时一看到“连接数据库失败”就直接去重置数据库密码但实际上数据库服务根本没起来。先确认依赖服务状态再一层层往深处查是这类问题最高效的路径。4.3 高危操作提醒与后续升级建议最后说点管理者视角的东西。vCenter 6.0 这个版本已经很老了VMware 对其支持早已结束。就算你把磁盘清干净、服务恢复好也解决不了产品本身架构设计的局限。特别是 6.0 的环境里Inventory Service 这种独立服务模型在 vCenter 7.0 以后已经被彻底移除整个 vCenter Server 的架构向简化、可维护性方向做了大幅调整。7.0 以后日志管理和空间规划都比 6.0 合理得多。如果你还在运维 6.0 或 6.5 这类老版本环境我认真建议你规划升级路线。升级前务必做好完整备份、记录好当前版本和所有扩展插件兼容性、选择维护窗口执行。否则这次你救了 Inventory Service下次也许就是 vpxd 或者整个 vCSA 都爬不起来。另外一个实际体会像“日志增长导致磁盘满”这类问题本质上不是技术问题而是管理问题。日志轮转策略是否配置到位、空间监控告警是否覆盖到 vCSA 的 /storage/log 分区、备份频率是否合理这些运维基本功做到位了绝大多数“服务起不来”的故障根本不会发生。我见过太多团队基础设施监控只覆盖了业务服务器却把 vCenter 这种管理核心的虚拟机当成了“工具机”不当回事——出问题只是时间问题。我在实际操作中最深的感受是处理这类问题心态上别急流程上别跳步。先把磁盘空间、依赖服务状态这些“外围因素”确认干净再动服务本身的配置。大部分时候“起不来”只是一个烟雾弹真正的病根早就在系统资源层埋下了。你解决了底层根因上层服务自然就活了。