K8s离线安装flannel镜像包全攻略:从打包到导入

发布时间:2026/10/13 4:59:59

K8s离线安装flannel镜像包全攻略:从打包到导入 简介这份资源面向正在搭建 Kubernetes 集群、需要为节点配置网络插件的运维与开发人员重点解决 flannel 镜像拉取困难、离线环境部署不便的问题。压缩包共 3 个文件以 2 个 tar 镜像包和 1 个 yaml 清单为主整体约 27.34MB其中 tar 文件用于导入 flannel 与 flannel-cni-plugin 两个核心组件镜像yaml 文件则提供配套的部署清单方便直接应用到集群。资源涵盖 flannel-cni-plugin:v1.1.2 与 flannel:v0.21.5 两个版本可满足常见 k8s 网络插件安装场景。目前已有 1613 人学习下载说明其在同类需求中具备一定参考价值。对于内网或镜像仓库受限的环境读者可借助这些离线镜像快速完成导入与部署减少因网络问题导致的安装阻塞同时结合清单文件理解 flannel 的部署结构与组件关系为后续网络排错与版本升级提供便利。1. 离线装 k8s 时flannel 镜像包到底卡在哪一步很多人在内网机房装 k8s卡住的地方不是 kubelet 配置也不是证书而是 flannel 的镜像拉不下来。控制节点kubeadm init跑完kubectl get nodes一直是 NotReadykubectl get pods -n kube-system里 flannel 那个 Pod 停在 ImagePullBackOff日志里翻来覆去就是dial tcp: i/o timeout或者no such host。这就是典型的「镜像包没备齐」——k8s 安装部署里最容易被低估的一环。flannel 本身是个 CNI 插件它需要的不只是一个flannel/flannel镜像还牵扯到flannel/flannel-cni-plugin以及初始化阶段 kubeadm 自己要用到的kube-apiserver、kube-controller-manager、kube-scheduler、kube-proxy、pause、etcd、coredns这一整套。标题说的是「安装 k8s 所需 flannel 必要镜像包」落到实操就是把 flannel 相关的镜像和 k8s 核心镜像一起打成 tar 包带到没有外网的环境里用docker load或ctr images import导进去让 flannel 能正常起 Pod节点从 NotReady 变 Ready。这篇写给两类人一是在内网、专线受限或纯离线环境里部署 k8s 的运维和平台工程师二是刚学 k8s、想在自己机器上用 containerd 或 docker 手动把 flannel 跑起来的新手。下面从镜像清单怎么定、tar 包怎么打、导进去怎么验证、踩过哪些坑一步步讲清楚。2. flannel 镜像包清单哪些必须打哪些可以省2.1 先分清 flannel 的两个镜像和 k8s 核心镜像flannel 从 v0.20 之后拆成了两个镜像一个是flannel/flannel跑 flanneld 主进程另一个是flannel/flannel-cni-plugin提供 CNI 二进制。很多人只拉了flannel/flannel结果 Pod 起来后 CNI 配置写不进去节点还是 NotReady。这两个必须一起备。k8s 核心镜像则由 kubeadm 决定。kubeadm config images list会列出当前版本需要的全部镜像包括registry.k8s.io/kube-apiserver、kube-controller-manager、kube-scheduler、kube-proxy、pause、etcd、coredns。这些镜像的 tag 跟你的 k8s 版本严格绑定比如 k8s 1.28 对应v1.28.xetcd 是3.5.9-0coredns 是v1.10.1。版本对不上kubeadm init 会直接报镜像缺失。flannel 的镜像 tag 则跟 k8s 版本无关跟 flannel 自己的 release 走。常见稳定版是v0.22.3、v0.23.0、v0.24.0。选哪个我一般看两点一是 flannel 官方 release notes 里对 k8s 版本的兼容说明二是你集群的 k8s 版本。k8s 1.24 以后移除了 dockershimflannel 的 CNI 插件版本要跟上否则 containerd 下会报failed to find plugin flannel in path。下面这张表是我在离线环境里常用的镜像清单按 k8s 1.28 flannel v0.23.0 举例镜像用途是否必须registry.k8s.io/kube-apiserver:v1.28.2控制面是registry.k8s.io/kube-controller-manager:v1.28.2控制面是registry.k8s.io/kube-scheduler:v1.28.2控制面是registry.k8s.io/kube-proxy:v1.28.2网络代理是registry.k8s.io/pause:3.9沙箱是registry.k8s.io/etcd:3.5.9-0存储是registry.k8s.io/coredns/coredns:v1.10.1DNS是flannel/flannel:v0.23.0flanneld是flannel/flannel-cni-plugin:v1.2.0CNI 插件是提示pause镜像的 tag 在不同 k8s 版本里可能是 3.6、3.7、3.9以kubeadm config images list输出为准不要凭记忆写。2.2 用 kubeadm 和 docker 两条命令把清单拉全在有外网的机器上先确认 kubeadm 版本再列镜像# 查看 kubeadm 版本确保和要部署的集群一致 kubeadm version -o short # 列出当前 kubeadm 需要的全部镜像 kubeadm config images list输出类似registry.k8s.io/kube-apiserver:v1.28.2 registry.k8s.io/kube-controller-manager:v1.28.2 registry.k8s.io/kube-scheduler:v1.28.2 registry.k8s.io/kube-proxy:v1.28.2 registry.k8s.io/pause:3.9 registry.k8s.io/etcd:3.5.9-0 registry.k8s.io/coredns/coredns:v1.10.1flannel 的两个镜像不在 kubeadm 列表里要单独拉# 拉取 flannel 主镜像和 CNI 插件镜像 docker pull flannel/flannel:v0.23.0 docker pull flannel/flannel-cni-plugin:v1.2.0逻辑说明kubeadm config images list只负责 k8s 自身组件flannel 作为第三方 CNI 必须手动补。参数上-o short让版本输出更干净方便脚本取值。如果你用的是 containerd 而不是 docker把docker pull换成ctr -n k8s.io images pull命名空间k8s.io不能省否则 kubelet 找不到镜像。拉完之后用docker images | grep -E flannel|kube|etcd|coredns|pause核对一遍确认 tag 和清单一致。这一步偷懒后面离线导入就会缺东少西。3. 把镜像打成 tar 包docker save 与 ctr 导入的实操3.1 docker save 打包的两种写法与体积控制镜像拉齐后用docker save打成 tar。可以一个镜像一个包也可以合并成一个包。合并包传输方便但单包过大时导入慢分镜像包灵活但文件多。我一般按「k8s 核心一个包 flannel 一个包」来分便于排查。# 把 k8s 核心镜像合并打成一个 tar 包 docker save -o k8s-core-images.tar \ registry.k8s.io/kube-apiserver:v1.28.2 \ registry.k8s.io/kube-controller-manager:v1.28.2 \ registry.k8s.io/kube-scheduler:v1.28.2 \ registry.k8s.io/kube-proxy:v1.28.2 \ registry.k8s.io/pause:3.9 \ registry.k8s.io/etcd:3.5.9-0 \ registry.k8s.io/coredns/coredns:v1.10.1 # flannel 两个镜像单独打一个包 docker save -o flannel-images.tar \ flannel/flannel:v0.23.0 \ flannel/flannel-cni-plugin:v1.2.0逻辑说明-o指定输出文件后面跟镜像全名含 registry 和 tag。合并打包时 docker 会把所有 layer 去重后写入所以总体积小于各镜像之和。参数上没有压缩选项tar 本身不压缩传输前可以gzip一下但导入前要gunzip回来因为docker load不认.tar.gz。打包完用ls -lh看体积k8s 核心包通常在 600MB 到 900MB 之间flannel 包在 100MB 左右。如果明显偏小说明镜像没拉全。3.2 离线端导入docker load 与 ctr images import 的差别离线机器上如果容器运行时是 docker直接# 导入 k8s 核心镜像 docker load -i k8s-core-images.tar # 导入 flannel 镜像 docker load -i flannel-images.tar # 核对导入结果 docker images | grep -E flannel|kube|etcd|coredns|pause如果运行时是 containerdk8s 1.24 以后默认docker load 导入的镜像在k8s.io命名空间里可能不可见要用ctr# 导入到 containerd 的 k8s.io 命名空间 ctr -n k8s.io images import k8s-core-images.tar ctr -n k8s.io images import flannel-images.tar # 列出确认 ctr -n k8s.io images ls | grep -E flannel|kube|etcd|coredns|pause逻辑说明-n k8s.io是关键kubelet 默认从k8s.io命名空间拉镜像导入到default命名空间等于白导。参数上ctr images import支持--all-platforms但离线环境一般只导当前架构不加也行。导入后如果ctr images ls能看到但 kubelet 还是拉不到检查/etc/containerd/config.toml里的sandbox_image是否指向了正确的 pause 镜像。注意docker 和 containerd 的镜像存储是两套docker load 进去的镜像不会自动出现在 containerd 里。先确认你的 kubelet 用的是哪个运行时再决定用哪条导入命令。4. flannel 镜像导入后 Pod 起不来的排查4.1 现象一ImagePullBackOff 但镜像明明导入了现象kubectl describe pod -n kube-system kube-flannel-ds-xxxxx显示Failed to pull image flannel/flannel:v0.23.0: ... not found但你ctr -n k8s.io images ls能看到这个镜像。原因flannel 的 DaemonSet yaml 里镜像地址可能带了 registry 前缀比如docker.io/flannel/flannel:v0.23.0而导入时用的是flannel/flannel:v0.23.0containerd 认为这是两个不同的引用。解决要么在导入时用完整地址docker.io/flannel/flannel:v0.23.0要么改 DaemonSet 里的image字段去掉docker.io/前缀。我一般统一用完整地址导入避免歧义。4.2 现象二Pod Running 但节点仍 NotReady现象flannel Pod 状态是 Runningkubectl get nodes还是 NotReadykubectl logs里 flannel 没报错。原因flannel 的 CNI 配置文件没写到/etc/cni/net.d/或者flannel-cni-plugin二进制没放到/opt/cni/bin/。flannel 容器启动时会做这个动作但如果宿主机目录挂载不对或者 CNI 插件镜像版本不匹配就会静默失败。解决进 flannel Pod 或直接在宿主机检查/etc/cni/net.d/10-flannel.conflist是否存在/opt/cni/bin/flannel是否有可执行权限。缺哪个补哪个然后重启 flannel Pod。4.3 现象三kubeadm init 报 the api server is not healthy after 4m0.00747357s现象控制节点初始化卡住最后报the api server is not healthy after 4m0.00747357sjournalctl -u kubelet里能看到failed to pull image registry.k8s.io/kube-apiserver。原因k8s 核心镜像没导入全或者导入到了错误的命名空间。kubelet 拉不到 apiserver 镜像静态 Pod 起不来健康检查自然超时。解决先ctr -n k8s.io images ls | grep kube-apiserver确认镜像在不在。不在就重新导入在的话检查 tag 是否和kubeadm config images list输出一致。版本差一个小版本都会导致拉取失败。4.4 现象四flannel 镜像导入后磁盘被撑爆现象导入几个 tar 包后/var/lib/containerd或/var/lib/docker占用暴涨节点磁盘告警。原因docker save 的 tar 包和导入后的镜像各占一份空间多个版本叠加更明显。flannel 和 k8s 核心镜像加起来接近 1GB如果反复导入不同版本旧镜像不会自动清理。解决导入前docker system df或ctr -n k8s.io images ls看现有镜像删掉不用的旧版本。导入后及时删除 tar 包。生产环境建议把镜像仓库搭在内网用 registry 而不是 tar 包分发长期看更省事。4.5 现象五flannel 版本和 k8s 版本不兼容现象flannel Pod 反复重启日志报Failed to create pod sandbox: ... failed to find plugin flannel in path。原因flannel v0.20 之前的版本不包含独立的 CNI 插件镜像或者插件版本和 containerd 的 CNI 配置不匹配。k8s 1.24 以后 containerd 默认配置对 CNI 插件路径有要求。解决升级 flannel 到 v0.22 以上确保flannel/flannel-cni-plugin镜像一起导入。检查/etc/containerd/config.toml里bin_dir是否指向/opt/cni/binconf_dir是否指向/etc/cni/net.d。5. 用 kubeadm 离线初始化的完整验证链路5.1 从导入镜像到节点 Ready 的最小验证命令镜像导入只是第一步要确认整条链路通按下面顺序走# 1. 确认 containerd 里镜像齐全 ctr -n k8s.io images ls | grep -E flannel|kube-apiserver|etcd|coredns|pause # 2. 初始化控制节点指定离线镜像仓库或跳过拉取 kubeadm init --pod-network-cidr10.244.0.0/16 --image-repositoryregistry.k8s.io # 3. 按提示配置 kubectl mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config # 4. 部署 flannel kubectl apply -f kube-flannel.yml # 5. 观察节点和 Pod 状态 kubectl get nodes -w kubectl get pods -n kube-system -w逻辑说明--pod-network-cidr必须和 flannel 的Network配置一致默认是10.244.0.0/16写错会导致 Pod 之间不通。--image-repository在离线环境里如果镜像已经导入本地kubelet 会优先用本地但显式指定可以避免它去外网拉。kubectl apply -f kube-flannel.yml里的 yaml 要从 flannel 官方 release 页面下载对应版本不要用旧版。验证标准kubectl get nodes显示 Readykubectl get pods -n kube-system里 flannel、coredns、kube-proxy 全部 Running。如果 coredns 一直 Pending通常是 flannel 没起或者网络 CIDR 冲突。5.2 验证 Pod 跨节点通信是否真的通了节点 Ready 不代表网络通。建两个测试 Pod 验证# 在 node1 上起一个 nginx kubectl run nginx-test --imagenginx --restartNever # 查看 Pod IP 和所在节点 kubectl get pod nginx-test -o wide # 在 node2 上起一个 busyboxping node1 的 Pod IP kubectl run busybox-test --imagebusybox --restartNever -- sleep 3600 kubectl exec -it busybox-test -- ping -c 3 nginx-test-pod-ip逻辑说明flannel 默认用 VXLAN 模式跨节点 Pod 通信走 overlay 网络。如果 ping 不通检查ip route里有没有 flannel.1 接口iptables -L -n里 FORWARD 链是否被 DROP。常见原因是宿主机防火墙没放行 VXLAN 的 8472/UDP 端口。提示测试完记得删掉测试 Podkubectl delete pod nginx-test busybox-test避免占用 IP 和资源。6. 把 flannel 镜像包做成可复用资产的两个技巧第一个技巧是给 tar 包加校验和版本清单。离线环境里 tar 包靠 U 盘或内网共享传递损坏是常事。我习惯在打包目录里生成一个manifest.txt记录每个 tar 包的 sha256 和包含的镜像列表# 生成校验和 sha256sum k8s-core-images.tar flannel-images.tar manifest.txt # 记录镜像清单 docker images --format {{.Repository}}:{{.Tag}} | grep -E flannel|kube|etcd|coredns|pause manifest.txt导入前先sha256sum -c manifest.txt校验不过就别导省得导到一半报错还得重来。这个习惯在多次跨机房交付时救过我好几回。第二个技巧是用内网 registry 替代 tar 包。tar 包适合一次性交付但集群扩容、版本升级时反复导入很痛苦。条件允许的话在内网起一个 registry把镜像docker tag成内网地址后docker pushkubelet 配置--image-repository指向它。flannel 的 yaml 里镜像地址也改成内网地址。这样新节点加入时直接拉不用再传 tar 包。# 给镜像打内网 registry 标签 docker tag flannel/flannel:v0.23.0 registry.internal:5000/flannel/flannel:v0.23.0 # 推送到内网 registry docker push registry.internal:5000/flannel/flannel:v0.23.0参数上registry.internal:5000换成你实际的 registry 地址端口和路径按需调整。containerd 那边要在/etc/containerd/config.toml里配置mirrors指向内网 registry否则还是会去外网拉。我自己的习惯是第一次离线交付用 tar 包同时把镜像推进内网 registry后续扩容只维护 registry。这样既解决了首次没有仓库的问题又避免了长期依赖 tar 包。flannel 镜像包这件事说到底不是拉几个镜像那么简单而是把「离线环境里 k8s 网络怎么稳定起来」这条链路走通。希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/10/13 4:59:59

