ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

VLAN Trunk通信过程详解:从802.1Q标签到跨交换机排障实践

VLAN Trunk通信过程详解:从802.1Q标签到跨交换机排障实践

做网络这一行,谁还没跟 trunk 打过几回交道呢?我第一次真正弄懂 trunk 通信过程,是在一个跨楼的二层组网项目里。当时两台交换机之间已经拉好了好几条网线,可楼下每个部门都是独立 VLAN,楼层交换机一多,线缆越拉越乱,端口却总不够用。后来有人提醒我:别一条 VLAN 拉一根线了,把两边的上联口配置成 trunk,一条线就能带着十几个 VLAN 一起跑。从那以后,我查故障第一反应就会先去看 trunk 状态。

这篇博文就以 VLAN Trunk 为例,把 trunk 的通信过程完整拆开:标签怎么打、协商怎么发生、帧在链路上到底长什么样、跨交换机通信时数据怎么走,再附上我在实际配置和排障里踩过的坑。不管是刚入门网络的新人,还是要独立组网或处理二层故障的运维,都值得花十分钟把这套逻辑捋顺。

1. 从多个VLAN到一条中继链路

1.1 为什么要用VLAN切割广播域

网络里没有VLAN时,所有设备共享一个二层广播域。ARP广播、DHCP发现、某些协议组播会在整个网段内扩散,局域网主机一旦多,广播报文损耗不可忽视。而且一旦出现二层环路,广播风暴会让交换机CPU占用迅速飙升,整个网络近乎瘫痪。引入VLAN后,广播域被切开,故障影响范围能缩小到一个VLAN内,这是VLAN存在的首要理由。

但这带来一个新问题:VLAN之间在二层是隔离的,如果两个交换机都划分了VLAN10、20、30,那交换机之间该怎么把不同VLAN的流量送过去?答案不是各自拉线,而是用 trunk 中继链路,让一条物理链路同时承载多个 VLAN 的帧。

1.2 最笨的办法与trunk做法的对比

如果按最朴素的想法,每台交换机上给VLAN10拉一条物理线、VLAN20再拉一条物理线,这样当然也能跑通,但工程上完全不可接受:楼层之间可能只有一两根预埋光缆,一根物理线只能承载一个VLAN,VLAN数量一多就没有扩展余地。trunk的做法是:一条物理链路把多个VLAN的帧全部封装好再发出去,接收方依靠帧里的VLAN标识还原出它属于哪个VLAN。这就像从一个个的专用小屋改成了一条共享主干道,每辆车挂了不同颜色的牌子,到了十字路口交警只看牌子就能分流向。

1.3 除了交换机互连,还有哪里依赖trunk

单臂路由是典型场景:交换机与路由器之间用一条trunk,路由器的物理接口上划分子接口,每个子接口对应一个VLAN的网关。如果三层交换机要实现VLAN间路由,其VLANIF接口本身也是基于二层的trunk承载。无线网络中,AP上联到AC的流量也常走trunk。所以trunk通信过程可以说是所有多VLAN场景的底座,不是某一台设备上的孤岛功能。

2. 决定通信成败的三个机制

2.1 802.1Q标签:给帧写上小区门牌号

802.1Q是IEEE标准,它定义了如何在以太网帧里插入VLAN标签。标准以太网帧结构中,在目的MAC(6字节)、源MAC(6字节)之后紧跟着类型/长度字段。802.1Q会在源MAC和类型字段之间插入4字节Tag:前2字节是TPID,固定为0x8100,表示这是一个带VLAN标签的帧;后2字节中包含3比特PCP优先级、1比特DEI丢弃指示和12比特VID,VID的取值范围是1到4094。这4字节就是核心,VLAN身份就在这里。

插入标签后,以太网帧最大长度从1518字节变成1522字节。如果业务数据已经是1500字节,加上4字节标签后会超过普通MTU长度,所以二层接口往往需要把MTU调大,或者在三层上做分片协商。很多VXLAN场景下,MTU问题都会在trunk这层爆发,这个细节我放到后面的排障章节里讲。补充一点:802.1Q标签是不对帧内容加密的,它只是信令,所以标签可以被误改或伪造,这也是后面安全风险的一个根源。

