第1章:Python环境与IB工具链准备

说实话,做IB网络运维自动化,第一步不是写代码,而是把环境搭好。我见过太多人上来就pip install,结果装了一堆冲突的包,最后全删了重来。嗯,咱们先把地基打牢。

1.1 Python3环境搭建

现在都2025年了,Python2早就退休了。我个人习惯用Python3.8以上版本,太老的版本有些库不支持。

Linux环境(CentOS/RHEL 7/8/9)

# 检查是否已安装
python3 --version

# 如果没有,用yum或dnf安装
sudo yum install -y python3 python3-devel

# Ubuntu/Debian系
sudo apt install -y python3 python3-dev python3-venv

我在项目中遇到过一个问题:系统自带的Python3版本太旧,比如CentOS 7默认是3.6。这时候我建议用源码编译安装,或者用EPEL源升级。

小技巧: 装完Python后,记得把pip也升级一下。
python3 -m pip install --upgrade pip

1.2 pip与虚拟环境

为什么一定要用虚拟环境?说白了,就是隔离依赖。你想想看,项目A需要paramiko 2.0,项目B需要paramiko 3.0,装在一起就打架了。

创建虚拟环境

# 创建
python3 -m venv ib_automation_env

# 激活
source ib_automation_env/bin/activate  # Linux/Mac
ib_automation_env\Scripts\activate     # Windows

# 退出
deactivate

我曾经犯过一个错:直接在系统环境里装了一堆包,结果某次升级把系统工具搞崩了。从那以后,每个项目我都老老实实用虚拟环境。

常用pip命令

命令 说明
pip list 查看已安装包
pip freeze > requirements.txt 导出依赖清单
pip install -r requirements.txt 批量安装依赖
pip show 包名 查看包详情

1.3 IB常用命令行工具

做IB网络运维,这几个命令你得闭着眼睛都能敲。我刚开始接触IB网络时,就是靠这几个命令一点点摸清网络状况的。

ibstat — 查看端口状态

# 查看所有IB端口
ibstat

# 输出示例
CA 'mlx5_0'
    Port 1:
        State: Active
        Physical state: LinkUp
        Rate: 100
        Base lid: 2
        LMC: 0
        SM lid: 1
        Capability mask: 0x0251486a
        Port GUID: 0x248a070300a1b2c3
        Link layer: InfiniBand

注意看State字段,如果是Active且Physical state是LinkUp,说明链路正常。我曾经排查过一个间歇性断连的问题,就是靠ibstat发现端口在Active和Down之间反复跳变。

ibstatus — 快速概览

ibstatus

Infiniband device 'mlx5_0' port 1 status:
    default gid:     fe80:0000:0000:0000:248a:0703:00a1:b2c3
    base lid:        0x2
    sm lid:          0x1
    state:           4: ACTIVE
    phys state:      5: LinkUp
    rate:            100 Gb/sec (4X EDR)

ibstatus比ibstat更简洁,适合快速看一眼。我个人习惯先用ibstatus扫一遍,发现问题再用ibstat细查。

ibv_devinfo — 设备详细信息

ibv_devinfo -d mlx5_0

hca_id: mlx5_0
    transport:                      InfiniBand (0)
    fw_ver:                         16.32.1000
    node_guid:                      248a:0703:00a1:b2c3
    sys_image_guid:                 248a:0703:00a1:b2c6
    vendor_id:                      0x02c9
    vendor_part_id:                 4115
    hw_ver:                         0x0
    board_id:                       MT_0000000010
    phys_port_cnt:                  1

这个命令能拿到固件版本、硬件型号这些信息。做资产盘点或者固件升级时,它特别好用。

核心知识点: 这三个命令的关系就像体检——ibstatus是量体温测血压,ibstat是拍X光片,ibv_devinfo是做CT扫描。日常巡检用ibstatus,排查问题用ibstat,深度诊断用ibv_devinfo。

1.4 Python调用系统命令的几种方式

自动化脚本的核心,就是用Python去调用这些IB命令行工具。这里有几种方式,我按推荐程度排个序。

方式一:subprocess模块(推荐)

import subprocess

# 执行命令并获取输出
result = subprocess.run(
    ['ibstat'],
    capture_output=True,
    text=True,
    check=True
)
print(result.stdout)

# 带参数
result = subprocess.run(
    ['ibv_devinfo', '-d', 'mlx5_0'],
    capture_output=True,
    text=True
)

# 检查返回值
if result.returncode == 0:
    print("命令执行成功")
else:
    print(f"错误信息: {result.stderr}")

为什么推荐subprocess?因为它安全、灵活。我见过有人用os.system(),结果命令注入出了大问题。subprocess的列表传参方式天然防注入。

方式二:os.system(不推荐)

import os

# 简单粗暴,但拿不到输出
exit_code = os.system('ibstat')
# 只能拿到退出码,0表示成功
避坑指南: 我曾经用os.system写过一个批量巡检脚本,结果某台机器的IB卡名里有个空格,命令直接炸了。从那以后,我再也不用os.system调外部命令了。

方式三:shutil.which + subprocess(最稳妥)

import shutil
import subprocess

# 先确认命令是否存在
ibstat_path = shutil.which('ibstat')
if ibstat_path is None:
    raise FileNotFoundError("ibstat未安装或不在PATH中")

# 再用完整路径执行
result = subprocess.run(
    [ibstat_path],
    capture_output=True,
    text=True
)

这种方式适合写生产脚本。先检查命令是否存在,再执行,避免脚本跑到一半报错。

封装成函数

def run_ib_command(cmd, args=None):
    """通用IB命令执行函数"""
    import shutil
    import subprocess
    
    cmd_path = shutil.which(cmd)
    if not cmd_path:
        return f"错误: {cmd} 未找到"
    
    full_cmd = [cmd_path]
    if args:
        full_cmd.extend(args)
    
    try:
        result = subprocess.run(
            full_cmd,
            capture_output=True,
            text=True,
            timeout=30  # 超时保护
        )
        return result.stdout if result.returncode == 0 else result.stderr
    except subprocess.TimeoutExpired:
        return f"错误: {cmd} 执行超时"
    except Exception as e:
        return f"错误: {str(e)}"

# 使用示例
print(run_ib_command('ibstat'))
print(run_ib_command('ibv_devinfo', ['-d', 'mlx5_0']))
我的经验: 封装函数时一定要加timeout参数。IB命令有时候会卡住,不加超时的话,整个脚本就挂在那了。我吃过这个亏,凌晨3点被电话叫醒,就是因为脚本卡住没发告警。

知识体系总览

下面这张图,把本章的核心内容串起来了。你可以把它当作一个检查清单,看看自己掌握了哪些。

第1章:Python环境与IB工具链准备 Python3环境 • 版本选择(3.8+) • 安装方式(yum/apt/源码) • pip升级 • 虚拟环境隔离 IB命令行工具 • ibstat(端口状态) • ibstatus(快速概览) • ibv_devinfo(设备详情) • 固件版本查询 • 端口速率/状态诊断 Python调用系统命令 • subprocess(推荐) • os.system(不推荐) • shutil.which + subprocess • 封装通用函数 • 超时与异常处理 核心目标:搭建可复用的IB网络自动化开发环境 环境隔离 → 命令熟练 → 安全调用 → 封装复用

这张图把本章的三个核心模块串起来了:先搭好Python环境,再熟悉IB命令行工具,最后学会用Python安全地调用这些命令。每一步都是下一步的基础。


公众号:蓝海资料掘金营,微信deep3321