K8s离线部署flannel镜像包:从拉取导出到导入验证的完整避坑指南
简介这份资源面向正在搭建 Kubernetes 集群、需要为节点配置网络插件的运维与开发人员解决 flannel 镜像拉取困难、离线环境无法部署 CNI 网络的问题。压缩包共 3 个文件包含 2 个 tar 镜像归档与 1 个 yaml 清单整体约 27.34MB其中 tar 文件用于导入 flannel 及 flannel-cni-plugin 镜像yaml 文件则提供配套的部署清单便于直接应用到集群。资源覆盖 flannel-cni-plugin:v1.1.2 与 flannel:v0.21.5 两个必要组件适合内网、离线或镜像仓库受限的场景使用能省去逐一下载与打标签的繁琐过程。目前已有 1613 人学习下载说明该组合在 k8s 网络部署中具有较高的实用参考价值。读者可借此快速完成镜像导入与插件部署减少因网络问题导致的 Pod 通信异常为后续集群网络调试与排错打下基础。1. 安装 k8s 所需 flannel 必要镜像包为什么离线环境总卡在第一步很多人在内网或离线机房装 k8s控制节点 master 初始化时卡在the api server is not healthy after 4m0.00747357s翻来覆去查 kubelet 日志最后发现根因不是配置写错而是 flannel 的镜像根本没拉下来。k8s 集群要跑起来CNI 插件是绕不过去的一环而 flannel 因为部署简单、依赖少成了大量生产环境和学习笔记里的首选。它的镜像包不像 kube-apiserver 那样由 kubeadm 自动处理需要你提前准备、手动导入到每个节点。这篇内容就是围绕「flannel 必要镜像包」这件事把需要哪些镜像、怎么导出导入、参数怎么配、离线环境怎么验证讲清楚。适合正在用 kubeadm 部署集群、或者维护内网 k8s 环境的运维和开发尤其是那些被镜像拉取失败折腾过的人。2. flannel 镜像包到底包含什么从组件构成到版本选择2.1 flannel 在 k8s 里的角色与镜像依赖关系flannel 的核心任务是给每个节点分配一个 Pod 网段让不同节点上的 Pod 能互相通信。它在 k8s 里以 DaemonSet 形式运行每个节点跑一个 Pod这个 Pod 里至少包含两个容器一个是 flannel 本体负责监听 etcd 或 k8s API 中的网络配置并写入本机路由另一个是 CNI 插件容器负责在 Pod 创建时调用 flannel 的配置来设置网卡。这两个容器对应的镜像就是你要准备的核心。常见做法是直接用quay.io/coreos/flannel这个镜像它内部已经打包了 flanneld 和 CNI 插件部署时只需要一个镜像就能跑起来。但有些老版本或定制版本会把 CNI 插件单独拆出来这时候你就需要额外准备quay.io/coreos/flannel-cni之类的镜像。判断方法很简单看你要用的 flannel 官方 YAML 里image字段写了几个不同的镜像地址。如果只有一个那必要镜像包就是这一个如果有两个就都要准备。版本选择上flannel 的版本要和你的 k8s 版本大致匹配。k8s 1.36 这类较新版本建议用 flannel v0.24 以上它对较新的 CNI 规范和内核特性支持更好。不要盲目追最新版因为 flannel 的镜像标签里带架构后缀比如v0.24.0-amd64选错了在 arm 节点上直接起不来。我一般会先确认集群所有节点的 CPU 架构再统一选一个多架构 manifest 的标签或者分别准备 amd64 和 arm64 两套。2.2 拉取与导出把 flannel 镜像做成 tar 包的标准流程在有外网的机器上先把镜像拉下来。以 flannel v0.24.0 为例命令如下# 拉取 flannel 主镜像注意标签要带架构后缀或使用多架构标签 docker pull quay.io/coreos/flannel:v0.24.0 # 如果 YAML 里还引用了 CNI 插件镜像一并拉取 docker pull quay.io/coreos/flannel-cni:v0.24.0 # 查看镜像 ID 和大小确认拉取成功 docker images | grep flannel拉取完成后用docker save导出成 tar 包。这里有个细节如果你要同时导出多个镜像可以写在一个命令里这样导入时一次完成不用分多次。# 将 flannel 相关镜像打包成一个 tar 文件 docker save -o flannel-images.tar \ quay.io/coreos/flannel:v0.24.0 \ quay.io/coreos/flannel-cni:v0.24.0 # 查看 tar 包大小确认没有异常 ls -lh flannel-images.tardocker save的参数-o指定输出文件后面跟一个或多个镜像名。导出的 tar 包包含了镜像的所有层体积可能比较大flannel 镜像通常在 100MB 左右加上 CNI 插件会到 150MB 上下。如果节点是 containerd 运行时导入方式不是docker load而是ctr或nerdctl这个后面会讲。2.3 镜像标签与架构避免导入后 Pod 一直 ImagePullBackOffflannel 的镜像标签里架构后缀很容易被忽略。比如你在 amd64 机器上拉quay.io/coreos/flannel:v0.24.0docker 会自动选择 amd64 的 manifest但导出的 tar 包在 arm64 节点上导入后kubelet 仍然会去拉取对应架构的镜像发现本地没有就报ImagePullBackOff。解决方法是要么在每个架构的机器上分别拉取并导出要么直接使用不带架构后缀的多架构标签让容器运行时自己选。另一个坑是镜像名不一致。flannel 官方 YAML 里写的可能是quay.io/coreos/flannel:v0.24.0但你导入后本地镜像名可能变成quay.io/coreos/flannel:v0.24.0-amd64kubelet 按 YAML 里的名字找不到就会去外网拉。所以导入后一定要用docker images或crictl images确认本地镜像名和 YAML 里完全一致。如果不一致可以用docker tag重新打标签。提示在离线环境里建议把 flannel 的 YAML 文件也一起准备好里面的 image 字段改成你本地导入后的准确镜像名避免运行时再去解析。3. 离线环境导入 flannel 镜像包docker 与 containerd 两条路径3.1 docker 运行时的导入与验证步骤如果节点用的是 docker 作为容器运行时导入很简单# 将 tar 包拷贝到目标节点然后导入 docker load -i flannel-images.tar # 确认镜像已经存在 docker images | grep flannel # 查看镜像的详细标签确保和 YAML 里一致 docker inspect quay.io/coreos/flannel:v0.24.0 | grep -i repotags导入后不要急着 apply flannel 的 YAML。先手动跑一个测试容器确认镜像能正常启动# 测试 flannel 镜像是否能正常运行 docker run --rm quay.io/coreos/flannel:v0.24.0 --version如果输出了版本号说明镜像完整。如果报错exec format error那就是架构不对需要重新拉取对应架构的镜像。这一步能帮你提前发现大部分镜像问题比等到 Pod 起来再排查要省时间。3.2 containerd 运行时的导入与 nerdctl 配合现在越来越多的 k8s 集群用 containerd 作为运行时docker 命令不一定能用。这时候导入镜像要用ctr或nerdctl。以ctr为例# 使用 ctr 导入镜像到 k8s.io 命名空间 ctr -n k8s.io images import flannel-images.tar # 查看导入结果 ctr -n k8s.io images ls | grep flannel注意-n k8s.io这个命名空间参数k8s 的 containerd 运行时默认使用k8s.io命名空间如果你不加这个参数镜像会导入到 default 命名空间kubelet 找不到。这是很多人踩过的坑现象就是明明ctr images ls能看到镜像但 Pod 还是ImagePullBackOff。如果节点上装了nerdctl操作会更接近 docker# 使用 nerdctl 导入同样要指定 k8s.io 命名空间 nerdctl -n k8s.io load -i flannel-images.tar # 验证 nerdctl -n k8s.io images | grep flannel导入完成后同样建议用ctr跑一个测试容器确认镜像能正常执行。containerd 下测试命令是ctr -n k8s.io run --rm quay.io/coreos/flannel:v0.24.0 test-flannel --version3.3 多节点批量分发用脚本减少重复劳动生产环境节点多一个个手动导入不现实。我一般会写一个简单的分发脚本把 tar 包和导入命令一起推到每个节点。假设你有一个节点列表文件nodes.txt每行一个 IP#!/bin/bash # 批量分发 flannel 镜像包并导入 IMAGE_TARflannel-images.tar NODE_LISTnodes.txt for node in $(cat $NODE_LIST); do echo 处理节点: $node # 拷贝 tar 包到目标节点 scp $IMAGE_TAR root$node:/tmp/ # 根据运行时类型选择导入命令这里以 containerd 为例 ssh root$node ctr -n k8s.io images import /tmp/$IMAGE_TAR rm -f /tmp/$IMAGE_TAR if [ $? -eq 0 ]; then echo $node 导入成功 else echo $node 导入失败请检查 fi done这个脚本里scp负责传输ssh远程执行导入。注意ctr导入后删除 tar 包避免占满/tmp。如果你的节点运行时是 docker把ctr -n k8s.io images import换成docker load -i即可。脚本里没有做并发节点多的时候可以加和wait并行但要注意控制并发数避免把网络打满。注意批量操作前先在单个节点上验证整个流程确认镜像名、命名空间、导入命令都正确再推到全部节点。我见过有人直接跑批量脚本结果所有节点都导入了错误的架构版本最后全部重来。4. flannel 镜像包避坑从 ImagePullBackOff 到网段冲突的排查记录4.1 现象Pod 一直 ImagePullBackOff但本地明明有镜像这是最常见的坑。现象是 flannel 的 DaemonSet Pod 状态为ImagePullBackOff但你在节点上docker images或ctr images ls能看到镜像。原因通常有三个一是镜像名和 YAML 里不一致比如本地是flannel:v0.24.0-amd64YAML 里写的是flannel:v0.24.0二是 containerd 命名空间不对镜像导入到了 default 而不是k8s.io三是 kubelet 配置了imagePullPolicy: Always即使本地有镜像也强制去外网拉。解决方法是先kubectl describe pod看 Events 里的具体拉取错误确认它要找的镜像名是什么然后对比本地镜像名用docker tag或ctr images tag改成一致如果是命名空间问题重新导入到k8s.io如果是imagePullPolicy把 YAML 里的策略改成IfNotPresent。4.2 现象flannel Pod 起来了但节点间 Pod 不通flannel Pod 显示 Running但不同节点上的 Pod 互相 ping 不通。原因可能是 flannel 的网段配置和节点已有网段冲突。比如你的节点内网是10.244.0.0/16而 flannel 默认也用10.244.0.0/16就会路由混乱。解决方法是修改 flannel 的 ConfigMap把Network字段改成不冲突的网段比如10.255.0.0/16然后重启 flannel Pod。另一个原因是内核没开 IP 转发。检查sysctl net.ipv4.ip_forward如果是 0执行sysctl -w net.ipv4.ip_forward1并写入/etc/sysctl.conf。这个在离线环境里经常被忽略因为默认镜像可能没带相关配置。4.3 现象导入镜像时报 no space left on device镜像 tar 包通常上百 MB导入时会解压到/var/lib/docker或/var/lib/containerd如果这些分区空间不够就会报no space left on device。解决方法是提前清理无用镜像和容器或者把数据目录迁移到更大的分区。用df -h查看/var/lib/docker或/var/lib/containerd的剩余空间确保至少有 2GB 以上。如果空间实在紧张可以在导出镜像时用docker save的--compress选项压缩 tar 包但导入时仍然需要解压空间。更彻底的办法是只导出必要的镜像层但 flannel 镜像本身不大通常清理一下旧镜像就能解决。4.4 现象flannel 版本和 k8s 版本不匹配导致 API 报错k8s 1.36 这类较新版本对 CNI 插件的 API 版本有要求。如果你用了很老的 flannel 版本比如 v0.11它的 CNI 配置格式可能不被新 kubelet 识别现象是 Pod 创建时 CNI 插件报错flannel Pod 日志里出现failed to load network config之类的信息。解决方法是升级 flannel 到 v0.24 以上并同步更新 YAML 里的镜像标签。升级时注意先导出旧版本的配置备份再替换镜像和 YAML最后重启 flannel DaemonSet。不要直接删除旧 Pod否则可能影响现有 Pod 的网络。4.5 现象离线环境里 flannel 去拉 etcd 镜像失败有些 flannel 部署方式依赖 etcd 存储网络配置如果你的 YAML 里 flannel 的 backend 是 etcd那它还会去拉 etcd 的镜像。离线环境里这个镜像也没准备就会导致 flannel Pod 起不来。解决方法是改用 k8s API 作为 backend或者提前把 etcd 镜像也加入必要镜像包。我一般推荐直接用 k8s API 模式少一个依赖少一个坑。5. 验证 flannel 镜像包是否真正可用三个必做检查5.1 用 crictl 检查镜像和 Pod 状态镜像导入后用crictl检查是最贴近 kubelet 视角的方式# 查看 k8s.io 命名空间下的镜像 crictl images | grep flannel # 查看 flannel Pod 的详细状态 crictl pods --name flannel # 如果 Pod 没起来看具体容器的日志 crictl logs container-idcrictl默认连接 containerd 的k8s.io命名空间所以它看到的镜像就是 kubelet 能用的镜像。如果crictl images里没有 flannel那 Pod 一定起不来。这一步能快速定位是镜像问题还是配置问题。5.2 跨节点 Pod 通信测试flannel 正常后在不同节点上各起一个测试 Pod互相 ping。可以用kubectl run快速创建# 在节点 A 上创建测试 Pod kubectl run test-a --imagebusybox --restartNever -- sleep 3600 # 在节点 B 上创建测试 Pod kubectl run test-b --imagebusybox --restartNever -- sleep 3600 # 获取 test-b 的 IP kubectl get pod test-b -o wide # 在 test-a 里 ping test-b 的 IP kubectl exec test-a -- ping -c 3 test-b-ip如果能 ping 通说明 flannel 的跨节点路由正常工作。如果 ping 不通检查节点路由表ip route看有没有 flannel 生成的10.244.x.x路由条目。没有的话说明 flannel 没正确写入路由可能是权限问题或 backend 配置问题。5.3 检查 flannel 的 ConfigMap 和实际网段flannel 的网段配置在 ConfigMap 里用kubectl get configmap kube-flannel-cfg -n kube-flannel -o yaml查看。重点看Network字段和实际节点路由是否一致。如果 ConfigMap 里是10.244.0.0/16但节点路由里出现的是别的网段说明 flannel 没有正确读取配置可能是 RBAC 权限不足或者 flannel Pod 没挂载到 ConfigMap。我一般会在部署后立刻做这三项检查确认无误再继续部署业务。这样即使后面出问题也能排除网络插件这个变量。flannel 镜像包这件事看起来只是导个 tar 包但真正落地时架构、命名空间、版本、网段每个点都可能让你多花几个小时。把这几步做扎实后面 k8s 集群的稳定性会好很多。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

