vCenter Server 7.0 完全宕机恢复实录 — STS 证书过期 + 连环故障排查
vCenter Server 7.0 完全宕机恢复实录 — STS 证书过期 + 连环故障排查
故障时间:2026-06-24 ~ 2026-06-25 vCenter 版本:7.0U3c (build 19234570) VCSA FQDN:vcenter.streamcomputing.com SSO 域:vsphere.local
一、故障现象
vCenter 完全不可用,vmware-vpxd-svcs 服务启动失败,所有依赖服务连锁宕机:
service-control --start vmware-vpxd-svcs
Error executing start on service vpxd-svcs. Details {
"id": "install.ciscommon.service.failstart",
"localized": "An error occurred while starting service 'vpxd-svcs'"
}
vSphere Client 无法访问,ESXi 主机失联,vCenter 管理功能完全中断。
二、根因总结
这次故障是三个独立问题叠加造成的连环宕机:
| # | 问题 | 根因 | 影响 |
|---|---|---|---|
| 1 | STS 签名证书过期 | 证书有效期 2024-03-21 ~ 2026-03-21,certificate-manager 不更新此证书 | SAML token 签发失败 → vpxd-svcs pre-start 脚本崩溃 |
| 2 | MACHINE_SSL_CERT VECS 存储为空 | 6月6日证书更新操作不完整,清空了存储但没重新导入 | STS Tomcat SSL connector 初始化失败 → STS 服务崩溃 |
| 3 | vpxd-svcs.json 配置文件丢失 | 原因不明,可能在某次操作中被误删 | vmon 无法识别 vpxd-svcs 服务 → 服务完全不可管理 |
故障链:
STS 签名证书过期 (2026-03-21)
↓
SAML token 签发被拒绝 ("Signing certificate is not valid")
↓
tagging_grpc_registration.py reregister_service() 失败
↓
vpxd-svcs pre-start 脚本退出 (exit code 1)
↓
vpxd-svcs JVM 从未启动 → 端口 10080 不监听
↓
vpxd 连接 localhost:10080 被拒 (Connection refused)
↓
vpxd Authz 初始化失败,重试 60 次后退出
↓
VCSA 完全宕机
三、详细排查过程
3.1 初始诊断:排除基础问题
# 磁盘空间(正常)
df -h # 所有分区使用率 < 35%
# 内存(正常)
free -h # 27G total, 6G used
# OOM(无)
dmesg | grep -i "oom\|killed" # 空
# PostgreSQL(正常运行)
service-control --status vmware-vpostgres # Running
3.2 分析 vpxd 日志:发现 Authz 连接失败
tail -100 /var/log/vmware/vpxd/vpxd.log
关键错误:
Failed to connect; <TCP '127.0.0.1 : 10080'>, e: 111(Connection refused)
Failed to connect to Authz service: vmodl.fault.HostCommunication
Failed to instantiate AuthzStorageProvider
Failed to initialize authorizeManager
Failed to start VMware VirtualCenter. Shutting down
vpxd 在尝试连接 localhost:10080 (vpxd-svcs 的 Authz 接口),但连接被拒绝 — 说明 vpxd-svcs 没有运行。
3.3 分析 vpxd-svcs pre-start 日志:发现 STS 证书过期
tail -50 /var/log/vmware/vpxd-svcs/pre-start-vpxd-svcs.log
关键错误:
ERROR:tagging_grpc_registration:Failed to reregister Tagging service grpc endpoints
invalidProperty = 'Invalid certificate'
进一步查看 vmon 日志:
grep "vpxd-svcs" /var/log/vmware/vmon/vmon.log | tail -20
发现 pre-start 脚本在 tagging_grpc_registration.py 第 119 行崩溃。
深入查看完整的 pre-start 日志,找到根本原因:
faultstring: The token authority rejected an issue request for
TimePeriod [startTime=Wed Jun 24 08:38:21 GMT 2026, endTime=...]
:: Signing certificate is not valid at Wed Jun 24 08:38:21 GMT 2026,
cert validity: TimePeriod [startTime=Thu Mar 21 03:41:59 GMT 2024,
endTime=Sat Mar 21 03:41:59 GMT 2026]
STS 签名证书在 2026-03-21 过期了!
3.4 检查证书状态
# 检查 VECS 所有证书存储
for i in $(/usr/lib/vmware-vmafd/bin/vecs-cli store list); do
echo "=== STORE: $i ==="
/usr/lib/vmware-vmafd/bin/vecs-cli entry list --store $i --text | grep -A2 "Not After"
done
发现:
- `MACHINE_SSL_CERT` 存储:**0 个条目(空!)**
- Solution User 证书(machine, vpxd 等):有效至 2036 年
- `BACKUP_STORE` 中有旧证书备份,Mar 21 2026 过期
3.5 检查 VMCA 根证书
openssl x509 -in /var/lib/vmware/vmca/root.cer -noout -dates
# notBefore=Jun 9 09:47:53 2026 GMT
# notAfter=Jun 6 09:47:53 2036 GMT
VMCA 根证书是有效的(2026-06-09 到 2036-06-06),只有 STS 签名证书过期了。
3.6 检查 STS 服务状态
cat /var/log/vmware/sso/sts-runtime.log.stderr
发现 STS 也崩溃了:
java.lang.Error: org.apache.catalina.LifecycleException:
Failed to initialize connector [Connector[...VECSAwareHttp11NioProtocol-7444]]
STS 的 Tomcat 需要从 MACHINE_SSL_CERT VECS 存储读取 SSL 证书,但存储是空的,所以 connector 初始化失败。
四、修复步骤
4.1 修复 MACHINE_SSL_CERT VECS 存储(修复 STS 崩溃)
# 1. 生成新私钥
/usr/lib/vmware-vmca/bin/certool --genkey \
--privkey=/tmp/machine_ssl.key \
--pubkey=/tmp/machine_ssl.pub \
--server=localhost
# 2. 创建证书配置(certool 使用 [Key = Value] 格式)
cat > /tmp/machine_ssl.cfg << 'EOF'
[Country = US]
[Name = vcenter.streamcomputing.com]
[Organization = vcenter.streamcomputing.com]
[OrgUnit = VMware Engineering]
[State = California]
[Locality = Palo Alto]
[IPAddress = ]
[FQDN = vcenter.streamcomputing.com]
[AltName = vcenter.streamcomputing.com]
EOF
# 3. 用 VMCA 签发新 Machine SSL 证书
/usr/lib/vmware-vmca/bin/certool --gencert \
--privkey=/tmp/machine_ssl.key \
--cert=/tmp/machine_ssl.cer \
--config=/tmp/machine_ssl.cfg \
--Name=vcenter.streamcomputing.com \
--server=localhost
# 4. 验证新证书
openssl x509 -in /tmp/machine_ssl.cer -noout -dates -subject -issuer
# notBefore=Jun 24 10:40:06 2026 GMT
# notAfter=Jun 23 10:40:06 2028 GMT
# subject= /CN=vcenter.streamcomputing.com
# 5. 导入到 MACHINE_SSL_CERT store
/usr/lib/vmware-vmafd/bin/vecs-cli entry create \
--store MACHINE_SSL_CERT \
--alias __MACHINE_CERT \
--cert /tmp/machine_ssl.cer \
--key /tmp/machine_ssl.key
# 6. 确认导入
/usr/lib/vmware-vmafd/bin/vecs-cli entry list --store MACHINE_SSL_CERT
# Number of entries in store : 1
# 7. 重启 STS
service-control --stop vmware-stsd
sleep 3
service-control --start vmware-stsd
sleep 15
service-control --status vmware-stsd # Running!
netstat -tlnp | grep 7444 # LISTENING!
4.2 确认 STS 签名证书在 vmdir 中的状态
使用 Python + ldap3 库连接 vmdir (LDAPS):
import ldap3, subprocess, os
WORK = "/tmp/sts-fix"
SSO_USER_DN = "cn=Administrator,cn=Users,dc=vsphere,dc=local"
sso_pass = "你的SSO密码"
server = ldap3.Server("ldaps://localhost:636", get_info=ldap3.ALL)
conn = ldap3.Connection(server, user=SSO_USER_DN, password=sso_pass, auto_bind=True)
# 搜索所有带 userCertificate 的对象
conn.search("dc=vsphere,dc=local", "(userCertificate=*)",
attributes=["dn", "cn", "userCertificate"])
for entry in conn.entries:
dn = str(entry.entry_dn)
if entry.userCertificate:
for i, cert_data in enumerate(entry.userCertificate):
if isinstance(cert_data, bytes):
with open(f"{WORK}/check_cert.der", 'wb') as f:
f.write(cert_data)
r = subprocess.run(["openssl", "x509", "-in", f"{WORK}/check_cert.der",
"-inform", "DER", "-noout", "-dates", "-subject"],
capture_output=True, text=True)
print(f" {dn}\n Cert {i}: {r.stdout.strip()}")
发现 TenantCredential-1 对象中的 STS 签名证书已经是新的(notBefore=Jun 24 08:59:53 2026, notAfter=Jun 6 2036),说明 vmdir 中的 STS 证书已经在之前某次操作中更新过了。
但 Lookup Service 中存储的服务注册信息仍然引用了过期的证书(Mar 21 2026),导致 reregister_service() 报 "Invalid certificate"。
4.3 重建 vpxd-svcs.json 配置文件
发现 /etc/vmware/vmware-vmon/svcCfgfiles/ 目录中缺少 vpxd-svcs.json:
ls /etc/vmware/vmware-vmon/svcCfgfiles/ | grep vpxd
# 只有 vpxd.json,没有 vpxd-svcs.json
vmon 日志确认:
Service vpxd-svcs not found.
Invalid service vpxd-svcs in profile CRITICAL. Ignoring.
在安装目录找到原始模板:
find /usr/lib/vmware-vpxd-svcs -name "*.json"
# /usr/lib/vmware-vpxd-svcs/scripts/conf/vpxd-svcs-lin.json ← 这就是原始配置!
复制到 vmon 配置目录:
cp /usr/lib/vmware-vpxd-svcs/scripts/conf/vpxd-svcs-lin.json \
/etc/vmware/vmware-vmon/svcCfgfiles/vpxd-svcs.json
chmod 644 /etc/vmware/vmware-vmon/svcCfgfiles/vpxd-svcs.json
chown root:cis /etc/vmware/vmware-vmon/svcCfgfiles/vpxd-svcs.json
重启 vmon daemon 让它重新加载配置:
service-control --stop vmware-vmon
sleep 5
service-control --start vmware-vmon
sleep 10
# 确认 vmon 现在能识别 vpxd-svcs
service-control --status vmware-vpxd-svcs
# Stopped: vmware-vpxd-svcs (之前是 "not found",现在是 "Stopped" — 成功!)
grep "vpxd-svcs" /var/log/vmware/vmon/vmon.log | tail -5
# Adding service vpxd-svcs. ← vmon 加载了新配置!
4.4 Patch pre-start 脚本绕过证书验证
tagging_grpc_registration.py 在调用 reregister_service() 时,Lookup Service 验证 spec 中的证书发现过期,返回 "Invalid certificate"。这个 gRPC 端点注册不是 vCenter 运行的核心功能,可以临时绕过:
# 备份原始脚本
cp /usr/lib/vmware-vpxd-svcs/scripts/linux/pre-start/tagging_grpc_registration.py \
/usr/lib/vmware-vpxd-svcs/scripts/linux/pre-start/tagging_grpc_registration.py.bak
# Patch:将 raise Exception 改为 warning,让脚本在 reregister 失败时继续执行
python3 << 'PYEOF'
path = "/usr/lib/vmware-vpxd-svcs/scripts/linux/pre-start/tagging_grpc_registration.py"
with open(path, 'r') as f:
content = f.read()
old = '''raise Exception("Tagging grpc reregistration failed while"
" executing vpxd-svcs prestart commands")'''
new = '''self.logger.warning("Continuing despite reregistration failure"
" - will retry on next restart")'''
content = content.replace(old, new)
with open(path, 'w') as f:
f.write(content)
print("Patched successfully!")
PYEOF
**注意**: 这是临时方案。后续需要通过 vSphere Client 的证书管理功能正确更新 Lookup Service 中的服务注册证书,然后恢复原始脚本。
4.5 按顺序启动所有服务
# 1. 确保核心基础服务在运行
service-control --start lookupsvc
sleep 10
service-control --start vmware-vapi-endpoint
sleep 10
# 2. 启动 vpxd-svcs(关键!)
service-control --start vmware-vpxd-svcs
sleep 20
service-control --status vmware-vpxd-svcs # Running!
netstat -tlnp | grep 10080 # LISTENING!
# 3. 启动 vpxd
service-control --start vmware-vpxd
sleep 60
service-control --status vmware-vpxd # Running!
# 4. 启动所有剩余服务
service-control --start --all
sleep 30
# 5. 最终状态
service-control --status --all
netstat -tlnp | grep -E "10080|443|7444"
4.6 验证恢复
# vpxd-svcs 健康检查
curl -sk http://localhost:10080/invsvc/invsvc-health
# <status>GREEN</status> ✅
# vpxd 日志确认正常
tail -30 /var/log/vmware/vpxd/vpxd.log
# 正在处理 loginByToken、retrieveContent 等正常请求 ✅
# 所有服务状态
service-control --status --all
# 35+ 个服务 Running ✅
五、关键经验教训
5.1 STS 签名证书 ≠ VECS 证书
vCenter 有两套证书系统:
- **VECS 存储**:Machine SSL、Solution User 证书,可用 `certificate-manager` 更新
- **vmdir LDAP**:STS 签名证书,存在 `TenantCredential-1` 对象中,`certificate-manager` **不会更新**
certificate-manager 的 8 个选项覆盖了 VECS 证书,但不包含 STS 签名证书。这是 vCenter 7.0 的已知缺陷。
5.2 MACHINE_SSL_CERT 为空导致 STS 崩溃
STS 的 Tomcat 使用 VECSAwareSSLImplementation,从 MACHINE_SSL_CERT VECS 存储读取 SSL 证书。如果存储为空,STS connector 初始化直接失败。
检查方法:
/usr/lib/vmware-vmafd/bin/vecs-cli entry list --store MACHINE_SSL_CERT
# 如果 "Number of entries in store : 0" 就是空的
5.3 vmon 配置文件丢失的恢复
vmon 的服务配置文件在 /etc/vmware/vmware-vmon/svcCfgfiles/ 目录。如果丢失,可以从安装目录恢复:
| 服务 | 模板位置 |
|---|---|
| vpxd-svcs | `/usr/lib/vmware-vpxd-svcs/scripts/conf/vpxd-svcs-lin.json` |
| 其他 | 对应的 `/usr/lib/vmware- |
恢复后必须重启 vmon daemon:
service-control --stop vmware-vmon
service-control --start vmware-vmon
5.4 vmdir LDAP 认证方式
vmdir 不支持 SASL DIGEST-MD5 和 StartTLS,但支持:
- **LDAPS (636) + simple bind**: `ldapsearch -x -H ldaps://localhost:636 -D "cn=Administrator,cn=Users,dc=vsphere,dc=local" -W`
- **Python ldap3 库**:比命令行 ldapsearch 更可靠
5.5 服务启动顺序很重要
vmdir → vmafd → vmcad → STS → lookupsvc → vapi-endpoint → vpxd-svcs → vpxd → 其他
vpxd-svcs 依赖 STS(签发 SAML token)、lookupsvc(服务发现)、vpostgres(数据库)。必须按顺序启动。
六、预防措施
6.1 定期检查证书过期
# 检查所有 VECS 证书
for i in $(/usr/lib/vmware-vmafd/bin/vecs-cli store list); do
echo "=== $i ==="
/usr/lib/vmware-vmafd/bin/vecs-cli entry list --store $i --text | grep "Not After"
done
# 检查 VMCA 根证书
openssl x509 -in /var/lib/vmware/vmca/root.cer -noout -dates
# 检查 STS 签名证书(在 vmdir 中)
# 用 Python ldap3 查询 TenantCredential-1 对象
6.2 设置证书过期告警
建议创建 cron job 定期检查证书有效期,提前 30 天告警:
#!/bin/bash
# /etc/cron.weekly/check-vcenter-certs.sh
WARN_DAYS=30
NOW=$(date +%s)
for store in MACHINE_SSL_CERT machine vpxd vpxd-extension vsphere-webclient hvc wcp; do
/usr/lib/vmware-vmafd/bin/vecs-cli entry list --store $store --text 2>/dev/null | \
grep "Not After" | while read line; do
date_str=$(echo $line | awk '{print $3, $4, $5, $6, $7}')
exp_date=$(date -d "$date_str" +%s 2>/dev/null)
days_left=$(( (exp_date - NOW) / 86400 ))
if [ "$days_left" -lt "$WARN_DAYS" ]; then
echo "WARNING: $store certificate expires in $days_left days ($date_str)"
fi
done
done
6.3 vCenter 7.0 STS 证书续期
VMware KB 有专门的 STS 证书续期文档。关键点是: 1. STS 签名证书存在 vmdir LDAP 中,不在 VECS 2. certificate-manager 不更新 STS 证书 3. 需要用 certool 生成新证书,通过 LDAPS 更新 vmdir
七、故障处理决策树
vpxd-svcs 启动失败
├── 检查磁盘空间 → df -h
├── 检查 vpxd 日志 → tail /var/log/vmware/vpxd/vpxd.log
│ └── Connection refused to localhost:10080?
│ └── vpxd-svcs 没运行 → 检查 pre-start 日志
│ └── tail /var/log/vmware/vpxd-svcs/pre-start-vpxd-svcs.log
│ ├── "Signing certificate is not valid"?
│ │ └── STS 签名证书过期 → 检查/更新 vmdir 中的 TenantCredential-1
│ ├── "Invalid certificate"?
│ │ └── Lookup Service 服务注册中证书过期 → patch pre-start 脚本
│ └── "Service not found"?
│ └── vpxd-svcs.json 丢失 → 从安装目录恢复
├── 检查 STS 状态 → service-control --status vmware-stsd
│ └── STS 崩溃?
│ └── 检查 sts-runtime.log.stderr
│ └── "Failed to initialize connector"?
│ └── MACHINE_SSL_CERT 为空 → 生成并导入新证书
├── 检查 VMCA 根证书 → openssl x509 -in /var/lib/vmware/vmca/root.cer -dates
└── 检查 vmdir → service-control --status vmdird (或 vmafdd)
八、涉及的日志文件清单
| 日志文件 | 用途 |
|---|---|
| `/var/log/vmware/vpxd/vpxd.log` | vpxd 主服务日志,看 Authz 连接错误 |
| `/var/log/vmware/vpxd-svcs/pre-start-vpxd-svcs.log` | vpxd-svcs pre-start 脚本日志,**最关键** |
| `/var/log/vmware/vmon/vmon.log` | vmon 服务管理器日志,看服务启动/崩溃记录 |
| `/var/log/vmware/sso/sts-runtime.log.stderr` | STS Java 进程 stderr,看 Tomcat 崩溃原因 |
| `/var/log/vmware/sso/vmware-identity-sts.log` | STS 详细运行日志 |
| `/var/log/vmware/sso/sts-prestart.log` | STS pre-start 日志 |
九、涉及的配置文件清单
| 文件 | 用途 |
|---|---|
| `/etc/vmware/vmware-vmon/svcCfgfiles/vpxd-svcs.json` | vpxd-svcs 的 vmon 服务定义 |
| `/usr/lib/vmware-vpxd-svcs/scripts/conf/vpxd-svcs-lin.json` | vpxd-svcs 配置模板(恢复用) |
| `/usr/lib/vmware-vpxd-svcs/scripts/linux/pre-start/tagging_grpc_registration.py` | pre-start 脚本(gRPC 端点注册) |
| `/usr/lib/vmware-vpxd-svcs/lib/server/config/dataservice.properties` | vpxd-svcs 配置(端口等) |
| `/var/lib/vmware/vmca/root.cer` | VMCA 根证书 |
| `/etc/vmware/install-defaults/vpxd-svcs.int.http` | vpxd-svcs HTTP 端口(10080) |
十、关键命令速查
# === 证书操作 ===
# 列出所有 VECS 存储
/usr/lib/vmware-vmafd/bin/vecs-cli store list
# 查看某个存储的证书
/usr/lib/vmware-vmafd/bin/vecs-cli entry list --store MACHINE_SSL_CERT --text
# 导入证书到 VECS
/usr/lib/vmware-vmafd/bin/vecs-cli entry create --store MACHINE_SSL_CERT --alias __MACHINE_CERT --cert /tmp/cert.cer --key /tmp/cert.key
# 生成新证书(certool 配置格式: [Key = Value])
/usr/lib/vmware-vmca/bin/certool --genkey --privkey=/tmp/key --pubkey=/tmp/pub --server=localhost
/usr/lib/vmware-vmca/bin/certool --gencert --privkey=/tmp/key --cert=/tmp/cert --config=/tmp/cfg --Name=xxx --server=localhost
# === vmdir LDAP 操作 ===
# LDAPS 查询
ldapsearch -x -H ldaps://localhost:636 -D "cn=Administrator,cn=Users,dc=vsphere,dc=local" -W -b "dc=vsphere,dc=local" "(userCertificate=*)" dn
# === 服务管理 ===
service-control --status --all # 查看所有服务状态
service-control --start vmware-vpxd-svcs # 启动单个服务
service-control --start --all # 启动所有服务
service-control --stop vmware-vmon # 重启 vmon(重新加载配置)
# === 日志查看 ===
tail -50 /var/log/vmware/vpxd-svcs/pre-start-vpxd-svcs.log # 最关键的日志
tail -50 /var/log/vmware/vmon/vmon.log # vmon 日志
cat /var/log/vmware/sso/sts-runtime.log.stderr # STS 崩溃日志
结语
这次故障的核心教训是:vCenter 证书管理远比想象中复杂。certificate-manager 工具只管 VECS 证书,STS 签名证书需要单独处理。建议:
- **定期检查所有证书**,包括 VECS 和 vmdir 中的 STS 证书
- **了解证书层次结构**:VMCA Root → Machine SSL / Solution Users / STS Signing
- **保留配置文件备份**:`/etc/vmware/vmware-vmon/svcCfgfiles/` 目录
- **理解服务依赖链**:STS → SAML token → vpxd-svcs pre-start → vpxd-svcs → vpxd
希望这篇文章能帮助遇到同样问题的同行。如果有疑问,欢迎留言交流。
最后更新:2026-06-25






