Skip to content

02 装机准备:IP 规划、基础设施服务与交换机配置

本章目标:把 12 台机器从「刚上架的裸金属」推进到「随时可以开始无人值守装机」的状态。装机失败 80% 的原因都在这一章:网口名字对不上、VLAN 没放行、UEFI 没开、ISO 下载不到、时间不同步。


2.1 装机方式选型

方式需要的东西12 台的工作量适用
A. ISO 手工安装U 盘/虚拟介质 + 逐台填表高(12 次重复劳动,易填错)单台、临时
B. ISO + 远程 config.yaml(本书主方案)HTTP 服务器托管 config + ISO;启动时加内核参数低(每台只需选一次启动项)有带外/可插介质,追求可靠
C. PXE / iPXE 全自动DHCP + TFTP/HTTP + iPXE 脚本最低(上电即装)大批量、机房有 PXE 基础设施
D. U 盘写入 config(离线)制作带 config 分区的 U 盘完全隔离网、无 HTTP 服务

方式 B 与 C 的配置文件完全相同,区别只在「怎么把 config 送到安装器手里」。本书以 B 为主线(第 3 章),并在 3.7 给出 C 的 iPXE 脚本变体,D 的做法在 3.8。

官方要求:ISO 分 Full ISO(内含全部容器镜像,离线/防火墙内必须用它)与 Net install ISO(装完再联网拉镜像)。内网环境一律用 Full ISO:harvester-v1.8.2-amd64.iso


2.2 资产与 IP 登记表(装机前必须填完)

把这张表填好,第 3 章的脚本直接读它生成 12 份 config。

#主机名管理 IP角色mgmt 网卡(MAC)VM 网卡(MAC)系统盘数据盘product_uuidVLAN91 宿主地址(可选)
01harvester-0110.181.0.11mgmt(create)eno1/eno2eno3/eno4/dev/sda/dev/sdb待填10.181.91.11
02harvester-0210.181.0.12mgmt(join)eno1/eno2eno3/eno4/dev/sda/dev/sdb待填10.181.91.12
03harvester-0310.181.0.13mgmt(join)eno1/eno2eno3/eno4/dev/sda/dev/sdb待填10.181.91.13
04harvester-0410.181.0.14worker/dev/sda/dev/sdb待填10.181.91.14
05harvester-0510.181.0.15worker/dev/sda/dev/sdb待填10.181.91.15
06harvester-0610.181.0.16worker/dev/sda/dev/sdb待填10.181.91.16
07harvester-0710.181.0.17worker/dev/sda/dev/sdb待填10.181.91.17
08harvester-0810.181.0.18worker/dev/sda/dev/sdb待填10.181.91.18
09harvester-0910.181.0.19worker/dev/sda/dev/sdb待填10.181.91.19
10harvester-1010.181.0.20worker/dev/sda/dev/sdb待填10.181.91.20
11harvester-1110.181.0.21worker/dev/sda/dev/sdb待填10.181.91.21
12harvester-1210.181.0.22worker/dev/sda/dev/sdb待填10.181.91.22

10.181.91.0/24 地址分配(与 1.5 决策一致):

区间用途谁在用
10.181.91.1网关(核心交换机 SVI)网络设备
10.181.91.2.10预留:网络设备 / DHCP 服务器 / Managed DHCP serverIP基础设施
10.181.91.11.22Harvester 宿主机(可选,HostNetworkConfig)12 台节点
10.181.91.50.99Harvester LoadBalancer IP 池LB VIP
10.181.91.101.200业务 VM 静态 IPVM
10.181.91.201.250DHCP 动态池(外部 DHCP 或 Managed DHCP)VM
10.181.91.251.254预留

⚠️ 三个池子(LB、静态 VM、DHCP)绝对不能重叠。重叠的症状是「偶发性 IP 冲突、VM 网络时通时断」,极难排查。定好之后写进 CMDB,并让 DHCP 服务器把 LB 段与静态段做成 exclusion。


2.3 基础设施服务准备

2.3.1 HTTP 服务器(托管 ISO 与 config)

在一台能被 12 台机器访问的服务器上(本例 10.181.0.5):

