单节点K8s部署Longhorn:存储抽象与运维实战

发布时间:2026/9/28 6:12:39
单节点K8s部署Longhorn:存储抽象与运维实战 很多人一听到单节点K8s就觉得这是练手环境随便挂个hostPath意思一下就行。我在实际折腾K8s三年多以后现在只要看到有人在单节点上直接跑数据库还拿本机目录当持久化盘就会忍不住劝一句别省这顿折腾后面数据丢起来真的肉疼。单节点 K8s 集群上部署 Longhorn 这个事听起来有点大材小用但真做下来你会发现它解决的是底层存储抽象和运维体验的问题而不是“我只有一台机器所以随便搞搞”。这篇文章会从为什么需要它、怎么准备环境到完整部署流程、参数调整、常见坑位一次讲清楚。无论你是刚搭好K8s想给有状态服务找个归宿还是想把Longhorn这套存储方案先跑通再考虑扩集群这篇文章都适用。1. 为什么单节点K8s也需要Longhorn1.1 单节点K8s的存储困境先聊一个最直接的问题单节点K8s上难道不能直接用本地磁盘吗当然能但K8s里默认的本地存储方案太“裸”了。emptyDir是随Pod生命周期走的Pod一删数据就没了hostPath虽然把目录挂到宿主机上但它没有容量限制、没有跨节点调度能力、也没有一个统一的接入层Pod里写的东西散落在各个路径下。你用hostPath跑nginx静态页面还没什么一旦跑MySQL、监控时序库这类有状态服务后面想迁移、备份、扩容每一步都很痛苦。在这种情况下需要一个通过CSI接口接入K8s的存储层。它在宿主机上划分出一块块逻辑卷通过PV/PVC抽象给应用使用。数据落在宿主机磁盘上但PV/PVC生命周期和Pod解耦Pod挂了重建还能通过PVC重新挂载。单节点集群虽然无法做跨节点副本但至少把“应用”和“数据”分开了这对日常开发和实验来说已经是一个质的提升。1.2 Longhorn是什么为什么选它而不是NFS/本地目录Longhorn是Rancher开源的一套云原生分布式块存储实现。它在K8s集群内运行一组控制器用CRD管理卷、节点、备份等资源通过CSI插件把块设备挂载到Pod里。你可以把它理解成一个控制器驱动的“软件定义存储”不需要单独硬件也不需要额外的分布式文件系统数据就存在K8s节点的磁盘目录里。那为什么单节点场景我推荐Longhorn而不是NFS或者直接本机目录NFS虽然简单但它依赖外部NFS服务而且NFS在块语义上比较弱数据库这类对并发和锁敏感的应用挂NFS经常踩性能坑。本机目录没有抽象层也不聊了。Longhorn的优势在于它是为K8s量身设计的有StorageClass、PVC生命周期管理、快照、备份、UI界面这些原生能力。哪怕只有一个节点你也能把它当成一个自带管理界面的“本地块存储服务”来用以后集群扩展成多节点时副本数调上去就能获得冗余不用推翻重构。1.3 单节点场景的适用边界不过我先把丑话说在前头单节点Longhorn不是高可用方案。它只有一个副本节点一挂数据就跟着挂。它适合的场景是开发测试环境、边缘盒子、家里的实验集群、或者用来跑不太要命但是又希望保留数据的服务。这也是标题里“单节点”这三个字的核心含义——你可以享受存储调度、卷管理、快照备份这些好用功能但不要指望它实现生产级的故障容错。如果你以后真的要把集群扩成三节点Longhorn的数据目录是沿用同一套方案平滑迁移的这一点倒是很香。这一节讲清楚“为什么”。下面进入实操前最无聊、但也最容易翻车的环境准备阶段。2. 部署前的环境准备与关键选型2.1 单节点K8s集群搭建方案kubeadm、k3s还是minikubeLonghorn要求一个可用的K8s集群。单节点集群搭建方案有不少我在实际对比后建议优先用kubeadm或k3s。kubeadm是官方推荐的集群搭建工具自定义程度高网络插件可以自己选适合想顺便完整走一遍K8s部署流程的朋友k3s则主打轻量把很多组件打包成一个二进制内存占用低在边缘设备或闲置小主机上跑特别舒服。minikube虽然适合本地学习但它的节点是虚拟机存储和网络层有点绕拿来跑Longhorn容易碰上兼容性坑我一般不建议。用kubeadm初始化一个单节点控制平面命令大致是这样kubeadm init --pod-network-cidr10.244.0.0/16初始化完成后记得装一个Pod网络插件比如flannel否则节点会一直是NotReady后面什么组件都跑不起来。这一步很多人会漏掉。装完网络插件后为了能让普通工作负载调度到这台唯一的节点上要么在Longhorn的配置里容忍控制平面污点要么直接去掉污点。我倾向于去掉污点让一个单节点集群更接近“普通节点”的调度行为kubectl taint nodes --all node-role.kubernetes.io/control-plane-如果你用的是老版本K8s污点key可能是node-role.kubernetes.io/master去掉污点时注意对应。这一步很多人忘了后续Longhorn的Pod会一直Pending后面排查章节还会讲到。2.2 安装依赖open-iscsi与nfs-commonLonghorn底层通过iSCSI协议把块设备挂载到Pod所在节点。这就要求集群里的每个节点上都装好open-iscsi客户端。别笑这个组件真的是坑王之王不少人在部署Longhorn后卡在Pod一直ContainerCreating查了半天最后发现是iscsi没装或者服务没启动。在Ubuntu/Debian上执行apt-get update apt-get install -y open-iscsi nfs-common systemctl enable --now iscsid在CentOS/Rocky上执行yum install -y iscsi-initiator-utils nfs-utils systemctl enable --now iscsidnfs-common不是Longhorn的硬依赖但Longhorn的备份恢复功能如果要访问NFS备份存储就需要它。反正装上没坏处。装完之后可以随手验证一下iscsiadm -m session没有报错就说明服务正常没会话不代表有问题这里只是确认命令能用服务在运行。2.3 版本兼容性与集群状态预检Longhorn对K8s版本有兼容范围当前主流版本要求K8s 1.21以上具体要以官方文档为准。我在部署前会习惯用几条常用命令把集群状态过一遍kubectl get nodes -o wide kubectl get pods -A kubectl version --short这里再提一句K8s现在已经默认用containerd作为运行时docker更多是“镜像构建工具”而不是“运行时”了。很多人分不清“k8s和docker区别”其实在排查存储问题的时候你只需要知道CSI挂载发生在节点内核层面跟运行时关系不大真正影响的是Linux内核模块和iscsi服务。另一点Longhorn本身是一个标准的K8s Operator案例它通过CRD定义Volume、Node、Engine等资源再由longhorn-manager控制器watch这些资源来干活。理解这个模型对后面排查问题会有很大帮助。预检的时候重点看节点状态是否是Ready系统盘剩余空间是否足够内核版本是否过老。Longhorn对内核模块有要求特别是iscsi_tcp和target_core_mod这类模块个别精简内核需要手动modprobe加载。不过现在绝大多数发行版默认都带了。3. 单节点部署Longhorn的完整流程3.1 使用Helm Chart安装Longhorn我推荐用Helm来安装Longhorn因为它可以很方便地设置单节点需要的参数。首先把Longhorn的Chart仓库加到本地helm repo add longhorn https://charts.longhorn.io helm repo update然后直接安装。但注意这里不能裸装因为你必须把副本数改成1否则默认三个副本会让Longhorn在一个单节点上拼命寻找第二名成员所有卷都会变成异常状态。所以至少带上这样几个参数helm install longhorn longhorn/longhorn \ --namespace longhorn-system \ --create-namespace \ --set defaultSettings.defaultReplicaCount1 \ --set persistence.defaultClassReplicaCount1 \ --set persistence.defaultClassDataLocalitybest-effort这里解释两个词defaultReplicaCount是Longhorn系统的全局默认副本数persistence.defaultClassReplicaCount是新建StorageClass默认副本数。两个都设为1才能保证后续创建PVC时自动继承“单副本”这个设定。dataLocality设为best-effort意思是数据尽量留在本地节点单节点场景下这就是最优解。如果是已经去掉污点的节点安装到这里基本就过了。如果保留了控制平面污点你还需要通过--set tolerations[0].key...这样的方式传入容忍度或者在values.yaml里补一段Tolerations配置。我的做法是直接写一个values文件把副本数、容忍度、UI NodePort都放在里面方便以后升级时复用。3.2 单节点必须调整的核心参数副本数、容忍度、默认存储类容忍度这个参数我先说结论如果你的单节点集群是kubeadm初始化的且没有去掉污点那必须配置容忍度否则longhorn-manager和instance-manager会调度失败。values文件里可以这样写defaultSettings: defaultReplicaCount: 1 defaultDataLocality: best-effort tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule如果你的K8s版本是1.24之前的污点key可能是node-role.kubernetes.io/master就换成那个。这里必须说明一个容易搞混的地方Longhorn组件自己有Pod调度PV卷的底层instance-manager也有自己的调度两者都要能落到这台唯一的节点上。所以在部署前就要想好你是要容忍污点还是直接去掉污点。我最省事的方案是去掉污点因为单节点上本来就只有这一台机器让调度器把数据面和控制面一起放在这台机器上是不用纠结的选择。安装完成后Longhorn会创建名为longhorn的StorageClass。我习惯把它标记为默认存储类这样之后创建的PVC如果不指定storageClassName也会自动走Longhornkubectl patch storageclass longhorn \ -p {metadata:{annotations:{storageclass.kubernetes.io/is-default-class:true}}}3.3 部署验证检查Pod、UI与控制平面安装完成后不要急着创建应用先看Pod状态。这一步我每次都会做而且会认真看每个Pod是不是Running、Ready。检查命令很简单kubectl -n longhorn-system get pods -o wide kubectl -n longhorn-system get svc如果你发现有一些Pod一直Pending马上用kubectl describe pod看看事件大概率是污点、资源不足或者镜像拉取问题。Longhorn的镜像通常托管在Docker Hub如果拉不动可以考虑给节点配置镜像加速器。这个自己斟酌。Longhorn UI是一个很有用的带有完整仪表盘的前端服务。默认是通过ClusterIP暴露的为了快速访问可以改成NodePortkubectl -n longhorn-system patch svc longhorn-frontend \ -p {spec:{type:NodePort}}然后通过kubectl -n longhorn-system get svc longhorn-frontend查端口访问http://你的节点IP:端口。UI里能看到节点状态、磁盘状态、卷列表、备份状态后面日常运维基本离不开它。3.4 创建测试PVC与工作负载验证读写光看Pod全部Running还不能算完必须创建一个PVC和测试Pod跑一次真正的数据写入。我习惯先建一个最小的PVCapiVersion: v1 kind: PersistentVolumeClaim metadata: name: test-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi创建后等PVC状态变成Bound这一步如果卡住多半是存储类、副本数或调度的问题可以回到上面检查。然后开一个一次性Pod写数据kubectl run test-pod --imagebusybox --restartNever \ --command -- sh -c echo longhorn-ok /data/test.txt cat /data/test.txt注意要在YAML里挂载PVC到/data目录不然上面的命令没有意义。写完后删除Pod再开一个Pod挂载同一个PVC看文件是否还在。这一步能确认PVC生命周期与Pod解耦数据不会因为Pod删除而消失。验证正常后单节点Longhorn的核心链路就走通了。接下来是让这套系统真正能长期稳定运行的优化和避坑。4. 单节点部署的配置优化与避坑指南4.1 数据目录与磁盘管理别把数据放在系统盘Longhorn默认在每个节点上找可挂载的磁盘目录来存放卷数据。如果你在安装时没有指定它会把宿主机根目录下的/var/lib/longhorn当成默认数据目录。如果系统盘空间不是特别充裕我强烈建议提前给Longhorn挂一块独立磁盘或至少独立分区然后在UI的Node页面把这块磁盘加到Longhorn的数据目录里并把系统盘移除或标记为不可调度。这个操作背后的逻辑很简单Longhorn的数据是会增长的你跑几个数据库、几个监控服务几十G很容易就没了。如果和系统日志、容器镜像缓存挤在同一块盘上一旦盘写满K8s节点可能直接进入压力状态到时候再清理就很被动。我在一台云主机上就遇到过因为容器镜像占满根分区导致Longhorn卷无法写入的情况最后是用软链接把镜像目录挪走才救回来。所以数据目录独立是单节点Longhorn稳定运行的第一优先级。4.2 性能调优SSD、挂载参数与Longhorn系统设置性能调优其实没有太多玄学第一步就是磁盘要用SSD。Longhorn本质上是把每份数据作为稀疏文件写到磁盘上然后再通过iSCSI暴露给节点中间多了一层读写因此对磁盘延迟比直连裸盘更敏感。HDD跑起来也能用但延迟会比较难看。然后建议改一下Longhorn的挂载相关参数。在StorageClass的parameters里可以设置mkfsParams文件系统参数如果不做具体数据库调优默认的ext4其实够用。比较有用的是把staleReplicaTimeout设成一个合理值比如30防止故障副本迟迟不清理。对于普通应用还可以设置migratable或allowRecurringJobWhileVolumeDetached之类的选项但单节点场景一般用不到。另一个直接影响性能的是系统设置里的“Data Locality”和“Remove Multiples Replicas on Same Node”。单节点集群下所有数据都在同一个节点上所以多个副本不仅没有任何意义还会白白浪费一半磁盘。把默认副本数设为1之后同一个卷在节点上只会存在一份副本空间利用率最高。如果你之前用多副本跑过UI里Volume的“Replicas”可能显示是同一个节点上的多个副本这种状态要手动清理否则磁盘会慢慢涨起来。4.3 快照、备份与监控单节点数据安全的补丁前面说了单节点Longhorn不带高可用但这不代表没有数据安全手段。Longhorn原生支持卷快照和备份。快照是卷在某时间点的只读状态可以随时回滚备份则是把卷内容复制到远端S3或NFS。我建议对重要卷开启定期快照比如每天做一次快照保留最近7天再定期把快照推送到S3。这样即使节点真的挂掉重建也能从外部备份把数据拉回来。快照和备份可以在UI里针对每个卷配置也可以在StorageClass里加RecurringJob。UI上的操作很直观点几下就行不需要记命令。但我建议至少在YAML里看一眼RecurringJob的CRD定义因为它也是Longhorn Operator能力的体现。监控方面Longhorn自带了Metrics接口可以被Prometheus抓取。部署Prometheus监控K8s的时候在Prometheus配置里加一个scrape jobtarget指向longhorn-backend:9500然后就能在Grafana里导入官方面板查看卷IO、节点容量、volume健康状态。单节点虽然规模小但一旦出了问题没有监控曲线排查就跟大海捞针一样。5. 常见问题与排查技巧实录5.1 PVC一直Pending多半是调度和容忍度问题我见过最多的情况就是PVC创建后一直处于Pending状态。遇到这种情况先判断是不是存储类不存在kubectl get storageclass然后kubectl describe pvc test-pvc看事件。如果是failed to provision volume with StorageClass之类的错多半是Longhorn那边没创建好卷。这时候去Longhorn UI看Volume列表往往能看到卷状态是detached或faulted或者是“找不到可调度节点”这类提示。单节点场景下最常见的原因就是instance-manager没有调度到节点上。instance-manager是承载卷引擎的组件如果节点有污点而Longhorn没配容忍度它就一直是Pending卷自然无法创建。重点排查kubectl -n longhorn-system get pods -o wide | grep instance-manager kubectl -n longhorn-system describe pod instance-manager-pod只要看到Pod事件里出现taint或者nodeSelector相关的内容就知道是调度问题按前面章节说的加容忍度或者去污点即可。还有一种可能是磁盘空间不足Longhorn要求数据目录至少有1GB可用空间如果宿主机根分区满了卷创建也会失败。5.2 Pod卡在ContainerCreatingiscsi与内核模块排查Longhorn的卷创建好了PVC也Bound了但业务Pod一直卡在ContainerCreating查看事件通常是MountVolume.MountDevice failed: rpc error: failed to mount .... 这种问题九成是节点上的iSCSI客户端没装好。先检查节点上open-iscsi到底装了没有which iscsiadm systemctl status iscsid如果命令不存在回到2.2节补装。如果服务是挂的启动它。启动后再检查内核模块lsmod | grep iscsi_tcp modprobe iscsi_tcp内核模块不加载iSCSI会话建立不起来挂载自然失败。还有一些老系统需要multipath-tools但单节点场景一般用不到。如果这些都没问题再去看Longhorn的csi-plugin Pod日志kubectl -n longhorn-system logs -l appcsi-plugincsi-plugin的日志会告诉你nodedriver有没有找到元数据以及挂载失败的具体ErrorCode。一般情况下把iscsi服务修好重启csi-plugin Pod就能解决。5.3 节点重启后卷状态异常恢复步骤与注意事项单节点集群最尴尬的时刻是重启宿主机。重启后可能会出现节点先NotReadyLonghorn UI里所有卷状态变成detached或者unknown的情况。如果只是临时重启过一会儿它会自动恢复但有时候会卡住。我建议的重启流程是先停掉业务应用再重启宿主机。如果已经重启且卷恢复不过来先看节点状态是否Ready再看iscsi服务是否重启成功。很多情况下iscsid不会随系统自动启动需要手动开启然后重启Longhorn相关Podsystemctl enable --now iscsid kubectl -n longhorn-system delete pod -l applonghorn-manager kubectl -n longhorn-system delete pod -l appcsi-plugin执行完这些等待Longhorn重新挂载卷。如果你的数据目录是独立磁盘还需要确认这块盘挂在原目录下没有因为UUID变化导致挂载点丢失。这一点在云主机上更常见——重启后数据盘可能没有自动挂载Longhorn找不到原来的卷文件。5.4 问题排查速查表从症状到方案一条龙为了让你以后不用翻全文我把常见问题整理成一张速查表症状可能原因排查命令 / 解决方式PVC一直PendingStorageClass不存在、副本调度失败、污点没容忍kubectl describe pvckubectl get storageclass看instance-manager是否ReadyPod卡在ContainerCreating节点缺open-iscsi、内部iscsid服务没启动、内核模块缺失which iscsiadmsystemctl status iscsidmodprobe iscsi_tcp重启后卷状态异常数据盘未自动挂载、iscsi服务没启动、Longhorn Pod未恢复mount -asystemctl enable --now iscsid重启longhorn-manager和csi-pluginUI访问不了Service类型是ClusterIP、NodePort被防火墙拦kubectl patch svc longhorn-frontend -p ...检查安全组卷状态faulted副本所在节点丢失、卷文件损坏查看Longhorn UI的Volume事件优先从快照/备份恢复数据写不进卷数据目录磁盘满、replica状态异常df -h清理旧镜像查看UI的Disk状态这张表是我在实际运维中反复用到的东西。单节点环境下很多问题其实就集中在iscsi、调度、磁盘这三个变量上只要把这三个变量吃透排错就会快很多。我个人在实际操作中的体会是单节点K8s上部署Longhorn最值得花时间的地方反而不是安装本身而是“想清楚这台机器要怎么用”。如果你把它当生产集群来要求它确实不够格但如果你把它当成一台有完整K8s存储体验的“开发服务器”那Longhorn能在有限硬件里给你极大的便利。最后再分享一个小技巧安装完成后记得把每个卷的快照策略都调成“至少保留一个”这样你后面在UI里做任何测试性的改造都不会因为手滑把一个好端端的卷给点没了。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询