2026/10/14 11:51:25

OpenStack实例创建报PortBindingFailed?排查Neutron端口绑定与物理网络映射

OpenStack实例创建报PortBindingFailed?排查Neutron端口绑定与物理网络映射 如果你在 OpenStack 环境里用 provider network 创建实例掉进PortBindingFailed: Binding failed for port ......的报错里别急着怀疑 Nova 调度问题大概率在 Neutron 的端口绑定环节。这个报错我前后踩过三轮每次都以为换一台计算节点就行结果发现根子在物理网络映射。本文把完整排障过程记录下来适合正在维护 OpenStack 控制面或者被端口绑定折磨的同行参考。1. 报错现场创建实例时PortBindingFailed到底长什么样1.1 第一次看到这个报错时的三个直观印象当时我在命令行执行创建实例大概是这样openstack server create \ --flavor m1.small \ --image cirros \ --network provider-net \ test-vm命令本身没有任何异常输出实例 ID 也正常返回。但等几秒钟再看状态画风就变了openstack server show test-vm输出的重点字段如下| status | ERROR | | fault | {message: PortBindingFailed: Binding failed for port 7e2c7f3a-..., code: 500}那会儿我第一反应是计算节点资源不够或者镜像有问题但把实例删了再创建依然报同样的错。三个直观印象很深刻第一实例状态不是ERROR中常见的 NoValidHost而是端口绑定失败服务端错误说明 Nova 已经调度成功是在网络绑定阶段掉链子。第二执行同样操作换成一个普通租户网络时实例能正常创建所以这不是镜像或者资源问题而是和 provider network 强相关。第三报错里带了端口 UUID这为后面定位提供了明确线索不需要从零开始查。1.2 报错发生的节点层和流程层定位想要快速定位这类报错得先搞清楚它在 OpenStack 请求链路里的位置。Nova 创建实例时计算功能会请求 Neutron 创建虚拟端口。Neutron 创建端口后并不会立刻“完成”而是需要选择一个计算节点上的 L2 agent让 agent 把端口实际绑定到本地网桥或物理网卡上。这个动作完成之后端口才会变为ACTIVE实例才能继续启动。PortBindingFailed的意思非常直白Neutron 尝试让 agent 绑定端口agent 返回失败。这个失败会被 Neutron 记录到端口状态里同时通过 Nova 的 fault 信息展示给用户。所以排查重心不应该是 Nova 的调度日志而应该是Neutron 当时选中了哪个 agent这个 agent 为什么没能完成绑定provider network 要求的物理网络映射在对应计算节点上是否真的存在。用一个生活化类比端口就像快递柜生成的取件码agent 是快递员。取件码已经生成但快递员手里没有对应格口的钥匙甚至找错了柜子最终订单只能失败。2. 为什么是provider network从网络模型理解这个坑2.1 provider network和普通租户网络的区别排障到后面会发现这类坑在provider network上出现频率远高于普通租户网络这不是偶然而是网络模型决定的。provider network 是 Neutron 直接管理物理网络的模式它不使用隧道封装而是直接在一台主机的物理网卡或者物理交换机 VLAN 上创建网络。常用的类型是flat和vlan。它的特点是每个节点要想把端口绑定成功节点本地必须有一条通往该物理网络的二层路径。而普通租户网络self-service network往往走 VXLAN 或 GRE overlay节点之间依赖隧道通信。隧道只要 IP 通、agent 在线绑定失败的原因通常集中在 agent 注册、隧道 IP 配置这些点上。两者看似都是“建端口”但底下的绑定逻辑完全不同。对比维度provider networkself-service network常见网络类型flat / vlanvxlan / gre / vlan是否直接依赖物理网络是必须指定 physical_network主要在 overlay 层面依赖物理网络跨节点通信方式物理网桥接物理网络隧道端点跨节点通信绑定失败常见原因物理映射配置、网桥连接、网卡状态agent 类型、隧道 IP 异常、overlay 配置当端口绑定失败时provider network 场景下我十次有八次都栽在“物理网络没有正确接入节点本地”这件事上而不是 Neutron 服务本身。2.2 PortBindingFailed的典型触发链路完整链路可以这样理解Nova 请求 Neutron 创建端口Neutron 生成端口对象开始bind_port流程。它先根据端口所属网络的类型、物理网络名、可用的 agent 类型选定一个候选 agent再把绑定请求发给这个 agent。agent 拿到端口后会去本机找对应的物理接口或者网桥尝试把端口挂上去。一旦出现以下任何一种情况绑定就会失败agent 配置里没有定义physical_network对应的映射对应物理接口名在机器上不存在接口存在但没有处于 UP 状态网桥存在但网桥里没有物理接口agent 本身状态不在线Neutron 选不到它。失败后Neutron 把端口标记成ERROR并向 Nova 返回PortBindingFailed。Nova 这边因为端口没有成功于是实例状态变成ERROR。这里面每一个节点都有对应的日志和状态可以查验。关键是不要被最外层的报错吓到按链路逐层剥下去就能找到根因。3. 按这个思路做排查手把手定位根因3.1 先给网络“验明正身”物理网络映射是不是一致的排障第一步先把网络对象的信息拿出来看清楚。用管理员身份执行openstack network show provider-net -f shell重点关注两个字段provider:physical_networkphysnet1 provider:network_typeflat注意provider 相关字段默认可能不展示确认当前用户带管理员权限或者显式指定-c provider:physical_network和-c provider:network_type提取。拿到这个physnet1之后接下来要检查 node 上的三层映射是否统一第一层Neutron 的 ml2 配置/etc/neutron/plugins/ml2/ml2_conf.ini的[ml2] flat_networks是否包含physnet1第二层network 对象里的provider:physical_network值是不是physnet1第三层计算节点 L2 agent 配置中映射表里的键名是不是physnet1。如果三层中任何一层的名称对不上端口绑定必然失败。我见过一个现场是网络对象里写的是physnet1但 agent 配置里写成physnet少了一个1结果报错持续了一下午。这种问题不靠日志很难看出来因为肉眼扫配置通常会忽略。3.2 再检查节点实际网卡与网桥状态确认映射名称一致后还只是第一步。接下来要确认计算节点上真实存在的网络设备状态。LinuxBridge agent 环境下在有问题的主机上执行ip link show brctl showOpen vSwitch agent 环境下执行ovs-vsctl show排查重点有两个一个是物理接口本身。确认它存在、状态是UP并且没有被人为 down 掉。物理接口如果变成DOWNagent 即使找到了接口也没法绑定。另一个是网桥状态。provider network 使用 flat 类型时agent 通常会把物理接口直接放进网桥然后在网桥上建立端口。如果brctl show里看到了网桥但网桥下的 ports 列表是空的那就说明网桥没有把物理接口桥接进来。这种情况下即使配置 mapping 正确、服务也活着端口绑定依然会失败因为 agent 想挂载的底层桥里根本没有通往物理网络的接口。这里有个容易被忽略的细节网桥名字可能是自动生成的比如brqxxxxxxxx不一定和网络名有直接对应关系。不要只看名字要看桥里的实际接口。3.3 日志才是真正说话的人三个日志按顺序看配置检查做完如果还定位不到就到了最关键的日志排查阶段。我的习惯是按这条顺序来先在 Nova 计算节点上看 nova-compute 日志拿到那个失败的端口 UUIDgrep -i PortBindingFailed /var/log/nova/nova-compute.log | tail -20一般能看到类似这样的记录PortBindingFailed: Binding failed for port 7e2c7f3a-...然后拿这个 UUID 去 Neutron server 节点看 neutron-server 日志grep -i 7e2c7f3a-... /var/log/neutron/neutron-server.log | tail -50这里会比较清楚地看到bind_port的流程包括选中了哪个 agent、agent 返回了什么错误。最后一步也很重要到报错计算节点上看对应 L2 agent 的日志。LinuxBridge 环境下日志路径通常是/var/log/neutron/linuxbridge-agent.log。执行grep -i No mapping /var/log/neutron/linuxbridge-agent.log | tail -20很多情况下你会直接看到这句话No mapping found for physical network physnet1这句话基本就是一锤定音说明 agent 配置里的physical_interface_mappings没有包含physnet1或者包含了但对应接口名在机器上找不到。日志顺序很关键。有的人上来就翻 agent 日志其实也合理因为 agent 日志最接近真相。但我更喜欢从 nova 拿到 UUID再到 neutron 确认事件最后落到 agent这样可以避免拿错端口、查错主机。3.4 两套配置文件对照错在哪一眼就知道了下面给一个非常典型的 LinuxBridge 配置对照方便直接复制比对。错误的配置假设实际网卡是ens33[linux_bridge] physical_interface_mappings physnet1:eth0这个配置如果出现在一台物理网卡叫ens33的机器上agent 只会一脸懵它找不到eth0这个设备自然绑定失败。正确的配置应该是[linux_bridge] physical_interface_mappings physnet1:ens33同理Open vSwitch agent 环境下配置不是physical_interface_mappings而是[ovs] bridge_mappings physnet1:br-ex这个br-ex是 OVS 网桥名不是物理接口名。很多人第一次上手时容易把 LinuxBridge 和 OVS 的配置搞混或者把br-ex当成一个网卡名去查ip link自然查不到。另外要特别提醒一点不要认为所有计算节点的网卡名必须完全一样。实际上不同机器因为硬件差异、系统版本等原因接口名可能叫eth0、ens33、enp3s0。只要 agent 配置里的映射和该机器实际接口名一致就行。之前遇到过一个环境控制节点是eth0一台计算节点升级后变成了ens33结果只有这一台机器创建实例报错其他机器都正常。这种“局部故障”最容易让人怀疑这台机器硬件坏了其实只是配置没跟上。4. 完整排障实例从报错到修好的全过程4.1 故障环境描述用一个脱敏后的环境举例。整套 OpenStack 部署结构非常简单一个控制节点两个计算节点LinuxBridge 作为 L2 agentprovider 网络是 flat 类型物理网络叫physnet1控制节点上物理出口网卡叫eth0。计算节点 A 的网卡也叫eth0计算节点 B 的网卡在系统升级后变成了ens33。运维同事反馈在节点 B 上创建的实例时不时出现PortBindingFailed而且不是每次必现有时候重启一下 Agent 就能恢复但过一阵又失败。直觉告诉我这不是偶发问题而是配置里有隐藏的不一致。4.2 排障执行过程含每一步的输出我按上面的排查顺序走了一遍。第一步查看 provider 网络信息openstack network show flat-net -f shell -c provider:physical_network -c provider:network_type输出provider:physical_networkphysnet1 provider:network_typeflat没问题网络对象本身是干净的。第二步检查节点 B 的 LinuxBridge agent 配置grep physical_interface_mappings /etc/neutron/plugins/ml2/linuxbridge_agent.ini输出physical_interface_mappings physnet1:eth0单看这行没问题。但继续看实际网卡ip -br link show我发现节点 B 上根本不存在eth0真实接口是ens33。问题就在这里agent 拿着不存在名字的eth0去找设备找不到物理接口自然也没法把网桥挂上。第三步看网桥状态brctl show输出里有一个brqxxxxxxxx的网桥但底下端口列表是空的。这说明 agent 已经尝试创建网桥但因为找不到物理接口桥变成了一个空桥。第四步看日志确认grep -i No mapping /var/log/neutron/linuxbridge-agent.log | tail -30实际输出No mapping found for physical network physnet1这句话出现后根因彻底明确。4.3 为什么重启服务之后依然要手工重建网桥找到根因后我把/etc/neutron/plugins/ml2/linuxbridge_agent.ini里面的映射改成了physical_interface_mappings physnet1:ens33然后重启了 neutron-linuxbridge-agent 服务。重启后我下意识地又看了一眼brctl show发现网桥里依然没有ens33。我当时愣了一下后来才反应过来LinuxBridge agent 不会主动把已经存在且状态异常的空网桥重新配置好尤其当网桥和设备都没变化时。处理办法是把那个空桥删掉再重启 agent让它按正确配置重新创建网桥。操作如下ip link set brqxxxxxxxx down brctl delbr brqxxxxxxxx systemctl restart neutron-linuxbridge-agent重启后再执行brctl show这次能看到ens33已经挂在网桥下bridge name interfaces brqxxxxxxxx ens33到这一步绑定的物理通路已经打通。4.4 验证结果把之前创建失败的实例删掉重新创建openstack server delete test-vm openstack server create \ --flavor m1.small \ --image cirros \ --network flat-net \ test-vm等几十秒后openstack server show test-vm -c status -c networks输出---------------------------------------------- | Field | Value | ---------------------------------------------- | status | ACTIVE | | networks | flat-net192.168.x.x | ----------------------------------------------然后我在另一台计算节点上 ping 这个 IP确认二层可达。provider network 本身不需要路由只要二层链路通了跨节点通信应该直接没问题。如果 ping 不通要优先检查安全组是否放行了 ICMP而不是一上来怀疑网络配置。5. 常见问题与排查技巧实录5.1 常见原因速查表把这类问题整理成一张速查表会省很多重复排查的时间。现象根因解决方向agent 日志报No mapping found for physical network xxxphysical_interface_mappings或bridge_mappings缺失或键名和网络对象不一致统一三层物理网络名称agent 日志报Interface eth0 not found配置里的接口名和实际设备名不一致用ip link确认实际接口名并修正配置网桥存在但端口仍然绑定失败网桥是空桥没有桥接物理接口删除空桥修正配置后重启 agent所有计算节点都报这个错ml2 配置里flat_networks没包含物理网络名或 agent 服务没正常运行检查/etc/neutron/plugins/ml2/ml2_conf.ini确认flat_networks只有某一台计算节点报错该节点接口命名或 agent 配置与其他节点不一致单独检查这台机器的映射和设备名端口状态是DOWN而不是ERROR绑定表面上成功但物理链路异常检查物理网卡是否 UP网线/交换机 VLAN 是否配置好修改配置后仍然失败旧的空桥或者旧 agent 缓存没有清掉删除空桥、重启 agent必要时重建端口5.2 我常用的快速检查命令集排这种错下面这组命令基本可以覆盖 80% 的场景我每次都会先跑一遍# 查看网络对象关键字段 openstack network show network -c provider:physical_network -c provider:network_type -f shell # 查看 agent 运行状态 openstack network agent list --sort-column Host # LinuxBridge 环境查看网桥 ssh compute-node brctl show # Open vSwitch 环境查看网桥 ssh compute-node ovs-vsctl show # 查看 agent 物理接口映射配置 ssh compute-node grep physical_interface_mappings /etc/neutron/plugins/ml2/linuxbridge_agent.ini # 看 nova 侧错误 ssh compute-node grep -i PortBindingFailed /var/log/nova/nova-compute.log | tail -20 # 看 neutron-server 侧绑定流程 grep -i binding /var/log/neutron/neutron-server.log | tail -50 # 看 agent 日志中的映射错误 ssh compute-node grep -i No mapping /var/log/neutron/linuxbridge-agent.log | tail -20这里特别提醒一句openstack network agent list里看到的 host 是 agent 上报的主机名一定要和实际报错计算节点对应起来。有时候机器名缩写不同或者 DNS 未解析容易认错主机导致在错误的节点上排查半天。5.3 一个容易被忽略的坑agent缓存和旧网桥我第三次踩这个坑时发现配置已经改对了日志也干净了但创建实例依旧失败。后来翻来覆去查才发现是旧的空网桥一直在占位置。LinuxBridge agent 如果已经建立过一个网桥重启时如果条件没变它可能会继续沿用旧状态。这个旧网桥如果没有桥接任何物理接口绑定端口时 agent 拿到的就是一个没有底层出口的桥自然失败。解决办法是“四步走”删除报错关联的失败实例避免旧端口继续占用删除异常的空网桥重启 agent再确认brctl show里物理接口已经挂载。另外还有个常见的隐性坑openstack network agent list中 agent 的admin_state_up如果为 False即使进程活着也不会参与绑定。如果列表里看到某个计算节点的 agent 状态不是UP先确认心跳和配置文件不要急着改网桥。6. 几次踩坑后的个人体会6.1 我后来每次都会先做三件事这类问题踩多了之后我的排障习惯发生了明显变化。现在再看到PortBindingFailed我不会先去翻 Nova 调度而是先问三个问题这个网络是什么类型这个网络的物理网络名是什么报错节点上 agent 的映射表里有没有这个名字把这三个问题回答完约等于已经排查完一半了。第二步是查实际设备而不是只看配置。配置是人的意图设备才是事实。物理接口名可能因为系统升级、硬件更换发生变化机器不会自动告诉你只有ip link show会说实话。第三步是改完配置后不急着创建实例先看网桥。很多问题不是配置改错了而是服务重启后没有按照新配置重建网络设备。确认网桥里已经挂上物理接口再创建实例成功率会高很多。6.2 留给同行的一句话OpenStack 的报错有时候看起来像一团乱麻但端口绑定这个环节的链条其实非常清晰网络对象、Neutron 配置、agent 配置、本地网桥设备四个环节只要有一个不一致错误就会在最外层以PortBindingFailed的形式冒出来。与其背一堆排障命令不如先把这个链路在脑子里理顺遇到问题时就知道该往哪一层找。我后来在项目里定了一个小规矩所有节点的物理接口映射必须统一写到部署文档里并且每次节点硬件变更后立即检查 mapping。这套规矩落实后团队里再没有人被这个报错卡超过十分钟。