尧图精选

SMBIOS与Redfish详解:从硬件资产盘点到带外管理落地

🕒 发布时间:2026/10/2 10:27:57 📁 来源:尧图网络
前几天在一个服务器运维交流群里又有人问怎么才能从一台机器上一次性拿到厂商、型号、序列号、BIOS 版本、内存槽位和当前功率底下有人回“跑 dmidecode”有人回“开 IPMI 自己拉”还有人直接说“上 BMC 网页慢慢点”。我当时给的答案是把 DMTF 这两套协议搞清楚这问题已经解决一大半——一套是 SMBIOS负责静态资产信息一套是 Redfish负责动态状态和带外管理。这篇是我准备写的 DMTF 相关协议系列第一篇就拿 Redfish 和 SMBIOS 这两个最常用的协议把它们“各自管什么、怎么配合、怎么落地”完整聊一遍。适合服务器运维、IDC 基础设施建设、硬件兼容性测试以及正在做资产系统或监控平台对接的朋友参考。1. 开篇先把底摸清DMTF 管着哪些服务器管理的事1.1 为什么这两年又得回头聊 DMTF 协议DMTF 全称 Distributed Management Task Force也就是分布式管理任务组。很多人第一次听到这个组织是因为见过它出的某一个标准但没太在意。实际上服务器管理领域绕不过去的好几个关键规范SMBIOS、Redfish、CIM/WBEM甚至曾经的 DASH都是 DMTF 在维护。这几年大家重新关注 DMTF核心原因很直接传统服务器管理方式已经不够用了。我举个例子以前机房里有几百台机器用 IPMI 拉硬件信息虽然能跑但那玩意儿是二进制协议返回的数据不直观想要对接自己的监控平台或者资产管理工具得自己写解码逻辑。而且不同厂商的网卡、功率、温度数据字段定义还不完全一样。Redfish 出来之后整个思路变了。它直接把带外管理接口做成了 HTTP 接口返回 JSON 数据像访问普通 Web API 一样就能拿到服务器状态。SMBIOS 则是从另一个维度补位它解决的是“操作系统内部看到的硬件信息”不需要带外网络开机就能读。一个是静态、带内、本地可读一个是动态、带外、网络可读两者正好形成互补。1.2 Redfish 和 SMBIOS两张牌各管哪一段我经常跟同事用一个比喻一台服务器相当于一个人SMBIOS 是写在身份证上的静态信息——姓名、籍贯、证件号基本不变化Redfish 则是体检报告和实时监护数据——心率、血压、体温随时在动而且能通过远程方式查看。对应到实际场景SMBIOS 主要在操作系统层面用比如 Linux 下的 dmidecode 工具、Windows 下的 msinfo32数据来源是固件在启动时留在内存里的 DMI 表。它包含厂商、产品型号、序列号、UUID、BIOS 版本、内存条信息、CPU 信息等适合做资产入库、硬件变更审计、序列号追溯。Redfish 则跑在 BMC 上走网络接口哪怕服务器操作系统挂掉了只要 BMC 还活着你依然能通过 Redfish 看到电源状态、温度、风扇转速、功耗甚至远程开关机、挂载镜像、升级固件。它适合做生产环境的带外监控、自动巡检、故障诊断和批量操作。这两套协议不是替代关系。真实落地的时候往往先靠 SMBIOS 把每一台机器的静态资产建档再靠 Redfish 把动态状态持续采集上来两边数据一拼才算把一台服务器管起来了。2. SMBIOS服务器固件里那张“硬件户口本”2.1 别被结构类型吓到Type 0/1/2/3/4/17 分别说什么SMBIOS 标准里有一个核心概念叫 Structure Type也就是结构类型。初次接触的人会被 Type 0、Type 1、Type 127 这些数字搞晕其实它就是一个编号体系每一种编号对应一类硬件信息。我列了一张常用表基本覆盖日常资产管理需求结构类型含义关键字段Type 0BIOS 信息厂商、版本、发布日期、BIOS 起始地址Type 1系统信息厂商、产品名、序列号、UUID、SKUType 2基板信息主板厂商、型号、序列号Type 3机箱/整机信息机箱类型、资产标签、机箱序列号Type 4处理器信息CPU 厂商、型号、频率、核心数、线程数Type 7缓存信息L1/L2/L3 缓存大小、结构Type 17内存设备内存类型、容量、频率、序列号、槽位Type 41设备类型板载设备、PCIe 设备类型与状态Type 127结束标记表示结构列表到此结束日常资产盘点用到最多的就是 Type 1、Type 2、Type 4 和 Type 17。Type 1 能拿到整机序列号和 UUIDType 2 能确认主板信息Type 4 和 Type 17 用来统计 CPU 和内存配置。这里有一个容易忽视的点SMBIOS 结构类型虽然全球统一但不同厂商往里填的字段完整度差别很大。有的服务器厂商会在 Type 1 里把产品名写得很规范比如 PowerEdge R750、SR650 V2但也有厂商只写一个非常含糊的内部代号这时候还需要结合 Type 2 和 Type 3 的信息综合判断。所以做资产系统的时候不要只依赖某一个字段多取几个字段做交叉校验更靠谱。2.2 实操Linux 下把 SMBIOS 信息读出来Linux 下最常用的 SMBIOS 读取工具是 dmidecode几乎所有的发行版软件源里都有。装好之后几条命令就能把关键信息捞出来# 读取系统整体信息Type 1 dmidecode -t 1 # 读取主板信息Type 2 dmidecode -t 2 # 读取 CPU 信息Type 4 dmidecode -t 4 # 读取内存信息Type 17 dmidecode -t 17如果不想看完整结构只想拿某个字段可以用-s参数直接取字符串这个在写脚本的时候特别方便dmidecode -s system-manufacturer dmidecode -s system-product-name dmidecode -s system-serial-number dmidecode -s system-uuid dmidecode -s bios-version除了 dmidecodeLinux 内核还会把一部分 DMI 信息暴露在/sys/class/dmi/id/目录下比如product_name、product_serial、bios_version。这种方式不依赖额外工具读取速度也更快适合在脚本里直接读取cat /sys/class/dmi/id/product_name cat /sys/class/dmi/id/product_serial cat /sys/class/dmi/id/bios_version做批量资产采集的时候我一般会配合 ssh 循环执行把每台机器的信息汇总成 CSV。比如这样一个小例子while read host; do echo -n $host, ssh $host dmidecode -s system-manufacturer; dmidecode -s system-product-name; dmidecode -s system-serial-number | tr \n , echo done servers.txt assets.csv这种采集方式不需要操作系统上装 agent只要 SSH 能通就能拿到完整的资产信息。对于已有操作系统运行的老旧机器是最快的摸底手段。2.3 SMBIOS 读数的三个经典坑第一坑虚拟机里的 SMBIOS 信息会被虚拟化软件改写。在 VMware、Proxmox、Nutanix 这类虚拟化平台上默认看到的产品名往往是“VMware Virtual Platform”或者“KVM”这类字样序列号也可能变成虚拟机的 UUID。这不能怪厂商因为虚拟化平台本来就会拦截并改写 DMI 数据。碰到这种情况要在宿主机层面去读取物理硬件的 SMBIOS而不是在虚拟机里读。第二坑同一个字段不同厂商的写法规格不同。比如内存信息有的厂商 Type 17 里会写清楚 Part Number 和序列号有的厂商则留空。又比如机箱资产标签Dell 喜欢写到 Type 3Lenovo 可能写到 Type 11 OEM 字符串里。做兼容性比较多的朋友应该深有体会所以解析的时候不能假设所有字段都有值代码里必须做空值兜底。第三坑UUID 字段的字节序问题。这个问题在后面的常见问题部分我会展开讲这里先提醒一句SMBIOS Type 1 里的 UUID 格式跟 RFC 4122 标准 UUID 不是完全一致的直接用 dmidecode 看到的结果和 Redfish 接口返回的 UUID 有可能会对不上。不是数据错了而是字节序转换规则不同。3. Redfish让带外管理接口长成 REST 风格是什么体验3.1 为什么大家要放弃 IPMI 投奔 Redfish在 Redfish 之前带外管理几乎就是 IPMI 的天下。IPMI 本身非常稳定很多老机房到现在还在跑但它的体验确实跟不上时代了。IPMI 走的是 RMCP 协议默认 UDP 623 端口返回的数据是二进制结构想拿到一条内存信息还要按偏移量手动解析开发效率很低。Redfish 最大的改变是把整个带外管理数据模型做成了基于 RESTful 架构的 HTTP/HTTPS 接口数据格式统一使用 JSON并且用 Schema 来描述资源结构。这意味着什么呢意味着你可以像调用微信公众号接口、支付接口一样用 curl、Python requests、甚至浏览器直接去请求服务器 BMC拿到结构化的数据。前端监控页面要展示温度曲线直接拉一次 Redfish Thermal 接口然后画图就行。Redfish 还有一个很实用的能力叫事件订阅也就是 EventService。BMC 可以主动把新事件推送到你指定的 Webhook 地址比如电源异常、风扇故障、温度过高这些事件会实时推送不用你反复去轮询。这个能力对监控告警来说非常省事我在后面的实操部分会给出一个订阅示例。3.2 入门 Redfish 先背下这套资源树Redfish 的 URL 结构可以用“资源树”来理解根节点固定是/redfish/v1/。从根节点出发最常见的就是这几个主干资源路径作用/redfish/v1/服务根入口列出所有服务/redfish/v1/Systems/计算机系统也就是逻辑服务器/redfish/v1/Chassis/机箱/硬件容器包含电源、温度、风扇/redfish/v1/Managers/BMC 管理控制器本身/redfish/v1/AccountService/账号服务管理本地用户/redfish/v1/SessionService/会话服务负责登录令牌/redfish/v1/UpdateService/固件更新服务/redfish/v1/EventService/事件服务支持订阅推送在 Systems 下面每一台逻辑服务器会有一个 Id比如1或者System.Embedded.1这取决于厂商实现。访问/redfish/v1/Systems/1就能拿到这台服务器的完整信息里面包含 AssetTag、Manufacturer、Model、SerialNumber、ProcessorSummary、MemorySummary、PowerState 这些字段。在 Chassis 下面每一台物理机箱也会有对应的子资源比如/redfish/v1/Chassis/1/Thermal返回温度传感器和风扇数据/redfish/v1/Chassis/1/Power返回功耗和电源状态。如果你只需要资产信息一般只要访问 Systems 就行如果你要做硬件健康监控Thermal 和 Power 是重点。3.3 实操curl 五分钟把服务器健康状态抓出来假设你有一台带 BMC 的服务器IP 是192.168.10.11BMC 管理账号是admin密码是admin123。先用最基本的 Basic Auth 试试根路径是否通curl -k -u admin:admin123 https://192.168.10.11/redfish/v1/注意我这里加了-k参数因为大多数 BMC 默认使用的是自签名证书不加-k会报证书校验失败。这一步如果能正常返回 JSON说明 Redfish 服务已经在运行。然后看系统信息curl -k -u admin:admin123 https://192.168.10.11/redfish/v1/Systems/1 | jq .加了jq是为了格式化 JSON实测中如果字段太多可以只筛选关键字段curl -sk -u admin:admin123 https://192.168.10.11/redfish/v1/Systems/1 \ | jq {Id, Manufacturer, Model, SerialNumber, PowerState, CPU: .ProcessorSummary.Model, MemGB: .MemorySummary.TotalSystemMemoryGiB}接下来抓机箱功耗和温度。不同厂商的路径可能略有差异但大体都是走 Chassis 资源下面的 Thermal 和 Powercurl -sk -u admin:admin123 https://192.168.10.11/redfish/v1/Chassis/1/Power | jq .PowerControl[0] | {PowerConsumedWatts, PowerCapacityWatts} curl -sk -u admin:admin123 https://192.168.10.11/redfish/v1/Chassis/1/Thermal | jq .Temperatures[] | {Name, ReadingCelsius, Status}如果发现Systems/1返回 404说明这台机器的 System Id 不一定是1。可以先访问/redfish/v1/Systems看集合里到底有哪些成员再按返回的实际 Id 去请求。这是我刚开始用 Redfish 时踩得最频繁的坑。3.4 进阶Python 巡检脚本连捞一整个机柜curl 适合临时调试但只要机器数量一多还是要写脚本。DMTF 官方维护了一个redfishPython 库封装了会话管理、认证、请求重试这些重复工作拿来写巡检脚本很顺手。如果不想引入额外依赖直接用requests也能做。我用一个简化版示例说明批量巡检的思路脚本会遍历 BMC 列表去/redfish/v1/Systems/1拉资产和运行状态import requests import json import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) BMC_LIST [192.168.10.11, 192.168.10.12, 192.168.10.13] USERNAME admin PASSWORD your-password # 建议改为环境变量或密钥管理 def get_system_summary(bmc): base_url fhttps://{bmc}/redfish/v1 with requests.Session() as sess: sess.auth (USERNAME, PASSWORD) sess.verify False resp sess.get(f{base_url}/Systems/1, timeout10) resp.raise_for_status() data resp.json() return { bmc_ip: bmc, model: data.get(Model), serial: data.get(SerialNumber), power_state: data.get(PowerState), cpu: data.get(ProcessorSummary, {}).get(Model), mem_gb: data.get(MemorySummary, {}).get(TotalSystemMemoryGiB), } if __name__ __main__: results [] for ip in BMC_LIST: try: results.append(get_system_summary(ip)) except Exception as exc: results.append({bmc_ip: ip, error: str(exc)}) for item in results: print(json.dumps(item, ensure_asciiFalse))这里用 Session 而不是裸请求是为了复用连接减少 TCP 握手开销。另外在 BMC 数量较多的时候requests默认每请求都重新建连会慢很多用 Session 是第一个有效优化手段。如果你还想让巡检更省事一点Redfish 支持$expand参数。比如直接请求curl -sk -u admin:admin123 https://192.168.10.11/redfish/v1/Systems?$expand. | jq .Members[] | {Model, SerialNumber, PowerState}这会把集合里的每个成员详细数据直接嵌在返回结果里省去了逐个请求成员详情的步骤。不过注意$expand.返回的数据体量会大不少BMC 解析起来也慢一些。在大型机房里我会控制并发数或者只在数量少于几十台的场景下使用。4. 落地上手工具选型、认证配置与安全边界4.1 Redfish 常用工具横向对比接触 Redfish 的人常常纠结到底用哪种工具我的建议是分场景别只押一种。下面这张表是我自己平时常用的工具组合工具适用场景备注curl jq单台调试、临时验证、写简单脚本几乎任何机器都有redfish Python 库批量巡检、平台对接开发DMTF 官方维护支持 Schema 校验requests python轻量定制化采集不依赖第三方 redfish 库灵活PowerShell Invoke-RestMethodWindows 环境下快速验证原生支持 REST写起来也快Postman / Apifox接口开发调试适合看返回结构、测试 Token厂商 CLIracadm / ilorest 等厂商特有字段设置只能配合自家硬件使用如果你是刚上手我建议先装一个 Postman把所有 GET 请求都试一遍把返回结构看清楚。等到要写自动化脚本的时候再用 Python redfish 库。这里还要推荐一个用于没有物理机的练手方案DMTF 官方有开源的 Redfish Interface Emulator可以跑在本地模拟一套标准的 Redfish 资源树你在上面做认证测试、接口联调都没问题。我自己在开发监控脚本的时候就经常先在模拟器上把逻辑调通再拿到真机上去跑省了不少现场调试的时间。4.2 认证配置与账号安全我这么设置Redfish 一般支持两种认证方式Basic Auth 和 Session Auth。Basic Auth 就是每次请求都在 Header 里带上用户名密码简单直接但密码会反复出现在网络请求中而且 BMC 每次都要做一次认证校验性能也不好。更推荐的做法是先用登录接口换取 Session Token。具体流程是请求POST /redfish/v1/SessionService/Sessions带上用户名和密码成功后返回的X-Auth-Token后续放在请求头里用# 1. 登录获取 token curl -sk -u admin:admin123 -X POST \ https://192.168.10.11/redfish/v1/SessionService/Sessions \ -H Content-Type: application/json \ -d {} # 2. 使用 token 访问 curl -sk https://192.168.10.11/redfish/v1/Systems/1 \ -H X-Auth-Token: 上一步返回的tokenSession Token 有有效期也能主动注销整体比 Basic Auth 安全一些。账号安全方面我的底线是三条第一拿掉所有默认账号和默认密码第二BMC 管理口只放在独立管理网段或者管理 VLAN绝对不能直接暴露到公网第三给关键账号配置登录失败锁定策略防止被暴力试密码。证书的问题也不能忽略。很多 BMC 出厂自带的 SSL 证书是自签名的企业环境里最好能换成你们自己的 CA 签发的证书。如果暂时换不了至少要让脚本在连接时做好证书校验策略不能因为是内网就无脑跳过校验。4.3 SMBIOS 与 Redfish 怎么配合落地资产管理资产管理最忌讳的是“只用一种数据源”。我曾经见过一个项目一开始只靠 Redfish 拉设备信息后来发现部分老服务器的 BMC 固件版本太旧Redfish 接口返回的 SerialNumber 字段是空的。这时候如果旁边没有 SMBIOS 数据做兜底这批设备在资产系统里就成了一堆“未知设备”。正常的落地方式是这样的先在每台服务器操作系统层面跑一轮 SMBIOS 采集脚本把厂商、型号、序列号、BIOS 版本这些基础字段入库存档。再通过 Redfish 带上外管理信息比如 BMC 版本、电源状态、功耗、温度、固件版本。两者通过序列号做关联序列号就成了天然的主键。在维护阶段也是这样。SMBIOS 适合做周期性全量核对比如每个月跑一次全量资产扫描Redfish 适合做实时的状态监控比如每 5 分钟拉一次 PowerState 和健康状态。静态信息变化少动态信息变化快用不同的采集频率去适配既能保证数据新鲜度又不会给 BMC 带来太大压力。5. 常见问题速查与实战避坑记录5.1 Redfish 调不通按这四条排查第一类问题是 HTTPS 证书验证失败。这个最简单先加-k跳过证书校验确认接口能通再去解决证书信任问题。注意某些 BMC 固件对 TLS 版本有要求老设备可能只支持 TLS 1.0/1.1而新版 curl 默认禁用这种时候要显式指定--tlsv1.2或者更新 BMC 固件。第二类问题是认证失败返回 401。排查顺序是确认账号是不是有 Redfish 访问权限确认密码里是否有特殊字符被 shell 转义再确认是不是触发了账号锁定策略。我之前遇到过一台服务器的 BMC 因为之前登录失败次数过多账号被锁了 30 分钟排查了老半天才反应过来。第三类问题是资源路径不对返回 404。不同厂商对 System Id 的命名规则不一样有Systems/1的也有Systems/System.Embedded.1的。不要硬编码路径先访问/redfish/v1/Systems看返回集合再根据odata.id动态拼路径。第四类问题是网络不通。Redfish 走的是带外管理口不是业务网卡。很多新人在服务器上 curl 内网 IP发现怎么都不通最后发现 BMC 管理口和业务口本来就是两张网卡IP 也是分开配置的。先ping一下 BMC 管理 IP再确认防火墙放行了 443 端口这才是正经排查顺序。5.2 SMBIOS 里的 UUID 和 Redfish 对不上这是我在做多厂商设备数据比对时遇到最多的问题。同一台机器dmidecode -s system-uuid得到的结果和 Redfish/redfish/v1/Systems/1里的 UUID 字段看起来可能是完全不同的两个值。第一次遇到的时候我也以为哪里弄错了后来翻了 SMBIOS 规范和 RFC 4122 才明白两者对 UUID 的字节序处理不一致。SMBIOS Type 1 结构里的 UUID 字段前三个组是 little-endian后两个组按 big-endian 存储而标准 UUID 字符串是按 RFC 4122 的网络字节序呈现的。所以 Raw 数据在转换时要把前 3 个组做字节反转。如果你拿到的是一个 hex 字符串可以这样转import uuid def smbios_uuid_to_standard(raw_hex): # raw_hex 例如 4c4c4544-0031-2d4a-8048-b7c04f593331 clean raw_hex.replace(-, ) b bytes.fromhex(clean) return str(uuid.UUID(bytesb[:4][::-1] b[4:6][::-1] b[6:8][::-1] b[8:]))如果你是直接读 dmidecode 输出有些版本的 dmidecode 已经帮你做了一次格式化所以它显示的字符串很可能和 Redfish 返回的不一样。遇到这种差异不要急着改数据先用字节序转换脚本验证一下确认是同一个值再继续。5.3 巡检脚本批量抓取时的性能雷区Redfish 虽然好用但 BMC 的本质还是一个嵌入式系统CPU 和内存资源非常有限。我在帮客户做几千台机器巡检的时候最开始的脚本是每台机器起一个并发线程结果跑了一会儿就有 BMC 开始丢响应有些甚至直接重启了。后来跟厂商工程师聊了才知道BMC 的 IPMI/Redfish 服务对并发连接数是有限制的一台机器同时有几个连接还好几十个连接打过来直接就把 BMC 打挂了。所以批量巡检的正确姿势是控制并发度。我现在的做法是并发数控制在 8 到 16 之间每台机器请求之间加一点随机延时大概 0.2 到 0.5 秒避免所有请求同时打过来。同时给每个请求设置合理的超时时间比如 10 秒超时就直接标记为失败不要一直等下去。另一个优化思路是减少请求次数。像前面的$expand.技巧可以把一个集合里所有成员的详情一次拉回来。要抓多台机器的时候还可以使用批量操作接口用一次请求操作多个目标资源。但要注意这种深操作对 BMC 的消耗也更大要评估好自己硬件的能力不要盲目上。关于采集频率静态资产信息一天拉一次就够动态状态信息也不要低于 30 秒一轮。如果监控平台想看实时趋势现在很多 BMC 其实有自己的历史数据查询接口可以让 BMC 自己存监控端按需补充拉取而不是自己高频轮询。5.4 事件订阅没生效多半是这两处问题用 Redfish 做告警推送最省心的方式是配置事件订阅。我见过不少人在这一步翻车明明配置了 Destination 和 EventTypes事件却没有推过来。查了一圈问题大多出在两个地方。第一Destination 地址不对。BMC 只能访问到它网络能到达的地址如果你的告警接收服务在业务网段而 BMC 管理口在管理网段两边网络不同路由事件自然推不过来。先要在 BMC 侧确认Destination 指向的 HTTP/HTTPS 端口可达然后再做订阅。第二EventTypes 没有配对。不同固件支持的 EventTypes 不完全一样常见的有Alert、StatusChange、ResourceUpdated、ResourceAdded、ResourceRemoved。如果只订阅了Alert但实际告警走的是StatusChange也会收不到。稳妥的做法是先通过查询/redfish/v1/EventService/看固件暴露了哪些支持类型再按照固件实际支持的类型去订阅。我在生产环境里一般会写一个健康检查任务定期向接收端发送测试事件确认订阅链路没有因为 BMC 重启或者网络策略变更而失效。毕竟告警通道这种事等出事的时候再去验证就晚了。最后再分享一点实际动手的体会如果你现在正准备做一套服务器管理系统我个人的建议是先从 SMBIOS 把资产老底摸清楚再上 Redfish 管动态状态两条腿走路信息才不会缺腿。Redfish 接口虽然比 IPMI 友好太多但不同厂商的实现质量还是有差距遇到奇怪问题不要先怀疑自己代码先拿厂商自带的工具在 BMC 上手动验证一遍接口往往能快速缩小问题范围。还有一点平时多留心固件更新Redfish 这类基于 Schema 的协议厂商会在固件迭代里不断补全接口字段同一个型号的老固件和新固件返回的数据完整度可能差着不少。这个系列我后续还会继续拆 DMTF 的其他协议感兴趣的可以先对照着把 SMBIOS 和 Redfish 的基础字段梳理清楚后面再聊其他内容会顺很多。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →