# Create Vlan Network

> 创建新的 VLAN 网络和对应的 Multus 网络配置。当用户需要新建 VLAN 网段、添加 Multus 网络定义时使用此技能。

- Skill: `majiayu000/create-vlan-network` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add majiayu000/create-vlan-network`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/create-vlan-network/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/create-vlan-network

---


# 创建 VLAN 网络

## 概述

在 home-ops 环境中创建新的 VLAN 网络，包括路由器配置、K8s 节点 VLAN 接口、Multus 网络定义三个层面。

## 前置条件

- 路由器 (OpenWrt) 的 SSH 访问权限
- Ansible 环境已配置
- 确定 VLAN ID 和子网规划

## 网络架构

```
路由器 (OpenWrt)          K8s 节点              Multus CNI
    |                        |                     |
 br-lan.XX  <--tagged-->  eth1.XX  <--macvlan-->  Pod
    |                        |                     |
192.168.XX.1             (无 IP)              192.168.XX.x
```

## 步骤

### 第一步：路由器 VLAN 配置

在路由器 `/etc/config/network` 中添加配置：

```config
# 新网络接口
config interface 'v<name>'
    option device 'br-lan.<vlan_id>'
    option proto 'static'
    option ipaddr '192.168.<vlan_id>.1'
    option netmask '255.255.255.0'

# VLAN 端口配置
config bridge-vlan
    option device 'br-lan'
    option vlan '<vlan_id>'
    list ports 'lan1:t'
    list ports 'lan2:t'
    list ports 'lan3:t'
```

同时更新文档 `docs/router/vlan.md`。

### 第二步：K8s 节点 VLAN 接口

更新 Ansible playbook `ansible/playbooks/setup-vlan.yaml`，在 `vlan_interfaces` 中添加：

```yaml
vlan_interfaces:
  - name: eth1.<vlan_id>
    vlan_id: <vlan_id>
    parent: eth1
```

执行 playbook：

```bash
ansible-playbook -i ansible/inventory/hosts.ini ansible/playbooks/setup-vlan.yaml
```

### 第三步：创建 Multus 网络定义

在 `k8s/infra/common/network/multus/networks/` 创建新的网络定义文件。

#### 类型一：需要 IPv6 直连（不使用 sbr）

适用于需要公网 IPv6 的服务（如 tailscale、qbittorrent）：

```yaml
---
# yaml-language-server: $schema=https://kubernetes-schemas.pages.dev/k8s.cni.cncf.io/networkattachmentdefinition_v1.json
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  name: multus-<name>
spec:
  config: |-
    {
      "cniVersion": "0.3.1",
      "name": "multus-<name>",
      "plugins": [
        {
          "type": "macvlan",
          "master": "eth1.<vlan_id>",
          "mode": "bridge",
          "ipam": {
            "type": "static",
            "routes": [
              {"dst": "0.0.0.0/5", "gw": "192.168.<vlan_id>.1"},
              {"dst": "8.0.0.0/7", "gw": "192.168.<vlan_id>.1"},
              {"dst": "11.0.0.0/8", "gw": "192.168.<vlan_id>.1"},
              {"dst": "12.0.0.0/6", "gw": "192.168.<vlan_id>.1"},
              {"dst": "16.0.0.0/4", "gw": "192.168.<vlan_id>.1"},
              {"dst": "32.0.0.0/3", "gw": "192.168.<vlan_id>.1"},
              {"dst": "64.0.0.0/2", "gw": "192.168.<vlan_id>.1"},
              {"dst": "128.0.0.0/3", "gw": "192.168.<vlan_id>.1"},
              {"dst": "160.0.0.0/5", "gw": "192.168.<vlan_id>.1"},
              {"dst": "168.0.0.0/6", "gw": "192.168.<vlan_id>.1"},
              {"dst": "172.0.0.0/12", "gw": "192.168.<vlan_id>.1"},
              {"dst": "172.32.0.0/11", "gw": "192.168.<vlan_id>.1"},
              {"dst": "172.64.0.0/10", "gw": "192.168.<vlan_id>.1"},
              {"dst": "172.128.0.0/9", "gw": "192.168.<vlan_id>.1"},
              {"dst": "173.0.0.0/8", "gw": "192.168.<vlan_id>.1"},
              {"dst": "174.0.0.0/7", "gw": "192.168.<vlan_id>.1"},
              {"dst": "176.0.0.0/4", "gw": "192.168.<vlan_id>.1"},
              {"dst": "192.0.0.0/9", "gw": "192.168.<vlan_id>.1"},
              {"dst": "192.128.0.0/11", "gw": "192.168.<vlan_id>.1"},
              {"dst": "192.160.0.0/13", "gw": "192.168.<vlan_id>.1"},
              {"dst": "192.169.0.0/16", "gw": "192.168.<vlan_id>.1"},
              {"dst": "192.170.0.0/15", "gw": "192.168.<vlan_id>.1"},
              {"dst": "192.172.0.0/14", "gw": "192.168.<vlan_id>.1"},
              {"dst": "192.176.0.0/12", "gw": "192.168.<vlan_id>.1"},
              {"dst": "192.192.0.0/10", "gw": "192.168.<vlan_id>.1"},
              {"dst": "193.0.0.0/8", "gw": "192.168.<vlan_id>.1"},
              {"dst": "194.0.0.0/7", "gw": "192.168.<vlan_id>.1"},
              {"dst": "196.0.0.0/6", "gw": "192.168.<vlan_id>.1"},
              {"dst": "200.0.0.0/5", "gw": "192.168.<vlan_id>.1"},
              {"dst": "208.0.0.0/4", "gw": "192.168.<vlan_id>.1"},
              {"dst": "224.0.0.0/3", "gw": "192.168.<vlan_id>.1"}
            ]
          }
        }
      ]
    }