订单系统分布式事务实战:库存预占、支付幂等与状态机设计

1. 为什么订单系统是分布式事务的“压力测试仪”订单系统不是普通业务模块,它是整个电商或SaaS平台里最典型的“多点协同、强一致性、高并发、低延迟”四重压力叠加体。我参与过三个不同量级的订单系统重构,从日单量2万的垂直类平台,到日单量…

2026/10/13 4:59:59

测试工程师晋升卡壳?沟通、协调与风险管理才是分水岭

这两年有个现象挺有意思:很多测试同学技术功底扎实,自动化框架写得溜,性能调优也能搞定,但一到晋升答辩就卡壳。反馈下来,评委说得最多的一句话不是“技术不够深”,而是“你做的事情影响面太小”“缺乏全局…

2026/10/13 4:59:58

综合能源系统优化实战:电热冷气协同调度与储能配置

综合能源系统这几年是园区、工厂、数据中心都在看的真问题——电、热、冷、气四种能源介质互相牵制,分时电价又把这个牵制换算成了真金白银。很多人以为上了储能、用了谷电就算“综合能源”了,但实际上,一套没有把热、冷、气放进统一调度框架…

2026/10/13 6:15:01

Spring Boot+Vue智能物流系统开发实践

1. 项目概述作为一名长期从事Java全栈开发的工程师,最近完成了一个基于Spring Boot的智能物流管理系统。这个系统是我为某高校计算机专业毕业设计指导的项目,同时也具备实际商业应用价值。在物流行业数字化转型的背景下,传统物流管理方式存在…

