服务器BMC带外管理实战:IPMI批量配置与Redfish API自动化运维

服务器带外管理是服务器运维的基础能力。BMC(Baseboard Management Controller)独立于操作系统运行,通过IPMI或Redfish协议提供远程电源控制、硬件监控、系统日志和固件更新功能。当操作系统无响应或网络中断时,带外通道仍可访问服务器。本文围绕IPMI批量配置、Redfish API自动化和带外监控告警,给出完整的实战方案。

BMC带外管理原理与IPMI工具链配置

BMC是服务器主板上的独立管理芯片,拥有独立网口或共享网口,分配独立IP地址。即使服务器关机(只要电源插头连接),BMC仍保持在线。IPMItool是管理BMC的标准命令行工具,支持本地和远程操作。

# 安装IPMI工具
yum install -y ipmitool
# 或
apt install -y ipmitool

# 加载内核模块(本地操作时需要)
modprobe ipmi_devintf
modprobe ipmi_si

# 配置BMC网络(本地操作,需root)
ipmitool lan set 1 ipsrc static
ipmitool lan set 1 ipaddr 192.168.10.100
ipmitool lan set 1 netmask 255.255.255.0
ipmitool lan set 1 defgw ipaddr 192.168.10.1
ipmitool lan set 1 access on

# 验证BMC网络
ipmitool lan print 1

# 创建BMC管理员账户
ipmitool user set name 3 ops-admin
ipmitool user set password 3 'StrongP@ssw0rd!'
ipmitool user enable 3
ipmitool channel setaccess 1 3 callin=on ipmi=on link=on privilege=4
ipmitool user priv 3 4 1

远程操作通过-H、-U、-P参数指定BMC地址和凭据:

# 远程电源控制
ipmitool -I lanplus -H 192.168.10.100 -U ops-admin -P 'StrongP@ssw0rd!' chassis power status
ipmitool -I lanplus -H 192.168.10.100 -U ops-admin -P 'StrongP@ssw0rd!' chassis power on
ipmitool -I lanplus -H 192.168.10.100 -U ops-admin -P 'StrongP@ssw0rd!' chassis power off
ipmitool -I lanplus -H 192.168.10.100 -U ops-admin -P 'StrongP@ssw0rd!' chassis power cycle
ipmitool -I lanplus -H 192.168.10.100 -U ops-admin -P 'StrongP@ssw0rd!' chassis power reset

# 硬件状态查看
ipmitool -I lanplus -H 192.168.10.100 -U ops-admin -P 'StrongP@ssw0rd!' sensor list
ipmitool -I lanplus -H 192.168.10.100 -U ops-admin -P 'StrongP@ssw0rd!' sel list
ipmitool -I lanplus -H 192.168.10.100 -U ops-admin -P 'StrongP@ssw0rd!' fru print

# 清除SEL(系统事件日志)
ipmitool -I lanplus -H 192.168.10.100 -U ops-admin -P 'StrongP@ssw0rd!' sel clear

批量服务器IPMI配置自动化脚本

机房环境下数十台服务器的BMC需要统一配置。使用Python脚本批量执行IPMI命令,配置文件驱动,支持并发执行:

#!/usr/bin/env python3
import subprocess
import json
import concurrent.futures
from dataclasses import dataclass

@dataclass
class ServerBMC:
    hostname: str
    bmc_ip: str
    bmc_user: str
    bmc_password: str
    os_ip: str  # 操作系统IP(用于关联)

def load_bmc_inventory(path: str) -> list[ServerBMC]:
    with open(path, 'r', encoding='utf-8') as f:
        data = json.load(f)
    return [ServerBMC(**item) for item in data]

def ipmi_command(bmc: ServerBMC, command: str) -> dict:
    cmd = [
        'ipmitool', '-I', 'lanplus',
        '-H', bmc.bmc_ip,
        '-U', bmc.bmc_user,
        '-P', bmc.bmc_password,
    ] + command.split()
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        return {
            'hostname': bmc.hostname,
            'bmc_ip': bmc.bmc_ip,
            'command': command,
            'returncode': result.returncode,
            'stdout': result.stdout.strip(),
            'stderr': result.stderr.strip(),
        }
    except subprocess.TimeoutExpired:
        return {
            'hostname': bmc.hostname,
            'bmc_ip': bmc.bmc_ip,
            'command': command,
            'returncode': -1,
            'stdout': '',
            'stderr': 'Timeout',
        }

def batch_config(servers: list[ServerBMC], commands: list[str], workers=10):
    results = []
    with concurrent.futures.ThreadPoolExecutor(max_workers=workers) as executor:
        futures = []
        for srv in servers:
            for cmd in commands:
                futures.append(executor.submit(ipmi_command, srv, cmd))
        for future in concurrent.futures.as_completed(futures):
            results.append(future.result())
    return results

servers = load_bmc_inventory('bmc_inventory.json')

# 批量执行:检查电源状态 + 查看SEL
results = batch_config(servers, [
    'chassis power status',
    'sel list',
])

for r in results:
    print(f"[{r['hostname']}] {r['command']}: {r['stdout'][:100]}")

实际运维中常用的批量操作场景包括:机房搬迁后批量设置BMC网络、安全审计后批量修改BMC密码、批量查看SEL日志排查硬件故障、批量重启无响应服务器。

Redfish API自动化运维实践

Redfish是DMTF推出的现代带外管理标准,基于RESTful API和JSON格式,替代IPMI的陈旧接口。主流服务器厂商(Dell iDRAC、HP iLO、Lenovo XCC、Supermicro)均已支持Redfish。Python redfish库简化API调用:

