跳到正文
cyxc.club

把跑在 PVE 里的 Kubernetes 换成三台物理机

/ 约 20 分钟

起因是朋友送给我一台 R730xd 和 6 块 960G SATA SSD,一直想做的裸机 K8s + Ceph 就有了盘。另外两台不是新买的,本来就是这套环境里的 pve1 / pve210.1.16.21 / 10.1.16.22),K8s 虚机一直跑在它们上面。16.23 不是这两台的同伴节点,而是另一套 PVE 里已经裁撤下来的机器,8 月 30 日之前就已经装好 Ubuntu,地址配成 10.1.16.23。三台对齐成双路 E5-2690 v4Mellanox ConnectX-4 Lx 25G(R887V)、后置盘位背板;内存从原来的两台各拆 8 条,每台 16G × 16。存储控制器 PERC H730P 当 HBA(有一个是 H730 没有 P)。业务口上 N9K C92160YC-X192.168.5.2),Eth1/1–1/6 对三台 25G SR,LACP 802.3adxmit_hash_policy=layer3+4lacp rate fast。有了这台现成裸机,再把 pve2、pve1 腾空后同样改成 Ubuntu 24.04.4。

2026-08-30 到 2026-09-03。集群 cyxck8s-01,kubeasz 3.6.7,Kubernetes v1.33.1,containerd 2.1.1,Calico v3.28.4(IPIP Always,etcd datastore),Rook v1.17.9,Ceph Squid 19.2.3。三台主机:k8s-10-1-16-2110.1.16.21)、k8s-10-1-16-22k8s-10-1-16-23。Po1/Po2/Po3 对这三台,access VLAN 40,mtu 9000。控制端在 16.23:docker exec kubeasz ezctl …,kubectl 打 https://10.1.16.23:6443(没有 apiserver VIP)。节点私仓当时是 10.1.16.23:5000 / easzlab.io.local:5000

升级和换底座是两件事。1.33.1 已经在 2026-08-23 七台虚机上升完,见 七台虚机上把 Kubernetes 升到 1.33.1(当时还是 1.32.3 → 1.33.1,Rook 1.16.6 → 1.17.9,Calico 3.28.3 → 3.28.4,etcd 3.5.20 → 3.5.21,containerd 2.0.4 → 2.1.1,kubeasz 3.6.6 → 3.6.7;Ceph 数据面刻意没动)。这篇写怎么把 K8s 节点从 PVE 虚机换成三台裸机(etcd 和 Ceph 全程活着搬),以及原来跑在 PVE 上的 业务客机怎么迁到 KubeVirt:开虚机的能力换底座,客机跟着走,IP 不换。

目录


要解决什么

换底座以前,K8s 跑在 7 台 QEMU 虚机 上:

角色 地址 宿主机
master / etcd 10.1.4.100 k8s-10-1-4-100 pve1 = 10.1.16.21,VMID 4100
master / etcd 10.1.4.101 k8s-10-1-4-101 pve1,VMID 4101
master / etcd 10.1.5.100 k8s-10-1-5-100 曾在 pve2 = 10.1.16.22
worker 10.1.4.102 / 10.1.4.103 pve1,VMID 4102 / 4103
worker 10.1.5.101 / 10.1.5.102 pve2

Pod CIDR 172.20.0.0/16,Service 10.68.0.0/16,kube-proxy IPVS。etcd 当时 leader 在 10.1.4.100。5.x 上的 OSD 是 osd.2 / osd.4 / osd.8,08-30 凌晨 16.23 进集群时还在;踢 5.x 时才 purge。

PVE 上还有另一类虚机:业务客机,不跑 K8s。它们在 VLAN 2010.1.4.0/24(PVE vmbr1 tag=20),一部分在 10.1.5.0/24。pve4 10.1.16.31 仍是 Proxmox,接 N9K Po4,这次不进 K8s(未来再改造)。

换底座要同时做完两件事:7 个 K8s 节点下 PVE,改成三台裸机;业务客机不能跟着宿主机一起没掉,开虚机的能力改由 KubeVirt 接,客机迁到物理机 /dev/kvm 上。嵌套 virt(nested=Y)只够试验,生产客机必须等节点变成裸机。