2.2 协商协议:trunk是“自动”出现的吗

很多同学对着设备互联端口什么都不做,结果发现两台交换机自动形成了trunk,这是因为端口模式里开启了动态协商。常见模式有:

本端模式对端模式协商结果
AccessAccessAccess,无tag
TrunkTrunkTrunk,强制走trunk
Dynamic autoDynamic desirable能协商成Trunk
Dynamic autoDynamic auto协商失败,保持Access
TrunkDynamic auto/desirable能协商成Trunk

表格里最关键的一点是:如果两边都设成了Auto,链路反而不会成为trunk;而如果一边是Desirable,另一边是Auto,才会协商成功。这个反直觉的特性曾经让不少人在施工现场挠头。

生产环境我的建议是:禁用自动协商,两边全部手动指定trunk。自动协商看着方便,但对安全不友好——它意味着你不想让某个口变成trunk,对端一台配置不当的交换机插上来时,端口可能自动被协商成中继,整个VLAN就暴露了。收敛和可控性永远比自动化更重要,尤其是对接入侧端口。

2.3 Native VLAN:唯一不贴标签的“默认车道”

Native VLAN这个概念经常让人栽跟头。在一个trunk口上,除了Native VLAN之外的所有VLAN都会打上802.1Q标签;发往Native VLAN的帧不打标签,直接用普通以太网帧在链路上传。接收方收到无标签帧时,会默认把这些帧归入其Native VLAN。

两端Native VLAN不一致是经典故障源。假如A端Native VLAN是10,B端Native VLAN是20。A端想发的VLAN10流量不会打标签,B端接收后发现没有标签,就把它归到自己的VLAN20,于是VLAN10的帧流入了VLAN20的广播域,二层隔离瞬间失效。更危险的是双标签攻击:攻击者在Access口发出带两层VLAN标签的帧,交换机剥掉外层后,内层标签仍保留,可能被trunk转发到不该去的VLAN。所以,安全基线通常要求把Native VLAN改成某个不收业务、没人用的黑洞VLAN,并且两端固定一致。

3. 一次完整通信过程的流水账

3.1 先搭一个拓扑画面

假设有SW-A和SW-B两台交换机,中间用一个物理口连接并配置为trunk,放行VLAN10和VLAN20。PC-A接在SW-A上,属于VLAN10;PC-B接在SW-B上,属于VLAN10;还有一个PC-C接在SW-B上,属于VLAN20。三个PC的IP如果都在同一网段,那是二层通信,不碰网关;如果PC-A要访问VLAN20的服务器,就需要经过网关,走单臂路由或三层交换机,trunk上同时会有多种VLAN的标签帧交错出现。先看PC-A ping PC-B,都是VLAN10,二层通信,这是最基础的场景。

3.2 PC-A到SW-A的Access口:入口先确定身份

PC-A发出的普通帧没有标签。SW-A的Access接口固定属于VLAN10,帧进入交换机后,交换芯片在内部给这块数据打上VLAN10的标识。注意,这时线上并没有插入802.1Q标签,Access口只是以一个VLAN的身份接收。交换芯片查MAC地址表,发现目标MAC应该从某个trunk口出去,于是把内部VLAN10信息放到帧里,在发出trunk口前把802.1Q Tag实际插入帧头。这才是“打标签”发生的真正位置。

3.3 中间的那根trunk:帧带着标签在跑

现在,连接SW-A和SW-B的物理线路上,以太网帧变成了:目的MAC(PC-B)、源MAC(PC-A)、TPID 0x8100、优先级/VID=10、协议类型、IP头……。交换机之间不关心IP地址,只看这个Tag就能知道该把帧交给哪个VLAN的上层。

这里有个常见误解:很多人以为Access口收到的帧也带Tag,或者Trunk口收到帧后交换机一定会把Tag剥掉。实际上,Tag是在“进入trunk口之前”由交换芯片加上,在“出trunk口”时保留;而Access口收到的是无Tag帧,交换机内部用虚拟接口的metadata保存VLAN归属,不一定改成线上Tag。抓包验证时,只有Trunk链路上的包才看得到0x8100,终端网卡抓包永远看不到Tag——除非网卡配置了VLAN。

