This commit is contained in:
2026-05-24 11:42:38 +08:00
commit 30d312ac35
521 changed files with 146481 additions and 0 deletions
+208
View File
@@ -0,0 +1,208 @@
---
tags: [计算机网络, VLAN, 802.1Q, Trunk, Access端口]
create time: 2026-05-17 23:30
---
# VLAN 与 Trunk
## 概述
VLAN(Virtual Local Area Network,虚拟局域网)允许在一台物理交换机上创建多个逻辑隔离的广播域。它是现代数据中心和办公网络的基本组织单元。
> [!QUESTION] 为什么需要 VLAN?
> 一台万兆交换机的 MAC 表通常限制在几万条以内,加上广播泛洪带来的开销,单广播域超过 2000 台主机会显著降低性能。VLAN 将大网络划分为多个小广播域,就像在一栋大楼里用防火墙隔出多个独立办公室——同一楼层但互不干扰。
## IEEE 802.1Q Tag 结构
### 不带 VLAN 的 Ethernet II 帧
```
┌──────────┬──────────┬──────┬─────────────┬──────┐
│ Dest MAC │ Src MAC │Type │ Payload │ FCS │
│ 6 bytes │ 6 bytes │ 2B │ 46-1500 B │ 4 B │
│ │ │0x0800│ │ │
└──────────┴──────────┴──────┴─────────────┴──────┘
←── 14 ──→ ←──MTU──→ ←── 4 ──→
Header Payload Tail
```
### 带 802.1Q Tag 的帧
```
┌──────────┬──────────┬──────┬───┬──────┬─────────────┬──────┐
│ Dest MAC │ Src MAC │Type │TPID │ TCI │ Payload │ FCS │
│ 6 bytes │ 6 bytes │ 2B │2B │ 2B │ 46-1500 B │ 4 B │
│ │ │0x0800│8100 │ VID │ │ │
└──────────┴──────────┴──────┴───┴──────┴─────────────┴──────┘
←── 14 ──→ │←──4──→│ ←──MTU──→ ←── 4 ──→
↑ 新增 4-byte Tag
```
### TCI (Tag Control Information) 位图
```
Bit 15 Bit 13-12 Bit 11-0
────────────────────────────────────
CFI | PCP (优先级) | VID (VLAN ID)
(1bit) | (3 bits) | (12 bits)
```
| 字段 | 大小 | 取值范围 | 说明 |
|------|------|---------|------|
| CFI | 1 bit | 0 或 1 | Canonical Format Indicator,传统以太网固定为 0 |
| PCP | 3 bit | 0–7 | Priority Code Point,QoS 优先级(见下表) |
| VID | 12 bit | 0–4095 | VLAN Identifier,**实际可用 1–4094** |
### PCP 优先级对照
| PCP | 用途 | 典型场景 |
|-----|------|---------|
| 0 | Best Effort | 普通数据流量 |
| 1 | Background | 后台低优先级的备份任务 |
| 2–3 | Excellent Effort | 文件传输等中等业务 |
| 4 | Critical Applications | 视频流会议 |
| 5 | Voice | 语音通话 VoIP(最高优先) |
| 6 | Network Control | 网络管理协议 |
| 7 | Reserved | 保留 |
## VLAN 端口类型
| 端口类型 | Access | Trunk | Hybrid(Huawei/H3C) |
|----------|--------|-------|---------------------|
| 允许 VLAN | 1 个(PVID) | 多个 | 多个(可配置) |
| 入栈标签 | 接收不带标签 → 打上 PVID | 所有到达的帧保持标签 | 根据配置决定 |
| 出栈标签 | 发送时剥离标签 | 发送时保留标签(除 PVID) | 按每 VLAN 配置 |
| 使用场景 | 接 PC/打印机/AP | 交换机互联、接路由器 | 灵活混合 |
### Access 端口示例
```mermaid
flowchart LR
PC["PC (无标签帧)"] -->|"发裸帧"| A["Access Port<br/>PVID = 10"]
A -->|"打上 Tag 10"| S["Switch 内部 VLAN 10 域"]
S -->|"移除 Tag"| B["Access Port<br/>PVID = 10"]
B -->|"发裸帧"| GW["网关 Router"]
style A fill:#DDA0DD,color:#000
style B fill:#DDA0DD,color:#000
```
> Access 端口对主机透明——主机看到的仍是普通以太网帧,完全不知道 VLAN 的存在。
### Trunk 端口示例
```mermaid
flowchart LR
SW1["Switch A"] -->|"Trunk<br/>携带多个 VID"| SW2["Switch B"]
Note over SW1,SW2: VLAN 10 流量: EtherType=0x8100, VID=10<br/>VLAN 20 流量: EtherType=0x8100, VID=20
style SW1 fill:#98FB98,color:#000
style SW2 fill:#98FB98,color:#000
```
## Router-on-a-Stick(单臂路由)
当路由器只有一个物理接口时,可以通过子接口 + VLAN 实现多个 VLAN 间路由:
```
VLAN 10 VLAN 20
┌──────────┐ ┌──────────┐
│ 192.168.10.x /24 │ │ 192.168.20.x /24 │
└──────┬───┘ └──────┬───┘
│ │
Access Access
│ │
┌──────┴───────────────────┴───┐
│ Switch │
│ Trunk Port (eth0.10 & .20) │
└──────┬───────────────────┬───┘
│ 子接口 eth0.10 │ 子接口 eth0.20
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Router │ │ Router │
│ eth0.10: 192.168.10.1/24 │ │ eth0.20: 192.168.20.1/24 │
└─────────────────┘ └─────────────────┘
```
> [!warning] 单臂路由的性能瓶颈
> 所有 VLAN 间的流量都经过同一个物理接口进出(先入后出),相当于**双倍带宽占用**。对于万兆环境,建议使用三层交换机做硬件 VLAN 间路由。
## 配置示例
### Linux Bridge 上的 VLAN
```bash
# 创建 vlan interface
ip link add link eth0 name eth0.10 type vlan id 10
ip link add link eth0 name eth0.20 type vlan id 20
# 设置 IP 并启用
ip addr add 192.168.10.1/24 dev eth0.10
ip addr add 192.168.20.1/24 dev eth0.20
ip link set eth0.10 up
ip link set eth0.20 up
# 查看
$ ip -d link show type vlan
4: eth0.10@eth0: <BROADCAST,MULTICAST,UP> mtu 1500 ...
link/ether aa:bb:cc:dd:ee:ff brd ff:ff:ff:ff:ff:ff promiscuity 0
vlan protocol 802.1Q id 10 reassemble 0
```
### Docker 中利用 VLAN
```yaml
# docker-compose.yml
services:
web:
networks:
frontend: # VLAN 10
ipv4_address: 192.168.10.10
backend: # VLAN 20
ipv4_address: 192.168.20.10
networks:
frontend:
driver: bridge
ipam:
config:
- subnet: 192.168.10.0/24
backend:
driver: bridge
ipam:
config:
- subnet: 192.168.20.0/24
```
## VLAN 边界与跨 Switch
```mermaid
sequenceDiagram
participant SW1 as Switch-A
participant Link as 交换机间链路
participant SW2 as Switch-B
SW1->>Link: Frame {EtherType:0x8100, VID:10}
Note over Link: Trunk 链路保持 802.1Q Tag
SW2->>SW2: 收到 → 识别 VID=10 → 在 VLAN 10 内转发
SW2->>SW2: 查 MAC 表 → 仅从同 VLAN 端口发出
```
**核心要点:** VLAN 信息随 802.1Q Tag 穿过 Trunk 链路传递到下一台交换机。每台交换机根据自己的 VLAN 数据库独立处理。
## 最佳实践
| 项目 | 建议 |
|------|------|
| VLAN ID 分配 | 管理 VLAN=1(不建议,安全风险),业务 VLAN ≥ 10 |
| Native VLAN | 修改默认 native VLAN(避免用 1),防 VLAN Hopping |
| VLAN 数量 | 单台交换机支持最大 4094 个 VLAN |
| Inter-VLAN 路由 | >10 个 VLAN 用三层交换机而非单臂路由 |
| 安全 | 未使用的端口划入"黑洞 VLAN"(无 IP 段),关闭 DTP 自动协商 |
## 关联笔记
- [[hhs/NETWORK/Ethernet帧结构]] — 802.1Q Tag 插入在 Ethertype 位置之前
- [[hhs/NETWORK/Switch与路由器]] — Switch 如何基于 VLAN 隔离广播域
- [[hhs/NETWORK/MAC地址与广播域]] — VLAN 缩小了广播域的规模