bash
mkdir -p /srv/harvester/{iso,configs}
cd /srv/harvester/iso
# 下载 Full ISO(有外网时);离线环境从有网机器拷贝过来
# https://github.com/harvester/harvester/releases/tag/v1.8.2
sha512sum -c harvester-v1.8.2-amd64.iso.sha512sum   # 校验,别跳过

# 起一个最简 HTTP 服务(生产建议用 nginx,可控制访问与日志)
cd /srv/harvester && python3 -m http.server 8080

nginx 版本(推荐,12 台并发拉 ISO 更稳):

nginx
server {
    listen 8080;
    server_name _;
    root /srv/harvester;
    autoindex on;
    # ISO 有 5GB+,务必放开这些限制
    client_max_body_size 0;
    sendfile on;
    tcp_nopush on;
    location ~* \.iso$ { limit_rate 0; }
}

✅ 验证(从任意一台待装机器的带外/临时系统,或从同网段机器):

bash
curl -sI http://10.181.0.5:8080/iso/harvester-v1.8.2-amd64.iso | head -3   # 期望 200 OK
curl -s  http://10.181.0.5:8080/configs/config-node01.yaml | head -5      # 期望看到 scheme_version: 1

⚠️ config.yaml 里含 token 与密码,不要放在公网可访问的路径。至少做到:内网隔离 + 装机完成后删除或加访问控制 + 不要把仓库里的 config 提交到公共 Git。

2.3.2 DNS(强烈建议配正反向记录)

dns
; 正向
harvester-01.example.local.   IN A 10.181.0.11
...
harvester-12.example.local.   IN A 10.181.0.22
harvester.example.local.      IN A 10.181.0.100     ; VIP,UI 访问名
; 反向
11.0.181.10.in-addr.arpa.     IN PTR harvester-01.example.local.
  • Harvester 不强制要求 DNS,但没有 DNS 时,UI 上的证书告警、Support Bundle、节点名解析都会更难用;接入 Rancher 时更需要一个稳定域名。
  • 若要用域名访问 UI,把域名写进装机配置的 sans(Subject Alternative Names),否则证书不含该域名,浏览器会报错。见 3.4。

2.3.3 NTP(不是可选项)

etcd 对时间偏差极其敏感:节点间时间漂移会导致 leader 选举异常、日志复制失败、证书校验失败。

bash
# 装机 config 里写死 NTP 服务器
os:
  ntp_servers:
    - ntp.aliyun.com
    - 0.suse.pool.ntp.org
    - 1.suse.pool.ntp.org

内网无外网时,必须自建 NTP(chrony)并让 12 台都指向它。装机后验证:

bash
chronyc sources -v      # 或 ntpq -p
timedatectl             # System clock synchronized: yes

2.3.4 可选:PXE 三件套(仅方式 C 需要)

  • DHCP:给待装机分配临时 IP,并下发 next-server / filename(iPXE 场景常用 DHCP option 66/67 或 vendor-class 判断)。
  • HTTP:托管 vmlinuzinitrdrootfs.squashfs(从 ISO 里解出)与 iPXE 脚本。
  • 注意:装机用的 DHCP 与 VM 网络的 DHCP 必须分开,别把 PXE 的 DHCP 服务接到 VLAN 91 上,否则 VM 会拿到 PXE 的地址。

2.4 宿主机侧准备(BIOS / 磁盘 / 网卡)

2.4.1 BIOS / UEFI 设置

项目要求说明
启动模式UEFI(关闭 CSM/Legacy)v1.8 起新装机只支持 UEFI;装机 config 里也会写 force_efi: true
虚拟化Intel VT-x / AMD-V = Enabled,VT-d/IOMMU 建议开启没开虚拟化,KubeVirt 起不来 VM
启动顺序一次性从 ISO/虚拟介质启动装完自动重启进硬盘
电源策略AC Power Loss → Power On(建议)断电恢复后自动开机
时间BIOS 时钟正确,时区统一(建议 UTC)与 NTP 一致

