news 2026/10/6 3:40:16

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从Rancher迁移到Sealos:Kubernetes集群私有化实战

1. 迁移前的盘点:先把家底摸清楚

1.1 为什么我决定从 Rancher 换到 Sealos

先亮结论:Rancher 本身不是不好,而是对“私有化交付”这个场景来说,它太重了。我手上有几十个集群要维护,Rancher 的多集群管理面板确实方便,但代价也实实在在:升级依赖组件多、UI 频繁改版、默认装一堆你用不上的功能,再加上它自己的资源占用,一台 4C8G 的机器光跑 Rancher 就快喘不过气了。而 Sealos 吸引我的点很直接:它把 Kubernetes 集群的安装、维护、组件管理都做成了一条命令的事,天然适合私有化环境,没有多余的“管理中心”,应用要什么组件就装什么组件。

这个决策不是拍脑袋。我在测试环境对比过两者的资源开销:一个全新搭建的 Rancher 集群,系统组件常驻内存大概 2~3GB;Sealos 部署的高可用集群,基础组件加起来不到 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、EndpointSlice,Rancher 默认的 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 搬过去。所以我的做法是:

  1. 在新集群准备好存储驱动和 StorageClass。如果是本地磁盘方案,我会用 OpenEBS 或者 Sealos 自带的存储组件,给每个节点加一块独立数据盘,避免把业务数据跟系统盘混在一起。
  2. 把“存储类名”统一规划好。原来 Rancher 用的local-path、nfs-client之类的名字,在新集群里尽量保持一致,这样工作负载 YAML 里指定的 storageClassName 不用改,省去大量改动。
  3. 对已经有数据的应用,单独做数据拷贝,这个后面在讲有状态服务时会展开。

这里有个细节:如果新集群的 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导出 SQL,PostgreSQL 用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 时区,旧集群里可能已经通过环境变量TZ=Asia/Shanghai做了调整,但这份配置不一定写在工作负载的 YAML 里,而是写在 Rancher 的全局配置里。导出的 YAML 里看不到,新集群就默认 UTC,结果 CronJob 定时任务全部对不上点。迁移后第一时间检查所有 CronJob 的调度时间和应用日志时间戳,这个坑十次里有八次会出现。

4. 流量切换与安全收尾:Ingress、证书和回滚预案

4.1 Ingress 与网关的适配

Rancher 环境最常见的 ingress-controller 是 nginx-ingress,Sealos 环境默认可能装的是 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 让所有流量一瞬间切到新集群。实战中更稳妥的方案是蓝绿切换:

  1. 先在旧集群旁边建好新集群,两边并行跑一段时间,验证数据同步和功能一致性。
  2. 用仅改动一台机器 hosts 的方式做“迷你验证”,确认新集群上这个应用的核心链路可用。
  3. 在流量入口层把少量比例(比如 5%~10%)的请求切到新集群,观察错误率和响应时间。
  4. 稳定运行一个业务周期后,再把全部流量切过去。

这套流程的意义在于,每一步都有回滚点。某一步出了问题,只需要把流量切回旧集群,不需要重新执行迁移和启动流程。回滚预案要提前写成脚本,不能说“到时候再想办法”,真到出问题的时候,人的判断力会直线下降,手写命令错误率高得离谱。

另外新集群上线后,旧集群至少保留到“新集群完整运行一个自然周”再关停。有些数据问题一周才暴露一次,比如周报任务、月底定时任务,太早释放旧集群,等于把后悔药扔了。

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 还是旧集群地址重新梳理内网映射关系,更新 hostAliases
Ingress 访问 404ingressClassName 未匹配检查 Ingress 的 class 字段和实际控制器是否一致
CronJob 时间不对容器默认 UTC 时区为 CronJob 补充 TZ 环境变量,或调整 Cron 表达式
应用启动成功但永不 Ready探针参数与资源规格不匹配调整 initialDelaySeconds 和 timeoutSeconds
Secret 导入后应用读不到Secret 类型不一致或 namespace 不对确认 type、namespace、mount 路径一致

5.4 迁移“隐形坑”名单

