做VMware运维的兄弟,对VCF 9.0这个版本应该不陌生。它是VMware Cloud Foundation的最新大版本,把计算、存储、网络、云管理全部揉进一套SDDC里统一管。表面上看起来,vCenter、NSX、Aria Operations这些组件都还在,但管理入口和操作模型已经变了很多。尤其是“操作对象”这个词,熟练用vSphere的人第一次切到VCF界面,十有八九会懵一下——以前是单个集群、单台主机去点看,现在是按工作负载域、按资源对象去看。而跟“操作对象”强绑定的“指标报告”,就成了日常运维里最绕不开、也最消耗时间的一件事。
我写这篇内容,就是想把VCF 9.0环境里围绕操作对象的指标采集、聚合、导出、分发这一整套流程做成自动化,分享一套我自己在真实环境里反复打磨过的方案。它不是什么高深的研究课题,就是很朴素的运维自动化需求:每周定时拉取集群、主机、虚拟机、存储的性能和容量指标,生成一份结构化报告,推送给需要的人,中间几乎不需要人介入。适合正在用VCF 9.0做生产环境运维、被手工报表折磨得够呛的同行参考。我尽量把选型逻辑、脚本细节、踩坑过程都讲透,你照着做,至少能把“每周一上午花两小时导Excel”这件事彻底终结掉。
1. 为什么要把VCF 9.0指标报告做成自动化 —— 需求拆解
先别急着写代码。我得先跟你对齐几个概念,不然后面所有操作你都会觉得悬浮。
1.1 操作对象到底是什么
在VCF 9.0的语境里,“操作对象”不是某个抽象的管理术语,而是指你在平台上能监控、能采集、能操作的所有被管资源实体。按我的习惯,会把它分成四类:
- 工作负载域级对象:比如Management Domain、VI Domain这类逻辑边界,VCF把多个vCenter Cluster打包成一个域,你在这个层级看的是整体容量和健康度。
- 计算与虚拟化对象:vCenter Server、Cluster、ESXi主机、Resource Pool、虚拟机。这是传统vSphere里最熟悉的维度。
- 存储对象:Datastore、存储策略、vSAN集群、容量和IO延迟都要在这里看。
- 网络对象:NSX分段、Tier-0/Tier-1网关、分布式防火墙规则的状态和流量数据。
为什么要区分这四类?因为每类对象的指标来源不一样。计算对象的指标可以在vCenter里拉,存储对象的指标部分要在vSAN或存储设备侧拿,网络对象的指标得从NSX的API出。如果你不做区分,直接用vCenter的性能API一把梭,出来的报告会缺不少关键信息。
1.2 手工报告模式的瓶颈:哪条线该自动化
我见过太多团队,VCF都上了9.0,指标报告还在用最原始的方式:登录Aria Operations,手工选择对象和时间范围,导出PDF或Excel,再把多个导出文件手工合并成一个汇报材料。这套流程真的能跑,但很痛。我把痛点分成三个层次:
- 规模痛点:当被管对象超过200个节点之后,手工导出Aria Operations的报表会非常慢。一个包含50台主机、400台虚机的报告,光等导出就要10分钟以上,而且数据列经常被截断。
- 时效痛点:领导要的是“本周趋势”,手工报告往往滞后一到两天。而自动化脚本只要定时任务设置好,周一早上8点报告准时躺进邮箱。
- 口径痛点:不同人导出来的报告,指标口径可能不一样。有人看实际使用率,有人看峰值使用率,有人看已分配容量。自动化脚本可以把口径固化在代码里,避免“这个月报告和上个月对不上”的尴尬。
我的分界线很简单:如果报告周期短于一周、对象数量超过50个、或者需要把多个域的指标合并到一张表里,这三条占任意一条,都应该走自动化。占两条以上,你还在手工做,那纯粹是透支自己的时间。这条分界线我建议你直接抄。
2. 技术路线选型:三条常见方案怎么选
目标清楚了,方案就好谈了。VCF 9.0环境下做指标报告自动化,大体上有三条路。
2.1 三种方案对比
我把三条主流路线放在一个表里对比,你在实际环境里大概率也就碰到这三个选择。
| 方案 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|
| PowerCLI脚本 | 原生支持vCenter和VCF模块,做成ps1直接跑,对vSphere运维最友好 | 依赖Windows环境或PowerShell Core;处理表格数据的能力弱;跨域合并指标(vCenter+NSX+vSAN)要切换多个模块 | 临时采集、单域小型环境 |
| REST API + Python | 一次把VCF/vCenter/NSX的API吃透,能拿到最多维度的原始数据;pandas做聚合分析很强;代码跨平台 | 需要处理认证token、分页、限流;对不熟悉API的人有学习成本 | 中大型环境、跨域报告、长期自动化的首选 |
| Aria Operations开箱报表+大数据导出 | 界面操作简单,自带很多现成Dashboard;支持计划任务触发报告导出 | 定制性差,很难把多对象合并成同一张自定义表;部署在VCF之上的自带报表对非标准需求经常水土不服 | 指标口径要求简单、只要固定模板的场景 |
额外说一句,互联网上常提的Ansible自动化运维、Agent之类的工具,在VCF 9.0的指标报告场景里我不推荐。Ansible擅长配置下发和状态巡检,而不是时间序列性能指标的采集聚合。指标报告的核心是“时序数据+统计分析”,Python的pandas在这一层几乎无解。
2.2 我的最终选择:Python + PowerCLI + SSH 的混合链路
我自己最终落地的方案,是一条混合链路:Python统一编排,PowerCLI按需补位,SSH/SFTP做跨平台文件分发。没有全押Python,也没有全押PowerCLI。原因很简单:
- VCF 9.0的SDDC Manager API能拿到工作负载域、主机、集群等对象的清单,这个接口很干净,用Python的requests直接调就行。
- vCenter的性能指标API(stats)在拿到MOR对象列表之后也能返回完整的时间序列数据,数据处理用pandas比PowerCLI处理CSV方便得多。这一层用Python是效率最优解。
- 但有些采集动作,比如vSAN的健康状态、某些NSX告警详情,API文档藏得很深,直接调经常遇到权限和请求格式的坑。这个时候先用PowerCLI拿到结果导出成JSON,再交给Python做后续分析,是最省力的路径。
- 报告分发环节里,如果你的自动化采集机是一台Ubuntu,而接收方或共享存储是一台Windows服务器,就需要SFTP或SSH通道来传文件。这是我在真实环境里绕不开的“Ubuntu传文件到Windows”场景。
这条链路的优势在于每一层都可以单独替换。API认证方式变了就改采集函数;报告模板要换就只改Excel生成模块;文件传输协议要调就换分发模块。模块之间靠明确定义的中间文件打交道,而不是硬耦合。这条路我实测在600台虚机、80台主机的环境下,全流程跑完只需8~12分钟,比手工至少快一个数量级。
3. 实操落地:从环境准备到完整脚本
下面进入正题。我会按“准备环境 → 采集对象清单 → 拉取指标 → 生成报告 → 跨平台分发 → 定时调度”的顺序,把整套实现过程完整走一遍。
3.1 环境准备与最小权限账号
我在Ubuntu 22.04上跑这套自动化,Python版本是3.10。需要装的库有这么几个:
pip3 install requests pandas openpyxl paramiko jinja2requests:调VCF和vCenter的REST API。pandas:指标数据的清洗、聚合、透视。openpyxl:写Excel报告,支持图表、样式、多Sheet。paramiko:实现SFTP跨平台文件传输(Ubuntu采集机 → Windows报告服务器)。jinja2:如果你不想用Excel,想生成HTML邮件正文,这个很管用。不是必需,但我强烈建议装。
账号准备这个环节,我踩过一次大坑,必须提醒你:千万别用vCenter的 administrator@vsphere.local 账号去跑脚本。虽然权限够了,但这个账号一旦在自动化代码里泄露,等于整个SDDC门户大开。正确做法是创建一个只读服务账号,在vCenter里分配只读角色,在Aria Operations里分配Viewer权限,在VCF SDDC Manager里分配View权限。最小权限原则不是安全团队的教条,是运维自动化必须有的底线。
账号信息也不要明文写死在脚本里。我在环境变量里放,或者用一个加密的配置文件存。脚本里这样读:
import os VCF_HOST = os.environ.get("VCF_HOST") VCF_USER = os.environ.get("VCF_USER") VCF_PASS = os.environ.get("VCF_PASS") VC_HOST = os.environ.get("VC_HOST")这个习惯越早养成越好,后面做Jenkins或者Cron调度时,密钥管理都会顺手很多。
3.2 指标数据采集:REST API + 对象清单
流程上,我会先把“操作对象清单”拿全,这是后面一切指标采集的基础。第一步调VCF的API,拿到所有工作负载域和关联的vCenter:
import requests import json def get_vcf_domains(): url = f"https://{VCF_HOST}/v1/domains" resp = requests.get(url, auth=(VCF_USER, VCF_PASS), verify=False) resp.raise_for_status() return resp.json().get("contents", [])这里有个常量要留意:VCF 9.0默认API访问token有效期一般是1800秒。如果脚本运行时间超过这个阈值,后半段调用会突然401。我的习惯是拿到token后,写一个自动刷新函数,每10分钟检查一次。
接着是用vCenter的API拉对象清单和指标。vCenter 7之后性能指标走的是/rest/com/vmware/cis/monitoring/perf接口,不过更通用的做法是直接用PowerCLI先导出To JSON。为什么我在这里绕一下?因为vCenter的API返回的是性能计数器ID,你得先去查每个计数器指标的含义,再拼成TOKEN去取数值,这套流程繁琐程度极高,调试一次就够呛。而PowerCLI的Get-VMHost、Get-VM、Get-VMHostsStatistics这些cmdlet封装好了,直接导出CSV或JSON给Python处理,开发效率翻倍。
# 用PowerCLI导出主机性能指标 Connect-VIServer -Server $vcHost -User $vcUser -Password $vcPass Get-VMHost | Select Name, State, ConnectionState, CpuUsageMhz, CpuTotalMhz, MemoryUsageGB, MemoryTotalGB | Export-Csv -Path /tmp/host_stats.csv -NoTypeInformation Disconnect-VIServer -Confirm:$falsePowerCLI导出的CSV进入Python之后,我按天做归一化,再按周聚合:CPU峰值使用率、平均使用率、内存峰值、磁盘读延迟、写延迟、IOPS等,一个pandas DataFrame轻松算完。这一步就是纯数据处理,网上有很多现成套路。
vSAN存储指标和NSX网络指标,我走同一个逻辑:能API拿就用API,API麻烦就先用CLI或PowerCLI把原始数据导出,Python统一消费。核心思路是“所有的原始数据都落成CSV/JSON中间文件,Python做最终分析”,这样采集端和分析端完全解耦。
3.3 报告生成与跨平台分发:Excel、邮件、SFTP
数据聚合完成,接下来是把DataFrame变成一份能看的报告。
我用openpyxl生成Excel,结构是这样的:第一个Sheet放“域概览”,第二个Sheet放“集群与主机性能Top10”,第三个Sheet放“虚拟机资源使用排行”,第四个Sheet放“存储容量与延迟”,第五个Sheet放“网络流量摘要”。每个Sheet里的数据都是从pandas透视表直接填入。
关键代码:
from openpyxl import Workbook from openpyxl.styles import Font, PatternFill from openpyxl.utils.dataframe import dataframe_to_rows wb = Workbook() ws = wb.active ws.title = "域概览" # 把聚合好的DataFrame写入Sheet for r in dataframe_to_rows(summary_df, index=False, header=True): ws.append(r) # 加一个简单的单元格样式,让标题行突出 for cell in ws[1]: cell.font = Font(bold=True) cell.fill = PatternFill(start_color="DDDDDD", end_color="DDDDDD", fill_type="solid")每一行的数据宽度要控制,比如虚拟机名称、CPU峰值、内存峰值、磁盘延迟、所属集群这些列,超过20列就会把Excel撑得没法看。我在生成之前会用pandas把列重命名成“主机名”“CPU峰值%”“内存峰值%”“读延迟ms”这样的短标题。
报告生成完,就要处理分发。我实测过三种方式最常用:
- 邮件推送:用
smtplib发HTML摘要+Excel附件。HTML摘要用jinja2渲染一个简单的表格模板,方便领导在手机上一眼看到关键数据。 - 本地留档:按日期命名保存,例如
report_20250113.xlsx,方便追溯历史。 - SFTP推送到Windows共享服务器:这就是热搜词里“Ubuntu传输文件到Windows”的典型落地场景。我用paramiko的SFTP实现:
import paramiko def sftp_upload(local_path, remote_path, host, username, password): transport = paramiko.Transport((host, 22)) transport.connect(username=username, password=password) sftp = paramiko.SFTPClient.from_transport(transport) sftp.put(local_path, remote_path) sftp.close() transport.close() print(f"uploaded {local_path} -> {remote_path}")这样的好处是公司领导在Windows的文件服务器上直接能看到报告,不必进Linux机器用命令行看,对非技术背景的同事绝对友好。
攻击和调度这块,我直接用Linux的crontab。每周一早上7点跑一次,大约8点半能出报告。如果你的环境里已有Jenkins,也可以包成Pipeline,但每周一次的固定报告我真没必要用Jenkins,一个cron表达式搞定的事情,增加一个重平台反而是负担。提醒一下:cron里的环境变量和交互式shell不同,python的requests依赖的代理设置要写清楚,否则脚本在cron里跑的时候会出现“明明手工能跑,定时就不行”的诡异情况。
4. 踩坑实录:常见问题与排查技巧
脚本能跑起来不算完,稳定跑半年不出问题才算。这块我把实际运行中遇到的高频问题整理成了速查表,你以后遇到类似情况可以直接对着查。
4.1 问题速查表
| 现象 | 原因 | 解决思路 |
|---|---|---|
| 脚本跑一半突然报401 | VCF或vCenter的token过期,默认有效期内调用超过时长 | 用refresh token定期更新,或拆分成短任务多次取token |
| 返回的对象列表只有25条 | API分页,未处理Page参数 | 循环拉取,直到返回数量小于pagesize |
| 指标的时间戳比本地时间偏差8小时 | API返回的是UTC时间 | 在pandas里统一tz_localize再tz_convert,保证报告时间口径一致 |
| Excel报告打开时提示文件损坏 | openpyxl写入时同时操作多个ws导致流未正常关闭 | 确保wb.save()在finally块里执行,且文件路径无中文字符 |
用了verify=False但requests报SSL错误 | 目标环境启用了自签名证书,requests版本较新 | 指定requests.packages.urllib3.disable_warnings(),并显式传入verify=False |
| cron跑不执行但手工执行正常 | cron环境变量缺失,python命令行路径问题 | cron里用绝对路径写python和脚本路径,并在脚本开头导出PATH |
| 拉取大量历史指标时报HTTP 500 | 一次性query的时间区间太长,API内存爆掉 | 按天分段拉取,每天240个采样点(5分钟间隔)为一段,合并后做周聚合 |
这些坑不是从官方文档翻出来的,是我真实环境里被绊倒过的地方。每一条后面都有一次加班调的回忆。尤其是UTC时间偏差那个问题,我第一版报告拿到手发现所有趋势图的峰值全部偏移了8小时,查了整整一个上午才定位到是时区问题。
4.2 我个人几次事故换来的经验
除了速查表,还有几条更细的经验,写在这里供你参考。
第一,关于采集粒度和报告粒度的匹配。vCenter里性能采集默认间隔是5分钟,意味着一天最多288个采样点。但如果你做的是“季度容量趋势”报告,没必要按5分钟粒度全量拉取,存储开销和API压力都很大。我后来改成:近7天报告用30分钟粒度,月报用2小时聚合,季度报只取日聚合值。这套方案基本能覆盖绝大部分场景,而且报告体积小很多,生成速度快了四五倍。
第二,写脚本一定要留运行日志。我在脚本里对每次API调用、每个步骤的完成状态、耗时都记录到run.log里。字段包括时间、调用的URL、HTTP状态码、返回的数据量。排查问题时,日志比什么debug工具都好使。没有日志,遇到“上周还好好的这周突然没报告”的情况,你只能干瞪眼。
第三,报告里的指标口径要单独写一个说明文件。比如“CPU使用率”在报告里究竟是指平均使用率还是峰值使用率,“容量”是已分配容量还是实际已用容量,这些在Excel里完全不直观。我在报告末尾加了一个“指标口径说明”隐藏Sheet,领导问起来直接把Excel甩给他看。省掉了太多解释成本。
第四,绝对不要在生产上试跑第一版脚本就做大范围批量拉取。先在测试域里跑通一个集群两条指标,确认数据准确了,再扩展到全量。我那次直接全量拉取vSAN指标,把存储API整到超时,生产环境监控一度中断,虽然后来恢复了,但那个教训足够我记一辈子。
5. 把这套机制扩展成自动化平台
在基础脚本跑顺之后,我建议你再往前迈一步:把“脚本”变成“平台化工具”。这一步不一定急,但方向比我现在做的多出很多可能性。
5.1 用pytest把采集脚本变成可回归的自动化测试
指标报告最怕的问题就是“改了模板之后,老数据对不上”。我在第二版就引入了pytest做回归测试。核心思路是:写几种固定的测试用例,每次改代码后跑一遍,确保核心指标函数输出不变。
比如测试“周聚合函数”的输入输出是否一致:
def test_weekly_aggregation(): raw_data = load_sample_csv() expected_peak = 86.5 actual_peak = weekly_peak_cpu(raw_data) assert abs(actual_peak - expected_peak) < 1e-6这个习惯坚持下来,半年后迭代版本从1.0到2.3,几乎没有因为改代码影响过线上报告。这算是自动化环节里容易被忽略但极其有价值的一步。
5.2 调度、日志、告警的闭环
自动化平台不能“只管生成报告”,还要管“没生成报告的告警”。
我用一个很轻量的方式实现这个闭环:在cron跑完所有任务后,追加一个check_report_exists.py的脚本,它检查当天的报告文件是否生成成功、文件大小是否大于某个阈值(比如100KB)、Excel里的Sheet数量是否等于预期值。如果失败,就调用企业微信或钉钉机器人webhook推送一条告警。这样即使脚本半夜挂了,你早上起床第一眼就能知道,而不是等领导来问“今天的报告呢?”才发现。
日志统一输出成JSON结构,按天归档。走到这一步,你手里这套东西已经不是“每周跑一次的小脚本”,而是一个有监控、有告警、有回归测试的迷你自动化平台。后续如果团队预算充足,可以直接把它包装成Jenkins Pipeline,在同一个仪表盘上同时管多个域的指标报告任务。
结尾
我最后的体会是:这类运维自动化工程,真正难的不是第一次跑通,而是让它稳定、口径清晰、可追溯。报告为别人而写,但其价值在它持续、准确地输出,让人放心依赖。运营这个系统时,我最大的感受是“把重复劳动交给机器,把时间留给自己去处理真正重要的故障和规划”。
最后再分享一个小技巧:给你的报告文件名加上“报告周期”和“生成耗时”。一份10分钟完成、2.3秒生成的周报告,能让所有用报告的人对齐时间的信任感。