ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

从Rancher迁移到Sealos:Kubernetes集群私有化实战

从Rancher迁移到Sealos:Kubernetes集群私有化实战 1. 迁移前的盘点先把家底摸清楚1.1 为什么我决定从 Rancher 换到 Sealos先亮结论Rancher 本身不是不好而是对“私有化交付”这个场景来说它太重了。我手上有几十个集群要维护Rancher 的多集群管理面板确实方便但代价也实实在在升级依赖组件多、UI 频繁改版、默认装一堆你用不上的功能再加上它自己的资源占用一台 4C8G 的机器光跑 Rancher 就快喘不过气了。而 Sealos 吸引我的点很直接它把 Kubernetes 集群的安装、维护、组件管理都做成了一条命令的事天然适合私有化环境没有多余的“管理中心”应用要什么组件就装什么组件。这个决策不是拍脑袋。我在测试环境对比过两者的资源开销一个全新搭建的 Rancher 集群系统组件常驻内存大概 2~3GBSealos 部署的高可用集群基础组件加起来不到 1GB。对私有化交付来说客户不会给你多好的机器省下来的资源就是实打实的可部署空间。另一个考量是运维复杂度Rancher 的架构里多了一个“管理面”你得额外维护证书、认证、agent 通信Sealos 的管理逻辑嵌在集群本身没有单独的 control plane 依赖排障链路短很多。1.2 盘点清单别漏掉这些“隐形资产”迁移前最忌讳的就是对着kubectl get all就以为看全了。get all这玩意儿会漏掉 namespace 级别的一堆资源而且它显示的字段并不完整。我做了这么多年迁移踩过的最大一个坑就是漏资产应用迁过去了结果日志采集的服务发现工作负载用的是 EndpointSlice 而不是 Service指标监控依赖的是 ServiceMonitor CRD这些一旦漏了新集群里应用表面正常但监控和日志全断。我建议把盘点分成五类来做工作负载类Deployment、StatefulSet、DaemonSet、Job、CronJob这些是业务的主体数量最多迁移优先级也最高。配置类ConfigMap、Secret注意 Secret 不光要盘点名字还要确认哪些被工作负载挂载、以什么方式挂载因为迁移后 key 改没改会直接影响启动。网络类Service、Ingress、NetworkPolicy、EndpointSliceRancher 默认的 ingress-controller 跟 Sealos 默认的可能不是同一个这里最容易出兼容问题。存储类PersistentVolumeClaim、StorageClass、PV 本身PV 是没法直接“跨集群搬”的这就是后面有状态服务难迁的根源。自定义资源类ServiceMonitor、PrometheusRule、cert-manager 的 Certificate、HPA 扩展等等这些 CRD 在新集群有没有装决定了迁移后功能是否完整。我的习惯是把盘点结果输出成一张表每行一个资源标注“名称、命名空间、类型、所属应用、是否有持久化数据、是否可以停机迁移”。这张表后面就是迁移计划的执行清单每迁完一个打一个勾心里有数。1.3 导出资源的通用姿势与注意事项盘点确认之后就开始导出。大多数人的第一反应是直接kubectl get deploy -n xxx -o yaml这个姿势没问题但不建议直接拿来就用。Rancher 管理的集群里几乎所有资源都会被塞进它的系统标签和注解像cattle.io/creator、cluster.cattle.io/...这一类这些字段在 Sealos 的新集群里没有任何意义直接 apply 过去轻则报警告重则因为 finalizer 卡在 Terminating。我常用的清洗方式是导出后用 yq 或 sed 把 metadata 里的uid、resourceVersion、creationTimestamp、generation、managedFields、ownerReferences、status以及所有 cattle 相关字段全部删掉。这里给一个能跑的最小脚本片段# 导出并清洗单个 Deployment kubectl get deploy nginx -n web -o yaml \ | yq del(.metadata.uid, .metadata.resourceVersion, .metadata.creationTimestamp, .metadata.generation, .metadata.managedFields, .metadata.annotations[field.cattle.io/*], .status) \ nginx-clean.yaml如果你是手工迁移少量应用这个脚本够用。如果规模大我更推荐直接把资源先落成目录结构比如manifests/namespace/kind/name.yaml然后统一清洗。重点是selector 和 pod template 里的 labels 必须保留原样这是 Deployment 跟 Pod 关联的纽带一旦改了Rollout 不会更新任何 Pod。2. 私有化底座搭建Sealos 环境的存储、镜像与网络准备2.1 部署规划与离线安装要点搭建 Sealos 私有化环境之前先想清楚一个原则迁移目标集群不是让你“先跑起来就行”而是要承担生产流量的所以高可用和可维护性必须一开始就建好。Sealos 支持一条命令拉起高可用 Kubernetes 集群但如果节点规划不合理后面扩容、维护都会很被动。我的推荐规划是至少 3 个 master 节点组成 etcd 高可用2~4 个 node 节点承载业务有状态应用单独打到带存储盘的节点上。不要为了省机器只搞单 master私有化交付里硬件一挂就是事故单 master 的集群一旦出问题恢复成本远高于多一台机器的成本。Sealos 在离线环境的安装要提前准备安装包包含 Sealos 二进制、集群镜像和需要用到的组件镜像。这一步建议在能联网的机器上先sealos pull拉好所需镜像再sealos save导出成 tar 包带到内网后sealos load导入。实际操作时最容易出错的是版本匹配镜像包和 Sealos 二进制版本不一致会出现莫名的加载失败。我的经验是每个环境打一套固定的版本组合记录下来写进交付文档不要图省事混用版本。2.2 存储与数据面准备PV、StorageClass、共享存储存储是迁移里最容易被低估的一环。Rancher 自带或使用环境里的 StorageClass到 Sealos 这边可能根本没有对得上的类名更要命的是不同的存储驱动对底层实现要求不一样导致同样一份 YAML 在新集群里完全跑不动。先理清一个概念PVC 是集群内的资源但它背后依赖的 PV 数据分布式在节点或存储设备上跨集群迁移不可能直接把 PV 搬过去。所以我的做法是在新集群准备好存储驱动和 StorageClass。如果是本地磁盘方案我会用 OpenEBS 或者 Sealos 自带的存储组件给每个节点加一块独立数据盘避免把业务数据跟系统盘混在一起。把“存储类名”统一规划好。原来 Rancher 用的local-path、nfs-client之类的名字在新集群里尽量保持一致这样工作负载 YAML 里指定的 storageClassName 不用改省去大量改动。对已经有数据的应用单独做数据拷贝这个后面在讲有状态服务时会展开。这里有个细节如果新集群的 StorageClass 名字跟旧集群不一样所有有状态工作负载的 YAML 都要改一遍包含volumeClaimTemplates里的类名。用 sed 批量替换要小心有时你只想改存储类结果把 ConfigMap 里的配置也误改了。建议改动前先把所有出现了storageClassName的文件列出来人工过一遍。2.3 镜像仓库与私有化拉取的姿势私有化环境最大的问题是镜像拉取。源集群里用的镜像都写在 docker hub 或者私有仓库里到了客户内网如果镜像仓库没同步好Deployment 起来就是 ImagePullBackOff而且这个报错会伴随整个迁移过程反复出现。我这里的标准动作是先在新环境搭建一个 Harbor 或 Registry然后把源环境所有工作负载用到的镜像全部同步过去。同步方式有两种取决于源环境能否联网能联网的用 skopeo copy 或 docker pull tag push写一个循环脚本批量处理。完全离线的在能联网的机器上docker pull后docker save成 tar再到内网docker load最后推送到内网仓库。批量替换镜像地址也有坑。我习惯先在 YAML 里用image: registry.old.com/xxx:v1.0这种旧地址格式查一遍然后统一替换成新仓库地址。只改镜像地址还不够还要检查imagePullSecrets如果新仓库是需要认证的私有仓库Pod 里没有对应的 Secret一样拉不下来。还有个隐性坑是镜像 tag 以latest结尾的情况。在内网环境如果所有节点都设置了imagePullPolicy: Always每次 Pod 调度都会去仓库重新拉取仓库里没有对应 tag 就会失败。我的做法是迁移前把所有latest全部重新打成一个带具体版本号的 tag避免后续不可控。3. 工作负载与数据迁移从 YAML 到业务的完整路径3.1 无状态服务最快搬迁但也有隐藏依赖无状态服务理论上是最简单的迁移对象导出一份 YAML、清洗、apply就完成了大半。但实际操作中无状态服务也会翻车最常见的翻车原因有三个。第一个是环境变量和配置的隐式依赖。很多应用读不到配置不会报“配置缺失”这种直白错误而是启动成功后连不上数据库、Redis 报错这类问题排查起来相当折磨人。我的建议是迁移前先把应用依赖的外部资源全部列出来数据库地址、Redis 地址、消息队列、内部 API 网关然后逐一核对新集群里这些地址是否通、域名是否解析正确。第二个是 hostAliases。很多企业内部服务不走 DNS直接在 Pod 里写 hostAliases 把某个域名映射到内网 IP。旧集群导出的 Deployment YAML 一般会带 hostAliases 字段但如果你的节点网络或者 Service 网段跟旧环境不一样这个 IP 很可能在新集群是错的出现服务间互相访问超时。第三个是健康检查的探针参数。旧集群节点资源紧张时很多应用的 readinessProbe 和 livenessProbe 参数其实已经踩在超时边缘了迁移到新集群后如果探针 interval 和 initialDelay 没有适配新环境的资源规格会出现 Pod 反复重启或者出现“启动成功了但永远不 Ready”的状态。无状态服务的迁移节奏是先迁一批非核心应用确认稳定后再迁核心应用。不要在迁移当天一股脑全上出了问题连回滚范围都判断不了。3.2 有状态服务数据库、中间件与持久化数据迁移有状态服务是整个迁移工程里难度最大的部分。我核心的原则只有一句话尽量走逻辑导入导出避免直接文件级拷贝。以数据库为例MySQL 用mysqldump导出 SQLPostgreSQL 用pg_dump到了新环境再导入。逻辑导出有几个好处版本跨度的兼容性更好、数据表结构可以趁机整理、导入过程能清晰看到报错。SQL 文件特别大的时候导入中断是常态几百 MB 的 SQL 导入到一半网络闪断整个库回滚是最让人头疼的情况。我的做法是分库分表导出每个表独立成一个.sql文件导入时逐个执行哪个失败就重试哪个。像mysql xxx.sql这种一把梭的姿势在动辄几个 GB 的数据量下基本都会出问题。文件级拷贝主要用在这些场景对象存储里的大量文件、本地盘上的索引数据、某些不接受停机导出的业务。如果一定要拷贝文件推荐用rsync先在旧集群跑一轮全量同步业务切到只读模式后再跑一轮增量同步然后切换。千万不要复制文件的同时业务还在写拷贝出来的数据全是裂脑状态对账对到崩溃。StatefulSet 迁移时有个关键点PVC 的名字必须跟volumeClaimTemplates生成的一致否则新 Pod 挂载旧数据时找不到卷。先手动建 PVC再让 StatefulSet 的副本按命名规则自动绑定这是标准姿势。对于现在很常见的大模型或 Dify 这类 AI 应用迁移还要特别留意向量库和模型文件的存储位置。向量库的数据如果混在普通 PVC 里文件量巨大优先走对象存储或块存储的快照方案模型文件体积也不小最好是放到独立的数据目录用 rsync 增量同步能省下不少时间。3.3 配置与密钥迁移Secret、ConfigMap、hostAliases、时区这一类资源单个都很小但是数量庞大而且它们的问题不在“迁移”本身而在“迁移后的一致性”。Secret 导出时默认是 base64 编码的直接导没问题但要注意新集群里 Secret 的 type 是否还是Opaque。还有一个容易被忽略的是 tls 类型的 Secret在 Rancher 环境里可能由 cert-manager 自动管理迁移到 Sealos 后如果 cert-manager 没有部署证书不会自动续期到期后整站 HTTPS 直接挂掉。时区问题也值得一提。很多容器镜像默认是 UTC 时区旧集群里可能已经通过环境变量TZAsia/Shanghai做了调整但这份配置不一定写在工作负载的 YAML 里而是写在 Rancher 的全局配置里。导出的 YAML 里看不到新集群就默认 UTC结果 CronJob 定时任务全部对不上点。迁移后第一时间检查所有 CronJob 的调度时间和应用日志时间戳这个坑十次里有八次会出现。4. 流量切换与安全收尾Ingress、证书和回滚预案4.1 Ingress 与网关的适配Rancher 环境最常见的 ingress-controller 是 nginx-ingressSealos 环境默认可能装的是 Traefik或者你在初始化时选择了 nginx。两个控制器在处理同一份 Ingress YAML 时注解体系完全不同比如白名单nginx.ingress.kubernetes.io/whitelist-source-range这种注解在 Traefik 里根本不生效而且是静默不生效接口照样被外部访问没有任何报错提示。我的做法是先把旧集群里的 Ingress 列表全部导出逐个确认这些注解在目标 ingress-controller 下的等价写法然后做一份“注解映射表”nginx.ingress.kubernetes.io/rewrite-target对应 Traefik 的traefik.ingress.kubernetes.io/rewrite-target不同版本写法有差异以实际为准涉及到 SSL 透传的确认目标控制器是否支持对应字段。涉及全局访问控制的必须验证白名单、Basic Auth 这类安全注解是否真的在新环境生效。还有一个小坑是ingressClassName。旧集群里可能默认用注解方式指定 ingress class新集群如果不设置这个字段控制器可能直接不理这条 Ingress出现 404 或者 503。这个我在测试环境就踩过因为 YAML 里什么都没写错就是访问不通。4.2 证书、内部域名和网络安全策略证书迁移要说清楚一件事内部系统用的自签证书不能只把 Secret 搬到新集群就算完。因为签发证书的 CA 根证书在旧环境的各台服务器上通常是被信任的新集群的节点能不能信任这张证书取决于根证书是否也一并安装。我的标准步骤是把 Secret 里的tls.crt和tls.key导出在新集群用kubectl create secret tls重新创建确保 Secret 名称跟 Ingress 引用的一致。然后在所有需要访问该服务的节点和客户机侧把签发该证书的根 CA 导入系统信任库。这一步如果漏做会出现 HTTPS 客户端报证书无效排查半天发现证书“明明迁过去了”但就是不被信任。内部域名也需要重新梳理。旧集群里各服务之间经常通过 Service 域名通信比如service.namespace.svc.cluster.local这类域名在新集群只要 Service 名字和 namespace 保持一致就能自动解析问题往往出在那些用了自定义域名访问内部服务的应用上这些域名在旧环境可能靠额外 DNS 配置或 hosts 文件解决新集群里没有相应配置就会连不上。4.3 蓝绿切换与快速回滚迁移风险最高的时刻是流量切换我强烈不建议直接改 DNS 让所有流量一瞬间切到新集群。实战中更稳妥的方案是蓝绿切换先在旧集群旁边建好新集群两边并行跑一段时间验证数据同步和功能一致性。用仅改动一台机器 hosts 的方式做“迷你验证”确认新集群上这个应用的核心链路可用。在流量入口层把少量比例比如 5%~10%的请求切到新集群观察错误率和响应时间。稳定运行一个业务周期后再把全部流量切过去。这套流程的意义在于每一步都有回滚点。某一步出了问题只需要把流量切回旧集群不需要重新执行迁移和启动流程。回滚预案要提前写成脚本不能说“到时候再想办法”真到出问题的时候人的判断力会直线下降手写命令错误率高得离谱。另外新集群上线后旧集群至少保留到“新集群完整运行一个自然周”再关停。有些数据问题一周才暴露一次比如周报任务、月底定时任务太早释放旧集群等于把后悔药扔了。5. 验证、监控与排雷实录5.1 迁移后的验收清单迁移后验收不能只看“Pod Running 就完事”这个状态只能证明容器拉起来了离业务可用还差得远。我有一套从浅到深的验收顺序基础设施层所有节点 Ready、CoreDNS 解析正常、StorageClass 可正常创建 PVC、Ingress 控制器能响应请求。应用层Deployment 副本数符合预期、日志无 ERROR 级报错、Pod 能被正确调度到有存储的节点。业务层登录、查询、关键业务链路逐一走一遍不放过写操作。数据层源库和目标库的行数对比、最大主键值对比、增量同步的延迟归零。针对数据层我想多说一句别只对行数一定要对“关键业务表的备注字段”之类的细节有时候行数一致但具体字段值不一致这类问题在逻辑导出导入的场景下很容易被忽略。5.2 日志、监控与告警重建Rancher 环境自带一套监控栈这套监控进不了新集群。迁移后如果不在 Sealos 环境重新部署监控和日志组件你的集群会变成“睁眼瞎”应用出问题全靠用户反馈才知道。日志这块我的标准动作是在 Sealos 新集群部署 Loki 或 ElasticSearch接入 node 节点的容器日志目录再按 namespace 和应用维度配置日志采集。这一步建议在业务迁移的同时就做不要等上完线再做因为上线当天问题最多恰恰是最需要日志帮助判断的时刻。监控告警主要覆盖三块节点层CPU、内存、磁盘、容器层Pod 重启次数、镜像拉取失败、业务层HTTP 5xx 响应、队列积压、注册中心实例数。前两层靠 Prometheus 加 exporter 就能搞定第三层通常需要应用暴露指标接口。Sealos 本身带有监控组件直接启用即可告警规则需要你根据旧集群的经验重新配置一遍尤其是磁盘空间和内存使用率这两条私有化环境最容易挂在这上面。5.3 高频问题速查表问题现象常见原因解决方案Namespace 一直 TerminatingRancher 的 finalizer 残留在 namespace 上清洗 YAML 时删掉 finalizer或在新集群手动 patch 移除PVC 创建成功但 Pod 挂载失败StorageClass 的驱动依赖未安装确认新集群对应存储驱动组件已部署必要时手动安装镜像拉取报 ImagePullBackOff镜像地址未替换或 imagePullSecret 缺失批量替换镜像地址重建 PullSecret 并绑定到 ServiceAccount服务间域名访问不通hostAliases 里的 IP 还是旧集群地址重新梳理内网映射关系更新 hostAliasesIngress 访问 404ingressClassName 未匹配检查 Ingress 的 class 字段和实际控制器是否一致CronJob 时间不对容器默认 UTC 时区为 CronJob 补充 TZ 环境变量或调整 Cron 表达式应用启动成功但永不 Ready探针参数与资源规格不匹配调整 initialDelaySeconds 和 timeoutSecondsSecret 导入后应用读不到Secret 类型不一致或 namespace 不对确认 type、namespace、mount 路径一致5.4 迁移“隐形坑”名单最后把上面所有经验浓缩成一份避坑名单这些都是常规操作发现不了、出问题才追悔莫及的点导出 YAML 时没清理 Rancher 的finalizers导致 namespace 删除不了。迁移了 PVC 但没迁移 StorageClass新集群没有任何类能绑定。改了镜像仓库地址却忘了imagePullSecretsPod 例常拉起失败。只迁了 Ingress 没迁 tls Secret页面证书报错。只迁了应用没迁 ServiceMonitor指标全丢。源库数据迁完没做行级校验上线后发现单表数据缺失。时区没统一定时任务全部乱套。假设旧集群的默认 ingress-controller 和新集群一样没有验证注解兼容性。这套迁移方案做完之后我的整体感受是Sealos 在私有化场景的交付体验确实比 Rancher 顺滑很多尤其在集群初始化和组件管理这块省了不少时间。但迁移本身是个系统工程工具只是其中一环真正决定成败的是对旧环境资产的完整盘点、对新环境的充分准备以及留好每一步的回滚退路。最后再分享一个小技巧在测试环境先完整走三遍迁移流程把每个步骤的耗时、报错、回滚点都记录成一张执行单正式迁移那天按执行单走你会发现“突发状况”比想象中少得多。
返回列表