3.4 SW-B收到Tag后的处理:读标识、查表、去标识

SW-B的trunk口收到带Tag的帧后,首先检查这个帧的VID是否在“trunk允许通过的VLAN列表”里。如果在,就拿到这个VLAN的上下文继续查MAC表;如果不在,直接丢帧。本例VID=10在列表里,SW-B查到目标MAC对应的是某个Access口,该口属于VLAN10;因为出口是Access口,交换芯片会在送出前把802.1Q Tag剥掉,把原始帧还给PC-B。PC-B看到的帧和普通局域网帧一模一样,这也说明Tag是只在交换机之间使用的信封,不是直接给终端看的内容。

3.5 跨VLAN时,trunk上的报文走向

换成PC-A要访问某个VLAN20的服务器(单臂路由场景)。PC-A发出目标MAC为网关MAC的帧,网关在路由器上。SW-A把帧从trunk口送到路由器,路由器在物理接口下划分子接口,其中一个子接口封装了VLAN10的Tag,另一个子接口封装VLAN20的Tag。路由器收到Tag为10的报文,剥掉Tag后做路由,然后从封装VLAN20的子接口发出,重新打上Tag为20;SW-B收到后查MAC表,在Access口剥离Tag发给服务器。这个过程中,trunk上一个方向可能同时跑着两种Tag的流量,交错出现,但交换芯片只认VID,天然在二层就做了分流。所以trunk的设计看起来简单,却是多VLAN环境能够成立的基石。

4. 配置trunk的标准动作与避坑点

4.1 手工配置trunk的最基本步骤

配置命令以某主流企业交换机的命令行风格为例,不同品牌关键字略有差异,但思路通用:

# 进入互联端口 interface GigabitEthernet0/0/1 # 强制指定trunk模式 switchport mode trunk # 只放行需要的VLAN,而不是默认全放行 switchport trunk allowed vlan 10,20 # 设置一致的native VLAN,建议使用业务不用的值 switchport trunk native vlan 999 # 关闭动态协商,避免对端接入后自动成为trunk switchport nonegotiate exit

逐条讲一下意图:第一行是进入接口;第二行是让端口进入trunk模式;第三行如果只写“switchport trunk allowed vlan 10,20”,部分设备会理解为覆盖原有列表,把之前默认允许的所有VLAN替换成10和20,这样能缩小风险面;第四行是native VLAN的调整,两端必须一致;第五行是关闭端口自动协商。很多人只记得第二行,后面三行全漏,结果就是上线后隔壁端口一插,把这个口协商成了trunk,安全基线直接破了。

4.2 链路聚合下的trunk:从一根线到一组口

当单条物理链路带宽不够,比如跑监控回传,1Gbps已经接近打满,就需要把多根物理线捆成一个逻辑trunk。企业里一般用链路聚合协议(如LACP)来协商成员口,两端把物理口加入同一个聚合组,组内接口配置保持一致。链路聚合后的逻辑端口依然可以作为trunk口来使用,VLAN标签规则不变,只是负载分担变成了基于源目MAC、IP等哈希算法。

这里有个容易被忽略的坑:聚合组里所有成员口的VLAN配置必须一致。某次我排查一个链路聚合故障,发现有一个成员口之前被单独执行过“allowed vlan remove”,其他成员口放行的VLAN比它多,结果部分VLAN的流量在这个成员口上被丢,而LACP协议层面还显示正常,业务却时断时续。后来排查到这个问题时,我人都愣住了。所以链路聚合配置完一定要用统一命令批量应用,不要手工单个口去改。

4.3 接口模式选型与Access的搭配

接入终端、PC、IP电话这类设备,接口一定是Access模式,并且PVID要设成该业务VLAN;交换机互联、路由器和三层设备对接,才用Trunk模式。在实际项目中,有不少人把上行口设成Access,结果VLAN跨不了交换机,或者更糟:把终端的口设成Trunk,终端发出的无Tag帧只能落在Native VLAN上,业务全乱。还有一种情况是直接在Trunk口下又加了一句“switchport access vlan 10”,这种混写会让端口同时拥有Access和Trunk属性,部分设备会有优先级差异,极易引发注意不到的丢包。所以配置前先想清楚这个端口要接的是什么角色,Access还是Trunk,不要写两套参数。