React生命周期深度解析:从类组件到Hooks的迁移实战

React生命周期深度解析:从类组件到Hooks的迁移实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 5:44:37 阅读更多 →
ICE中间件环境搭建与Demo实战:跨语言通信避坑指南

ICE中间件环境搭建与Demo实战:跨语言通信避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 5:43:37 阅读更多 →
PS5日常管理方案:存储扩展、存档备份、网络诊断与散热维护

PS5日常管理方案:存储扩展、存档备份、网络诊断与散热维护

PS5 入手之后,大家通常兴奋一周,然后很快就会被三个现实问题拉回地面:硬盘又满了、某个游戏的存档想备份却不知道从哪下手、联机对战时不时给你来个延迟抽风。我自己折腾了一圈之后,干脆整理了一套面向 PS5 日常使用的通用管理方案…

2026/10/13 5:43:37 阅读更多 →

最新新闻

使用 xquad 的区间整数域构建投资组合再平衡(Portfolio Rebalance)模型

使用 xquad 的区间整数域构建投资组合再平衡(Portfolio Rebalance)模型

【免费下载链接】xquad A rust implementation of the Quip Networks quantum virtual machine. 项目地址: https://gitcode.com/gh_mirrors/xq/xquad 点击查看 免费下载 本文以 xquad 仓库中的 Portfolio Rebalance 示例 为主线,讲解如何用 XQCP 约束编…

