简介:面向需要在离线或内网环境快速部署Rancher v2.4.5的Kubernetes运维与开发人员,该镜像包将Rancher Server/Agent及其依赖的Flannel网络插件、Prometheus节点监控组件、kube-proxy等常见镜像统一导出,能够有效解决内网环境从外网拉取镜像困难、镜像版本匹配烦琐的痛点。压缩包采用zip格式打包,共7个文件,包含5个tar格式的镜像导出包、1个flannel.yaml网络编排文件以及1个ReadMe说明文档,整体约178.1MB,文件类型与用途清晰,便于按需核对和加载。目前已有289人学习下载,适合正处于K8s平台搭建、Rancher环境初始化阶段的技术人员。镜像包具体涵盖rancher-agent v2.4.5、mirrored-flannelcni-flannel v0.16.1及对应cni-plugin、kube-proxy v1.17.0、prom-node-exporter v0.18.1等组件,使用docker load即可一次性导入所有镜像;配合自带的flannel.yaml可直接复用网络编排配置,显著减少手动拉取与配置时间,尤其适合镜像仓库受限或离线交付的场景,帮助使用者快速拉起Rancher管理面,并降低组件版本不一致带来的排错成本。无论是生产环境初始化还是测试环境搭建,都能获得稳定的镜像来源。
1. 离线环境下部署Rancher V2.4.5,真正要准备的不是那一个镜像
k8s平台上,Rancher V2.4.5的docker镜像包,解决的核心问题是离线、内网环境里怎么把一套可视化的集群管理平台完整搬进去。做交付时经常只拿到一个rancher/rancher:v2.4.5镜像,以为这就是镜像包的全部,结果docker run之后local集群一直起不来,页面虽然打开了,下面却没有任何可管理的k8s集群。真正要准备的是一整套镜像清单:Rancher主镜像、rancher-agent、以及一堆被重命名过的k8s组件镜像。这篇文章按一线交付的常见做法,把镜像清单怎么生成、镜像包怎么打包搬运、目标机怎么导入启动、以及最常翻车的五个地方一次讲清楚,适合正在做k8s平台离线部署的运维和交付工程师参考。
2. 从rancher-images.txt生成镜像清单:先搞清楚V2.4.5到底依赖哪些镜像
2.1 清单里为什么会有几十个镜像:Rancher把整套k8s组件都管起来了
Rancher不是被部署进一个现成的k8s集群就算完,它第一次启动时会自己初始化一个local集群,再通过这个local集群对外提供集群管理能力。也就是说,V2.4.5的容器起来了,只代表Rancher的UI进程活了;如果你打开页面发现local集群一直初始化,或者cattle-system、kube-system里的pod集体Pending,那基本可以断定是组件镜像没有进目标机。k8s和docker在这个场景里的分工也很直白:docker负责把Rancher管理平台容器跑起来,而k8s组件镜像负责把集群里的节点、namespace、pod这些抽象变成真实可用的资源。
Rancher为了做离线交付,把依赖的上游镜像都重新打到了自己的仓库前缀下,镜像名看起来是rancher/mirrored-*、rancher/pause、rancher/rancher-agent这几种。release资源里会放一个rancher-images.txt,把V2.4.5可能用到的镜像逐行列出来,这个文件就是做镜像包的源头。第一次做的人容易漏掉这一步:手动从Docker Hub拉几个看起来相关的镜像就开始部署,最后要么local集群起不来,要么导入外部集群时agent镜像拉不到。
下面的表是镜像清单里最常见的几组,部署前建议先对着这个分组核对一遍。
| 镜像分组 | 典型命名 | 主要作用 | 缺失时的表现 |
|---|---|---|---|
| 主镜像 | rancher/rancher:v2.4.5 | Rancher平台本体,UI和API入口 | 容器无法启动或功能不完整 |
| agent镜像 | rancher/rancher-agent | 被管集群节点上的注册组件 | 导入集群后节点反复重试 |
| k8s组件镜像 | rancher/mirrored-* | etcd、coredns、flannel等核心组件 | local集群初始化失败 |
| 辅助镜像 | rancher/pause | 每个pod的沙箱容器 | pod一直ContainerCreating |
2.2 在Linux上拉取并规整清单:tag里的sha256后缀有什么讲究
获取rancher-images.txt的常见路径是release页面的Assets,文件名一般就叫这个。下载之后不要急着开拉,先做三件事:确认文件不空、确认主镜像在清单里、确认每行格式统一。
# 下载release资源里的rancher-images.txt,下载地址按实际Assets替换 wget -O rancher-images.txt <你的下载地址> # 行数太少说明文件可能没下载完整 wc -l rancher-images.txt # 主镜像肯定要在清单里,返回1才正常 grep -c "rancher/rancher:v2.4.5" rancher-images.txt # 看前几行,注意tag格式 head -5 rancher-images.txt上面命令里,wc -l 是排查下载残缺最直接的手段,V2.4.5的清单通常是几百行的量级,如果只有几十行,先怀疑下载而不是怀疑Rancher。grep -c 是确认目标版本的主镜像确实在清单里,避免后面拉取时才发现用的清单跟Rancher版本不匹配。head 则是用来观察tag格式,V2.4.x的镜像tag往往带sha256后缀,越早看清楚越不容易在save/load时吃亏。
tag里带sha256后缀这件事,很多新手会忽略。它保证了多节点拉取到的镜像内容完全一致,防止Docker Hub上相同tag内容被覆盖后集群节点间版本漂移。离线环境的代价是tag变长、导出导入时容易丢tag,这个坑留到第5章详细说。
拉下来之后,建议先对清单做一次规整,去掉空行、注释,排序去重。
# 去掉注释和空行,排序去重,生成干净的输入文件 grep -v '^#' rancher-images.txt | grep -v '^$' | sort -u > images.txt # 看一眼实际需要的镜像种类 wc -l images.txt这里为什么要去重:同一组件镜像可能在多个k8s小版本里重复出现,不去重的话,后面批量pull、tag、push都会做无效劳动。sort -u 之后的行数才是你真正要打包的镜像种类。注意这一步不要顺手把k8s版本相关的镜像过滤掉,第一次做离线包建议全量拉,一次十几GB量级,比裁剪后现场缺镜像再补包可控得多。
3. 把镜像包做出来:Harbor中转和save/load两种搬运方式怎么选
3.1 批量拉取时docker镜像下载慢怎么破:重试脚本与按需裁剪
镜像清单规整好之后,下一步是在一台能访问外网的机器上把镜像全部拉下来。这里最磨人的就是docker镜像下载慢。几十个镜像逐个拉,中间任何一个网络抖动都可能让整个流程中断,所以不要手动一条条docker pull,写一个带重试的循环脚本,让它自己跑。
# images.txt 是上一章规整好的清单 while IFS= read -r image; do [ -z "$image" ] && continue echo "==> docker pull $image" n=1 until docker pull "$image"; do echo "第 $n 次重试失败: $image" n=$((n + 1)) if [ $n -gt 5 ]; then echo "$image" >> pull_failed.txt break fi sleep 5 done done < images.txt # 全部跑完后,再单独补拉失败列表里的镜像 while IFS= read -r image; do docker pull "$image" done < pull_failed.txt这个脚本用until循环而不是for循环,关键是让它在单次网络抖动时自动重试而不是直接中断。重试次数限制在5次,超过就写进pull_failed.txt,脚本执行完统一核对失败列表,比盯着终端看效率高很多。sleep 5是给Docker daemon一点喘息时间,避免连续失败时把registry侧触发限流。
拉取前还有一个常见的优化手段:在/etc/docker/daemon.json里配置registry-mirrors。这是针对Docker Hub镜像下载慢最直接的解法,但它的作用范围有限,只能加速走Docker Hub的镜像,而且加速器本身也看网络质量。
{ "registry-mirrors": ["https://docker.mirrors.example.com"] }# 修改后重启docker daemon sudo systemctl restart docker配置完镜像加速器后再跑批量脚本。如果你在机房做离线交付,我一般会建议把打包机放在外网带宽质量好的网络环境里,让脚本通宵跑,第二天早上只看pull_failed.txt就行。下载慢是外网打包阶段最大的时间开销,值得专门安排机器和时间。
3.2 走内网Harbor:打tag、push和docker客户端insecure-registries配置
镜像拉齐之后,常见的搬运方式有两种。第一种是推送到内网Harbor,这是后续要长期管理多个节点、需要扩容时最推荐的方式,因为k8s节点在创建或加入集群时随时可能拉镜像,只靠一次load进去的离线镜像包只能管住当前这台机器。
假设你在Ubuntu上已经有一个内网Harbor,先建一个名为rancher的项目,然后把所有清单镜像重新打tag推到里面。
# 把镜像推送到内网Harbor,PROJECT按实际地址替换 PROJECT="reg.infra.local/rancher" while IFS= read -r image; do [ -z "$image" ] && continue # 去掉rancher/前缀,避免出现 reg/rancher/rancher/xxx 这种多余层级 short="${image#rancher/}" docker pull "$image" docker tag "$image" "$PROJECT/$short" docker push "$PROJECT/$short" done < images.txt这个循环里最关键的是short="${image#rancher/}" 这行。如果不截掉前缀,镜像名会变成reg.infra.local/rancher/rancher/rancher:v2.4.5,结构又长又容易在后续配置里出错。截掉后是reg.infra.local/rancher/rancher:v2.4.5,看起来清爽,Harbor里按项目拉取也方便。
内网Harbor通常会遇到一个前置问题:只开了HTTP,而docker客户端默认强制走HTTPS。不改配置直接push会报“http: server gave HTTP response to HTTPS client”,这个报错不是Harbor坏了,是客户端不信任HTTP仓库。
# Ubuntu/CentOS都在 /etc/docker/daemon.json 里加insecure-registries sudo tee /etc/docker/daemon.json <<'EOF' { "insecure-registries": ["reg.infra.local"] } EOF sudo systemctl restart docker注意这里如果Harbor监听的不是80或443,insecure-registries里要写全地址带端口,比如reg.infra.local:8443。配置完后先docker login验证一下,再跑批量推送脚本。Harbor这个方案一旦打通,后续Rancher创建集群时只需在启动参数里指定系统默认仓库,所有节点组件都会自动从内网Harbor拉取,省去逐台机器load的体力活。
3.3 没有Harbor时的裸搬运:save、split和rsync的配合
如果内网环境连Harbor都没有,或者只是单机临时验证,那只能用docker save导出、docker load导入的裸搬运方式。
# 把images.txt里所有镜像合并导出成一个tar包 docker save -o rancher-v2.4.5.tar $(cat images.txt) # 查看tar包体积 du -sh rancher-v2.4.5.tar # 文件太大时分卷,方便用移动介质或小批量传输 split -b 8G rancher-v2.4.5.tar rancher-v2.4.5.part. # 到达目标机器后合并 cat rancher-v2.4.5.part.* > rancher-v2.4.5.tar # 导入 docker load -i rancher-v2.4.5.tarsave之前先确认本机所有镜像tag都在,这一步极其重要,否则导出tar里会有镜像ID但没有tag,导入后会出现大量 镜像。split分卷的大小按你的传输方式定,走rsync可以不分卷,走移动硬盘建议分8G或16G一块。load的时候目标机磁盘要有足够空间,tar文件本身和展开后的镜像层都要占用磁盘空间,建议留出tar体积两倍以上的空闲。
裸搬运和Harbor方案怎么取舍,我总结成一句话:单机试验、节点少、没精力维护仓库服务,用save/load;要长期管理多台k8s节点、后续还要扩容加节点,就直接上Harbor,后面省的人工成本会远超搭Harbor投入的时间。
4. 目标机器导入镜像并启动Rancher:docker run参数与集群初始化
4.1 导入前的磁盘与docker权限检查:permission denied这个报错怎么处理
镜像tar到了目标机器,先别急着load。第一步看磁盘,第二步确认docker权限,这两个地方出问题比镜像本身更难排查。
# 确认docker根目录所在分区 docker info | grep "Docker Root Dir" # 查看该分区剩余空间 df -h /var/lib/docker # 开始导入,tar文件大时可能需要几分钟到几十分钟 docker load -i rancher-v2.4.5.tar # 检查主镜像是否导入成功 docker images | grep "rancher/rancher.*v2.4.5"Docker Root Dir返回的路径如果是/var/lib/docker,那df -h看的就是这个分区的剩余空间。load大tar时,磁盘空间消耗等于tar体积加展开后的镜像层体积,别只看tar文件本身大小。导入完成后grep主镜像tag是最快的验证方式,如果grep不到,再回头检查tar是否完整。
load时最常见的报错是“permission denied while trying to connect to the docker api”。这个报错的原因通常是当前用户不在docker用户组里,或者系统刚装完docker,当前shell会话还没有拿到socket权限。
# 把当前用户加入docker组 sudo usermod -aG docker $USER # 让当前会话立即生效,不用重新登录 newgrp docker # 验证能否直接执行docker命令 docker version这里有个细节要说明:newgrp docker只在当前终端会话生效,如果你开了新的SSH窗口,还是要重新登录一次。如果你发现sudo docker能用,普通用户docker直接报permission denied,那基本就是这个问题,加完组立刻就能解决。
4.2 用docker run拉起rancher/rancher:v2.4.5:端口、数据目录、系统默认仓库
镜像导入完成后,启动Rancher的命令是标准的docker run,但有几个参数必须一次配对,尤其是数据目录和重启策略,漏掉任何一个后面都会很被动。
docker run -d --name rancher-server \ --restart=unless-stopped \ -p 80:80 -p 443:443 \ -v /opt/rancher:/var/lib/rancher \ -e CATTLE_SYSTEM_DEFAULT_REGISTRY=reg.infra.local/rancher \ rancher/rancher:v2.4.5 --no-cacerts参数说明:
| 参数 | 作用 | 漏配的后果 |
|---|---|---|
| --restart=unless-stopped | 机器重启后自动拉起Rancher | 重启后容器不会自己恢复 |
| -p 80:80 -p 443:443 | Rancher UI和API入口 | 页面无法访问,agent连接也走443 |
| -v /opt/rancher:/var/lib/rancher | 持久化所有集群和数据状态 | 容器一删,集群配置全丢 |
| CATTLE_SYSTEM_DEFAULT_REGISTRY | 后续创建集群时统一定向内网Harbor | 节点组件镜像去外网拉取,离线直接失败 |
| --no-cacerts | 走外部已有证书体系,避免自签CA证书冲突 | 多集群导入时agent证书校验出问题 |
端口之所以强调留在80和443,是因为Rancher默认会按这个端口生成访问地址和证书校验逻辑,第一次做就不要加戏改端口,等整套跑通后再考虑用负载均衡承接。数据目录/opt/rancher是我个人的习惯位置,你可以换成任何有空间的路径,最关键的是必须挂到容器里的/var/lib/rancher。CATTLE_SYSTEM_DEFAULT_REGISTRY的值就是你前面Harbor项目路径,末尾不要加斜杠。如果用的是save/load裸搬运方案,这个环境变量可以不写,不影响单机启动。
启动前顺手确认一下80和443没被占用。
ss -lntp | grep -E ':80|:443'如果有其他进程占了端口,先停掉或换个端口部署,否则docker run会直接报端口绑定失败。
4.3 local集群Active前的等待:先确认pause、coredns这些组件镜像都在
容器起来后,Rancher要初始化数据库、生成证书、创建local集群,这个过程需要几分钟到十几分钟。不要频繁重启容器,它内部有重试和状态迁移逻辑,反复docker restart反而可能打断初始化。
观察进度最直接的方法是看容器日志和local集群状态。
# 实时看Rancher启动日志 docker logs -f rancher-server # 容器起来后,在容器里看节点状态 docker exec -it rancher-server kubectl get nodes # 看所有namespace下的pod状态 docker exec -it rancher-server kubectl get pods -A正常情况最终会看到一个Ready的节点,以及cattle-system、kube-system里的pod全部Running。如果看到kube-system下pause或coredns相关pod一直Pending或ImagePullBackOff,基本可以断定是组件镜像没导全。用describe看事件里的镜像名,再去目标机上检查docker images是否有对应tag。
# 查看具体pod的详细事件,Events区域会有拉取失败原因 docker exec -it rancher-server kubectl describe pod -n kube-system <pod名> | tail -30这个阶段最重要的一点是:不要把时间花在反复重启Rancher容器上,先看缺什么镜像、补什么镜像。local集群的初始化逻辑会等镜像可用后自动继续,镜像补齐后重启一次rancher-server即可。
5. Rancher V2.4.5离线部署避坑:五个高频翻车点与排查顺序
5.1 现象:local集群一直Unavailable,节点NotReady
这是离线部署Rancher时出现频率最高的问题。现象是Rancher主容器起来了,UI也能打开,但首页的local集群一直是Unavailable状态,节点NotReady,cattle-system和kube-system下面的pod大量Pending或ImagePullBackOff。
原因通常不是Rancher配置错了,而是镜像包本身就是残缺的。打包时只导入了rancher/rancher主镜像,rancher-images.txt里其他辅助镜像一个都没带,导致kubelet想创建Sandbox容器时找不到pause镜像,coredns、flannel这些组件更是无从拉起。
解决方法是回目标机上核对镜像数量。
# 看本地镜像总数,和打包机/清单数量对比 docker images | wc -l # 用清单文件逐行检查哪些镜像不在 while IFS= read -r image; do docker image inspect "$image" >/dev/null 2>&1 || echo "缺失: $image" done < images.txt补完镜像后docker restart rancher-server,它会继续之前的初始化流程。这里不要删除容器重建,local集群的etcd状态还指望容器内的数据卷,重启比重建安全。
5.2 现象:load成功之后tag全是 ,docker run还是去外网拉镜像
有些现场打包机导出的tar没有丢镜像层,但导入后docker images里出现一堆 ,docker run指定的tag完全找不到,导致容器尝试去外网拉镜像。离线环境下外网不可达,最终报“manifest unknown”或“repository does not exist”。
原因出在save之前的本地镜像tag不完整。Docker save是按repo:tag导出内容的,如果打包机上某些镜像是通过sha256 digest方式被拉下来的,或者本地只有镜像ID没有tag,导出的tar里自然也没有可用的tag。
这个问题最可靠的解决路径不是在目标机上现场补tag,而是回打包机把所有镜像重新规整后再导一次。规整的核心是逐行检查每个清单镜像是否有本地tag。
# 打包机上执行,确认每个镜像都能被inspect到 while IFS= read -r image; do docker image inspect "$image" >/dev/null 2>&1 || echo "missing: $image" done < images.txt如果有missing输出,就重新docker pull那个镜像,pull成功后再跑一遍,直到全部通过,然后再执行save。目标机上如果已经导入了一堆 ,不要指望手动打tag能逐个救回来,重新导一份干净的tar比现场修可靠得多。
5.3 现象:导入外部k8s集群时cattle-system反复重启
在另一台k8s节点上执行Rancher生成的agent配置后,cattle-system命名空间下的cattle-cluster-agent或cattle-node-agent反复CrashLoopBackOff,日志里要么是“x509: certificate signed by unknown authority”,要么是“Failed to connect to the Rancher Server”。
原因通常有两个。一是Server URL配置成了Rancher所在机器的hostname,外部节点解析不了这个内部主机名,agent自然连不上。二是离线环境下agent镜像不在本地,也没有配置内网系统默认仓库,agent pod拉取镜像失败。
排查先看agent日志里的实际URL和报错。
kubectl get pod -n cattle-system kubectl logs -n cattle-system <agent-pod名> --tail=50确认Server URL能通过IP解析和访问后,再从两个方向解决。镜像方面,确保引入外部集群的机器上已经load过rancher-agent镜像,或Rancher启动时配置了CATTLE_SYSTEM_DEFAULT_REGISTRY,让agent自动从内网Harbor拉取。证书方面,自签场景下检查Rancher部署时是否带了--no-cacerts参数,证书冲突时在启动命令尾部加上这个参数重新部署,能少掉一大半证书校验问题。
5.4 现象:服务器重启后Rancher没起来,数据像丢了
这个翻车点最阴险。现象是机器重启后docker ps里看不到rancher-server容器,手动用同样的docker run命令再启动,UI里集群数据变成空白,像是要从头初始化。
原因一般是两个参数没同时配上:--restart=unless-stopped没写,Docker不会在机器重启后自动拉起容器;更严重的是-v数据卷没挂,所有集群状态、local集群的etcd数据都写在容器可写层里,容器一旦被清理,数据就没有了。
解决起来要分情况:如果容器还在,只是没自动启动,docker start rancher-server就能恢复;如果容器已经删了但宿主目录/opt/rancher还在,用原先的docker run命令重新启动,数据会重新挂载回来;如果连宿主目录都没有,数据基本无法找回,只能重新初始化。
# 检查数据目录是否还完整 ls -l /opt/rancher # 数据还在就直接重新创建容器 docker run -d --name rancher-server \ --restart=unless-stopped \ -p 80:80 -p 443:443 \ -v /opt/rancher:/var/lib/rancher \ rancher/rancher:v2.4.5另外如果部署在CentOS7上且SELinux处于enforcing状态,挂载宿主目录给容器写有时候会报Permission denied,可以先执行chcon -Rt container_file_t /opt/rancher再启动容器,这是SELinux标签问题,不是目录权限问题。
5.5 现象:k8s集群起来了,但跨节点pod网络不通
还有一种场景是local集群已经Active,但pod之间跨节点访问超时,防火墙规则看起来没问题,实际上flannel或calico的pod一直在CrashLoop。
原因还是镜像不完整。离线环境下flannel相关镜像没导入,CNI根本没能建立起来,网络自然不通。另外MTU不匹配也会表现出类似症状,物理网卡MTU与CNI默认MTU不一致时,跨节点流量会在封装层被静默丢弃。
先看kube-system里的网络组件状态。
docker exec -it rancher-server kubectl get pod -n kube-system -o wide如果是镜像缺失,参照第5.1节的方式补全flannel相关镜像并重启节点上kubelet。如果是MTU问题,把CNI的MTU参数调整成与物理网卡一致,同时确认每台节点上bridge-nf-call-iptables没有被关掉。
# 临时打开bridge流量经过iptables sysctl -w net.bridge.bridge-nf-call-iptables=1 # 写入sysctl.conf,重启后不丢 echo "net.bridge.bridge-nf-call-iptables=1" >> /etc/sysctl.confdocker网络不通这个问题的排查原则是:先镜像、后MTU、再内核参数。镜像缺失是最多见的离线部署原因,前面两步确认完再改内核参数,不要一上来就调网络策略。
6. 部署完怎么验证一套镜像包是否真的可用:清单比对与升级前的备份判断
镜像包交付出去的最后一关,我习惯用清单比对脚本做完整校验,而不是只看到UI能打开就算完。
# 期望清单,来自镜像包制作阶段 sort images.txt > expected.txt # 目标机上的实际镜像 docker images --format '{{.Repository}}:{{.Tag}}' | grep -v '<none>' | sort > actual.txt # 输出在expected中存在但实际缺失的镜像 comm -23 expected.txt actual.txtcomm命令只输出第一列独有的行,也就是缺失的镜像。如果这个命令返回为空,说明目标机上的镜像与清单完全一致,可以放心进行下一步。如果返回非空,按缺失镜像逐个补齐,再跑一次校验。这个脚本我建议固化到交付文档里,每台目标机器交付前都要执行一遍。
校验通过后,UI访问、local集群Active、导入集群注册,这三个验证点过一遍,部署才算真正闭环。再提醒一句关于升级的判断:V2.4.5这个版本已经很老了,后续升级到2.5、2.6的路径变化很大,离线环境升级前一定要先在测试环境跑通新版本的完整镜像包,不要在客户现场赌小版本升级顺利。升级前把/opt/rancher整个目录打包备份,这是唯一的后悔药。
我在交付现场吃过的最大一次亏,就是图省事只导了主镜像就跑客户现场,结果local集群一晚上没起来,最后老老实实从头补全镜像包。从那以后的习惯是:离线交付前一定要完整跑一遍清单校验,所有Rancher容器必须带重启策略和数据卷挂载,绝不省略。这个流程看起来多花十分钟,实际省掉的是不知道什么时候会来的事故排查时间。希望帮到你。
本文还有配套的精品资源,点击获取