更硬的约束是:4.100 占着 16.21。pve1 上 4100–4103 还在跑,宿主机腾不空,不能像踢 5.x 那样直接把最后一台吹掉。所以不能整集群重装。etcd 一个成员一个成员换,OSD out → PG clean → safe-to-destroy → purge,N9K 口跟着装机改。业务客机先冷迁到已经裸机化的节点上的 KubeVirt,10.1.4.0/24 再跟着最后一批客机切 VLAN。

960G 上控制器时常见 Foreign RAID5。做成 OSD 前:

Terminal window
storcli /c0 /fall delete

清完再当 JBOD。values 里只写 /dev/disk/by-id/wwn-0x…,不写 /dev/sdX

目标只有三台 master,kubeasz [kube_node] 空。每台后舱 2 块 Intel S4510 960Gssd OSD。KubeVirt 跑在这三台裸机上,系统盘用 ceph-block

16.23 怎么进集群

16.23 Ubuntu 24.04 是 8 月 30 日之前装好的,地址就是 10.1.16.23。接 N9K Po3(Eth1/5+1/6),access VLAN 40、mtu 9000。Po3 装好后不再改。

08-30 凌晨开工时,控制端还在 4.100。OSD 报告写在 k8s-10-1-4-100 上。etcd 仍是 4.100 / 4.101 / 5.100,leader 在 4.100。pve1 / pve2 都还在跑虚机。策略已经定了:16.23 先接走 16.22 上那一组(5.x),再腾空 pve2 重装 16.22。本阶段只做 worker + 2×960G OSD,不做 add-etcd / add-master,不踢 5.100。

在 4.100 上:

Terminal window
docker exec kubeasz ezctl add-node cyxck8s-01 10.1.16.23

add-node 在 04:40 排查开始时已经成功。16.23 出不了 docker.io,rook/ceph:v1.17.9 从 4.100 导入;Ceph 走内网仓库。

Rook 的 placement.all 和各组件 affinity 求交集、不是覆盖。Helm rev 10–13 试过两种错法:只把 16.23 加进 all → mon/mgr 被往 16.23 滚,mgr 起不来,挡住 OSD;只加 osd / prepareosdall 不含 16.23 → prepare 的 nodeSelector 和 affinity 矛盾,Pending。正确写法:all 含将要跑 OSD 的节点,mon / mgr 单独锁还活着的那几台。当时 all / osd / prepareosd 含 16.23,mon / mgr 仍锁 4.100 / 4.101 / 5.100。

节点进了,盘也对上 WWN,prepare 还是起不来。根因是物理机 + bond + Calico IPIP 的 TCP 校验和,下一节。

ICMP 通,OSD 起不来

排查集中在 2026-08-30 04:40–05:22。Helm 当时 rev 13,两块 960G:

当时设备 WWN 序列号 后来
sdb wwn-0x55cd2e414f78e403 BTYS824003US960CGN osd.9(槽 13)
sdc wwn-0x55cd2e414fc5c28f BTYS828403EZ960CGN osd.10(槽 12)

rook-ceph-osd-prepare-k8s-10-1-16-23-gfnrq 能扫到盘、对上 WWN,卡在向 mon 要 bootstrap 密钥:

ceph auth get-or-create-key client.bootstrap-osd ... --connect-timeout=15
failed to get or create auth key for client.bootstrap-osd: exit status 1

旧三台(4.100 / 4.101 / 5.100)prepare 都是 Completed。故障期间 9 个旧 OSD 一直 up+in,mon quorum a,c,e 没破(ClusterIP 10.68.205.222 / 10.68.165.197 / 10.68.255.73),业务 IO 没停。placement 当时 mon/mgr 仍锁旧三台,没有往 16.23 滚。

对照:

测试 虚机节点上的 Pod 16.23 上的 Pod
mon ClusterIP :6789 / :3300 不通
到对端 Pod 的 ICMP
CoreDNS UDP :53
CoreDNS TCP :53、mgr/osd TCP 不通

