如果你维护的 Rancher 平台遇见过这种问题——在 UI 创建集群时 Kubernetes 版本下拉框里能选的版本就那么几个,或者离线环境里 RKE 集群反复拉不到系统镜像,那大概率需要动一下rke-metadata-config这个配置了。这个配置平时不怎么露面,但一旦要自定义系统镜像、切换 Kubernetes 版本,或者想让 Rancher 按你的私有仓库来部署集群,它就是一个绕不开的关键环节。这篇文章适合负责 Rancher 日常运维的人员,也适合正在做离线部署、要把 Rancher 搬到内网环境的朋友。
我会从配置本身长什么样讲起,再完整走过一遍“查看-自定义-应用-重置”的流程,最后把我踩过的坑和排查思路一并整理出来。整个过程尽量按我实际操作的习惯来写,不绕弯子,能直接照着用的我都放在最前面。
1. 先搞明白 rke-metadata-config 到底是个什么存在
1.1 它的本质与存储位置
rke-metadata-config在 Rancher 体系里,可以被理解成“RKE 集群的出厂配置手册”。Rancher 每次创建 RKE 集群时,都需要知道系统镜像列表、核心组件参数、版本映射关系、网络插件的默认配置等等。这些信息不是写死在代码里的,而是集中放在 metadata 配置里,方便在特殊环境下替换。
从存储形态上看,它通常就是一个 ConfigMap,位于 Rancher 管理集群(也就是我们常说的 local 集群)的cattle-system命名空间下。你可以用下面这条命令快速确认它是否存在:
kubectl -n cattle-system get configmap rke-metadata-config如果 Rancher 是较新版本,或者部署方式有调整,也有可能在别的命名空间里。拿不准的时候直接全局搜一下:
kubectl get configmap -A | grep -i rke-metadata搜不到也别慌,可能你的部署是通过启动参数--metadata-config传入的外部文件,那 Rancher 就会以文件内容为准,不会单独生成 ConfigMap。后面我会说怎么判断。
1.2 它到底管着哪些关键信息
我拆开看过不少次这个配置,核心内容大致可以分成三块:
rke部分:存放 RKE 引擎使用的系统镜像列表(如 etcd、kube-apiserver、kube-controller-manager、kube-scheduler、kubelet、kube-proxy、pause、coredns、metrics-server 等),以及各个组件的默认参数。k3s部分:如果你同时也用 Rancher 管理 K3s 集群,这里的镜像和启动参数就是给 K3s 用的。rancher部分:记录 Rancher 自身版本相关的元信息,用于版本映射和升级判断。
在我们最常用的 RKE 场景里,rke-metadata-config中的镜像列表是最关键的。因为你在 Rancher UI 里选择某个 Kubernetes 版本时,后面真正拉取的镜像 tag 全部来自这份配置。如果镜像地址写的是 Docker Hub 官方地址,而你的环境根本访问不了外网,那创建集群就会卡在拉镜像那一步。
1.3 什么时候你会需要动它
我实际接触到的场景主要就这几种:
- 离线部署或内网部署:需要把所有系统镜像同步到私有仓库,同时把 metadata 里的镜像前缀全部替换成私有仓库地址。
- 定制 Kubernetes 版本:Rancher 默认只显示官方测试过的版本,但你可能实际需要某个特定小版本,或者某个打了特殊补丁的版本,那就要往 metadata 里补条目。
- 修改组件默认参数:比如想把默认的 etcd 快照间隔调大,或者想给 kubelet 加几个启动参数,直接在 metadata 里改对应的 services 配置会更省事。
- 排查版本不匹配问题:当 Rancher UI 下拉框里的版本列表和实际环境对不上,或者创建集群时报“找不到对应镜像”,大概率就是 metadata 数据太旧或内容被改乱了。
这个配置就像 Rancher 和 RKE 集群之间的一座桥。桥本身不直接干活,但桥的方向错了、宽度窄了,对岸的集群业务就会出问题。
2. 动手前必须知道的配置读取方式
2.1 通过 kubectl 查看当前配置
先看 ConfigMap 的整体内容,最稳的方式是导出成 YAML:
kubectl -n cattle-system get configmap rke-metadata-config -o yaml如果是通过--metadata-config传入文件的,也可以直接看 Rancher server 的 Deployment 启动参数:
kubectl -n cattle-system get deploy rancher -o yaml | grep metadata输出里如果有类似--metadata-config=/tmp/metadata.json的字段,那就说明这个实例用的是外部文件模式。这种情况下,你直接改 ConfigMap 是无效的,Rancher 启动时已经把文件读进内存了,改文件后必须重启 Pod 才会重新加载。
把配置内容导出来之后,建议立刻保存一份到本地留作备份。这个习惯特别重要,我后面还会反复强调,因为 metadata 里一两处小改动出错,可能影响的是整个平台创建新集群的能力。
2.2 通过 Rancher API 检查元数据状态
除了 kubectl,Rancher API 里也能看到部分元数据信息。如果你习惯用 API 做变更,可以这样获取集群信息:
curl -k -u <用户名>:<密码> https://<rancher-server>/v3/clusters在返回结果里,annotations或labels字段中往往带着cluster.rke.metadata之类的键。这个可以用来对比 ConfigMap 里的内容是否和实际集群状态一致。最终创建 RKE 集群时真正生效的数据,以 Rancher 控制器从 metadata 配置中解析出来的结果为准。
2.3 看懂配置里的几个关键字段
一眼看过去,rke-metadata-config的 JSON 内容不算短,但真正需要关注的字段并不多。以 RKE 部分的system-images为例子:
{ "rke": { "system-images": [ "rancher/hyperkube:v1.24.17-rancher1", "rancher/etcd:v3.5.6-rancher1", "rancher/rke-tools:v0.1.96", "rancher/pause:3.6", "rancher/nginx-ingress-controller:nginx-1.5.1-rancher1", "rancher/coredns-coredns:1.9.3", "rancher/metrics-server:v0.6.2", "rancher/kubelet-pause:v1.24.0" ], "services": { "etcd": { "backup_config": { "interval_hours": 12 } }, "kubelet": { "extra_args": { "max-pods": "110" } } } } }system-images是按固定顺序排列的完整镜像清单,创建集群时 RKE 会按 tag 逐个拉取。services部分则保存了各组件的默认参数,extra_args里可以塞额外的启动参数,这种方式比创建完集群后再手工改节点配置要干净得多。
3. 自定义 rke-metadata-config 的完整实操
3.1 修改系统镜像与私有仓库地址
这是我最常做的操作,尤其在内网环境。目标是把镜像源从默认的rancher/前缀改成私有仓库的前缀。
先备份:
kubectl -n cattle-system get configmap rke-metadata-config -o yaml > rke-metadata-config-backup.yaml然后编辑:
kubectl -n cattle-system edit configmap rke-metadata-config进入编辑器后,找到metadata.json里的内容,把镜像前缀整体替换。例如把:
rancher/hyperkube:v1.24.17-rancher1改成:
registry.example.local/rancher/hyperkube:v1.24.17-rancher1这里的替换要覆盖system-images里所有镜像,包括rancher/etcd、rancher/rke-tools、rancher/pause等等,一个都不能漏。漏了任何一个,创建集群时都会在对应组件初始化阶段报ImagePullBackOff。
有个省事的小技巧:如果镜像数量较多,先导出 metadata.json,用 sed 批量替换,再整体写入 ConfigMap。步骤是:
kubectl -n cattle-system get configmap rke-metadata-config -o jsonpath='{.data.metadata\.json}' > metadata.json sed -i 's#rancher/#registry.example.local/rancher/#g' metadata.json写回时如果没有metadata.json这个键,先创建临时 ConfigMap,再替换。更直接的方式是编辑 YAML,把整个 data 区域替换掉。
注意:不要把替换范围搞到非镜像字段上。比如某些镜像版本号里也含
rancher1这种字符串,不加限制地替换会把版本信息一起改掉,导致镜像不存在。我的习惯是只替换rancher/这种带斜杠的镜像前缀,而不是替换rancher单词本身。
3.2 添加或切换 Kubernetes 版本条目
某些场景下,你不需要全部自定义,只是想在版本下拉框里面多一个可选版本。这时可以在 metadata 配置中新增一个版本条目。
RKE 部分的版本信息通常在rke字段下维护,大致结构是:某个版本号对应一组系统镜像和 k8s 版本参数。你可以从官方 metadata 里复制一条已有的版本记录,再修改版本号和镜像 tag。
假设我想添加v1.24.18-rancher1,做法是:
- 在
system-images里复制一条v1.24.17-rancher1对应的镜像列表,改成v1.24.18-rancher1。 - 在
k8s_service或版本关联字段里增加新版本指向。
具体字段名可能因 Rancher 版本不同而异,我建议在 UI 里确定目标版本的镜像组合,而不是凭猜的。如果实在拿不准,先在测试环境的 Rancher 上改完,看看创建集群的版本列表是否出现新版本,再推到生产。
3.3 修改 RKE 系统镜像组件的版本参数
这类需求通常来自组件调优。比如想把 etcd 自动备份间隔改成 6 小时,可以在services.etcd.backup_config里加参数:
"etcd": { "backup_config": { "interval_hours": 6, "retention": 20 } }保存后重新触发集群升级或编辑集群配置,RKE 会读取新的参数。如果你发现参数没有被应用,优先检查是不是放错了层级。services下面应该直接是组件名(etcd、kubelet、kube-apiserver 等),组件名下面才是具体配置,层级错一位就会静默失效。
3.4 让修改生效的正确姿势
ConfigMap 修改完,Rancher 不会每次都热加载。最稳妥的生效方式有两种:
第一种,重启 Rancher Server 相关 Pod:
kubectl -n cattle-system rollout restart deployment rancher等待 Pod 重新 Running 后,进入 UI,再看版本下拉框和集群创建流程是否按预期变化。
第二种,如果是通过启动参数加载的外部文件,直接修改文件内容后重启 Rancher:
kubectl -n cattle-system delete pod -l app=rancher如果 Rancher 以多副本模式部署,一次重启一个 Pod 也够;但为了保险,建议同时观察日志,确保新配置确实被加载:
kubectl -n cattle-system logs -l app=rancher --tail=200 | grep -i metadata当日志里出现类似Using custom metadata from ...的提示,就说明加载成功了。
4. 重置 rke-metadata-config 与恢复默认设置
4.1 什么情况下需要重置
我的判断标准很简单:当配置内容已经不可控,或者被改得连 Rancher 自己的版本映射都乱了,那就别继续修补了,直接重置回默认状态,再重新定制。
常见信号包括:
- Rancher UI 里 Kubernetes 版本列表变成空的,或者只显示极少数旧版本。
- 创建集群时报错,日志里提示
failed to parse metadata config。 - 系统镜像里混入了手改坏的前缀或 tag,导致几乎所有镜像都拉取失败。
- 升级 Rancher 后,metadata 内容需要刷新到新版本,但旧的自定义内容一直残留。
4.2 手动重置的两种方式
方式一:删除现有 ConfigMap,让 Rancher 重建默认配置。
kubectl -n cattle-system delete configmap rke-metadata-config kubectl -n cattle-system rollout restart deployment rancher这种做法适合 ConfigMap 模式。Rancher 启动后检测到 ConfigMap 缺失,会用内置的默认元数据重新生成。此时再查看 ConfigMap,就会发现它回来了,内容默认且干净。
方式二:移除启动参数,恢复内置配置。
如果当初是用--metadata-config=加载外部文件的,需要把 Rancher Deployment 里的启动参数删掉,然后重启 Pod:
kubectl -n cattle-system edit deploy rancher在args里找到--metadata-config和对应的文件路径,删掉这两行,保存后等待 Pod 重建。Rancher 会用默认元数据启动,相当于完成了重置。
注意:如果集群已经用自定义 metadata 创建,重置配置本身不会自动迁移或修改这些集群的数据。重置只影响之后新建集群或后续升级操作时读取到的元数据。别指望重置配置能把已有的集群恢复出厂设置,那不在这个配置的管辖范围内。
4.3 重置后的验证与回滚
重置后不要急着创建集群,先花几分钟验证三件事:
第一,ConfigMap 已重建:
kubectl -n cattle-system get configmap rke-metadata-config第二,版本列表恢复正常:
kubectl -n cattle-system logs -l app=rancher --tail=50 | grep -i version第三,API 返回的集群版本映射没有报错。
如果重置后反而出现新的异常,通常是 Rancher 版本升级后默认 metadata 与旧配置之间出现兼容性问题。此时可以用之前备份的 YAML 恢复:
kubectl apply -f rke-metadata-config-backup.yaml kubectl -n cattle-system rollout restart deployment rancher恢复后再手动改掉有问题的字段,不要直接拿备份文件覆盖生产环境——备份文件里可能还保留着导致问题的脏数据。
5. 实战中的常见问题与排查记录
5.1 配置改了却没生效
这个情况我遇到好几次,最后发现原因几乎都集中在两点。
一是没有把修改写到正确的位置。比如system-images是给 RKE 用的,如果只改了k3s部分的镜像,RKE 集群当然不会变化。二是在修改后没有重启 Rancher Server 对应的 Pod。对于外部文件模式,这个问题尤其明显。
排查时可以这样走:先确定 Rancher 的启动方式,然后确认修改的文件或 ConfigMap 是哪个,最后查看 Rancher 日志有没有加载 metadata 的记录。用日志里出现的时间点,对比配置文件的修改时间,基本能判断是否加载成功。
5.2 集群创建时一直卡在拉镜像阶段
离线环境里特别容易遇到。创建 RKE 集群时,任务卡在pull image或imagePullBackOff,日志里的镜像地址指向外网默认仓库。
这种情况,问题几乎都出在镜像没有被全部替换。有人只改了system-images里开头两三个,后面的一整串漏掉了。RKE 引擎是严格按照镜像列表逐个拉取的,任何一个漏网之鱼都会导致集群初始化失败。
我的处理办法是:把 metadata 里的所有镜像地址列出来,写个脚本统一检查私有仓库里是否都存在:
kubectl -n cattle-system get configmap rke-metadata-config -o jsonpath='{.data.metadata\.json}' | jq -r '.rke.system-images[]'把输出的镜像名称加上私有仓库前缀,在仓库管理后台逐个查询 tag。缺哪个就同步哪个,保证列表和仓库完全对齐后再去创建集群。
5.3 误删配置导致 Rancher 行为异常
删除 ConfigMap 后,Rancher 会用默认配置重建,这个行为本身没问题。但有些环境里,删除时机不对会造成短暂的不一致。比如正在创建集群的过程中删掉 metadata 配置,正在进行的任务可能瞬间丢失元数据解析能力,创建任务直接失败。
恢复起来倒不难,重新触发集群创建或升级就行。但生产环境建议避开集群变更窗口期做这类操作。我的习惯是先备份,再在维护窗口期内操作,并把 Rancher 的所有 Pod 都重启一遍,确保控制器状态统一。
5.4 私有仓库拉取镜像认证失败
改了镜像前缀后,集群节点还需要有访问私有仓库的凭证。metadata 本身不保存这些认证信息,所以不要指望改完配置就会自动完成认证。
RKE 集群在创建时会读取节点上 Docker 已经配置好的仓库凭证。如果私有仓库需要认证,先在节点上执行:
docker login registry.example.local或者在 RKE 集群配置的private_registries里添加认证信息。这样节点拉取镜像时才能真正通过。这个配置和 metadata 是两个维度,一个管“拉什么镜像”,一个管“怎么认证”,缺任何一个都不行。
6. 一份可以直接参考的定制-重置检查清单
我每次改rke-metadata-config的时候,都会对着下面这个清单走一遍,你可以直接拿走用:
- 修改前先备份当前 ConfigMap,保存到本地文件。
- 确认当前 Rancher 是 ConfigMap 模式还是外部文件模式。
- 如果是外部文件模式,直接改文件并重启 Rancher Pod。
- 如果是 ConfigMap 模式,编辑后重启 Rancher Deployment。
- 修改镜像前缀时,用带斜杠的匹配方式,避免误改版本号。
- 同步私有仓库时,确保所有镜像 tag 都真实存在。
- 配置完成后,重启 Rancher 相关 Pod,再查看日志确认加载成功。
- 在测试环境验证版本下拉框和集群创建流程,再推向生产。
- 出现不可控问题时,用备份文件恢复,而不是手动猜着改。
- 不要在集群创建或升级过程中做 metadata 配置变更。
这套流程走完之后,我自己的体会是:rke-metadata-config不是一个需要频繁改的东西,真正麻烦的是改的时候没有完整链路意识。镜像列表、服务参数、私有仓库认证、Rancher 重启验证,这四个环节必须一起考虑,单独改哪一环都会在后续集群操作时爆雷。最后再分享一个细节:重置之后,可以先创建一个小规模的“验证集群”,确认整个 metadata 链路没问题,再继续处理大量集群创建任务。多花这十几分钟,能省掉后面很多半夜排查的时间。