```

#### 类型二：mDNS 或内网服务（使用 sbr）

适用于智能家居等需要 mDNS 发现的服务：

```yaml
---
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  name: multus-<name>
spec:
  config: |-
    {
      "cniVersion": "0.3.1",
      "name": "multus-<name>",
      "plugins": [
        {
          "type": "macvlan",
          "master": "eth1.<vlan_id>",
          "mode": "bridge",
          "capabilities": { "ips": true, "mac": true },
          "ipam": {
            "type": "static",
            "routes": [
              {"dst": "0.0.0.0/0", "gw": "192.168.<vlan_id>.1"}
            ]
          }
        },
        {
          "type": "sbr"
        }
      ]
    }
```

### 第四步：更新 kustomization.yaml

在 `k8s/infra/common/network/multus/networks/kustomization.yaml` 中添加新文件：

```yaml
resources:
  - main.yaml
  - iot.yaml
  - ipv6.yaml
  - <new-network>.yaml # 新增
```

### 第五步：在服务中使用 Multus 网络

在 HelmRelease 的 Pod annotations 中添加：

```yaml
defaultPodOptions:
  annotations:
    k8s.v1.cni.cncf.io/networks: |
      [{
        "name": "multus-<name>",
        "namespace": "network",
        "interface": "eth1",
        "ips": ["192.168.<vlan_id>.XX/24"],
        "mac": "02:XX:XX:XX:XX:XX"
      }]
```

生成 MAC 地址：

```bash
printf '02:%02X:%02X:%02X:%02X:%02X\n' $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256))
```

### 第六步：批量重启 Multus 服务

为使用 Multus 的 Deployment/StatefulSet 添加 label `app.ooooo.space/multus: "true"`，然后批量重启：

```bash
# default namespace
kubectl rollout restart -n default -l app.ooooo.space/multus deployment
kubectl rollout restart -n default -l app.ooooo.space/multus statefulset

# network namespace
kubectl rollout restart -n network -l app.ooooo.space/multus deployment
kubectl rollout restart -n network -l app.ooooo.space/multus statefulset
```

### 第七步：更新文档

更新以下文档：

1. `README.md` - 服务 IP 表格和 multus 网络定义表格
2. `k8s/infra/common/network/multus/networks/README.md` - 网络类型说明
3. `docs/router/vlan.md` - VLAN 定义表格

## 现有网络类型

| 网络名         | Master 接口 | 子网            | 用途                                                   | 使用 sbr |
| -------------- | ----------- | --------------- | ------------------------------------------------------ | -------- |
| multus-main    | eth1        | 192.168.6.0/24  | 保留备用                                               | 是       |
| multus-iot     | eth1.50     | 192.168.50.0/24 | mDNS 智能家居(不关心视频流udp或者可以指定接口发送mdns) | 是       |
| multus-homekit | eth1.50     | 192.168.50.0/24 | mDNS 智能家居(无法指定接口udp)                         | 否       |
| multus-ipv6    | eth1        | 192.168.6.0/24  | IPv6 直连/UDP                                          | 否       |

## 注意事项

- **不创建新 VLAN 的情况**: 如果只需要不同的路由策略，可以复用现有 VLAN，只创建新的 Multus 网络定义

- **IP 规划**: 建议 VLAN ID 与子网第三段保持一致（如 VLAN 50 → 192.168.50.0/24）
- **防火墙**: 新 VLAN 需要在路由器配置对应的防火墙区域

## 验证

1. 检查路由器接口: `ssh router "ip addr show br-lan.<vlan_id>"`
2. 检查节点接口: `ansible k8s -m shell -a "ip link show eth1.<vlan_id>"`
3. 检查 Multus 网络: `kubectl get net-attach-def -n network`
4. 测试 Pod 网络: 部署测试 Pod 并验证连通性

## 参考

- 现有网络定义: `k8s/infra/common/network/multus/networks/`
- VLAN 文档: `docs/router/vlan.md`
- Ansible Playbook: `ansible/playbooks/setup-vlan.yaml`