overlay 路由在。4.100 上有 172.20.19.64/26 via 10.1.16.23 tunl0从 16.23 出去的 TCP 到其他节点 workload 被丢掉。 ping 通不能证明 mon 通。

在 4.101(mon-a,172.20.99.243)的 tunl0 上抓到测试 Pod 172.20.19.108

172.20.19.108 > 172.20.99.243.6789: Flags [S],
cksum 0xcfb6 (incorrect -> 0x6098)

SYN 已经到达对端 tunl0,没有再转到 mon 的 cali*,也没有 SYN-ACK。同接口上来自 4.102 / 4.103 的 TCP 正常。4.101 上 cali-tw-*ctstate INVALID 丢包。

16.23 是 物理机 + 802.3ad bond + 真实网卡 offload。Pod TCP 经 tunl0 做 IPIP 后,内层 checksum 没重算。对端 conntrack 标 INVALID,Calico 丢掉。虚机节点走 virtio,历史加节点没踩中,tx-checksum-ip-generic: on 在它们上面无事。

立刻恢复:

Terminal window
ethtool -K tunl0 tx off

之后 16.23 Pod → mon ClusterIP / Pod IP、DNS TCP、mgr :9283 全部恢复。持久化两件事。本节点 Felix(对象 FelixConfiguration/node.k8s-10-1-16-23)补:

spec:
featureDetectOverride: ChecksumOffloadBroken=true

systemd tunl0-disable-tx-csum.serviceAfter=network-online.targetExecStart=/sbin/ethtool -K tunl0 tx offRemainAfterExit=yes,enable。开机和 calico-node 重建 tunl0 之后再关一次。当时没改集群 FelixConfiguration/default,避免扩大变更。

还有次因。kubeasz roles/kube-node 先落 /etc/cni/net.d/10-default.conf(bridge mynet0,subnet 就是 172.20.0.0/16),Calico role 再 state=absent。空窗期内 DaemonSet 会走旧 CNI。16.23 上 mynet0 因挂了 virt-handler 的 veth 而是 UPvirt-handler 的 IP 曾是 172.20.0.2。4.103 上也有这座桥,但是 DOWN / NO-CARRIER,不抢流量。处理:

Terminal window
kubectl -n kubevirt delete pod -l kubevirt.io=virt-handler --field-selector spec.nodeName=k8s-10-1-16-23
ip addr del 172.20.0.1/16 dev mynet0 # 桥 down
rm -rf /var/lib/cni/networks/mynet
ls /etc/cni/net.d/ # 只留 10-calico.conflist

virt-handler 重建后地址变成 172.20.19.109。checksum 是主因,mynet0 是加料。两件事都要做。

然后删 Failed Job rook-ceph-osd-prepare-k8s-10-1-16-23 和对应 status ConfigMap,重启 rook-ceph-operator。16.23 prepare 29 秒 Completeceph-volume raw 做出 osd.9 / osd.10(class ssd,weight 各 0.87329,host CRUSH 1.74658)。集群当时 11 OSD,容量从约 1.8 TiB 到约 3.5 TiB,回填大约 111 MiB/s。旧三台 prepare 被顺带重跑,都是 Completed,旧 OSD 没中断。

下一台物理机还会中。 16.22、16.21 add-node 之后、动 Rook 之前,同一套:tunl0 tx off + 本节点 Felix + 清 mynet0。等这一波 PG active+cleanadd-etcd / add-master

进 etcd,踢 5.x,控制端切过来

OSD 报告写完时(05:22)明确还没做 add-etcd / add-master,也没踢 5.100。同一天白天做完。精确钟点没有留下;18:24 对照现网时已经结束。

在 4.100 上:

Terminal window
docker exec kubeasz ezctl add-etcd cyxck8s-01 10.1.16.23
docker exec kubeasz ezctl add-master cyxck8s-01 10.1.16.23

etcd 从 4.100 / 4.101 / 5.100 变成 16.23 + 4.100 + 4.101。然后把 kubeasz 容器、ezctl、私仓 :5000 迁到 16.23,kubectl 改打 https://10.1.16.23:6443。4.100 上的 kubeasz 和 :5000 按计划先留着。Calico etcd_endpoints / can-reach 改过。/etc/hostscalicoctl.cfg 里后来还带着已删除的 5.x,数据面已经对。

踢 5.x 的顺序和后来踢 4.101 一样,不能先 del-node:osd.2 / osd.4 / osd.8 out → PG clean → safe-to-destroy → purge;del-etcd / del-master 10.1.5.100del-node 10.1.5.10110.1.5.102。5.x IP ping 不通。节点剩 5 台 Ready(16.23 + 4.100 / 4.101 / 4.102 / 4.103)。mon 变成 a,c,f。8 个 OSD、393 PG active+clean

到 08-30 18:24,16.23 已经是控制端,5.x 已踢完。pve1 / pve2 还在跑剩下的虚机。后面才是腾空 pve2、重装 16.22。

PVE 客机改由 KubeVirt 接

PVE 拆掉之后不再用它开虚机。替代方案是集群里的 KubeVirt + CDI:hypervisor 就是这三台的 /dev/kvm,不再套一层 QEMU 嵌套。

迁法是冷迁。客机在 PVE 上关机,把 qcow2 拷到还活着的节点(常见是先落到 16.23 /var/tmp),再灌进 PVC:

Terminal window
/root/kubevirt/bin/virtctl image-upload pvc <pvc> \
--namespace=kubevirt \
--size=<Gi> \
--storage-class=ceph-block \
--access-mode=ReadWriteOnce \
--image-path=<local.qcow2> \
--uploadproxy-url=https://10.68.21.39 \
--insecure \
--force-bind \
--wait-secs=600

CDI uploadproxy 是 ClusterIP https://10.68.21.39,必须带 --insecureceph-block 现网默认 Filesystem;不写 volumeMode 变成 Block 时,上传会报 available storage -1。一例是 60Gi 的系统盘,客机规格大约 4C/4G。

能改成容器的那部分不进 KubeVirt,直接变成 k8s 工作负载(其中一套 LB 是 10.1.10.4)。其余上 KubeVirt,nodeSelector 钉在已经裸机的节点上。

二层有一次硬切。PVE 客机原来在 VLAN 20;KubeVirt 的二层口在 VLAN 40。盘可以先迁、虚机可以先在 40 上起来,但 10.1.4.0/24 还挂在 VLAN 20 时,这些 IP 在 40 上没有 ARP。交换机上的网段必须等客机都迁完,再一次性挂到 VLAN 40。迁完未切网前 ping 不通,是预期。

09-03 时已经在 KubeVirt 上、地址没变的客机:

节点 客机地址
16.22 10.1.4.2910.1.4.5410.1.4.5310.1.5.10
16.23 10.1.5.210.1.5.310.1.5.7

网卡从 macvlan 换成 linux-bridge

Multus 没换,换的是它调的那张二层网。默认 Pod 网一直是 Calico。Multus 只给 KubeVirt 再挂一张物理口,客机自己配 10.1.4.x / 10.1.5.xIP 不换

迁客机时走的是 macvlan。NAD kubevirt/bond0

{ "type": "macvlan", "master": "bond0", "mode": "bridge", "ipam": {} }

当时故意不把 bond0 奴进 linux bridge,宿主机 10.1.16.x 留在 bond0 上。虚机 YAML 是 bridge: {}。KubeVirt 这条 binding 会把客机 MAC 挪到 dummy,macvlan 自己换成随机地址。交换机按客机 MAC 回包,宿主机网卡对不上,二层就断。KubeVirt 官方不支持 macvlan(issue 5483)。当时每台跑 virt-launcher 的节点开 kv-macvlan-macfix.service,把 NIC MAC 改回客机地址。这是治标,少一台没装这个服务的节点就会没网。

09-03 改成 linux-bridge,和 PVE 的 vmbr 同一类模型:

bond0(不再配地址,只做 LACP)
└── br0(宿主机 10.1.16.x / 默认路由挪到这里)
└── Multus NAD kubevirt/br0(type: bridge)
└── virt-launcher tap → 客机

linux bridge 靠 FDB 学客机 MAC,不再要求 veth 和客机 MAC 一致。三台的 kv-macvlan-macfix.service 已经 stop + disable,没有在跑。unit(/etc/systemd/system/kv-macvlan-macfix.service)和脚本(/root/kubevirt/scripts/fix-macvlan-guestmac.sh)还在,没有删。NAD 是新建一份,不能改 原来的 kubevirt/bond0:那是集群一份对象,一改还在 macvlan 上的虚机会一起断。

{ "cniVersion": "0.3.1", "name": "br0", "type": "bridge", "bridge": "br0", "ipam": {} }

每台节点还要:netplan 把地址从 bond0 挪到 br0br0 MAC 钉死原 bond0,少抖 ARP);net.bridge.bridge-nf-call-iptables=0(以及 ip6),否则 iptables 拦二层转发,ARP 仍不通。虚机 YAML 的 bridge: {} 不用改,只把 networkNamekubevirt/bond0 改成 kubevirt/br0换 NAD 必须重启虚机virtctl restart 或停再开),运行中不能热换。

先改负载最少的 16.21 做试点,确认关掉 macfix 再重启虚机仍然通,再按同样 netplan 改 16.22、16.23,把这台上的虚机切过去。客机 IP 不变。

顺序不能反

每一台都是:先当 worker 挂 OSD,再 add-etcd / add-master,再踢它接替的那组虚机。 16.23 自己进集群时,这些命令在 4.100 上敲;切过来之后才改在 16.23 上敲,例如 16.22:

Terminal window
docker exec kubeasz ezctl add-node cyxck8s-01 10.1.16.22
docker exec kubeasz ezctl add-etcd cyxck8s-01 10.1.16.22
docker exec kubeasz ezctl add-master cyxck8s-01 10.1.16.22

踢旧节点同样带集群名和 IP,例如 del-etcd / del-master 10.1.4.101del-node 10.1.4.10210.1.4.103

16.23 先进集群(worker → OSD → etcd/master)→ 踢 5.x → 控制端切到这台
→ 腾空 pve2(客机先迁到 16.23 上的 KubeVirt)→ 装 16.22 → 踢 4.101
→ drain 4.102 / 4.103(给 16.21 腾空)
→ 4.100 离集群、关 4100
→ 装 16.21 → 三票回来
→ 10.1.4.0/24 从 VLAN 20 一次挂到 VLAN 40(KubeVirt 客机二层回来)

16.21 加入前会有一段 只有 16.23 + 16.22 两票 的窗口。这段不要过夜。

Calico 用 etcd 当 datastore。每次 etcd 成员变化,改 etcd_endpoints 再 rollout。踢 4.101 之后写成:

https://10.1.16.23:2379,https://10.1.4.100:2379,https://10.1.16.22:2379

备份过 calico.yaml.bak.pre-8.6。原来的 calicoctl.cfg 里还带着 4.101 和 5.100。

Rook placement 继续拆开 all / mon / osd,求交集、不是覆盖。16.23 那次 Helm rev 10–13 的两种错法见上面。

第二台:先 worker 和盘,再进 etcd

08-30 晚上 pve2 已空。pvecm delnode pve2 时 homelab 集群 quorum 丢过一次corosync-quorumtool 加手写 corosync.conf 拉回来。擦 16.22 NVMe。N9K Po2(Eth1/3+1/4)从 trunk 20,40,3961 改成和 Po3 一样:

switchport mode access
switchport access vlan 40
mtu 9000
description new-k8s-10.1.16.22
no lacp suspend-individual
lacp rate fast

ezctl add-node cyxck8s-01 10.1.16.22 结果 97 ok / 0 failed,立刻关 tunl0 TX checksum。

Terminal window
ctr -n k8s.io images export - rook/ceph:v1.17.9 | ssh root@10.1.16.22 ctr -n k8s.io images import -

两包大约 508.7 MiB + 525.5 MiB,import 大约 58 秒。16.23 缺 layer 时从还活着的 10.1.4.103 补 blob。

Multus thick 当时是 multus-cni:v4.2.4-thick,默认 limit 50Mi。灌镜像和重开节点时 OOM 137 / CONSTRAINT_MEMCG,kubelet 报 FailedCreatePodSandBoxPost "http://dummy/cni": EOF。manifest 在 /root/kubevirt/multus/multus-daemonset-thick.yaml。先提到 256Mi。4.100 那次事故 256Mi 仍 OOM。只加内存治不了:v4.2.4 的 thick daemon 没有并发上限,节点重启时本机非 hostNetwork Pod 的 CNI ADD 同时打进来,同一个 cgroup 里再 fork Calico,内存按并发涨。08-31 凌晨升到 v4.3.0-thick(上游 PR #1510):connectionLimit: 16,request 128Mi / limit 1GipriorityClassName: system-node-critical。operator 卡在 rook-ceph-detect-version 时,16.22 的 prepare 会一直不出现,和 CNI 是同一类问题。

然后才 add-etcd + add-master。etcd 短暂四成员:16.23 / 4.100 / 4.101 / 16.22。4.101 上的 OSD 一次:

Terminal window
ceph osd out 1 5 7

等 PG clean,safe-to-destroy,purge,drain 4.101,改 Calico endpoints,del-etcd / del-master 10.1.4.101,停 VMID 4101qm shutdown 超时后 stopped)。

关 4101 时有人在 VNC 里误 qmstop 4100(大约 08-30 23:48)。4.100 上 Multus 再 OOM,mon/osd 掉过一截,对象曾到 33% degraded;4.100 上顶上来的是 mon-h。4100 必须当时就拉起来,它还占着 16.21。

摘 mon-a 时遇到 Pending:hostPath 还钉在 4.101,placement 已经不含 4.101。手工 ceph mon remove a,停 operator 再开,新 mon 是 g@16.22。Rook 不回收字母。终态叫 f / g / i,不要改回 a / b / c。

占着 16.21 的那台最后走

4.100 不能先杀。08-31 给它打污点 migration.cyxc/hold=true:NoSchedule。CNPG 主库还在 4.102 上时,先把副本切到已经裸机的节点。harbor 在 4.101 上,用 kubectl cnpg switchover;其余用 status patch,例如:

Terminal window
kubectl patch cluster "$cluster" --subresource status --type merge \
-p "{\"status\":{\"targetPrimary\":\"$dest\"}}"

当时切过的实例包括 gitlab → gitlab-postgres-2、jumpserver → jumpserver-postgres-1、kf2-panopticon → kf2-panopticon-postgres-2、osspilot → osspilot-postgres-2。切完再 drain 4.102(大约 8 分钟)、4.103。

pve1 上剩下的业务客机冷迁到已经在跑的 KubeVirt(16.23 / 16.22),腾空后再关 4100、擦 NVMe。IP 还在 VLAN 20 时,客机在 VLAN 40 上看不到二层,这是预期。

09-02:集群节点列表已经没有 4.100,etcd 两票 16.23+16.22,4100 仍占 pve1 直到擦盘前关掉。Po1(Eth1/1+1/2)改成和 Po3 一样的 access 40、mtu 9000。装机时 Eth1/1 无光(Rx N/A),只插了 1/2,光功率大约 −1.1 dBm。

16.21 的 ConnectX-4 要 FEC BaseR,否则协商失败,日志里有 Link training failure, Remote side is not ready yetmlx-fec-baser.service

Terminal window
ethtool --set-fec eno1np0 encoding baser
ethtool --set-fec eno2np1 encoding baser

add-node 10.1.16.21 → 同一套 IPIP 修复(virt-handler 例 172.20.108.65)→ 用户要求 add-etcd / add-master 再挂 OSD → 三票 16.23 / 16.22 / 16.21。Multus /etc/cni/net.d/00-multus.confclusterNetwork 改成 /host/etc/cni/net.d/10-calico.conflist

Rook helm rev 23 上 16.21 的 OSD 时,如果 mon.count: 3 但 placement 只有 22/23,operator 报 failed to schedule mons连 prepare 都不跑。临时 mon.count: 2 才放出 osd.0 / osd.1(WWN wwn-0x55cd2e414f83ef72 / wwn-0x55cd2e414f52a515)。回填大约 50–75 MiB/s,体量大约 495 GiB,期间开过 noout。rev 24 第三 mon 是 i@16.21