最后把上面所有经验浓缩成一份避坑名单,这些都是常规操作发现不了、出问题才追悔莫及的点:

  • 导出 YAML 时没清理 Rancher 的finalizers,导致 namespace 删除不了。
  • 迁移了 PVC 但没迁移 StorageClass,新集群没有任何类能绑定。
  • 改了镜像仓库地址却忘了imagePullSecrets,Pod 例常拉起失败。
  • 只迁了 Ingress 没迁 tls Secret,页面证书报错。
  • 只迁了应用没迁 ServiceMonitor,指标全丢。
  • 源库数据迁完没做行级校验,上线后发现单表数据缺失。
  • 时区没统一,定时任务全部乱套。
  • 假设旧集群的默认 ingress-controller 和新集群一样,没有验证注解兼容性。

这套迁移方案做完之后,我的整体感受是:Sealos 在私有化场景的交付体验确实比 Rancher 顺滑很多,尤其在集群初始化和组件管理这块省了不少时间。但迁移本身是个系统工程,工具只是其中一环,真正决定成败的,是对旧环境资产的完整盘点、对新环境的充分准备,以及留好每一步的回滚退路。最后再分享一个小技巧:在测试环境先完整走三遍迁移流程,把每个步骤的耗时、报错、回滚点都记录成一张执行单,正式迁移那天按执行单走,你会发现“突发状况”比想象中少得多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/6 3:39:57

html-to-json实战:HTML表格高效转JSON的结构化指南

简介&#xff1a;这是一款将HTML文档转换为JSON结构的Python开源工具&#xff0c;重点支持智能识别HTML表格并将表头自动映射为JSON键名&#xff0c;适合网页数据抓取、前端开发与自动化测试场景中需要结构化提取页面内容的开发者使用。压缩包共32个文件&#xff0c;包含7个Pyt…

作者头像 李华
网站建设 2026/10/6 3:39:37

自绘CListCtrl的常见误区:从Owner Draw到NM_CUSTOMDRAW的正确切换

做MFC控件美化的时候&#xff0c;最容易被网上老代码带偏的坑&#xff0c;就是自绘CListCtrl时照搬CListBox那套Owner Draw流程。最近我就在CListCtrl派生类里写了ON_WM_MEASUREITEM_REFLECT&#xff0c;也重写了DrawItem(LPDRAWITEMSTRUCT lpMeasureItemStruct)&#xff0c;样…

作者头像 李华
网站建设 2026/10/6 3:39:36

JProfiler 8.0.2 Windows x64安装与Java性能分析入门实战

JProfiler_windows-x64_8_0_2 这个安装包&#xff0c;我在Windows机器上装过不下十次了&#xff0c;从个人开发机到团队的测试服务器&#xff0c;基本都是同一个套路&#xff1a;双击exe、配许可证、连上Java进程、开分析。它是我在Java性能分析这个方向上用得最多、也最愿意推…

作者头像 李华
网站建设 2026/10/6 3:39:26

Lasso超参数调整与模型选择:L1稀疏原理到sklearn实践

做机器学习的人大概都遇到过这种场景&#xff1a;手里一张宽表&#xff0c;几十个特征&#xff0c;业务方拍着胸脯说"每一个都有业务含义"&#xff0c;可真跑起线性回归来&#xff0c;要么系数奇奇怪怪&#xff0c;要么测试集一验证就崩。这种时候Lasso就是绕不开的选…

作者头像 李华
网站建设 2026/10/6 3:39:12

无感FOC核心算法:龙伯格观测器原理、离散化与参数整定全解析

1. 无感FOC里为什么绕不开状态观测器做无感FOC控制&#xff0c;核心问题就一个&#xff1a;转子位置和速度怎么拿。装编码器或霍尔&#xff0c;成本上去了&#xff0c;而且很多场景根本装不下。所以行业内主流方案是走无感路线——不装位置传感器&#xff0c;靠电机的电压电流反…

作者头像 李华
网站建设 2026/10/6 3:38:58

许三观卖血记:男人的爱不是低三下四,而是关键时刻挺身而出

读《许三观卖血记》是很多年前的事了&#xff0c;但书中那些密密麻麻的细节&#xff0c;像许三观弓着背坐在门槛上喝黄酒的样子、许玉兰站在街口数落他的声音&#xff0c;一直留在我脑子里。后来我把这本书重读了两遍&#xff0c;越读越觉得&#xff0c;余华写这个故事&#xf…

作者头像 李华