2.4.2 磁盘

  • Harvester 只支持本地磁盘与硬件 RAID。不要在宿主机上做 LVM/软 RAID 后指望 Harvester 认。
  • install.device(系统盘)会被格式化install.data_disk(数据盘)给 Longhorn 用。两者必须是不同物理盘。
  • 硬件 RAID:把系统盘做成 RAID1(两块小盘)是可以的,此时 /dev/sda 就是 RAID 卷;数据盘建议直通(JBOD/HBA 模式)给 NVMe,性能最好。
  • ⚠️ 盘符会漂移/dev/sda//dev/sdb 在不同批次机器上可能对应不同物理盘。装机前一定用 lsblk -o NAME,SIZE,MODEL,SERIAL,TRAN 逐台确认,必要时用 /dev/disk/by-path/... 或按 serial 确认。
  • 磁盘性能要求:每盘 5000+ 随机 IOPS(SSD/NVMe)。management 节点的存储还要满足 etcd 的速度要求(etcd 慢 = 整个集群卡)。

2.4.3 网卡命名与确认

Harvester 使用 systemd 的网卡命名(eno1enp3s0f0ens5…),config 里写的名字必须在目标机器上真实存在

从任意 LiveCD/临时系统(或用带外 KVM 挂载 ISO 启动到安装器界面但不安装)执行:

bash
ip -br link                                   # 列出所有网卡与状态
for i in $(ls /sys/class/net | grep -v lo); do
  echo "$i $(cat /sys/class/net/$i/address) $(ethtool $i 2>/dev/null | grep -i 'speed\|link detected' | tr '\n' ' ')"
done
lshw -class network -businfo 2>/dev/null | head -20   # 看 PCI 位置,确认哪个口接了哪根线

判断哪个口接管理网、哪个口接 VM 网的实操技巧:拔掉一根线看哪个口变 DOWN;或者只在管理交换机上接线,看哪个口能拿到链路。把结论写进 2.2 的登记表。

⚠️ 本书所有 config 同时写 namehwAddr(MAC)。安装器以 MAC 优先匹配,这样即使不同批次机器网口命名不同(eno1 vs enp1s0f0),配置仍然有效。这是批量装机最重要的一个习惯。

2.4.4 product_uuid 唯一性检查

bash
cat /sys/class/dmi/id/product_uuid       # 每台机器执行,登记到表里,确保 12 个值互不相同

