主题
01 架构与网络设计
本章目标:在动手装机器之前,把「这套 12 节点 Harvester 到底由什么组成、流量怎么走、IP 怎么分」彻底想清楚。这一章的产出物是一张确认过的网络拓扑图和一份 IP 分配表——它们会直接决定第 2、3 章的装机参数和第 4 章的网络对象。
1.1 Harvester 是什么:一句话与一张图
Harvester = 跑在裸金属上的 Kubernetes(RKE2)+ 虚拟化(KubeVirt)+ 分布式存储(Longhorn)+ 一套把这些能力包装成人话的 UI/CRD。
它不是「一个虚拟化软件装了个 Web 界面」,而是「一个 Kubernetes 集群,把虚拟机当成一种工作负载来调度」。理解这一点,后面所有排障思路都会顺:VM 出问题,往往要先看 Pod、Node、PVC、CNI 这一层。
text
┌──────────────────────────────────────────────────────────────────────┐
│ Harvester UI / API (通过 VIP 10.181.0.100 访问,HTTPS + ingress) │
├──────────────────────────────────────────────────────────────────────┤
│ Harvester CRD 层 │
│ VirtualMachine(Template) / Image / Backup / ClusterNetwork / │
│ VlanConfig / NAD(VM Network) / IPPool / LoadBalancer / Upgrade │
├──────────────────────────────────────────────────────────────────────┤
│ 能力层 │
│ KubeVirt(VM 生命周期,virt-launcher Pod) │
│ Longhorn(分布式块存储,VM 磁盘 = PVC = Longhorn volume) │
│ Harvester Network Controller(bridge/VLAN/bond,Multus CNI) │
│ Harvester Load Balancer(L4 LB,把外部流量导到 VM) │
│ Harvester Cloud Provider(给 Guest K8s 集群提供 LB/CSI) │
├──────────────────────────────────────────────────────────────────────┤
│ 底座:RKE2(Kubernetes)+ Canal(Flannel VXLAN + Calico 策略) │
│ Elemental / SUSE Linux Micro(不可变宿主机 OS,UEFI 引导) │
└──────────────────────────────────────────────────────────────────────┘关键组件与我们要关心的点
| 组件 | 在本书中的作用 | 你要记住的事 |
|---|---|---|
| RKE2 | Kubernetes 发行版,管理 12 个节点 | 前 3 台是 server(etcd + control plane),其余是 agent;kubectl 走 VIP |
| KubeVirt | 把 VM 表达为 VirtualMachine CR,用 virt-launcher Pod 承载 qemu 进程 | VM 的运行状态 = Pod 状态;kubectl get vmi 看实例 |
| Longhorn | VM 磁盘的实际存储,3 副本跨节点 | 存储网络默认走 mgmt;副本重建有等待间隔(默认 600s) |
| Canal(Flannel+Calico) | 集群 overlay 网络,Pod/VM 管理网 | 默认 Pod CIDR 10.52.0.0/16,VXLAN 占用 50 字节 → VM 管理网 MTU 1450 |
| Multus + harvester-network-controller | 给 VM 挂第二块「直通」网卡 | VLAN 网络是 bridge 模式,CNI 不分配 IP(ipam:{}),IP 由 VM 内部 DHCP/静态决定 |
| Harvester LB | 四层负载均衡 | 只能用于 VLAN 网络,需要 VM 装 qemu-guest-agent 才能拿到后端 IP |
| Elemental / SLE Micro | 不可变宿主机 OS | 宿主机是只读镜像系统,改配置要用 CloudInit CRD 或官方支持的方式,别手改 /etc |
1.2 12 节点的角色划分
Harvester 的规则很朴素:第一台装机的节点是 management;集群达到 3 台及以上时,随后加入的前两台自动提升为 management,组成高可用控制面。 其余节点是 worker(compute)。
| 节点 | 主机名 | 管理 IP | 角色 | 说明 |
|---|---|---|---|---|
| 1 | harvester-01 | 10.181.0.11 | management(etcd + control plane) | install.mode: create,定义 VIP 与 token |
| 2 | harvester-02 | 10.181.0.12 | management | install.mode: join |
| 3 | harvester-03 | 10.181.0.13 | management | install.mode: join,凑齐 etcd 3 副本 |
| 4 | harvester-04 | 10.181.0.14 | worker | join |
| 5 | harvester-05 | 10.181.0.15 | worker | join |
| 6 | harvester-06 | 10.181.0.16 | worker | join |
| 7 | harvester-07 | 10.181.0.17 | worker | join |
| 8 | harvester-08 | 10.181.0.18 | worker | join |
| 9 | harvester-09 | 10.181.0.19 | worker | join |
| 10 | harvester-10 | 10.181.0.20 | worker | join |
| 11 | harvester-11 | 10.181.0.21 | worker | join |
| 12 | harvester-12 | 10.181.0.22 | worker | join |
集群公共地址:
| 用途 | 地址 |
|---|---|
| 集群 VIP(UI / API / ingress) | 10.181.0.100 |
| 管理网关 | 10.181.0.1 |
| VM 直通网网关(核心交换机 SVI) | 10.181.91.1 |
| LB 对外 VIP 池 | 10.181.91.50 – 10.181.91.99 |
⚠️ management 节点也会跑 VM。Harvester 不会自动禁止在 management 节点上调度虚拟机。生产上建议做两件事之一:给 VM 配 nodeSelector/亲和性只落在 worker,或用资源预留(
guaranteedInstanceManagerCPU、系统预留)保证控制面不被 VM 抢死。本书在第 7 章给出具体做法。
⚠️ 每台节点的
product_uuid必须唯一(/sys/class/dmi/id/product_uuid)。同型号批量克隆的机器、或某些虚拟化环境里,这个值重复会导致 VM 实时迁移等操作报错。装机前逐台核对一次,成本极低,收益极高。
1.3 Harvester 的三层网络模型(必须先建立的 mental model)
Harvester 的网络对象是三层递进的,很多人卡住就是因为把它们混为一谈:
text
第 1 层 ClusterNetwork(集群网络)
例:mgmt(内置)、cn-vm(我们新建)
含义:一组物理链路资源池,"VM 流量可以从哪几张网卡走"
│
▼ 由 VlanConfig 把具体节点 + 具体网卡 + bond 方式绑定上来
第 2 层 VlanConfig(网络配置,UI 上叫 Network Config)
例:vlan-cfg-vm → clusterNetwork: cn-vm,nodeSelector 选中 12 台,
uplink.nics: [eno3, eno4],bond mode: 802.3ad
含义:谁(哪些节点)用哪几张卡(uplink nics)接入第 1 层
│
▼ 在已经"通电"的 ClusterNetwork 上再打 VLAN 标签
第 3 层 VM Network = NetworkAttachmentDefinition(NAD)
例:default/net-91 → vlan: 91,clusternetwork: cn-vm
含义:VM 网卡真正引用的对象,一个 NAD = 一个可选网络只有第 2 层覆盖了某个节点,该节点上的 VM 才能选到挂在这个 ClusterNetwork 上的第 3 层网络。 这就是「UI 里创建 VM 时网络下拉框是空的」的根因,第 4 章和第 8 章都会反复回到这一点。
1.3.0 网络基础速成(不熟悉网络概念的读者先读这一节)
第 2、4、5、8 章会反复用到 VLAN、bond、bridge、masquerade、MTU、DHCP 这六组概念。这里用本书的实际环境把它们一次讲清,每组只讲「本书要用到的那部分」;已经熟悉的读者可以直接跳到 1.3.1。
① VLAN:一根网线里跑多张「互相隔离的网」
以太网帧里可以插入一个 4 字节的 VLAN 标签(IEEE 802.1Q),声明「这个包属于哪张网」。交换机按标签把一张物理网切成多张逻辑二层网,不同 VLAN 之间二层完全隔离(互收不到广播),要通信必须经三层网关。
text
普通帧: [ 目的MAC | 源MAC | 类型 | 数据 ]
带标签: [ 目的MAC | 源MAC | 802.1Q 标签(VLAN 91) | 类型 | 数据 ]
└── 4 字节,含 12 bit VLAN ID(1–4094)交换机端口对 VLAN 的三种处理方式(这是第 2 章交换机配置的全部背景知识):
| 端口形态 | 收包行为 | 发包行为 | 本书用在哪 |
|---|---|---|---|
| access(接入口) | 只属于一个 VLAN;收到带标签的包直接丢弃 | 剥离标签后发出 | 接普通终端;不适合接 Harvester 的 VM 网卡 |
| trunk(干道) | 接受「放行列表」里所有 VLAN 的带标签包 | 带标签发出 | 接 eno3/eno4 的端口,放行 VLAN 91 |
| native VLAN(本征) | trunk 上唯一允许不带标签进出的 VLAN | 该 VLAN 的包剥离标签发出 | mgmt 口若 untagged 就是它 |
一句话记住本书的硬性要求:VM 网络 net-91 里写了 vlan: 91,VM 发出的包就带着 91 标签经过宿主机 bridge 和 bond,最后到达交换机端口;端口不放行 91,包在交换机入口就被丢弃。 这就是 2.5 节反复强调「trunk 放行 VLAN 91」的原因,也是排障时「宿主机一切正常但包出不去」的头号嫌疑。
② bond:两张网卡当一个用
bond(链路聚合)把多张物理网卡合成一个逻辑口(本书的 mgmt-bo、cn-vm-bo),目的是冗余(坏一根线不断网)和带宽叠加。七种模式只需要记住这张表:
| 模式 | 一句话解释 | 交换机侧要不要配合 |
|---|---|---|
balance-rr(0) | 轮流从每个口发包,吞吐最高但可能乱序 | 要(静态聚合) |
active-backup(1) | 一主一备,主坏秒切,带宽=单口 | 不要配合,最省心 |
balance-xor(2) | 按源/目的 MAC 或 IP 哈希选链路 | 要(静态聚合) |
broadcast(3) | 所有口都发一份,极特殊场景 | 要(静态聚合) |
802.3ad(4) | 用 LACP 协议两端动态协商聚合,生产首选 | 要,且必须配 LACP |
balance-tlb(5) | 发送方向负载均衡,接收单口 | 不要 |
balance-alb(6) | 收发都均衡,靠改写 ARP 应答实现 | 不要 |
关键结论:bond 两端模式必须匹配。宿主机用 802.3ad 而交换机没配 LACP 时,bond 口看起来 up、VLAN 也都在,但 LACP 协商不成功,包随机走不通——这是第 8 章案例 1 的真实事故。判断方法只有一条:cat /proc/net/bonding/cn-vm-bo 里 Partner Mac Address 不是全 0。本书的选择:mgmt 用 active-backup(装机期不依赖交换机配置),cn-vm 用 802.3ad(交换机侧已配 LACP)。
③ Linux bridge:宿主机上的「软件交换机」
Harvester 为每个 ClusterNetwork 在每台宿主机上创建一对设备:
text
物理网卡 eno3/eno4 ──► bond 口 cn-vm-bo ──► bridge cn-vm-br ──► tapXXXX ──► VM 的网卡
(上联,聚合) (软件交换机, (virtio 后端)
按 VLAN 过滤转发)cn-vm-br就是一台软件版接入交换机:VM 的 tap 设备和上联 bond 都插在它的「端口」上。- 它开启了 VLAN filtering:每个端口有自己的 VLAN 放行表。VM 网络
net-91创建后,控制器会给相关端口加上91;bridge vlan show dev cn-vm-bo看到91才说明标签能过。 bridge fdb show br cn-vm-br是它的 MAC 地址表(哪台 VM/外部机的 MAC 在哪个端口学到的)。排障时先看 FDB:MAC 学到了说明二层已到宿主机,问题在 VM 内部或以上;学不到说明 VLAN/交换机/物理链路有问题。
命名规则:<ClusterNetwork 名>-br(bridge)与 <ClusterNetwork 名>-bo(bond),所以 ClusterNetwork 名字要短——Linux 接口名上限 15 字符(见 1.4)。
④ masquerade vs bridge:VM 两种接法的本质区别
KubeVirt 给 VM 接网络有两种绑定方式,本书两种都用,务必分清:
text
masquerade(管理网 eth0,NAT 模式)
VM 内: eth0 = 10.52.7.31/32,网关 169.254.1.1(链路本地地址,不在任何网段里)
│ 所有出向包先发给这个“假网关”
▼
virt-launcher Pod(10.52.x.x 网段,Canal/VXLAN overlay)
│ iptables/nftables NAT:源地址改写成节点地址
▼
宿主机 mgmt-bo → 管理网 10.181.0.0/24 → 出网关
后果:外部看到的是“节点在发包”,无法反向直连 VM;VM 重启 IP 会变。
bridge(VLAN 网 eth1,二层直通模式)
VM 内: eth1 = 10.181.91.101/24,网关 10.181.91.1(真实交换机 SVI)
│ 带 VLAN 91 标签的原始帧
▼
tap → cn-vm-br(放行 91)→ cn-vm-bo → eno3/eno4 → 交换机 trunk → 外部
全程无 NAT、无隧道,VM 与 10.181.91.0/24 上的物理机完全同层。对照记忆:masquerade 回答的是「VM 怎么借力集群网络出去」,bridge 回答的是「VM 怎么变成业务网段里的一台真机器」。本书「外部直接 SSH VM」的需求只有 bridge 能满足。
⑤ MTU 与那「50 字节」
MTU 是一帧能承载的最大字节数,默认 1500。两个必须记住的数字:
- 走 mgmt 的 VM 网卡 MTU = 1450:Canal 的 VXLAN 隧道每包加 50 字节头(外层以太网 14 + IP 20 + UDP 8 + VXLAN 8),VM 若按 1500 发包,封装后变成 1550 字节被物理网丢弃。
- 走
net-91的 VM 网卡 MTU = 1500(与VlanConfig一致),因为 bridge 直通没有封装开销。
MTU 不一致的典型症状是**「小包通、大包死」**:ping(默认 64 字节)正常,SSH 能登录,但 scp 大文件、HTTP 大响应直接卡死。验证方法(DF 置位、payload = MTU − 28):
bash
ping -M do -s 1472 -c3 10.181.91.1 # MTU 1500 的链路应通过
ping -M do -s 8972 -c3 10.181.91.1 # 全路径开 jumbo(9000)后才应通过⑥ DHCP 四步与克隆体撞车
VM 用 DHCP 拿地址时发生四步交互(UDP 67/68 端口):
text
VM ──DISCOVER(广播:谁有地址?)──►
VM ◄─OFFER(我有个 10.181.91.205)── DHCP 服务器
VM ──REQUEST(我就要这个)────────►
VM ◄─ACK(成交,租约 3600 秒)─────排障时在 VM 内 sudo tcpdump -i eth1 -n 'port 67 or port 68':只看到 DISCOVER 没有 OFFER = 二层没到 DHCP 服务器(回 L0–L2 查 VLAN/trunk),四步齐全才算网络层没问题。
⚠️ DHCP 靠「客户端标识」区分机器。netplan(Ubuntu 16.04+)默认用 DUID(源自 /etc/machine-id)而不是 MAC。从模板/快照克隆的 VM 若没清 machine-id,会带着相同 DUID 去请求,DHCP 服务器发出同一个 IP,造成地址冲突。解法是双保险:networkData 里写 dhcp-identifier: mac(5.3.4),黄金镜像里清 machine-id(6.6.1)。真实案例见 8.4 案例 4。
概念 → 章节索引
| 概念 | 首次出现 | 深入讲解 | 排障入口 |
|---|---|---|---|
| VLAN / trunk | 本节 | 2.5 交换机配置 | 8.2.1–8.2.3 |
| bond / LACP | 本节 | 4.2.1、4.4 | 8.2.2、案例 1 |
| bridge / FDB | 本节 | 1.4 数据路径、4.5 | 8.2.3 |
| masquerade / bridge | 本节 | 5.1 五个事实 | 8.2.7、案例 3 |
| MTU | 本节 | 1.5 Q4、4.9.2 | 8.2.3 MTU 陷阱 |
| DHCP / DUID | 本节 | 4.8 Managed DHCP、5.3.4 | 8.2.6、案例 4 |
1.3.1 内置的 mgmt 集群网络
- 装机时由
install.management_interface定义,本环境是eno1 + eno2的 bond,静态 IP 在10.181.0.0/24。 - 它同时承载:节点管理、Kubernetes API、UI/ingress、Longhorn 存储流量(未单独建存储网络时)、以及默认的 VM overlay 网络。
- 默认 MTU 1500;挂在 mgmt 上的 VM 网卡 MTU 是 1450,因为 Canal(Flannel VXLAN + Calico)每包有 50 字节开销。跑大包/存储/Jumbo 的业务必须注意这一点。
1.3.2 VM 的两条上网路径(本环境最关键的一张对比表)
| 维度 | Management Network(管理网 / overlay) | VLAN Network(本环境的 net-91) |
|---|---|---|
| KubeVirt 绑定方式 | masquerade(iptables/nftables NAT) | bridge(Linux bridge 直通) |
| VM 里看到的网卡 | eth0(第一块) | eth1(第二块,可热插拔) |
| IP 来自哪里 | 集群 Pod CIDR 10.52.0.0/16,由 KubeVirt/CNI 分配 | CNI 不分配(NAD 里 ipam:{}),由 VLAN 91 上的 DHCP 服务器或 VM 内静态配置决定 |
| 网段是否与外部同层 | 否,是集群内部 overlay | 是,与 10.181.91.0/24 上的物理机同二层/同网关 |
| 外部能否直接访问 VM | 不能(默认只能从集群节点内访问;对外要靠 LB / NodePort / Ingress) | 能,直接 ssh user@10.181.91.x |
| VM 能否主动出外网 | 能,经宿主机 NAT 出 mgmt 网关 | 能,经 VLAN 91 网关 10.181.91.1 出 |
| MTU | 1450(overlay 开销) | 跟 ClusterNetwork 的 MTU 一致(本环境 1500,可上 9000) |
| 跨节点 VM 互通 | 走 VXLAN 隧道(UDP 8472),受 mgmt 带宽影响 | 走物理 underlay,性能与安全隔离更好 |
| 是否支持 Harvester LB | 否(LB 只支持 VLAN 网络) | 是 |
| 典型用途 | VM 与集群内部通信、被 Ingress/LB 暴露 | 业务对外服务、被外部系统直连、与物理机同网段互访 |
结论:本环境的需求「VM 需要一块额外网卡、在
10.181.91.0/24里直接与外部通信」,只能用 VLAN Network 实现。管理网保留用于集群内部通信与出网兜底。
1.3.3 关于 IP 分配,必须记住的三句话
- Harvester 的 VLAN 网络本身不发 IP。 NAD 的
spec.config里ipam是空对象,CNI 只负责把 VM 的网卡桥接到带 VLAN 标签的二层域,剩下的地址由 VM 自己解决。 - VM 内部拿 IP 有三种办法,按推荐度排序:
- 外部 DHCP(VLAN 91 上已有的 DHCP 服务器 / 核心交换机 DHCP)——生产最常见;
- 静态 IP + cloud-init networkData——地址可控、可编排,本书批量交付方案采用这种;
- Harvester Managed DHCP 插件(
harvester-vm-dhcp-controller,实验特性,需单独安装 addon,用network.harvesterhci.io/v1alpha1的IPPool定义地址池)——适合没有 DHCP 服务器的隔离环境,详见 4.6。
- 地址规划要避开保留段:
10.42.0.0/16、10.43.0.0/16、10.52.0.0/16、10.53.0.0/16。10.181.91.0/24与之不冲突,安全。
1.4 一个数据包从 VM 到外部的完整路径
以「外部机器 10.181.91.200 SSH 到 VM 10.181.91.101」为例,逐跳看清路径。每一跳都给出验证命令,这是第 8 章排障的基础。
text
外部客户端 10.181.91.200
│ (VLAN 91, 同一二层)
▼
核心交换机 SVI 10.181.91.1 ──► trunk 端口(放行 VLAN 91,tagged)
│
▼ 物理链路
Harvester 节点 eno3 / eno4 ← 验证:ethtool eno3 | grep -i link
│
▼ bonding(802.3ad / active-backup)
bond 上联口:cn-vm-bo ← 验证:cat /proc/net/bonding/cn-vm-bo
│
▼ Linux bridge + VLAN 过滤(vid 91)
bridge:cn-vm-br ← 验证:bridge vlan show dev cn-vm-bo
│ bridge fdb show br cn-vm-br
▼ tap 设备(VM 的 virtio 网卡后端)
tapXXXX(属于 virt-launcher Pod 的网络命名空间)
│
▼
VM 内部 eth1 = 10.181.91.101 ← 验证:VM 内 ip -br addr; ip route对应的宿主机对象命名规则(很重要,排障全靠它):
| ClusterNetwork 名字 | 生成的 bridge | 生成的上联 bond | VLAN 子接口(HostNetworkConfig 才有) |
|---|---|---|---|
mgmt(内置) | mgmt-br | mgmt-bo | mgmt-br.<vid> |
cn-vm(本环境) | cn-vm-br | cn-vm-bo | cn-vm-br.91 |
命名规则是
<clusterNetwork 名>-br与<clusterNetwork 名>-bo。给 ClusterNetwork 起名时要短、要合法(小写字母、数字、-),因为它会变成 Linux 接口名的一部分,而 Linux 接口名有 15 字符限制。cn-vm-br8 个字符,安全;production-vm-network-br就会被截断出问题。
✅ 一键体检(在任一节点上执行):
bash
ip -br link | grep -E 'cn-vm|mgmt' # 应该看到 cn-vm-br / cn-vm-bo / eno3 / eno4
bridge link show # 看哪些 tap/物理口挂在哪个 bridge
bridge vlan show dev cn-vm-bo # 看 VLAN 91 是否被放行
bridge fdb show br cn-vm-br | head # 看 VM MAC 是否学习到1.5 设计决策与权衡(把「为什么」写下来,将来接手的人才不会乱改)
Q1:为什么不让 VM 直接用 mgmt 网络?
技术上完全可以(Harvester 支持在 mgmt 上建 VLAN 网络),但生产不推荐:
- mgmt 同时跑 etcd、API、ingress、Longhorn 存储复制流量。VM 业务流量一挤进来,存储和控制面会先出问题,表现为 etcd 慢、API 超时、卷副本降级——排障极其痛苦。
- 官方最佳实践明确建议:每个节点有两张以上网卡时,为 VM 建独立的 ClusterNetwork,否则只能用管理网承载 VM 流量,HA 与性能都不保证。
- 本环境每台机器有 4 个网口,正好 2+2 分开,这是最省心、最容易讲清楚的拓扑。
决策:VM 直通流量走独立 ClusterNetwork cn-vm(eno3 + eno4)。
Q2:VLAN 91 tagged,还是 untagged network?
Harvester 的 VM Network 有两种:VLAN 网络(打标签)和 untagged 网络(不打标签,直接用该 ClusterNetwork 的原生二层)。
| VLAN 网络(本方案) | untagged 网络 | |
|---|---|---|
| 交换机侧 | trunk 放行 VLAN 91 | access 或 native VLAN |
| 与物理网络隔离 | 好,一个 ClusterNetwork 上可以并存多个 VLAN(91、92、93…) | 差,一个 ClusterNetwork 只有一个原生域 |
| 扩展性 | 后续加 10.181.92.0/24 只需再建一个 NAD | 需要新的 ClusterNetwork + 新网卡 |
| 适用 | 多网段、多租户、与现有 VLAN 规划一致 | 极简环境、单一网段 |
决策:用 VLAN 91 tagged。 一台机器的两张 VM 网卡(bond)上可以同时跑 91/92/93 多个 VLAN,未来扩容不需要动物理布线。
Q3:bond 模式怎么选?
| 模式 | 交换机要求 | 带宽 | 备注 |
|---|---|---|---|
active-backup(1) | 无(access/trunk 都行) | 单口 | 最稳,装机阶段和 mgmt 推荐 |
balance-xor(2) | 静态聚合 | 聚合 | 需要交换机侧对应配置 |
802.3ad(4) | 必须配 LACP | 聚合 | 生产 VM 网络推荐;配错就完全不通 |
balance-tlb(5) / balance-alb(6) | 无 | 聚合(发送) | 交换机不支持聚合时的折中 |
决策:
mgmt:active-backup(装机阶段最不依赖交换机配置,先把集群拉起来)。cn-vm:802.3ad,前提是网络组已在两台接入交换机上配好 LACP 聚合组(跨交换机需 MLAG/堆叠)。若交换机侧一时无法配合,先用active-backup把业务打通,后续再改 VlanConfig 的bondOptions.mode(改的时候节点上不能有 VM 在跑该网络,见 4.8)。
⚠️ 802.3ad 配错的表现非常有迷惑性:
cn-vm-bo接口存在、bridge vlan也有 VLAN 91,但 VM 就是拿不到 IP、ping 不通网关。第一步永远先看cat /proc/net/bonding/cn-vm-bo里的MII Status和Partner Mac Address(LACP 协商成功才会有 partner MAC)。
Q4:MTU 用 1500 还是 9000?
- 默认 1500,最安全,交换机不用改。
- 9000(jumbo)能显著提升存储与大流量业务性能,但要求全路径一致:VM 网卡、bridge、bond、物理网卡、交换机端口、网关、对端服务器,任何一跳不支持就出现「小包通、大包断」的黑洞故障。
- Harvester 有个硬约束:同一个 ClusterNetwork 下所有 VlanConfig 的 MTU 必须一致,否则 webhook 直接拒绝新建/修改。
决策:一期用 1500 打通业务;如果确实需要 jumbo,按第 4.8 节的完整流程(停 VM → 改配置 → 验证 → 起 VM)在变更窗口做。
Q5:要不要单独建存储网络(storage network)?
12 节点、3 副本的 Longhorn,存储复制流量不小。单独建存储网络(cn-stor)能把复制流量从 mgmt 剥离,但代价是多占两张网卡 + 多一套 VLAN + 配置复杂度上升。
决策:一期不建,Longhorn 走 mgmt。 但把 mgmt 做成 2 口 bond(10GbE 及以上)以留余量;若后续观察到 mgmt 拥塞(存储延迟升高、etcd 抖动),再按官方存储网络文档增建。注意存储网络会保留 10.42/10.43/10.52/10.53 这些段,规划 VLAN 网段时要避开。
Q6:VM 的默认路由该走哪边?(双网卡最大的坑)
VM 有两块网卡:eth0(管理网,10.52.x.x,网关是 KubeVirt 的 NAT 网关)和 eth1(10.181.91.x,网关 10.181.91.1)。如果两块网卡都装默认路由,后生效的那条会覆盖前一条。
官方文档明确警告过这个现象:当 VM 一块网卡接 mgmt、另一块接 VLAN 网络时,如果 VLAN 网络的网关覆盖了默认路由,节点可能无法访问 VM 的管理网 IP —— 表现为 UI 里 VM 的 IP 显示不出来、qemu-guest-agent 通道异常、节点 ping 不到 VM 的 10.52.x.x。
决策(本书统一做法):
eth0(管理网):DHCP,保留默认路由(metric 100)。eth1(VLAN 91):静态或 DHCP,只加本网段路由 + 一条 metric 更大的默认路由(metric 200),或者干脆不装默认路由、只按需加明细路由。- 具体 cloud-init 写法见 5.4,验证方法见 8.3。
1.6 容量与高可用规划
1.6.1 硬件基线(官方生产要求 vs 本环境)
| 项目 | 官方生产最低 | 本书假设的单机配置 | 备注 |
|---|---|---|---|
| CPU | 16 核(x86_64/ARM64,需硬件虚拟化) | 32 核 | 打开 BIOS 里的 VT-x/AMD-V |
| 内存 | 64 GB | 256 GB | VM 内存不可超卖太多,见下 |
| 系统盘 | 500 GB(建议 1TB+) | 960 GB SSD × 1(/dev/sda) | 装 OS 与容器镜像 |
| 数据盘 | 500 GB 起,建议 1TB+ | 3.84 TB NVMe × 1(/dev/sdb) | Longhorn 磁盘,随机 IOPS ≥ 5000 |
| 网卡 | 管理网 1 张(建议 2),VM 网 1 张(建议 2),≥ 10GbE | 4 × 10GbE | 与 1.5 的 2+2 决策一致 |
| 交换机 | 支持 port trunking(VLAN) | 支持 trunk + LACP | VLAN 91 必须放行 |
| 引导模式 | UEFI(v1.8 强制) | UEFI | Legacy BIOS 装不了 |
⚠️ 不支持嵌套虚拟化(VM 里再跑 KVM)、不支持笔记本、不支持混合架构集群(x86 与 ARM 混在一个集群)。同集群内 CPU 规格尽量一致,否则实时迁移会受限(需要相同 CPU model/特性)。
1.6.2 可分配资源怎么算
Harvester 的可分配资源不等于物理资源,有三块要先扣掉:
- 系统/ kube 预留:宿主机 OS + RKE2 + KubeVirt + Longhorn 组件本身要吃 CPU/内存。
- Longhorn Instance Manager CPU:由设置项
guaranteedInstanceManagerCPU控制(默认每个 IM 预留一定百分比的 CPU)。存储流量大时不要调太低。 - VM 的 requests/limits:Harvester UI 创建 VM 时会同时生成
resources.requests(调度依据)与limits(上限)。只有 requests 参与调度,limits 大于 requests 就是超卖。
| 超卖项 | Harvester 设置 | 建议 |
|---|---|---|
| CPU/内存总超卖比 | overcommit-config(Settings 里) | 生产 ≤ 150% CPU、内存尽量不超卖(内存超卖会触发 OOM/交换,VM 体验极差) |
| 存储超卖 | Longhorn storage-over-provisioning-percentage | 结合 Thin-provision 卷的实际使用率设,建议 ≤ 200% 并配告警 |
12 节点粗算示例(单机 32C/256G,扣除预留后按 28C/220G 可用):
text
总可分配 ≈ 12 × 28 = 336 vCPU,12 × 220 ≈ 2.6 TB 内存
management 节点(3 台)建议预留 50% 给控制面与存储 → 实际给 VM 用 ≈ 3 × 28 × 50% + 9 × 28 = 42 + 252 = 294 vCPU(按 150% 超卖可到 ~440)这类估算只做容量对话用,真正上线前用
kubectl describe node | grep -A6 'Allocated resources'看实际水位。第 7 章的巡检脚本会自动输出。
1.6.3 故障域与高可用要点
| 层面 | 机制 | 你要做的 |
|---|---|---|
| 控制面 | etcd 3 副本(3 台 management) | 别只装 2 台;升级/维护时一次只动一台,等 etcd 健康再动下一台 |
| VIP | vip_mode: static,kube-vip 在 management 节点间漂移 | 确保 VIP 10.181.0.100 未被占用,且交换机允许 gratuitous ARP |
| VM 可用性 | evictionStrategy: LiveMigrate + 节点故障时 KubeVirt 重新调度 | 需要共享存储(Longhorn 多副本,默认满足);开启 VM HA 相关设置 |
| VM 磁盘 | Longhorn 3 副本跨节点 | 反亲和:同一 VM 的多个磁盘副本不落同一节点(Longhorn 默认行为) |
| 同类 VM 分散 | Pod anti-affinity / VM Scheduling 标签 | 关键业务的多个 VM 打散到不同节点,避免一台宕机全灭 |
| 自动均衡 | virtual-machine-auto-balance addon | VM 分布不均时自动迁移,建议开启并设好阈值 |
| 副本重建 | Longhorn replica-replenishment-wait-interval(默认 600s) | 节点短暂重启(<10 分钟)不会触发大规模重建,这是好事;计划内长停机可临时调小 |
1.7 本章交付物与验证清单
在进入第 2 章之前,确认下面每一项都有明确答案(建议直接写进项目文档):
- [ ] 12 台机器的主机名、管理 IP、序列号、product_uuid 已登记,且 uuid 唯一。
- [ ] 每台机器的 4 个网口名字(
eno1..eno4或实际名字)与 MAC 已登记。 - [ ] VIP
10.181.0.100已确认未被占用(arping -D -I eno1 10.181.0.100)。 - [ ] 管理网关、DNS、NTP 可用(
ping 10.181.0.1、dig @10.181.0.2 harvester.local、chronyc sources或ntpq -p)。 - [ ] 交换机侧:VLAN 91 已创建,SVI
10.181.91.1已配置,12 台机器接 VM 网的端口为 trunk 且放行 VLAN 91,LACP 聚合组已配(若用 802.3ad)。 - [ ]
10.181.91.0/24内的地址分配表已定:宿主机段、VM 静态段、LB 池、DHCP 池互不重叠。 - [ ] 已确认 Pod/Service 保持默认(
10.52.0.0/16/10.53.0.0/16/10.53.0.10),且 VLAN 网段与保留段不冲突。 - [ ] 决定 MTU(1500 / 9000)与 bond 模式(active-backup / 802.3ad),并与网络组达成一致。
- [ ] 准备一台 HTTP 服务器(如
10.181.0.5:8080)用于托管 ISO 与 12 份 config.yaml。
下一章:把这些前置条件逐一落地,包含交换机配置样例与可执行的检查脚本。