5. 常见问题与排查方法实录

5.1 跨交换机不通,但本地联通一切正常

典型现象:PC-A能ping通本交换机同网段设备,但ping不通对端设备。我习惯按这个顺序查:

  1. 看物理链路和协议状态是否都Up;
  2. 确认互联端口确实是trunk模式;
  3. 查看trunk放行的VLAN列表是否包含业务VLAN;
  4. 检查两端Native VLAN是否一致;
  5. 抓包确认线上帧是否带Tag且VID正确;
  6. 再查MAC表,看目标MAC是否学到,以及从哪个接口学到的。

很多人一上来就ping目标IP,发现不通就去调IP,这是在错误的方向上浪费力气。二层跨交换机通信,本质上是找MAC表项,IP只是包装壳。如果MAC表项缺失,多半是VLAN或Tag的问题,调IP没用。这里还要补一句:如果使用远程SSH、Telnet管理交换机,排查时尽量不要在这些互联口上同时做变更,以免管理通道被破坏,最好带Console或独立带外管理,否则一旦配置错误,你连设备都进不去了。

5.2 trunk的Allowed列表“看起来没问题”,但业务就是不通

我遇过一个很典型的隐蔽故障:有人在交换机上用命令把某些VLAN从Trunk口移除,操作时误把目标VLAN也一起移除了,后来加VLAN又没有指定正确接口,业务VLAN在Trunk口没有放行。表面看Trunk口状态Up,协议也Up,MAC表里却始终学不到远端MAC。这类问题用一句话总结:Trunk的放行列表是白名单,不是显式放行的VLAN一律不会转发到对端。排查时最好的方法是直接执行查看命令,查看类似“Allowed VLAN on trunk”的字段,一条一条和业务VLAN清单对。如果有自动化的网络管理平台,还可以定时比对基线,避免人工漏配。

另外要小心命令的覆盖语义。某些设备上,switchport trunk allowed vlan add 10,20是在原有列表里追加;而直接写switchport trunk allowed vlan 10,20可能直接覆盖整表。这种细微差别会导致你原本放行了VLAN1-100,结果补一条10,20反而把100以后的VLAN全删了。操作前先查清设备的命令行为,不要把“以为”当成“事实”。

5.3 Native VLAN不一致:一切看起来正常,广播却四处乱跑

故障表现比较怪:大体能通,但偶尔有设备掉线,抓包发现很多本不该出现的广播报文跨了VLAN。这种经常就是两端Native VLAN对不上。因为Trunk口本来对Native VLAN不打标签,A端发出来的是无标签帧,B端把它理解为自己的Native VLAN,一旦两个VLAN不同,隔离就被打穿。

安全视角更要重视:如果Native VLAN设为默认的VLAN1,且Trunk放行列表包含VLAN1,那么当一个Trunk口连接了不受信任的设备时,登录VLAN1的设备可能被利用。双标签攻击的原理前面说过,攻击者在Access口发一个带有两层标签的帧,交换机剥掉外层Tag后,剩下内层Tag在Trunk上继续传播,可能直达攻击者指定的VLAN。防御措施有三条:把Native VLAN改成未使用的黑洞VLAN;Trunk放行列表别包含Native VLAN和其他敏感VLAN;Trunk口上禁用动态协商。这三条说起来简单,但很多运维体系里一直没有落地。

5.4 抓包验证:在Trunk上按帧里的Tag还原真相

如果怀疑Tag有问题,最可靠的办法是抓包。准备一台笔记本,接在支持端口镜像的交换机上,把镜像源设成出问题的trunk口,然后在笔记本上抓包。抓到以后,会看到帧头里有一个“802.1Q Virtual LAN”的字段,里面能看到priority、DEI、ID等信息。如果业务VLAN=10,那么该字段的ID应该是10;如果看到ID=0或其他值,说明VLAN标记异常。