2026/10/13 6:15:01

图吧工具箱:硬件检测与性能评估的集成解决方案

1. 图吧工具箱:硬件爱好者的瑞士军刀作为一名长期折腾硬件的玩家,我深知在电脑维护和性能评估过程中最头疼的就是工具分散——CPU检测用一个软件、显卡测试又要另外下载、硬盘健康度还得再找工具。直到遇到图吧工具箱,这个由国内知名硬件社区…

2026/10/13 6:15:01

Abis信令分析实战:从GSM基站抓包到故障定位

简介:本资源是面向通信工程专业学生、网络运维工程师及GSM协议研究者的ABIS接口深度学习资料包,聚焦基站与BSC间信令交互原理与实践分析,助力理解GSM核心网架构、信令流程建模及常见故障定位。压缩包共99个文件,涵盖25份PDF协议规…

2026/10/13 6:10:01

信息极简场景下的项目拆解方法论:从三字母到可执行方案

1. 当标题只剩三个字母时,我在想什么拿到“rea”这个标题的时候,我盯着屏幕愣了大概十秒钟。没有项目正文,没有关键词,没有摘要描述,连热搜词和网络热词都是空的。这大概是做内容拆解最极端的一种情况——你手里只有一…

2026/10/13 5:19:27

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/12 12:01:26

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/12 12:54:07

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/13 0:04:41

基于Triton部署YOLO目标检测:从训练脚本到线上服务

简介:这份资源面向希望将目标检测模型落地到生产环境的深度学习开发者与算法工程师,聚焦于用 Triton Inference Server 部署 YOLOv9 的完整实战方案,解决从训练权重到线上推理服务之间的工程化难题。压缩包共 16 个文件,约 886KB&…

2026/10/13 0:04:41

手把手教你云端部署Qwen-Image-2.1:从GPU选型到在线文生图服务

Qwen-Image-2.1 这个开源的图像生成模型,最近在内容创作和 AI 应用圈子里热度相当高。它属于通义 Qwen 系列里的视觉生成分支,让我眼前一亮的是它对中文长文本的理解能力——以前用那些老方案生成带中文文字的图,十个里九个是“乱码印刷体”&…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