1. 从一个报错说起为什么这个RPC连接问题值得单独聊clnt_create: RPC: Port mapper failure - Unable to receive: errno 113 (No route to host)——这行报错凡是在Linux环境下折腾过NFS挂载、做过RPC服务调试、或者维护过分布式存储集群的人大概率都见过。它不像语法错误那样直白也不像权限拒绝那样一目了然而是卡在“网络可达性”和“服务注册”之间的灰色地带让人第一反应往往是“网络没问题啊能ping通”然后陷入反复重启服务的死循环。这个报错的核心含义其实很明确客户端在尝试通过clnt_create创建一个RPC客户端句柄时需要先联系目标主机上的port mapper端口映射器通常监听在TCP/UDP 111端口由它来告知目标RPC服务实际监听的端口号。而errno 113 (No route to host)说明客户端在尝试接收port mapper的响应时底层网络栈直接返回了“无法到达主机”。注意这里的关键词是“Unable to receive”——不是连接被拒绝不是超时而是路由层面就已经不通了。这篇文章适合三类人看第一类是在运维岗位上突然遇到NFS挂载失败、被这个报错卡住的朋友第二类是在开发RPC服务时本地测试正常但跨主机调用就报这个错的工程师第三类是想系统理解RPC调用链路、port mapper工作机制的技术爱好者。我会从原理拆到实操把排查路径、参数配置、常见坑点全部铺开尽量做到你看完就能直接上手定位问题而不是对着报错发呆。需要提前说明的是errno 113这个错误码在不同场景下可能由不同原因触发但围绕clnt_create和port mapper的组合出现时排查思路是有规律可循的。下面我按“先理解机制、再拆解原因、最后落地排查”的顺序展开中间会穿插我自己踩过的坑和实测有效的操作步骤。2. 先把调用链路搞清楚clnt_create到底做了什么2.1 RPC调用中port mapper的角色定位要理解这个报错必须先搞清楚RPC服务在网络上是怎么“被找到”的。很多人习惯性地认为我启动了NFS服务它就应该监听在2049端口客户端直接连2049就行了。但实际上RPC体系的设计要复杂一层。在RPC的经典实现中服务端程序启动时会先向本机的port mapper注册自己“我是某个程序编号、某个版本号的服务我现在监听在某个端口上。”port mapper本身固定监听在111端口它的作用就像一个电话总机——你打总机告诉它你要找哪个部门它告诉你分机号是多少。clnt_create这个函数做的事情就是根据你提供的主机名、程序编号、版本号和协议类型先联系目标主机的port mapper111端口查询目标服务实际监听的端口然后创建一个指向该端口的客户端句柄。整个过程分两步第一步是“问总机”第二步是“拨分机”。所以当报错信息里出现Port mapper failure时说明问题出在第一步——连总机都没联系上。而errno 113 (No route to host)进一步说明不是总机不接电话而是你的电话线根本没通到那栋楼。2.2 errno 113与常见网络错误的本质区别很多人会把No route to host和Connection refused、Connection timed out混为一谈觉得都是“连不上”。但它们在排查方向上有本质区别。Connection refused意味着你的请求到达了目标主机但目标端口上没有程序在监听操作系统直接回了一个RST包。这说明网络是通的问题在服务端。Connection timed out意味着你的请求发出去了但迟迟没有收到任何响应通常是防火墙丢包或者目标主机宕机。这说明网络路径可能存在问题但不确定。No route to host则更底层——你的操作系统在尝试发送数据包时路由表里找不到到达目标地址的路径或者ARP解析失败或者中间路由器返回了ICMP不可达消息。简单说数据包还没出你的机器或者刚出去就被打回来了就已经知道“此路不通”。这个区别非常关键。当你看到errno 113时排查重点应该放在路由、ARP、防火墙规则、网卡状态这些层面而不是去检查NFS服务有没有启动、port mapper有没有运行。方向错了再怎么重启服务都是白费。2.3 为什么“能ping通”不代表RPC能通这是最容易被误导的地方。很多人的第一反应是ping一下目标主机发现能通就认定网络没问题。但ping走的是ICMP协议而RPC的port mapper查询走的是TCP或UDP的111端口。这两条路径在以下情况下会出现分歧防火墙对ICMP放行但对TCP/UDP 111端口做了限制或丢弃目标主机有多张网卡ICMP响应从A网卡回来但RPC请求被路由到了B网卡中间网络设备对ICMP和TCP/UDP的处理策略不同ARP缓存过期或错误导致数据包无法正确封装所以正确的做法是不要只依赖ping要用telnet、nc或者rpcinfo直接测试111端口的可达性。这一点我在后面会给出具体的命令。3. 逐层拆解errno 113在RPC场景下的六大触发原因3.1 路由表缺失或错误导致数据包无法出站这是最直接的原因。当你的主机路由表中没有到达目标网段的路由条目时操作系统在发送数据包时会直接返回ENETUNREACH或EHOSTUNREACH对应到errno就是113。这种情况常见于新配置的服务器没有设置默认网关、多网卡环境下路由优先级混乱、或者手动添加了错误的路由规则。排查方法是ip route get 目标IP看看操作系统实际会选择哪条路径。如果返回unreachable那就说明路由表有问题。我遇到过一次典型场景一台测试机同时接入了办公网和实验网默认路由指向办公网网关但目标NFS服务器在实验网段。结果就是ping能通因为ICMP走了实验网的直连路由但RPC请求被默认路由带到了办公网网关网关不知道怎么转发直接回了ICMP不可达。3.2 防火墙规则拦截了111端口的RPC查询防火墙是另一个高频原因。很多环境的防火墙策略是“默认拒绝按需放行”管理员可能放行了NFS的2049端口但忘了放行port mapper的111端口。这时候客户端尝试联系111端口防火墙直接丢弃或拒绝表现可能就是No route to host。需要注意的是不同防火墙的行为不同。iptables的DROP目标会导致超时REJECT目标会返回ICMP不可达可能表现为errno 113而某些硬件防火墙可能直接返回ICMP host unreachable。所以看到errno 113时不要假设防火墙一定是“拒绝”状态也可能是“丢弃”状态被中间设备转换成了不可达消息。3.3 ARP解析失败导致局域网内通信中断如果目标主机和你在同一个局域网内No route to host很可能意味着ARP解析失败了。操作系统需要知道目标IP对应的MAC地址才能封装以太网帧如果ARP请求没有得到响应数据包就发不出去。ARP失败的原因包括目标主机关机或网卡故障、ARP缓存中有错误的静态条目、VLAN配置不一致导致ARP请求无法到达目标、或者中间有ARP代理配置错误。排查方法是arp -n查看ARP缓存或者用arping直接测试ARP层可达性。3.4 网卡状态异常或链路层故障物理层和链路层的问题也会表现为No route to host。比如网卡被down掉了、网线松动、交换机端口被禁用、VLAN配置错误等。这种情况下操作系统可能仍然保留着路由表条目但实际数据包无法通过网卡发送出去。排查时用ip link show确认网卡状态是UP还是DOWN用ethtool检查链路状态用ip -s link查看是否有发送错误计数增长。3.5 目标主机多网卡环境下的回程路由问题这是一个比较隐蔽的原因。目标主机有两张网卡A网卡在192.168.1.0/24网段B网卡在10.0.0.0/24网段。你的客户端在10.0.0.0/24网段请求发到了目标主机的B网卡。但目标主机在回复port mapper查询时根据其路由表选择了A网卡作为出口。如果你的客户端无法从A网卡所在的网段被访问回复包就到不了你手里。这种情况下ping可能正常因为ICMP可能走了正确的路径但RPC查询的回复包走了错误路径。排查方法是在目标主机上用ip route get 客户端IP确认回程路由必要时添加策略路由。3.6 虚拟化与容器环境中的网络隔离在虚拟机或容器环境中No route to host还可能由虚拟网络配置引起。比如虚拟交换机的安全组规则、容器的网络命名空间隔离、overlay网络的隧道故障等。这类问题的排查需要结合具体的虚拟化平台工具但基本思路仍然是先确认二层可达再确认三层路由最后确认端口过滤。4. 实操排查手册从零定位errno 1134.1 第一步确认基础网络可达性拿到报错后不要急着改配置先做最基础的连通性测试。我习惯按以下顺序执行# 1. 确认目标主机IP是否可达ICMP层 ping -c 3 目标IP # 2. 确认路由路径 ip route get 目标IP # 3. 确认ARP缓存同网段场景 arp -n | grep 目标IP # 4. 确认网卡状态 ip link show这四步能快速排除掉物理层、链路层和路由表层面的明显问题。如果ip route get返回unreachable后面的测试就不用做了直接去修路由。如果ping不通但路由存在重点查ARP和防火墙。提示有些环境禁用了ICMPping不通不代表网络有问题。这时候直接跳到端口测试。4.2 第二步直接测试111端口连通性ping通不代表111端口通。用以下命令直接测试port mapper端口# 使用nc测试TCP 111端口 nc -zv 目标IP 111 # 使用telnet测试 telnet 目标IP 111 # 使用rpcinfo直接查询port mapper rpcinfo -p 目标IPrpcinfo -p是最直接的验证方式它做的就是clnt_create类似的事情——联系目标主机的port mapper并列出注册的服务。如果这个命令也报No route to host说明问题确实在port mapper的可达性上。如果rpcinfo能成功但你的程序报错那问题可能在程序使用的协议类型TCP还是UDP或者程序编号上。4.3 第三步检查本机防火墙与目标防火墙防火墙排查要两头做。先看本机有没有出站限制# 查看本机iptables规则 iptables -L -n -v # 查看本机nftables规则新版系统 nft list ruleset # 查看firewalld状态 firewall-cmd --list-all然后确认目标主机的入站规则。如果你能登录目标主机检查其防火墙是否放行了111端口和RPC动态端口范围。RPC服务除了port mapper的111端口外实际服务还会监听一个动态端口这个端口也需要放行。注意很多教程只让你放行111和2049但NFS相关的RPC服务如mountd、statd可能监听在随机端口上。生产环境建议在/etc/sysconfig/nfs或/etc/nfs.conf中固定这些端口然后在防火墙中精确放行。4.4 第四步用tcpdump抓包确认数据包走向当以上步骤都无法定位时抓包是最可靠的手段。在客户端和目标主机同时抓包对比数据包的发送和接收情况# 在客户端抓取目标IP的111端口流量 tcpdump -i any -nn host 目标IP and port 111 -w client.pcap # 在目标主机抓取来自客户端的流量 tcpdump -i any -nn host 客户端IP and port 111 -w server.pcap分析要点如果客户端有发送但没有收到任何回复说明数据包在中间被丢弃了如果客户端收到了ICMP unreachable消息抓包中会显示如果目标主机根本没收到包问题在中间网络如果目标主机收到了但没有回复问题在目标主机的防火墙或port mapper服务状态。4.5 第五步验证port mapper服务本身状态如果网络层确认没问题接下来确认目标主机的port mapper是否正常运行# 在目标主机上检查rpcbind服务状态 systemctl status rpcbind # 确认111端口监听状态 ss -tlnp | grep 111 ss -ulnp | grep 111 # 本地查询port mapper rpcinfo -p localhost如果rpcbind没有运行或者111端口没有监听那客户端自然无法完成port mapper查询。但这种情况通常报的是Connection refused而不是No route to host所以如果确认是errno 113网络层问题的可能性更大。5. 高频场景复盘那些年我踩过的errno 113的坑5.1 场景一多网卡服务器路由优先级导致的“假连通”某次在实验室环境部署一套分布式存储三台服务器各有两张网卡一张接管理网一张接存储网。客户端在管理网存储服务在存储网。ping管理网IP通rpcinfo却报No route to host。排查后发现目标主机的默认路由指向管理网网关但port mapper的回复包根据路由表选择了管理网网卡作为出口。而客户端实际上是通过存储网发起请求的回复包从管理网出来后就找不到回客户端存储网IP的路径了。解决办法是在目标主机上添加策略路由让来自存储网段的请求从存储网网卡回复# 添加路由表 echo 200 storage /etc/iproute2/rt_tables # 添加策略路由规则 ip rule add from 存储网IP table storage ip route add default via 存储网网关 table storage这个坑的隐蔽性在于ping测试的是管理网连通性而实际RPC请求走的是存储网两条路径的行为不一致。5.2 场景二防火墙REJECT规则伪装成“无路由”某次在云主机上配置NFS安全组只放行了2049端口没有放行111端口。客户端报No route to host第一反应是路由问题查了半天路由表都正常。后来用tcpdump抓包发现客户端发出的SYN包收到了ICMP port unreachable消息但被系统转换成了EHOSTUNREACH。云平台的安全组通常采用“静默丢弃”策略但某些配置下会返回ICMP不可达。这种情况下报错信息会误导排查方向。解决办法很简单在安全组中放行TCP/UDP 111端口以及RPC动态端口范围。5.3 场景三容器环境中的网络命名空间隔离在容器中运行RPC客户端连接宿主机或其他容器中的RPC服务时如果容器使用了none网络模式或者自定义网络配置不当也会出现No route to host。容器的网络命名空间与宿主机隔离路由表和iptables规则都是独立的。排查时需要在容器内部执行ip route和nc测试而不是在宿主机上测试。如果容器使用的是bridge模式确认容器有正确的默认网关且宿主机的iptables没有拦截容器流量。5.4 场景四ARP缓存污染导致的间歇性失败这个问题比较少见但确实存在。局域网中如果有两台设备配置了相同的IPIP冲突ARP缓存可能会在正确的MAC和错误的MAC之间来回切换。当ARP缓存指向错误的MAC时数据包发到了错误的设备上自然得不到响应。表现是RPC调用时好时坏arp -n查看时MAC地址会变化。解决办法是清除ARP缓存ip neigh flush all然后找到IP冲突的设备并修正配置。5.5 场景五IPv6与IPv4双栈环境下的地址选择问题在双栈环境中主机名可能同时解析到IPv4和IPv6地址。如果clnt_create选择了IPv6地址但IPv6路由不可达就会报No route to host。而ping可能默认走IPv4显示连通正常。排查时用getent hosts 主机名查看解析结果确认程序实际使用的是哪个地址族。必要时在/etc/hosts中强制指定IPv4地址或者调整gai.conf的优先级。5.6 常见问题速查表现象可能原因快速验证方法解决方向ping通但rpcinfo报113防火墙拦截111端口nc -zv IP 111放行TCP/UDP 111同网段报113ARP解析失败arping IP检查ARP缓存和VLAN跨网段报113路由表缺失ip route get IP添加正确路由多网卡环境报113回程路由不对称目标机ip route get 客户端IP配置策略路由容器内报113网络命名空间隔离容器内ip route检查容器网络配置时好时坏报113ARP缓存污染或IP冲突arp -n观察MAC变化清除ARP缓存排查冲突双栈环境报113IPv6路由不可达getent hosts 主机名强制使用IPv46. 从修复到预防让RPC连接稳定下来的配置建议6.1 固定RPC服务端口范围RPC服务的动态端口是很多问题的根源。防火墙管理员不知道要放行哪些端口客户端也不知道服务实际监听在哪里。在生产环境中我强烈建议固定RPC服务的端口范围。对于NFS相关的RPC服务可以在/etc/nfs.conf新版或/etc/sysconfig/nfs旧版中配置# /etc/nfs.conf 示例 [mountd] port20048 [statd] port32765 outgoing-port32766 [lockd] port32767 udp-port32767配置完成后重启相关服务然后用rpcinfo -p确认端口已经固定。这样防火墙只需要放行111、2049以及这几个固定端口即可大大降低排查复杂度。6.2 在防火墙中精确放行RPC相关端口以firewalld为例创建一个专门的服务定义# 创建自定义服务 firewall-cmd --permanent --new-servicenfs-rpc firewall-cmd --permanent --servicenfs-rpc --add-port111/tcp firewall-cmd --permanent --servicenfs-rpc --add-port111/udp firewall-cmd --permanent --servicenfs-rpc --add-port2049/tcp firewall-cmd --permanent --servicenfs-rpc --add-port2049/udp firewall-cmd --permanent --servicenfs-rpc --add-port20048/tcp firewall-cmd --permanent --servicenfs-rpc --add-port20048/udp firewall-cmd --permanent --servicenfs-rpc --add-port32765-32767/tcp firewall-cmd --permanent --servicenfs-rpc --add-port32765-32767/udp # 应用服务 firewall-cmd --permanent --add-servicenfs-rpc firewall-cmd --reload提示如果使用iptables规则顺序很重要。确保放行规则在拒绝规则之前并且注意ESTABLISHED,RELATED状态的连接跟踪规则要存在。6.3 用rpcinfo做日常健康检查与其等报错了再排查不如把rpcinfo纳入日常监控。一个简单的检查脚本#!/bin/bash TARGET目标IP if rpcinfo -t $TARGET 100003 3 /dev/null 21; then echo OK: NFS RPC service reachable else echo FAIL: Cannot reach NFS RPC service on $TARGET # 进一步诊断 echo --- Route info --- ip route get $TARGET echo --- Port 111 test --- nc -zv -w 3 $TARGET 111 fi这个脚本可以放在cron中定时执行也可以在部署脚本中作为前置检查。关键是它能在问题影响业务之前就发出告警。6.4 多网卡环境下的路由配置规范对于多网卡服务器建议在/etc/iproute2/rt_tables中为每个网段定义独立的路由表并配置策略路由规则。基本原则是请求从哪个网卡进来回复就从哪个网卡出去。# 假设网卡eth1对应10.0.0.0/24网段 ip rule add from 10.0.0.100 table eth1_table ip route add 10.0.0.0/24 dev eth1 src 10.0.0.100 table eth1_table ip route add default via 10.0.0.1 table eth1_table配置完成后用ip route get 10.0.0.x from 10.0.0.100验证回程路径是否正确。6.5 容器与虚拟化环境的网络检查清单在容器或虚拟机中部署RPC客户端时按以下清单逐项确认容器是否有独立的网络命名空间路由表是否正确容器到目标主机的111端口是否可达在容器内执行nc测试宿主机的iptables或nftables是否对容器流量做了额外限制如果使用overlay网络隧道是否正常MTU是否匹配DNS解析在容器内是否正常是否解析到了预期的IP地址这些检查项看起来琐碎但每一条都对应着我实际遇到过的故障场景。尤其是MTU不匹配的问题在小包测试时正常一旦RPC传输较大数据就失败表现可能不是errno 113而是超时但排查思路是相通的。7. 几个容易被忽略的细节和我的个人经验7.1 errno 113不一定意味着“完全不通”有时候No route to host是间歇性的尤其是在无线网络或负载均衡环境下。数据包可能通过某条路径时成功通过另一条路径时失败。这种情况下ping和nc的单次测试可能碰巧成功让你误以为问题解决了。我的做法是用ping -c 100或者nc循环测试多次观察失败率。如果失败率不是零就说明存在路径或策略的不稳定因素需要继续深挖。7.2 注意区分TCP和UDP的port mapper查询clnt_create默认可能使用UDP协议进行port mapper查询而rpcinfo -p默认也使用UDP。但有些防火墙只放行了TCP 111而没有放行UDP 111导致rpcinfo -tTCP成功但程序默认的UDP查询失败。排查时两个协议都要测rpcinfo -t 目标IP 100003 3 # TCP方式 rpcinfo -u 目标IP 100003 3 # UDP方式如果TCP通而UDP不通检查防火墙的UDP规则。反过来也一样。7.3 主机名解析顺序可能影响结果clnt_create的第一个参数是主机名如果主机名解析到了错误的IP比如/etc/hosts中有一条过期的记录就会连接到错误的地址。排查时用getent hosts 主机名确认解析结果必要时直接在程序中使用IP地址绕过DNS。7.4 系统日志中往往有更多线索/var/log/messages或journalctl -xe中可能记录了内核层面的网络错误比如martian source、ICMP host unreachable等。这些日志能帮你确认数据包是在本机被拦截的还是在中间网络被丢弃的。# 查看内核网络相关日志 dmesg | grep -i route\|unreachable\|martian journalctl -k --since 10 minutes ago | grep -i network\|route7.5 最后再分享一个快速判断的小技巧当你拿到clnt_create: RPC: Port mapper failure - Unable to receive: errno 113这个报错时按以下顺序快速判断ip route get 目标IP——如果返回unreachable直接修路由结束。arping 目标IP同网段——如果无响应查ARP和二层网络。nc -zv 目标IP 111——如果失败但路由正常查防火墙。rpcinfo -p 目标IP——如果TCP通UDP不通查UDP防火墙规则。在目标主机上rpcinfo -p localhost——如果本地都查不到查rpcbind服务状态。这五步走下来九成以上的errno 113问题都能定位到具体原因。剩下的疑难杂症就需要抓包和策略路由分析了。我在实际运维中最大的体会是不要被ping的结果迷惑也不要一上来就重启服务先把数据包的路径搞清楚问题往往比想象中简单。