Longhorn 分布式存储介绍

发布时间: 更新时间: 总字数:5197 阅读时间:11m 作者: IP上海 分享 网址

Longhorn 是一个轻量级、可靠且易于使用的 Kubernetes 分布式块存储系统,100%开源,可在任何地方运行。

介绍

Longhorn 是一个轻量级且功能强大的云原生 Kubernetes 分布式存储平台,可以在任意基础设施上运行。Longhorn 与 Rancher 结合使用,将帮助您在 Kubernetes 环境中轻松、快速和可靠地部署高可用性持久化块存储。

架构总览:控制面与数据面分离

Longhorn 的设计核心在于微控制器模式(Micro-controller pattern)

  • 控制面 (Control Plane):由 longhorn-manager 负责,处理全局调度、API 响应。
  • 数据面 (Data Plane):由 longhorn-instance-manager 及其内部运行的 longhorn-engine 进程负责,直接处理 I/O。

核心服务组件详细解析

以下是核心服务的详细使用总结和底层逻辑:

Longhorn Manager (longhorn-manager) —— 大脑

`longhorn-manager 是指挥官,负责逻辑调度,它的生死不影响现有数据的读写。

  • 部署形态:DaemonSet(每个节点运行一个)。
  • 功能
    • 它不直接处理数据读写。
    • 它监听 Kubernetes API (CRD changes)。
    • 它负责调度:决定 Replica 放在哪个节点,决定 Volume 挂载在哪个节点。
    • 它通过 gRPC 指挥 longhorn-instance-manager 启动或停止 Engine/Replica 进程。
  • 关键点:如果 longhorn-manager 挂了,正在运行的 Volume 不会中断(因为数据面是独立的),但无法执行 Attach/Detach 或创建快照等操作。

Longhorn Instance Manager (longhorn-instance-manager) —— 进程管家

longhorn-instance-manager 是数据面的核心载体。所有的 Engine 和 Replica 都是它肚子里的子进程。运维 Longhorn 最关键的就是保障 Instance Manager 的资源充足且稳定。

  • 部署形态:DaemonSet(每个节点运行一个,Pod 名字通常带 instance-manager-xxxe-xxx,新版本已合并)。
  • 核心逻辑
    • 这是一个中介服务。Longhorn 为了避免为每个 Volume 启动单独的 Pod(那样太重了,且 IP 资源浪费),选择在一个 Pod 内部通过 spawn 进程的方式来运行 Engine 和 Replica。
    • Instance Manager 就像是一个专用的 Docker 守护进程,负责在其 Pod 内部启动、监控、停止 longhorn-engine 二进制进程。
  • 资源消耗这是排查性能问题的核心。 所有的 I/O 流量最终都流经这个 Pod。如果节点上 Volume 很多且 I/O 很大,该 Pod 的 CPU 会飙升。
  • 日志排查:查看 Volume 崩溃原因时,不要只看 Manager 日志,必须看 Instance Manager 的日志,因为 Engine 的标准输出(stdout/stderr)会被重定向到这里。

在生产环境中,给 longhorn-instance-manager 预留足够的 CPU Request/Limit,并监控其日志,因为它是整个存储系统最繁忙的地方。

Longhorn Engine (longhorn-engine) —— 逻辑核心

longhorn-engine 是业务逻辑,它实现了数据的复制算法、快照合并和重建逻辑。

  • 形态:并非独立的 Pod,而是运行在 instance-manager Pod 内部的进程
  • 角色分为两种
    1. Engine Controller (Volume Head)
      • 对应 Volume,一个 Volume 只有一个活跃的 Controller。
      • 通常运行在 挂载了该 Volume 的节点 上(为了本地读写性能)。
      • 作用:接收来自文件系统的读写请求,将写请求同步分发给所有健康的 Replicas。
    2. Engine Replica (Data Store)
      • 对应后端存储文件。
      • 运行在存储数据的节点上。
      • 作用:接收 Controller 发来的数据并写入底层磁盘(/var/lib/longhorn/replicas/...),并利用 Linux sparse file 特性存储。
  • 高可用机制:当 Controller 发现某个 Replica 写入失败,会将其标记为 Error,并不影响 I/O,稍后 Manager 会启动重建流程。

Longhorn CSI Plugin —— 桥梁

  • 包含csi-attacher, csi-provisioner, csi-resizer, longhorn-csi-plugin
  • 作用:Kubernetes 的 kubelet 调用 CSI 接口来 Mount 磁盘。CSI Plugin 收到请求后,调用 Longhorn Manager 的 API 说:请把这个 Volume 挂载到本节点

服务交互流程(数据路径)

为了理解这些服务如何协作,我们看一个写入操作的流程:

  1. Pod 发起写入:业务 Pod 向挂载路径写入数据。
  2. 内核块设备:数据进入 /dev/longhorn/vol-name 设备。
  3. Engine Controller:该设备由 longhorn-engine (Controller 进程) 托管。Controller 进程运行在 instance-manager Pod 中。
  4. 网络传输:Controller 将数据包复制,通过 TCP 网络并发发送给分布在不同节点上的 longhorn-engine (Replica 进程)。
  5. 落盘:Replica 进程(也在各节点的 instance-manager 中)收到数据,写入本地磁盘文件(backing file)。
  6. 确认:所有 Healthy Replica 确认写入成功后,Controller 返回成功给业务 Pod。

相关进程

longhorn controller:I/O 的总指挥

如果不运行 controller,Longhorn 的 Volume 就只是一堆躺在硬盘上的静态文件(Replica)。controller 的作用是将这些静态文件激活为一个可读写的块设备。

核心职责

  1. 前端暴露 (Frontend):创建一个 Linux 块设备(如 /dev/longhorn/vol-name),供文件系统挂载。
  2. 读写分发 (Fan-out Write)
    • :收到 4KB 数据 -> 并发发送给所有 Healthy Replicas -> 等待确认 -> 返回成功。
    • :收到请求 -> 从任意一个响应最快的 Healthy Replica 读取 -> 返回数据。
  3. 高可用仲裁:监控 Replica 的连接状态。如果某个 Replica 写入超时或报错,Controller 会将其踢出(Mark as Error),保证 Volume 整体可用。

关键参数解析 (Flags)

longhorn controller 通常由 longhorn-instance-manager 启动,命令结构如下:

longhorn controller <volume-name> --frontend <type> --replica tcp://IP:Port ...

参数分类 参数名 说明 技术细节与思考
网络控制 --listen 监听地址 (IP:Port) 通常监听 localhost:Port。这是控制平面(Longhorn Manager)向它发送指令(如扩容、快照、添加 Replica)的 gRPC 接口。
前端接口 --frontend 核心参数,决定设备类型 socket: 创建一个 Unix Domain Socket,用于内部通信或 vhost-user。
tgt-blockdev / tgt-iscsi: 使用 TGT (Linux SCSI Target Framework) 创建 /dev/longhorn/xxx 块设备。这是 K8s Pod 挂载的基础。
副本管理 --replica 初始副本列表 格式为 tcp://<Replica-IP>:<Port>。启动时,Controller 会尝试连接这些地址。注意:这只是初始列表,运行中可以通过 gRPC 动态增删。
容量定义 --size 卷大小 (Bytes) 必须与 Replica 的大小一致,否则启动失败。
升级/恢复 --upgrade 升级模式标记 告诉 Controller 这是一个热升级过程,它会尝试接管现有的 socket 连接,确保 I/O 不中断。

核心参数深度剖析:--frontend

这是理解 Longhorn 性能和兼容性的关键参数。Controller 如何让 Linux 内核看到这个磁盘?

  1. tgt-blockdev (默认/主流)
  • 机制:Longhorn 启动一个 tgt (Linux SCSI Target) 进程作为伴生进程。
  • 流程:Controller 进程 <–> TGT 进程 <–> /dev/longhorn/vol-name 块设备。
  • 优点:兼容性极好,所有 Linux 发行版都支持 SCSI/Block 设备。
  • 缺点:I/O 路径较长(用户态 -> 内核态 -> 用户态 -> 网络),有一定的上下文切换开销。
  1. socket (主要用于 v2 Data Engine 或特殊场景)
  • 机制:不创建块设备,直接暴露一个 Unix Socket。
  • 场景:用于 SPDK (Storage Performance Development Kit) 场景,或者作为 VM 的 vhost-user 后端。
  • 优点:极致性能,完全绕过内核。

Controller 的运行时行为与交互

理解参数后,我们需要知道 Controller 运行起来后在做什么,这对于排错非常有用。

场景一:Replica 故障处理 (Degraded Mode)

假设启动参数为: longhorn controller vol-1 --replica tcp://10.0.1.1:9502 --replica tcp://10.0.1.2:9502

  1. Controller 启动,连接两个 Replica。状态:Healthy
  2. 事件:写入请求到达,发往 1.1 和 1.2。
  3. 故障:1.2 网络断开或磁盘满,写入返回 Error。
  4. 反应:Controller 将 1.2 标记为 ERR
  5. 结果:后续的 I/O 只发给 1.1。Volume 状态变为 Degraded(降级),但业务 不感知,读写不中断。

场景二:动态添加副本 (Rebuilding)

当 Longhorn Manager 决定重建副本时,它不会重启 Controller 进程来修改 --replica 参数,而是:

  1. Manager 调用 Controller 的 gRPC API
  2. 发送 ReplicaAdd 指令。
  3. Controller 动态建立与新 Replica 的 TCP 连接,并开始后台同步。

架构思考:Controller 的设计哲学

为什么 Longhorn 要设计一个独立的 controller 进程,而不是让挂载端直接连 Replica?

  1. “瘦” 控制器 (Thin Controller)

longhorn controller 被设计得非常轻量。

  • 无状态:它不持久化存储任何数据(数据全在 Replica 里)。
  • 内存态:它只在内存中维护谁是健康的 Replica这张表。如果 Controller 崩溃重启,它只需要重新连接 Replica,就能恢复工作。
  1. 写放大的源头 (Source of Write Amplification)

这是分布式存储的代价。

  • 参数 --replica 指定了几个地址,Controller 就必须把一份流量放大几倍发送出去。
  • 性能瓶颈点:Controller 的网络带宽通常是瓶颈。如果网络带宽是 1Gbps,3 副本模式下,业务最大写入速度只有 330Mbps(因为 100MB 业务数据 = 300MB 网络流量)。
  1. 前端可插拔

通过 --frontend 参数的设计,Longhorn 解耦了核心存储逻辑对外暴露协议

  • 今天可以用 iSCSI/TGT。
  • 明天可以用 NVMe-oF(Longhorn v2 正在做的)。
  • 只要 Controller 的核心逻辑(读写分发、快照管理)不变,前端接口可以随意替换以适应新的内核技术。

longhorn replica:数据的最终守护者

longhorn replica 进程是 Longhorn 存储的最底层单元,它直接操作磁盘文件。每一个 Longhorn Volume 的副本(Replica),在所在的节点上都对应一个运行着的 longhorn replica 进程。

核心作用

  • 服务端:启动一个 TCP 服务器(通常监听随机高位端口),等待 Engine Controller 的连接。
  • 落盘:接收 Controller 发来的数据块(4KB 对齐),写入本地目录下的稀疏文件(Sparse File)。
  • 快照管理:维护快照链(Snapshot Chain),管理 .img 数据文件和 .meta 元数据文件。

关键参数解析 (Flags)

执行命令通常形如: longhorn replica --listen IP:Port --size <bytes> /path/to/replica/directory

参数 说明 技术细节
--listen 监听地址与端口 用于与 Engine Controller 通信。Controller 会把数据扇出(Fan-out)给所有 Replica 的这个端口。
--size 卷大小 (Bytes) 定义卷的逻辑大小。Replica 初始化时会检查元数据,如果大小不匹配会报错。
--backing-file 基础镜像路径 (重要) 如果该 Volume 基于某个 Backing Image(如 VM 镜像),Replica 会以只读方式挂载该路径作为底层数据源。
directory (位置参数) 存储目录 指定数据实际存放在宿主机的哪个目录下,通常是 /var/lib/longhorn/replicas/<pvc-name>-<random-id>/

底层工作机制

longhorn replica 启动时,它会在指定目录下寻找或创建以下文件:

  1. volume.meta: 存储卷的元数据(大小、Head 文件的位置、父子快照关系)。
  2. volume-head.img: 当前活跃的读写层。所有新的写入都发生在这里。
  3. volume-snap-xxx.img: 历史快照文件(只读)。
  4. revision.counter: 用于防止脑裂和数据陈旧,记录写入序列号。

longhorn sync-agent:幕后的搬运工

longhorn sync-agent 是一个辅助服务,它的存在感不如 Controller 和 Replica 强,但在 数据恢复(Rebuild)备份(Backup) 场景中起决定性作用。

核心作用

它通常作为 Daemon 运行在 longhorn-instance-manager Pod 内部(或者在旧版本中作为 sidecar)。它的核心职责是解决**如何在两个 Replica 之间高效传输巨大的稀疏文件**

  • 副本重建 (Rebuilding):当一个节点挂了,新节点启动一个新的空 Replica 时,Controller 无法通过普通 I/O 把旧数据补回来。这时,Controller 会命令 sync-agent 从一个健康的 Replica 把所有快照文件过来。
  • 接收器模式:它本质上是一个 gRPC Server,专门处理文件的接收和同步操作。

关键参数解析

执行命令通常形如: longhorn sync-agent --listen IP:Port

参数 说明 技术细节
--listen 监听地址与端口 默认监听 0.0.0.0:8002 (端口可能随版本变化)。Controller 通过此端口下发同步指令。

工作流程深度交互

为了理解 sync-agent 的价值,我们看一个 Replica 重建流程

  1. 场景:Replica A(健康),Replica B(新创建,空的)。
  2. 指令:Engine Controller 发现 B 是空的,需要从 A 同步数据。
  3. 调用:Controller 通过 gRPC 呼叫 Replica B 旁边的 sync-agent
  4. 传输
    • Replica B 的 sync-agent 会主动连接 Replica A。
    • 不是通过 Controller 中转数据(那样会把 Controller 堵死)。
    • 它是直接从 Replica A 的磁盘读取快照文件,流式传输到 Replica B 的磁盘。
  5. 完成:文件传输完毕后,Controller 将 B 加入活跃后端列表。

longhorn replica、sync-agent 对比与总结

特性 longhorn replica longhorn sync-agent
关注点 实时 I/O (Hot Path) 批量数据传输 (Cold/Warm Path)
通信协议 自定义 TCP 协议 (高性能,低延迟) gRPC / HTTP (控制流与大文件流)
何时忙碌 业务应用读写数据时 副本重建、克隆卷、恢复备份时
资源消耗 消耗 CPU (校验和计算) 和 磁盘 IOPS 消耗 网络带宽 (节点间拷贝数据)
如果挂了 卷降级 (Degraded) 或 卷不可用 无法重建副本,无法备份,但不影响在线读写

思想与思考:为什么这样设计?

Longhorn 将 replica(实时读写)和 sync-agent(后台同步)分开,体现了 控制流与数据流分离 以及 快慢路径分离 的架构思想。

  1. 避免阻塞主路:如果在 Engine Controller 的主 I/O 线程中处理几百 GB 的副本重建数据拷贝,那么业务 I/O 的延迟会瞬间飙升甚至超时。
  2. 专业分工
    • replica 进程极致优化 4K 随机写性能。
    • sync-agent 优化大文件的流式传输和断点续传。
  3. 微服务化instance-manager 就像一个操作系统,里面运行着负责读写的 replica 进程和负责运维搬运的 sync-agent 进程,互不干扰。

运维总结与常见问题 (Troubleshooting)

在管理这些服务时,以下经验至关重要:

服务组件 常见状态/问题 排查/处理思路
Longhorn Manager CrashLoopBackOff 检查 K8s API 连接,检查 CRD 是否完整。如果 Manager 重启,不会导致 IO 中断。
Instance Manager High CPU/Memory 这是正常的,如果负载过高,考虑隔离 Longhorn 节点或限制单节点 Volume 数量。不要随意 Kill 这个 Pod,杀掉它会导致该节点所有 Volume 瞬间掉线
Instance Manager Image GC 问题 如果 K8s 节点磁盘压力大触发 GC,可能会误删 engine 二进制镜像,导致无法启动新进程。
Longhorn Engine Volume Detached 意味着 Controller 进程挂了。通常是因为网络抖动导致 Replica 全部断连,触发了 Engine 的自我保护机制(Faulted)。
Longhorn Engine Upgrade 升级 Longhorn 时,实际上是替换 longhorn-manager 镜像 -> 创建新的 instance-manager -> 重启 Engine 进程。这就是 Longhorn 所谓的Live Upgrade,I/O 会有瞬间暂停但不断开连接(前端使用 iSCSI/TGT 或用户态 socket 保持 fd)。

特殊服务补充

除了上述核心,还有两个相关服务值得注意:

  • Share Manager (share-manager)
    • 仅在 ReadWriteMany (RWX) 模式下出现。
    • 它是一个单独的 Pod,内部运行 NFS Server。Longhorn 将 Volume 挂载给它,它再通过 NFS 暴露给多个业务 Pod。
  • Backing Image Manager
    • 用于管理基础镜像(如 VM 的 qcow2 镜像)。负责下载、分发这些只读层。

参考

  1. https://www.rancher.cn/longhorn/
  2. https://documentation.suse.com/cloudnative/rancher-manager/latest/zh/integrations/longhorn/overview.html
  3. https://longhorn.io/docs/1.10.0/deploy/install/install-with-kubectl/
本文总阅读量 次 本站总访问量 次 本站总访客数
Home Archives Categories Tags Statistics