资讯动态

单节点Rancher离线安装的关键一步:镜像仓库证书信任与私有Registry配置

发布时间:2026/10/20 8:11:49 来源:尧图企业网站定制
开头先讲一个场景。有次帮一哥们搭单节点Rancher环境镜像按文档同步进内网仓库了docker run也把Rancher容器拉起来了浏览器访问HTTPS页面都正常结果一创建下游Kubernetes集群节点状态就一直卡在Provisioning最后直接Failed。翻日志全是x509和超时。查了一下午问题根本不在Rancher本身而是整个离线链路里那条最容易被忽略的信任链——节点上的容器运行时根本不认内网Registry的自签证书同时Rancher也没被告知去内网仓库拉系统组件。这篇就围绕单节点Rancher离线安装这条链路重点把那个“关键一步”讲透。不管你是刚接触Kubernetes还是已经在生产环境用过Rancher只要内网环境准备离线部署这篇都能帮你少踩很多坑。1. 离线链路里的关键角色镜像仓库与信任关系1.1 单节点Rancher为什么也要单独搭一个仓库很多人以为“单节点Rancher”就是在一台机器上跑一个rancher/rancher容器装好就能用。这句话对一半。Rancher Server本身确实只是个容器但它要做的事情远不止“启动一个Web界面”。你后面要创建下游集群下游节点的kubelet、pause、coredns、ingress-controller这些镜像Rancher默认都会从docker.io等公共仓库拉取。离线环境下没有公网拉取通道就必须有一个内网镜像仓库承担“中转站”的角色。即使你只管理一个下游集群、只跑几个应用这个仓库也绕不开。它不是可选项而是离线部署的地基。而且这里有个容易误判的点很多教程会把重点放在“怎么把镜像包导进去”但实际项目里真正决定成败的往往是“节点拉镜像时信不信任这个仓库”。后面会专门讲。1.2 离线部署的三段式链路离线安装Rancher整个过程可以拆成三段第一段在一台有外网连通的环境上把Rancher相关镜像拉下来打包成tar。第二段把镜像包拷贝到内网导入到私有镜像仓库并重新打上内网仓库的tag。第三段内网节点从私有镜像仓库拉取镜像启动Rancher容器并完成Kubernetes集群初始化。三段各有关键点。第一段容易漏镜像尤其只拉了主镜像、没拉系统组件镜像第二段容易漏改tag镜像push进仓库后tag还是原来的docker.io/rancher/...拉到节点上照样找不到第三段是重灾区错误大多发生在运行时与仓库的TLS握手阶段。单节点部署看似简单但它把三个角色压缩到了一台机器上Rancher Server、内嵌K3s/containerd、还可能同时要跑下游节点。角色越多镜像来源链路越复杂任何一个环节断了表象都是一样的——集群创建失败。1.3 大多数部署“卡壳”的位置从实际经验看离线安装Rancher最容易卡住的不是镜像打包失败也不是Registry起不来而是“所有东西都看起来正常但就是拉不动镜像”。典型表现Rancher容器起来了但页面加载很慢或者部分功能报错。创建下游K3s集群时节点注册成功但Pod一直Pending。节点日志里有x509: certificate signed by unknown authority或者failed to resolve reference。这些问题背后基本都是同一个根因内网镜像仓库用的是自签HTTPS证书而各个容器运行时的CA信任链里没有这把证书。再加上Rancher的全局镜像仓库地址没有设置系统组件还在尝试去公网拉当然拉不到。所以标题里的“关键一步”用一句话概括就是让内网仓库成为Rancher唯一可信的镜像来源并让所有涉及拉镜像的组件都信任这个仓库。2. 用registry:2快速搭一个支持HTTPS的内网仓库2.1 仓库选型与命名规划实现内网镜像仓库方案很多。生产环境我会优先考虑带Web界面、带权限管理的企业级仓库比如Harbor这一类。但如果你只是单节点Rancher离线安装部署一个轻量的registry:2完全够用它不依赖外部数据库占资源少也方便排查。我建议的示例环境规划角色配置Rancher节点IP192.168.10.10域名rancher.internal镜像仓库与Rancher同机域名registry.internal端口5000操作系统Ubuntu 20.04 / CentOS 7.9均可软件Docker、k3s、registry:2这里有个细节值得说一下仓库地址建议用域名而不是IP。虽然用192.168.10.10:5000也能跑但后面证书SAN、镜像tag、节点配置都要跟着地址走。用域名统一管理迁移和排障都轻松很多。离线环境没有DNS不要紧在各节点上写/etc/hosts就行。2.2 签发自签证书并写入Registry配置registry:2要想启用HTTPS需要提供证书和私钥。这里我不用自签的单张证书而是先创建一个私有CA再给registry发一张带SAN的服务器证书。这样做的好处是后续所有节点只需要信任同一个CA换仓库域名、加新仓库时不需要在每台机器上重新信任证书。先创建证书目录mkdir -p /opt/registry/certs cd /opt/registry/certs生成CA私钥和CA证书openssl genrsa -out ca.key 2048 openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj /CNOffline Registry CA生成仓库服务器的私钥和证书签名请求openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr -subj /CNregistry.internal用CA给服务器证书签名加上SAN字段这样IP访问和域名访问都能通过证书校验printf subjectAltNameDNS:registry.internal,IP:192.168.10.10\n san.conf openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ -out server.crt -days 1825 -extfile san.conf然后写registry配置文件。registry:2默认读取容器内的/etc/docker/registry/config.yml我们把TLS证书路径和存储路径都配置好version: 0.1 storage: filesystem: rootdirectory: /var/lib/registry http: addr: :5000 tls: certfile: /certs/server.crt keyfile: /certs/server.key启动registry容器docker run -d --name registry --restartalways \ -p 5000:5000 \ -v /opt/registry/config.yml:/etc/docker/registry/config.yml \ -v /opt/registry/certs:/certs \ -v /opt/registry/data:/var/lib/registry \ registry:2.8.3到这里一个支持HTTPS的私有镜像仓库就起来了。如果你的仓库需要账号密码还可以用htpasswd生成认证文件在config.yml里加一段auth配置。不过为了控制篇幅示例先不开启认证后面会单独提醒认证对信任链的影响。2.3 启动Registry并完成推送自测仓库起来后先用curl验证HTTPS是否正常。在仓库本机执行curl --cacert /opt/registry/certs/ca.crt https://registry.internal:5000/v2/返回{}就说明HTTPS接口正常。这里注意如果不加--cacertcurl大概率会报证书错误这是正常的说明自签证书已经在工作。接着做一次真实的推拉测试。从我自己的经验看这一步建议认真做比后面反复排查节省时间。# 拉一个测试镜像 docker pull alpine:3.19 # 打上内网仓库tag docker tag alpine:3.19 registry.internal:5000/test/alpine:3.19 # 推送 docker push registry.internal:5000/test/alpine:3.19 # 清理本地tag验证能从仓库拉回 docker rmi registry.internal:5000/test/alpine:3.19 docker pull registry.internal:5000/test/alpine:3.19如果push和pull都成功说明仓库本身没问题可以进入下一阶段。3. 关键一步让每一层容器运行时都信任内网仓库3.1 信任链断在哪镜像已入库节点仍拒连这是整篇文章最想让你记住的部分。很多部署失败不是说镜像没进去而是“镜像进去了但节点不敢连”。打个比方内网仓库是一个需要验身份证的门口保安你把行李镜像搬进了仓库不代表每个搬运工节点都认识保安。所有来拉镜像的客户端都要在TLS握手阶段先核验仓库的证书。仓库的证书是私有CA签发的客户端没有这把CA连接就会在握手中被拒。具体到Rancher环境里至少有三个“客户端”要认识这把CA宿主机上的Docker守护进程节点上的K3s/containerd运行时Rancher容器内部的内嵌K3s/containerd只配其中一两个都会留下死角。3.2 宿主机Docker/runtime的信任配置如果Rancher节点用的是Docker来管理容器信任配置很简单。在宿主机上创建Docker单仓库证书目录把CA文件放进去sudo mkdir -p /etc/docker/certs.d/registry.internal:5000 sudo cp /opt/registry/certs/ca.crt /etc/docker/certs.d/registry.internal:5000/ca.crt sudo systemctl restart docker这个目录名必须带端口号因为registry监听的是5000不是默认的443。Docker守护进程在连接registry.internal:5000时会优先从这个目录读取ca.crt作为信任锚点。验证方式sudo docker login registry.internal:5000 sudo docker pull registry.internal:5000/test/alpine:3.19如果之前本地已经有同名镜像tagpull不会真正走仓库可能“假成功”。建议先docker rmi删掉本地tag再pull。如果节点上运行的是K3s或RKE2Docker的配置不生效因为K3s自带containerd。这时候要写registries.yamlsudo mkdir -p /etc/rancher/k3s sudo tee /etc/rancher/k3s/registries.yaml /dev/null EOF mirrors: registry.internal:5000: endpoint: - https://registry.internal:5000 configs: registry.internal:5000: tls: ca_file: /opt/registry/certs/ca.crt EOF然后重启K3s服务sudo systemctl restart k3s如果是RKE2节点路径换成/etc/rancher/rke2/registries.yaml重启服务名改成rke2-server或rke2-agent。3.3 Rancher容器内部也需要信任CA这一条容易漏。很多人把宿主机Docker和K3s的信任都配好了结果Rancher容器自己初始化时仍然拉不到系统组件镜像日志报x509。原因很简单Rancher Server容器内部也跑了一套K3s/containerd它自己在初始化cattle-system时也要去访问内网仓库。容器内部的系统CA链和宿主机是隔离的宿主机信任不代表容器内信任。解决思路是把CA文件挂载进容器并让容器更新CA证书列表。启动Rancher容器时先挂载CA文件docker run -d --name rancher-server --restartunless-stopped --privileged \ -p 80:80 -p 443:443 \ -v /opt/registry/certs/ca.crt:/usr/local/share/ca-certificates/offline-ca.crt \ rancher/rancher:v2.7.9容器起来后执行一次CA证书更新再重启Ranchersudo docker exec rancher-server update-ca-certificates sudo docker restart rancher-server这一步看起来不起眼但如果你跳过后面大概率会在“系统组件镜像拉取”这个环节卡很久。Rancher容器内部的子系统仓库信任和外部节点的仓库信任是两个不同的信任域都要配。3.4 常见错配现象与定位方法信任链配错的表现各不相同这里列一份错误信息对照表方便你排查时直接对照报错关键词问题方向x509: certificate signed by unknown authority某层运行时没有信任私有CAserver gave HTTP response to HTTPS client节点用HTTPS访问但仓库监听的是HTTPconnection refused仓库服务没起来或防火墙没放行端口manifest unknown镜像没有推全或tag前缀写错401 Unauthorized仓库启用了认证但运行时没有登录凭证有一个快速定位思路从“离仓库最近”的客户端开始验。先在仓库本机用curl验HTTPS再用Docker从本机pull一次再切到Rancher节点上用节点运行时pull一次最后才看Rancher容器内部。按这个顺序排查能快速把范围缩小到某一层。4. 启动Rancher时指定SystemDefaultRegistry4.1 docker run参数逐项拆解把信任链配好之后再启动Rancher命令就比之前完整得多docker run -d --name rancher-server --restartunless-stopped --privileged \ -p 80:80 -p 443:443 \ -e CATTLE_SYSTEM_DEFAULT_REGISTRYregistry.internal:5000 \ -v /opt/registry/certs/ca.crt:/usr/local/share/ca-certificates/offline-ca.crt \ -v /opt/rancher:/var/lib/rancher \ rancher/rancher:v2.7.9逐个参数说清楚-p 80:80 -p 443:443Rancher Web界面的HTTP/HTTPS入口。--privilegedRancher容器需要修改iptables、挂载文件系统等特权模式是官方标准做法。-e CATTLE_SYSTEM_DEFAULT_REGISTRYregistry.internal:5000这是“告诉Rancher去哪里拉系统镜像”的核心参数。-v /opt/registry/certs/ca.crt:/usr/local/share/ca-certificates/offline-ca.crt把CA文件放进容器内供容器内部运行时信任。-v /opt/rancher:/var/lib/rancherRancher的数据持久化目录容器升级后数据不丢。容器起来后记得执行一次sudo docker exec rancher-server update-ca-certificates sudo docker restart rancher-server4.2 CATTLE_SYSTEM_DEFAULT_REGISTRY的作用边界这个环境变量的含义很多人理解得不够透。它指定的是Rancher系统组件的镜像仓库前缀也就是Rancher自身要部署的cattle-system、监控、认证、UI组件等镜像不再从默认公网仓库拉而是统一从你填的地址拉。但它不负责业务应用的镜像。你在业务命名空间里手动创建Deployment时镜像地址该写什么还是写什么。比如你部署一个业务服务镜像得已经推到了内网仓库并且运行时能信任这个仓库业务Pod才能正常拉起。还有一个容易踩的点如果你启动时忘了设置这个环境变量也不要慌可以到Rancher UI的Settings里找到system-default-registry把它改成内网仓库地址。但注意改完之后已经部署过的组件不会自动更新镜像源有些组件要重启甚至重建才会生效。所以更推荐在第一次启动时就把环境变量带上后面省事。4.3 下游集群的私有仓库设置与节点注册Rancher Server起来了下游集群的配置也有对应设置。创建K3s或RKE2集群时集群的高级选项里通常有一个类似“Private Repository”或“Registry”的字段填registry.internal:5000。填完后Rancher生成的节点注册命令会自动带上--system-default-registry registry.internal:5000参数。节点注册命令长这样示意一下curl -fL https://192.168.10.10/system-agent-install.sh | sudo sh -s - --server \ https://192.168.10.10 --token xxxxx --ca-checksum xxxxxxxxxx \ --etcd --controlplane --worker --system-default-registry registry.internal:5000注意这里的--system-default-registry是给下游节点用的它只能保证“下游k3s组件从内网仓库拉”并不能替代节点本身的信任配置。节点上如果没有写registries.yaml注册后照样会因为证书问题拉不到pause镜像。所以顺序应该是先给所有节点配好信任链再在Rancher里创建集群并注册节点。5. 一份可复现的验证清单与踩坑复盘5.1 部署完成后的快速自检把下面这张表当成部署后的体检清单每一项都过一遍再开始创建业务集群。验证点命令/操作期望结果仓库HTTPScurl --cacert /opt/registry/certs/ca.crt https://registry.internal:5000/v2/返回{}Docker信任先删本地tag再docker pull registry.internal:5000/test/alpine:3.19拉取成功hosts解析getent hosts registry.internal输出仓库IPRancher容器CAdocker exec rancher-server update-ca-certificates无报错Rancher容器运行docker logs rancher-server --tail 50无x509/unauthorized报错UI登录浏览器访问https://192.168.10.10能设置管理员密码并登录下游集群Pod创建集群后kubectl get pods -A所有Pod处于Running镜像来源查看一个Pod的yamlkubectl get pod -n cattle-system -o yamlImage前缀包含registry.internal:5000这张表看着简单但每次部署时我基本都会跑一遍。离线的坑就是这样前期省一步后面可能要多花一小时排查。5.2 两个我实际遇到的典型故障第一个故障证书信任断裂节点注册后马上Failed。现象是节点K3s日志里持续滚动x509: certificate signed by unknown authority。当时宿主机Docker的信任已经配好但忽略了下游节点走的是K3s内嵌containerd它读的是registries.yaml而不是Docker配置。把CA路径写进/etc/rancher/k3s/registries.yaml并重启K3s后问题立即消失。第二个故障Rancher Server起来了但创建集群时一直等镜像。排查发现集群模板里没有设置私有仓库节点注册命令没有带--system-default-registry于是节点还在尝试从公网仓库拉pause镜像。补上集群级别的Registry配置重新生成带参数的注册命令问题解决。这两个故障说明一件事离线部署里“成功”和“真正走通了”之间有好几层落差。镜像load成功不代表能从仓库拉页面能打开不代表所有组件都在从这个仓库拉。每一层都要单独验证。5.3 后续升级与维护时要留意的细节离线环境是一次性的但之后升级维护会反复遇到同类问题。有几个细节建议提前做第一所有节点上把CA文件放到统一路径比如/opt/certs/offline-ca.crt这样以后批量脚本管理方便。不要各自的路径都不一样排障时非常痛苦。第二Rancher升级新版本前必须先把新版本的镜像清单同步到内网仓库再升级Server。不要在镜像不足的情况下直接拉新版本否则升级过程中会卡在镜像拉取。第三自签CA有有效期建议在日历里设置过期提醒。CA过期后所有节点都要重新信任影响面比想象中大。第四离线环境的NTP时钟同步别忽略证书校验强依赖系统时间。有一台节点时钟偏差大就可能出现“证书未生效”或“证书过期”的怪错。最后说点实在的如果让我总结单节点Rancher离线安装最核心的经验就两句话先把内网仓库跑起来并配合好证书然后让Rancher和所有下游节点都明确用这个仓库。信任链对了镜像地址对了剩下的都是一步步走流程。最后分享一个我自己的小习惯每次部署我会把证书生成命令、镜像清单、Rancher启动命令、节点注册命令四样东西单独存一个目录留档。下次遇到相似环境直接照着自检清单过一遍比重新翻文档省太多时间。这种离线环境的坑记录一次受益很久。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