重复的后果:VM 实时迁移等操作报错(官方 issue #4025)。同批次克隆的虚拟机模板装机、或某些 OEM 批次会踩到。


2.5 交换机配置

目标拓扑:每台 Harvester 有 4 个 10GbE 口,eno1/eno2 接管理交换机(或同一台交换机的管理 VLAN),eno3/eno4 接业务交换机做聚合,trunk 放行 VLAN 91。

text
             ┌────────────────────────┐        ┌────────────────────────┐
             │  管理交换机 (SW-MGMT)   │        │ 业务交换机对 (SW-A/B)   │
             │  VLAN 10 (mgmt)        │        │  VLAN 91 (VM 直通)      │
             │  SVI 10.181.0.1        │        │  SVI 10.181.91.1        │
             └───────▲────────▲───────┘        └───▲──────────────▲─────┘
                     │        │  trunk/LACP         │   port-channel
              eno1 ──┘        └── eno2         eno3 ┘              └── eno4
                     └────── Harvester 节点 ×12 ──────┘
                bond mgmt-bo (active-backup)   bond cn-vm-bo (802.3ad)

2.5.0 交换机概念与 Harvester 对象的对应关系(先对齐词汇)

和网络组沟通时最容易卡住的是「各说各话」。先把两边词汇对齐(概念详解见 1.3.0):

交换机侧的说法本书/Harvester 侧的对象配置在哪
access 口不接任何 Harvester VM 网络
trunk 口 + allowed vlan 91NetworkAttachmentDefinition net-91vlan: 912.5.2 / 4.6
native VLAN管理网 untagged 时 management_interface.vlan_id: 03.3 config.yaml
port-channel / Eth-Trunk(LACP)VlanConfig.spec.uplink.bondOptions.mode: 802.3ad2.5.2 / 4.4
SVI / Vlanif 接口VM 的默认网关(cloud-init 里 via 10.181.91.15.3
端口 MTU / jumbo frameVlanConfig.spec.uplink.linkAttributes.mtu + NAD 的 mtu4.9.2

把这张表发给网络组,配错率会显著下降。

2.5.1 必须落实的 5 件事

  1. 创建 VLAN 91,并配置三层网关(SVI/路由口)10.181.91.1/24
  2. eno3/eno4 的端口配置为 trunk,且放行 VLAN 91(tagged)
    • ⚠️ 官方明确要求:与 bond 网卡相连的物理交换机端口必须严格配置为 trunk,要接受 tagged 流量并按 VM 网络使用的 VLAN ID 打标发送。配成 access 口 = VM 收不到带标签的包 = 完全不通。
  3. eno1/eno2 的端口:若管理网是 untagged(native VLAN),access 口即可;若管理网也带 VLAN(config 里写 management_interface.vlan_id),则同样要 trunk 放行该 VLAN。
  4. LACP 聚合组(仅当 bond 用 802.3ad):跨两台交换机时需要 MLAG / vPC / 堆叠;否则改用 active-backup
  5. MTU:全路径一致。默认 1500 不用改;要上 jumbo,则交换机端口、SVI、上联、网关全部改成 9000(或 9216),并逐跳验证。

2.5.2 配置样例(Cisco IOS 风格,仅作语法参考,请按你的设备型号核对)

text
! ---- VLAN 与网关 ----
vlan 91
 name harvester-vm
!
interface Vlan91
 description Harvester VM direct network
 ip address 10.181.91.1 255.255.255.0
 no shutdown
!
! ---- 接 eno3/eno4 的端口(LACP 聚合,放行 VLAN 91)----
interface range TenGigabitEthernet1/0/1 - 2
 description harvester-01 vm bond (eno3/eno4)
 switchport mode trunk
 switchport trunk allowed vlan 91
 channel-group 11 mode active
 no shutdown
!
interface Port-channel11
 description harvester-01 cn-vm bond
 switchport mode trunk
 switchport trunk allowed vlan 91
!
! ---- 接 eno1/eno2 的管理端口(native VLAN 10 示例)----
interface range TenGigabitEthernet1/0/3 - 4
 description harvester-01 mgmt bond
 switchport mode trunk
 switchport trunk native vlan 10
 switchport trunk allowed vlan 10
 spanning-tree portfast trunk

华为 / H3C 等价要点(命令名不同,概念一一对应):

text
vlan batch 91
interface Vlanif91
 ip address 10.181.91.1 24
interface Eth-Trunk 11
 mode lacp-static
 port link-type trunk
 port trunk allow-pass vlan 91
interface 10GE1/0/1
 eth-trunk 11

2.5.3 交换机侧验证

text
show vlan id 91                      # VLAN 存在且端口在位
show interfaces trunk                # 91 在 allowed & active 列表
show etherchannel 11 summary         # LACP 状态为 SU(bundled)
show interfaces port-channel11       # 成员口 up
ping 10.181.91.1                     # 从同 VLAN 的其他机器能通网关

⚠️ STP 与 PortFast:VM 的 MAC 会在宿主机 bridge 上频繁变化,接入端口如未开 portfast/edge,可能出现几十秒的 STP 学习期导致「刚开机 ping 不通」。同时确认交换机没有开端口安全限制 MAC 数量——一台宿主机上会有大量 VM MAC(bridge 模式下 VM MAC 会出现在物理端口上),限制过小会把端口 err-disable。

2.5.4 交换机侧 5 个最高频错误(按踩坑频率排序)

#错误配置症状对照检查
1trunk 的 allowed vlan漏了 91(最常见,尤其默认只允许 1 的设备)宿主机一切正常,VM 完全收不到包show interfaces trunk 里 91 必须在 allowed active 两列
2LACP 两端模式不一致(一端 802.3ad、一端静态聚合或没配)时通时不通,随 hash 浮动宿主机 Partner Mac Address 全 0(见 8.4 案例 1)
3把 VM 网口配成 access,或 native VLAN 配错VLAN 91 完全不通端口模式必须是 trunk;native VLAN 只给 mgmt 用
4未开 portfast/edgeVM 开机后 30 秒左右才通,被误判为 cloud-init 慢端口加 spanning-tree portfast trunk 类配置
5端口安全(port-security)限制 MAC 数量该节点上第 N 台之后的 VM 全部断网,端口 err-disable关掉或调大上限;一台宿主机会暴露所有 VM 的 MAC

这 5 项全部能在 2.5.3 的命令输出里验证,装机前让网络组逐项签字确认,可以省掉 80% 的「为什么不通」。


2.6 凭据、密钥与版本准备

项目本环境取值说明
ISO 版本harvester-v1.8.2-amd64.iso与 config 的 scheme_version: 1 对应
config schemescheme_version: 1升级 ISO 版本时此值一般不变,只有配置格式升级才变
install.token32 位随机串第一台 create 时生成,11 台 join 必须完全一致
os.password(rancher 用户)强密码默认用户是 rancher;密码需满足:长度 > 8、含大小写、数字、特殊字符;不能以 ! 开头;含 - 时必须加引号
os.ssh_authorized_keys运维公钥强烈建议:装机时就把公钥塞进去(注意字段名是下划线,不是 os.ssh.authorized_keys
os.sshd.disable_password_authtrue配合上面的公钥,装完即禁止 SSH 密码登录(详见 3.5)
os.modules[kvm, vhost_net]官方要求的内核模块
备份目标S3 兼容 / NFS第 7 章要用,装机阶段先决定位置并确认可访问

生成 token 与密码:

bash
openssl rand -hex 16                                   # token(32 字符)
openssl rand -base64 24 | tr -d '/+=' | cut -c1-20     # 密码候选(再手工加特殊字符)

⚠️ 密码策略的坑(来自官方文档与实测):

  • 密码必须以字母或数字开头;! 开头会被解析出问题。
  • - 的密码在 YAML 里必须用引号包起来,否则被解析成列表。
  • 长度不足 8 位或缺少字符类别时,装机后 UI 会强制改密码(设置 xxx 相关流程)。
  • 12 台的 os.password 建议一致(便于自动化),但要纳入密钥管理系统;装机完成后应按第 7 章流程轮换。

2.7 装机前预检脚本

把下面脚本保存为 appendix/ops/preflight.sh,在每台待装机器的临时系统(LiveCD/带外 ISO 启动的 shell)里跑一遍;装机后再跑一次做基线留存。

bash
#!/usr/bin/env bash
# appendix/ops/preflight.sh
# Harvester 装机前预检 - 每台机器执行
# 用法: sudo bash preflight.sh <HTTP_SERVER>  例: sudo bash preflight.sh http://10.181.0.5:8080
set -uo pipefail
HTTP="${1:-http://10.181.0.5:8080}"
fail=0
ok(){ echo "  [OK]   $*"; }
bad(){ echo "  [FAIL] $*"; fail=$((fail+1)); }
warn(){ echo "  [WARN] $*"; }

echo "== 1. 引导模式 =="
[ -d /sys/firmware/efi ] && ok "UEFI 引导" || bad "不是 UEFI 引导(v1.8 新装必须 UEFI)"

echo "== 2. CPU 虚拟化 =="
grep -qE 'vmx|svm' /proc/cpuinfo && ok "硬件虚拟化已开启" || bad "未检测到 vmx/svm,请在 BIOS 打开 VT-x/AMD-V"
echo "     核心数: $(nproc)"

echo "== 3. 内存 =="
mem_gb=$(awk '/MemTotal/{printf "%d", $2/1024/1024}' /proc/meminfo)
[ "$mem_gb" -ge 64 ] && ok "内存 ${mem_gb}GB" || warn "内存 ${mem_gb}GB,低于生产建议 64GB"

echo "== 4. product_uuid =="
uuid=$(cat /sys/class/dmi/id/product_uuid 2>/dev/null || echo UNKNOWN)
echo "     product_uuid = $uuid  (请登记并核对 12 台互不相同)"

echo "== 5. 磁盘 =="
lsblk -d -o NAME,SIZE,MODEL,ROTA,TRAN | sed 's/^/     /'
for d in sda sdb; do
  [ -b /dev/$d ] && ok "/dev/$d 存在 ($(lsblk -dn -o SIZE /dev/$d))" || warn "/dev/$d 不存在,请核对 install.device / data_disk"
done
[ "$(lsblk -dn -o ROTA /dev/sdb 2>/dev/null)" = "0" ] && ok "/dev/sdb 是 SSD/NVMe" || warn "/dev/sdb 可能是机械盘,Longhorn 性能会不达标"

echo "== 6. 网卡 =="
for n in eno1 eno2 eno3 eno4; do
  if [ -e /sys/class/net/$n ]; then
    mac=$(cat /sys/class/net/$n/address)
    st=$(cat /sys/class/net/$n/operstate)
    ok "$n  mac=$mac  state=$st"
  else
    bad "$n 不存在(config 里写了它就会匹配失败;请核对实际网口名或依赖 hwAddr)"
  fi
done

echo "== 7. 网络连通性 =="
ping -c1 -W2 10.181.0.1 >/dev/null 2>&1 && ok "管理网关 10.181.0.1 可达" || bad "管理网关不可达"
for ip in 10.181.0.100 10.181.0.11 10.181.0.12; do
  ping -c1 -W2 $ip >/dev/null 2>&1 && warn "$ip 已有响应(确认是否冲突)" || ok "$ip 未被占用"
done
curl -sI "$HTTP/iso/harvester-v1.8.2-amd64.iso" | head -1 | grep -q 200 \
  && ok "ISO 可下载: $HTTP/iso/..." || bad "ISO 下载失败: $HTTP/iso/..."

echo "== 8. 时间同步 =="
timedatectl 2>/dev/null | grep -i synchronized | sed 's/^/     /'
date -u '+     当前 UTC:xxx'

echo
[ $fail -eq 0 ] && echo "预检通过,可以开始装机。" || echo "预检有 $fail 项 FAIL,请先处理。"
exit $fail

装机后(集群已 Ready)在节点上执行的基线留存:

bash
kubectl get nodes -o wide | tee /root/baseline-nodes.txt
kubectl get clusternetwork,vlanconfig,nad -A -o wide | tee /root/baseline-network.txt
ip -br addr | tee /root/baseline-ip.txt

2.8 装机顺序与时间预算

12 台不要一起装。顺序与并发度建议如下:

阶段机器动作预计耗时
0HTTP 服务器上传 ISO、生成 12 份 config、验证可下载30 min
1harvester-01create 装机,验证 VIP/UI/单节点健康20–40 min
2harvester-02、03join,验证 etcd 3 副本、management 角色40 min(可并发)
3harvester-04 … 07join,4 台并发40 min
4harvester-08 … 12join,5 台并发40 min
5全集群加固:关密码登录、开监控/日志 addon、配置备份、建 ClusterNetwork2 h

要点:

  • 先装 01,确认它自己健康再装 02/03。第一台是 token 与 VIP 的定义者,它有问题后面全废。
  • join 的并发不要超过 5 台:新节点加入会触发控制面证书分发、Longhorn 初始化、镜像拉取,并发太高会让 etcd 与 API 压力陡增,出现 join 超时。
  • 每台装机耗时主要由磁盘速度决定(分区 + 写 squashfs + 首次启动拉镜像)。NVMe 系统盘约 20 分钟,SATA SSD 可能 40 分钟以上。
  • 中途失败:直接重装机(ISO 覆盖安装)比排障更快。装机是幂等的破坏性操作。

2.9 本章验证清单

  • [ ] 12 台机器的登记表填写完整(含 MAC、盘符、product_uuid)。
  • [ ] preflight.sh 在 12 台上全部 0 FAIL。
  • [ ] HTTP 服务器上 ISO 校验和正确,curl -I 返回 200。
  • [ ] DNS 正反向记录已配(或明确决定不配并记录原因)。
  • [ ] NTP 服务可达,或已准备内网 NTP。
  • [ ] 交换机:VLAN 91 + SVI 10.181.91.1 + trunk 放行 + LACP(如用 802.3ad)已配置并验证。
  • [ ] 从一台同 VLAN 的测试机可以 ping 10.181.91.1,并能在 VLAN 91 上抓到自己的 DHCP/ARP 流量(可选:tcpdump -i <if> -e vlan 91)。
  • [ ] token / 密码 / SSH 公钥已生成并妥善保存。
  • [ ] 备份目标(S3/NFS)已准备并可从集群访问。

下一章:写 config.yaml,把 12 台机器真正装起来。