#!/usr/bin/env python3
import redfish
import json

# 连接BMC Redfish API
client = redfish.RedfishClient(
    base_url='https://192.168.10.100',
    username='ops-admin',
    password='StrongP@ssw0rd!',
    default_prefix='/redfish/v1',
    timeout=15,
    max_retry=3,
)
client.login(auth='session')

# 获取服务器基本信息
response = client.get('/redfish/v1/Systems/1')
system_info = response.dict
print(f"厂商: {system_info['Manufacturer']}")
print(f"型号: {system_info['Model']}")
print(f"序列号: {system_info['SerialNumber']}")
print(f"CPU: {system_info['ProcessorSummary']['Count']}核 {system_info['ProcessorSummary']['Model']}")
print(f"内存: {system_info['MemorySummary']['TotalSystemMemoryGiB']} GB")
print(f"电源状态: {system_info['PowerState']}")

# 远程电源控制
client.post('/redfish/v1/Systems/1/Actions/ComputerSystem.Reset',
            body={'ResetType': 'On'})
client.post('/redfish/v1/Systems/1/Actions/ComputerSystem.Reset',
            body={'ResetType': 'ForceRestart'})
client.post('/redfish/v1/Systems/1/Actions/ComputerSystem.Reset',
            body={'ResetType': 'GracefulShutdown'})

# 获取传感器温度数据
temp_response = client.get('/redfish/v1/Chassis/1/Thermal')
for sensor in temp_response.dict.get('Temperatures', []):
    print(f"{sensor['Name']}: {sensor['ReadingCelsius']}C (上限: {sensor['UpperThresholdCritical']}C)")

# 获取磁盘健康状态
storage = client.get('/redfish/v1/Systems/1/Storage')
for drive in storage.dict.get('Drives', []):
    drive_resp = client.get(drive['@odata.id'])
    d = drive_resp.dict
    print(f"磁盘 {d['Id']}: {d['Name']} 状态: {d['Status']['Health']} 容量: {d['CapacityBytes']//1024//1024//1024}GB")

# 设置虚拟媒体(远程挂载ISO镜像安装系统)
client.post('/redfish/v1/Managers/1/VirtualMedia/1/Actions/VirtualMedia.InsertMedia',
            body={
                'Image': 'https://nfs-server/images/ubuntu-22.04.iso',
                'Inserted': True
            })
# 设置下次启动从虚拟CD-ROM引导
client.patch('/redfish/v1/Systems/1',
              body={'Boot': {'BootSourceOverrideTarget': 'Cd', 'BootSourceOverrideEnabled': 'Once'}})
# 重启生效
client.post('/redfish/v1/Systems/1/Actions/ComputerSystem.Reset',
            body={'ResetType': 'ForceRestart'})

client.logout()

带外监控集成与硬件告警自动化

将BMC监控数据接入Prometheus,实现硬件级别告警。使用redfish-exporter采集Redfish指标:

# docker-compose.yml 部署redfish-exporter
version: '3.8'
services:
  redfish-exporter:
    image: umgsoftware/redfish-exporter:latest
    ports:
      - "9610:9610"
    environment:
      - REDFISH_TIMEOUT=15
    volumes:
      - ./redfish_targets.yml:/etc/redfish_exporter/targets.yml

# redfish_targets.yml
targets:
  - name: web-01
    host: https://192.168.10.101
    username: ops-admin
    password: 'StrongP@ssw0rd!'
  - name: web-02
    host: https://192.168.10.102
    username: ops-admin
    password: 'StrongP@ssw0rd!'
  - name: db-01
    host: https://192.168.10.201
    username: ops-admin
    password: 'StrongP@ssw0rd!'

Prometheus告警规则覆盖硬件关键指标:

# 服务器温度超标
- alert: ServerTemperatureHigh
  expr: redfish_temperature_celsius{sensor=~"CPU.*"} > 85
  for: 2m
  labels:
    severity: critical
  annotations:
    summary: "{{ $labels.target }} CPU温度超过85C"

# 磁盘故障
- alert: DiskFailure
  expr: redfish_drive_health{health="Critical"} == 1
  for: 1m
  labels:
    severity: critical
  annotations:
    summary: "{{ $labels.target }} 磁盘 {{ $labels.drive_id }} 状态异常"

# 电源模块故障
- alert: PowerSupplyFailure
  expr: redfish_power_supply_health{health="Critical"} == 1
  for: 1m
  labels:
    severity: warning
  annotations:
    summary: "{{ $labels.target }} 电源模块故障"

# 风扇停转
- alert: FanFailure
  expr: redfish_fan_rpm == 0
  for: 1m
  labels:
    severity: critical
  annotations:
    summary: "{{ $labels.target }} 风扇 {{ $labels.fan_name }} 停转"

带外监控与操作系统层面的监控形成互补。当OS无响应时,带外通道仍能报告硬件状态,帮助快速定位是硬件故障还是系统问题。批量BMC配置脚本配合Redfish API自动化,百台规模服务器机房的带外管理效率可从逐台手工操作提升到分钟级批量完成。固件升级也通过Redfish API批量推送,避免人工逐台登录BMC Web界面操作。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/fu-wu-qi-bmc-dai-wai-guan-li-shi-zhan-ipmi-pi-liang-pei-zhi/

(0)
小编小编
上一篇 6小时前
下一篇 6小时前

相关推荐