2026/10/13 6:33:48 阅读更多 →
PS5新手到进阶:初始化、SSD扩容与散热维护全攻略

PS5新手到进阶:初始化、SSD扩容与散热维护全攻略

如果你手里正好有一台PS5,或者正打算入坑这台主机,那“AnyPS5”这个标题应该会让你有点好奇:什么叫Any?其实拆开理解很简单,Any就是“任何一台、任何一个场景、任何一类玩家”都适用的意思。不管你是刚拆封的新手、纠结…

2026/10/13 6:33:48 阅读更多 →
Muse Gadgets:让本地AI Agent真正操控物理硬件

Muse Gadgets:让本地AI Agent真正操控物理硬件

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 6:33:48 阅读更多 →
从梯度下降到Adam:一文搞懂深度学习优化器演进与调参实战

从梯度下降到Adam:一文搞懂深度学习优化器演进与调参实战

1. 困境起点:下山这件事,为什么会让算法被“逼”出来做机器学习的朋友应该都有过这种体验:早上信心满满地把模型丢上去训练,下午回来看loss曲线,发现它像一条坏掉的心电图——要么不动,要么剧烈抖动&#x…

2026/10/13 6:33:48 阅读更多 →
Apache Calcite JSON/YAML 模型完全指南:从 Schema 定义到 Lattice 物化

Apache Calcite JSON/YAML 模型完全指南:从 Schema 定义到 Lattice 物化

后端数据库 【免费下载链接】calcite Apache Calcite 项目地址: https://gitcode.com/gh_mirrors/ca/calcite 点击查看 免费下载 Apache Calcite 允许用户用 JSON 或 YAML 两种格式的"模型(model)"文件来描述数据源的逻辑结构——…

2026/10/13 6:33:48 阅读更多 →
大模型训练基础:梯度下降、反向传播、mini-batch和计算图

大模型训练基础:梯度下降、反向传播、mini-batch和计算图

1. 这四件事是怎么组成一次参数更新的很多人一看到“大模型训练”就紧张,觉得门槛高到不行,又是并行又是算力又是几个T的显存。但实际上,你把训练这件事拆到最小单元,它始终是在重复同一个动作:取一批数据,…

2026/10/13 6:32:47 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →