迁移 Zeabur 集群
我之前的 Zeabur 集群是独立跑在一台物理机上的,物理机相比云服务器的劣势之一就是底层存储的数据安全性 —— 云服务器的硬盘通常是由云服务商保证了安全性不同,物理硬盘坏了就是坏了
而不幸的是,不久前我就遇到了…… 所有数据差点消失,幸亏坏的盘并没有完全坏,以只读方式还能读(只是不能写)算是挽留了我的数据
但那以后我就一直在思考怎么保证数据安全,经过数个不同的方案研究,我最终的选择是 —— 将整机移动到 PVE 中 然后在 PVE 的底层使用 RAID 1 硬盘
方案敲定,行动开始 —— 我整个的迁移不太具有可复制性,因此写一篇完整的「迁移指南」确实不太有意义,但中间确确实实遇到了一些小问题,我觉得记录下来还是比较有价值的
💡 我两台机器(原 Zeabur 物理机和新的在 PVE 里面装的虚拟机):
- 在同一个机房
- 都是用的 RHEL 系的系统
- 内部文件系统都是 LVM + xfs
将 PVE 的硬盘改成 RAID1
我的 PVE 并不是在安装时就直接做好 RAID1 的,因此保证安全性的第一点是将 PVE 的硬盘改成 RAID1
⚠️ 需要注意的是,RAID 只是冗余,不是备份也无法替代备份
这次我的迁移也顺便把备份加上了,但备份又是一个较大的话题,因此本文不会写备份相关的内容,如果未来有机会我会单独写一篇文章,不过可以顺便说一嘴的是,我选用的备份方案是 Velero
我没有阵列卡,那么硬盘改 RAID 就只能是通过软 RAID 来组,在 Linux 下组软 RAID 有两种办法,一是利用 mdadm 组 RAID,另一种则是用 lvm 组 RAID;二者各有优劣,我为了灵活性选择了 lvm 的方案 —— 我现在是 2 块 1TB 的硬盘,使用 lvm 的话后面扩容可以很方便的通过加 1 块 2TB 的硬盘来得到完整的 2TB 可用 RAID1 空间,而如果不用 lvm 虽然也能实现但相对来说更加麻烦,且有难以避免的 degrade 时段
哦对,还有,做冗余不能只将数据做冗余,也要考虑引导,都是老步骤,复制下 ELF 分区、重做下 grub 引导,没什么值得说的,有什么问题问问 ChatGPT 它应该能相当完美的回答。
假设我们现在的环境是:原有的数据卷 /dev/sda3
、原有的 VG pve
、原有的 LV pve/root
/pve/swap
pve/data
、新的数据卷 /dev/sdb3
首先将新的数据卷转换为 PV pvcreate /dev/sdb3
然后将它加入至 VG vgextend pve /dev/sdb3
将 pve/root
转换为 RAID1 十分简单:一行命令 lvconvert --type raid1 -m1 pve/root /dev/sda3 /dev/sdb3
搞定
pve/swap
是个 swap 分区,没有做 RAID1 的必要,我们跳过
难点来到了 pve/data
这个逻辑卷 —— 它不是一个普通的 LV 而是一个 Thin Pool,如果我们直接执行 lvconvert --type raid1 -m1 pve/data /dev/sda3 /dev/sdb3
LVM 会报错 Operation not permitted on LV pve/data type thinpool.
可以认为 Thin Pool 是一个「逻辑逻辑卷」,它事实上分成了 meta 和 data 两部分(通过 lvs -a
命令可以看到,它是用 pve/data_tmeta
和 pve/data_tdata
组合而成的),所以我们说是对它做 RAID1 但事实上想做的是对它底层依赖的 meta 和 data 做 RAID1 —— 这样,Thin Pool 本身和从这个 Thin Pool 所分配出去的子 LV 也都是 RAID1 了。
所以我们要做的是,将它的底层数据卷转换为 RAID1 即可:
1 | lvconvert --type raid1 -m1 pve/data_tmeta /dev/sda3 /dev/sdb3 |
然后等待 lvs -a
的输出中 Cpy%Sync 列变为 100% 即为 RAID 转换完成。
哦对,还有一件事情,虽然示例中我用的另一块盘也是 SATA 盘做例子,但事实上我的另一块盘是 NVME 的,因此我上面说的「pve/swap
不用做 RAID1」之外,我其实还将 pve/swap
给移动到了新的盘上
将 LV 从一个 PV 移动到另一个 PV 的命令:pvmove -n pve/swap /dev/sda3 /dev/nvme0n1p3
迁移方案的选择
物理机迁移到 PVE 最直接的方法就是直接做整盘磁盘镜像然后导入,这种方案没什么可说的,也是最简单的
但是基于下面几个原因
- 我想换个系统,原来的系统是 CentOS Stream,嗯…… 不太适合一个稳定的环境使用
- 原来的系统在装 Zeabur 之前还装了一些别的东西,现在已经不需要了
- 我所有有价值的数据全都在 k3s 里面了,其实只要迁移 k3s 数据就行,而且我也想试试到底怎么迁移下集群,都要迁移哪些数据
- 我讨厌 Live CD 带的 Bash 的体验,特别是我可能还得用 IPMI 的 Remote Console 而不是自己的本地终端 SSH 过去
- 我原来其实也不是一块硬盘,而是两块硬盘组的 LVM 卷,两块盘都有数据,整盘迁移还得在 live cd 版系统里面折腾下加载 LVM
- 我原来物理机的启动用的 UEFI,但新的跑在虚拟机里面的引导用的 BIOS
- 整机迁移我也得迁移完去 PVE 里面改各种网卡、硬盘的映射什么的,也不容易
- 嗯…… 我没有一块多余的足够大的盘让我存这么大的磁盘镜像了 = =
我最后放弃了整盘迁移的方案,而是选择 rsync 拷贝 k3s 相关的数据:
- 在 Zeabur 中添加一个新的 Dedicated Server 让它为我们安装 k3s 的相关内容
- 安装好以后,执行
/usr/local/bin/k3s-killall.sh
停止整个集群、删除给 zeabur 用的 ssh key、在 zeabur 中删除这个服务器 - 利用 rsync 拷贝所有集群需要的数据
- 启动 k3s 服务,耐心等待它把原来所有的镜像下好
- 登录 zeabur 面板,执行一次 Reinstall Zeabur Service
将 ufw 换成 firewalld
我之前使用的防火墙时 ufw,它简单易用,但有一个非常重要的缺陷:只要 k8s 暴露的端口,它没办法阻止
因此,趁着这次,换回 firewalld 了;根据 Zeabur 的说明和 k3s 文档,需要执行下面的内容放行相关流量
1 | firewall-cmd --permanent --zone=public --add-service=ssh # 22 |
注:我个人不建议放开 30000-32767 —— 我询问过 Zeabur 支持人员,不放开这些端口不会影响 Zeabur 本身的能力,只是非 http 类型的端口映射无法被访问。Zeabur 会默认将所有端口都暴露到公网,部分端口所对应的服务可能有安全问题,所以我的建议是不要添加 30000-32767
两台规则,而仅在确实需要访问映射的端口时再添加
注 2:如果你是基于你自己需要的目的去访问内部服务(如数据库、Redis),我非常不建议你将这些服务暴露到公网,而是应当使用 zproxy 通过代理访问这些内部服务(当然,你需要将 zproxy 本身使用的端口放开)
不停机更换 IP
zeabur 和 k3s 本身对于「本机 IP 」有一定的偏好,如果要改的话比较麻烦,所以简单起见,我的选择是:
假设原机器 IP 1.1.1.1,现在新的机器 IP 2.2.2.2,我将两个机器的 IP 对调下就好了
云主机换个 IP 轻轻松松,物理机换个 IP 就很麻烦,特别是远程物理机换 IP(好吧,其实可以直接登录 IPMI 在 Remote console 里面改 IP 的,但我们当这个不存在)
不过挺好的一点是,我可以通过引入一个新的临时 IP 让这两台机器都不离线的情况下对调下 IP
💡 我这两台机器在同一个内网、网关相同、DNS 相同,都是手动指定的 IP 没有使用 DHCP
假设两台机器的网卡都是 eno1、临时 IP 是 3.3.3.3
流程是:
- 虽然和换 IP 的流程没关系,但是建议先执行
/usr/local/bin/k3s-killall.sh
把整个机器的 k3s 停掉 - 在原机器(1.1.1.1)执行
nmcli con mod eno1 +ipv4.addresses "3.3.3.3/24" && nmcli dev reapply eno1
让这个机器有 1.1.1.1 和 3.3.3.3 两个 IP - 通过 3.3.3.3 登录原机器(1.1.1.1 + 3.3.3.3),执行
nmcli con mod eno1 -ipv4.addresses "1.1.1.1/24" && nmcli dev reapply eno1
让这台机器只剩下 3.3.3.3 一个 IP - 登录新机器(2.2.2.2)执行
nmcli con mod eno1 +ipv4.addresses "1.1.1.1/24" && nmcli dev reapply eno1
让这个机器有 1.1.1.1 和 2.2.2.2 两个 IP - 通过 1.1.1.1 登录新机器(2.2.2.2 + 1.1.1.1)执行
nmcli con mod eno1 -ipv4.addresses "2.2.2.2/24" && nmcli dev reapply eno1
让这台机器只剩下 1.1.1.1 一个 IP - 通过 3.3.3.3 登录原机器,执行
nmcli con mod eno1 +ipv4.addresses "2.2.2.2/24" && nmcli dev reapply eno1
让这个机器有 2.2.2.2 和 3.3.3.3 两个 IP - 通过 2.2.2.2 登录原机器(2.2.2.2 + 3.3.3.3)执行
nmcli con mod eno1 -ipv4.addresses "3.3.3.3/24" && nmcli dev reapply eno1
让这台机器只剩下 2.2.2.2 一个 IP - 好了,现在原机器 IP 变成了 2.2.2.2、新机器 IP 则变成了 1.1.1.1 —— 对调完成
🤷 显得繁琐了点,但其实不难
利用 rsync 迁移数据
主要有两部分的信息我们需要迁移
- Zeabur 连接集群所用的 SSH 凭据
- 集群本身的各种配置、数据
我们需要用 rsync 同步下面的文件/目录到新的集群:
/etc/rancher/k3s
k3s 配置及连接集群的凭证/var/lib/rancher/k3s/server/db/
k3s 数据库/var/lib/rancher/k3s/server/token
k3s 内部授权 token/var/lib/rancher/k3s/storage
使用的 local volume 的存储路径
同步时使用的命令为(在原机器上执行)
1 | P=/etc/rancher/k3s # 依次使用上面所需要同步的路径 |
在启动前,删掉下面的目录(k3s 启动时会自动重新创建)
/var/lib/rancher/k3s/server/cred
/var/lib/rancher/k3s/server/tls
合并卷容量
我为虚拟机分配了 512GB 的硬盘,但我没想到的是我使用的 Automatic Disk Partition 竟然将绝大多数空间给了 /home
导致我迁移数据一半告诉我没空间了 = =
幸好,虽然这个奇怪的硬盘分区有点烦人,但 RHEL 系一律使用 LVM —— 它也只是个 LV 而已!简简单单,删掉这个 LV 把空间匀给 root 就好了
对了,删除 /home
挂载点要记得改 /etc/fstab
,不然下次系统可能启动不起来
更新 node
因为 Zeabur 不允许同一个 IP 有两个 Dedicated Server 出现,所以安装的过程中是使用了一个新的 IP 装的
在迁移完,如果想用回原来的 IP,需要修改 /etc/systemd/system/k3s.service.env
文件里面的 K3S_NODE_NAME
然后启动起来看看 kubectl get nodes
,如果还有原来的 IP 的 Node,删了就好
Pod 扩容
我数据迁移完一启动各种飙红,仔细一看原来是 Pod 数量超限(默认 110),需要修改 kubelet 配置
在 /var/lib/rancher/k3s/agent/etc/kubelet.conf.d
目录下,创建一个 01-max-pods.conf
,里面写
1 | apiVersion: kubelet.config.k8s.io/v1beta1 |
然后执行 systemctl restart k3s
就好
哦对,这个其实我之前就改过,但是迁移的时候漏了,你可以看看原来机器的 /var/lib/rancher/k3s/agent/etc/kubelet.conf.d
目录下有没有除了 00-k3s-defaults.conf
以外的文件,有的话最好前面 rsync 的时候直接一起迁移了,省事