要注意,抓包器看到的帧长度会变成1522字节而不是普通以太网的1518字节,如果抓包软件默认显示1518以下才算以太网帧,需要调整过滤条件。另外,交换机的镜像口本身如果在Access模式下,可能又会把Tag剥掉再转发给笔记本,最终看不到Tag。所以镜像口要配置成类似Trunk或专用镜像模式,别在镜像口上再套一层Access转换。这是我当年踩过的一个坑,看到抓包里全是Plain帧,还以为Trunk根本没加Tag,差点带偏排障方向。

5.5 MTU与Jumbo帧:大包丢了,小包却健步如飞

二层Trunk的Tag会让最大帧长度增加4字节,很多二层交换机内部都忍得了这个MTU,但一旦跨三层口、VXLAN这类封装场景,额外头部会带来连锁反应。典型故障是:小包、普通TCP网页能打开,但数据库备份或大文件传输频繁卡死,ping大包测试却能稳定复现。这时要检查接口MTU是否不小于1518/1522字节,三层路由口上还要考虑路径MTU发现与TCP MSS问题。

一个简单有效的排查测试是:从终端连续ping大尺寸的包,比如带1472字节载荷(加上IP头20字节+ICMP头8字节,正好1500),再依次递增,看哪里开始分段或丢包。如果加上Tag后的帧被物理传输层卡住,MTU调整往往立竿见影。不过别一上来就全局开Jumbo,大帧会带来碎片化和兼容性问题,建议只在必要链路或业务VLAN里开。

6. 安全加固与个人经验备忘

6.1 让Trunk口“少而窄”

安全上有个原则叫最小化暴露面。Trunk口只应该出现在需要多VLAN互通的设备之间,如交换机互联、路由器和核心交换机之间。对终端的口一律Access,不给它动态协商的机会。Trunk的Allowed VLAN只放行业务必需的那些VLAN,别图省事让它跑所有VLAN;Native VLAN改成不承载业务的黑洞VLAN;如果设备支持,还可以启用MAC地址表安全、风暴抑制、端口安全等策略,这些都值得写成基线模板。

6.2 我实际配置中踩过的几个坑

第一次配Trunk时,我按照教科书把两头都设成Trunk,结果发现链路是Up了,但跨交换机VLAN10就是不通。慢工细活一查,原来两台设备默认的Native VLAN分别是1和999,靠动态协商把链路变成了Trunk,但Native VLAN不一致,无标签的VLAN1流量被对端归到999,管理用的地址不在一个网段,设备直接失联。后来我把两端Native VLAN统一成业务无关的VLAN999,再手动固定模式,重启后一切正常。从此我养成了习惯:任何涉及Trunk的变更,都会在配置前同时截屏两端的当前状态,变更后立刻验证,绝不留“等会儿再看”的尾巴。

还有一次,某项目为了防环把核心交换机互联口上加了禁用生成树的功能,结果某个设备上又启用了一个协议和Trunk联动,临时出现环路。所以配置Trunk时,STP、边缘端口、协商模式这些参数要一起想,不能只顾着VLAN和Tag。链路层的事情永远是一套组合拳,单点配置再漂亮也不行。

6.3 后续还能怎么扩

如果你已经掌握了单条Trunk的通信过程,接下来可以试试链路聚合下的Trunk、VXLAN对Trunk标签的封装、以及带无线管理VLAN的混合场景。现代网络里“一条Trunk带多个VLAN”依然是基础,但VXLAN、SDN这些新协议会在这个基础上做更多抽象。掌握扎实的二层Tag基础,再往上走就不慌。

做了这么多年网络,我越来越觉得trunk这个功能像一门基础手艺,听起来简单,但能顺溜地把它讲清楚、排查明白的人,并不像看上去那么多。它的价值不在于那条链路本身,而在于它把VLAN从单台设备的孤岛中解放出来,让整个局域网的二层拓扑真正变得可设计、可扩展。每次网络出问题,我第一反应都是先看trunk状态、看allowed列表、看native VLAN,这套习惯救了我不止一次。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进