VLAN 和 BGP

09-02 晚上改过 N9K SVI:10.1.4.1/24 从 VLAN 20 挪到 VLAN 40 secondary。终态(09-03 核对):

SVI 地址
Vlan5 192.168.5.2/26 管理
Vlan20 10.1.6.1;secondary 10.1.3.x/27
Vlan40 10.1.16.1;secondary 10.1.4.1/24 + 10.1.5.1/24

MetalLB ConfigMap:

peers:
- peer-address: 192.168.5.2
peer-asn: 65533
my-asn: 65528
address-pools:
- name: default
protocol: bgp
addresses:
- 10.1.10.0/24

N9K:router bgp 65533neighbor 10.1.16.21/22/23 remote-as 65528 disable-connected-checkno neighbor 10.1.4.100 / 10.1.4.101。没有 ECMP,冲突时最老的 eBGP 邻居 16.23 为 RIB best。连 N9K SSH 要旧算法:

Terminal window
ssh -o HostKeyAlgorithms=+ssh-rsa \
-o KexAlgorithms=+diffie-hellman-group14-sha1 \
admin@192.168.5.2

看起来怪的都不是缺口

2026-09-03 09:16:

现网
节点 只有 k8s-10-1-16-23 / 22 / 21。无 4.x、5.x
etcd / apiserver 三票 healthy。:2379 / :6443 都在听。控制端 16.23
kubeasz hosts [etcd] [kube_master] 三个 10.1.16.x[kube_node]
Ceph HEALTH_OK。mon f@23 / g@22 / i@21。6/6 up+in。393 PG active+clean
VIP Traefik 10.1.10.3(根路径 404 正常)。k8s-gateway 10.1.10.53
MetalLB Speaker AS 65528,N9K AS 65533,peer 192.168.5.2,池 10.1.10.0/24 /32

OSD(后舱 960G,class ssd):

节点 OSD WWN
16.23 osd.9 / osd.10 wwn-0x55cd2e414f78e403 · wwn-0x55cd2e414fc5c28f
16.22 osd.2 / osd.4 wwn-0x55cd2e414f563b2f · wwn-0x55cd2e414f8568d6
16.21 osd.0 / osd.1 wwn-0x55cd2e414f83ef72 · wwn-0x55cd2e414f52a515

mgr 当时 placement 只有 22/23,count=2,16.21 上没有 mgr。不要为了对称去改。

MetalLB:16.21 宣告 16 条,22 / 23 各 17 条。16.21 不宣告 10.1.10.3,因为 Traefik externalTrafficPolicy=Local,这台没有 Traefik Pod。要三机都宣告,先让 Traefik 在 16.21 上也有 Pod,不是缺 BGP 邻居。

PVE 不再承担这批业务虚机。

以后再加物理机

add-node 之后、prepare 之前:

Terminal window
ethtool -K tunl0 tx off
ethtool -k tunl0 | grep tx-checksumming # off
ls /etc/cni/net.d/ # 只有 10-calico.conflist
# virt-handler 的 Pod IP 必须是 172.20.<本机块>.x,不能是 172.20.0.2

本节点 Felix 加上 ChecksumOffloadBroken=true,systemd 开机再关一次 tunl0 TX checksum。ConnectX-4 先确认 FEC BaseR。OSD 只写 /dev/disk/by-id/wwn-0x…。先 worker 和盘,PG 干净了再:

Terminal window
docker exec kubeasz ezctl add-etcd cyxck8s-01 <IP>
docker exec kubeasz ezctl add-master cyxck8s-01 <IP>

改 Calico etcd_endpoints。Rook placement 拆开 all / mon / osd。N9K 加 BGP 邻居。客机先迁 KubeVirt 再拆宿主机。

也可以把 ChecksumOffloadBroken=true 做到集群 FelixConfiguration/default,所有节点都关,CPU 开销很小。当时没扩大变更,一台一台写的节点级配置。