商店现已上线

我们打造用于网站、AI 智能体和 LLM 训练的 Workstation AI 机器——在线配置并购买。

获取同行价格
AI 产品
AI 实验室OpenAI 智能体Claude 代理Grok BotWorkstation AI 原生 CRM营销所有产品
AI 解决方案
应用型 AIAI 智能体生成式 AIAI 自动化AI 技能提升中小企业 AI 套餐企业 AI 实验室AI 工作站NVIDIA 硬件与软件NVIDIA 加速计算私有 AIGPU 集群边缘 AI行业 AI
AI 服务
平台现代化数字工程数据基础与 AI自主运营AI 咨询DevOps 自动化网络安全软件开发智能体构建MLOps 搭建GPU 租赁
关于我们
公司我们的故事合作伙伴客户案例
AI 数据中心
AI 洞察Jev 系列基准测试实验室模型选择
技术说明
文档
Linux 操作系统UbuntuRed Hat Enterprise LinuxSUSE LinuxAlpine LinuxDebian, Rocky & AlmaLinux
AI 云平台AWS & Amazon BedrockGoogle Cloud & Vertex AIMicrosoft Azure & AI FoundryGPU 云与算力市场
私有 AI 数据中心面向律师事务所面向会计师事务所本地部署平台全面安全的云
工具Ring PromoterJobshout
新闻
博客
联系我们登录

面向现代企业的 AI 工作站、AI 多智能体软件、GPU 基础设施和智能代理解决方案。

联系我们

AI 解决方案

应用型 AIAI 智能体生成式 AIAI 自动化AI 技能提升中小企业 AI 套餐企业 AI 实验室行业 AI

产品

所有产品Workstation AI native CRM 与 ERP营销OpenAI 智能体Ring PromoterJobshout

公司

关于我们公司AI 数据中心为什么选择Workstation合作伙伴客户案例定价联系TenthMatrix

资源

AI 洞察技术说明文档Linux 操作系统AI 云平台私有 AI 数据中心博客搜索网站地图
英国办公室
77-79 Marlowes, Hemel Hempstead HP1 1LF路线指引 — 从 M25 外环伦敦 20 号出口驶出公司编号: 11641870周一至周五:上午 9:00 - 下午 6:00 GMT
+44 7515 356 146
比利时办公室
Workstation SRL, Rue Vanderkindere 34, 1180 Uccle, BrusselsBE 0751.518.683周一至周五:上午 9:00 - 下午 6:00 CET
+32 492 45 67 46
印度办公室
#159 Sector 9, Pocket 1, DDA Flats, 110077 Dwarka, New Delhi
+91 98881 98841

© 2026 Workstation AI。保留所有权利。

隐私数据删除Cookie服务条款网站地图

NVIDIA, the NVIDIA logo, RTX, RTX PRO, Blackwell, CUDA, NVLink, MGX, Omniverse, Spectrum-X, Quantum, BlueField, DGX and HGX are trademarks and/or registered trademarks of NVIDIA Corporation in the US and other countries. AMD, the AMD Arrow logo, EPYC, Instinct, Ryzen and Threadripper are trademarks of Advanced Micro Devices, Inc. Dell and PowerEdge are trademarks of Dell Inc. or its subsidiaries. Intel and Xeon are trademarks of Intel Corporation or its subsidiaries. AMAX, AceleMax and LiquidMax are trademarks of AMAX Engineering Corporation. All other product names, logos and brands are the property of their respective owners. We use them only to identify the products we describe, supply or support; their use does not mean their owners endorse us.

Loading blog...

首页 / 博客
KubernetesDevOpsDatabaseBackend

用于生产 k3s 集群的 Longhorn 存储:动态 PVC 扩展、复制和灾难恢复

k3s 和 Rancher 上使用 Longhorn 的生产级分布式存储

Balinder Walia2026年4月12日19 min read
Longhorn k3s storage

存储是Kubernetes中最难的问题。计算是无状态且可替换的——杀死一个 Pod,安排另一个 Pod。 Networking 拥有成熟的 CNI 插件和服务网格。 But storage?存储是状态所在,数据在重新启动后仍然存在,单个错误配置可能意味着永久数据丢失。对于运行生产工作负载(数据库、消息队列、应用程序状态)的 k3s 集群,您需要一个分布式、弹性、可扩展且可操作的存储解决方案。 Longhorn 就是这样的解决方案。

Longhorn 是适用于 Kubernetes 的轻量级、可靠且易于使用的分布式块存储系统。它最初由 Rancher Labs(现为 SUSE 的一部分)开发,是一个 CNCF 孵化项目,专为简单性很重要但生产可靠性不容妥协的集群而构建。与需要专用存储节点和深厚专业知识的 Ceph 或提供零冗余的本地路径配置程序不同,Longhorn 实现了 k3s 集群所需的精确平衡:跨节点的分布式复制、动态卷扩展、云对象存储的集成备份、快照和灾难恢复 - 所有这些都通过干净的 UI 和 Kubernetes 原生 CRD 进行管理。

本指南涵盖了在 k3s 上部署 Longhorn 进行生产所需的一切:架构内部结构、安装方法、StorageClass 配置、动态 PVC 扩展、复制策略、备份和灾难恢复、卷加密、数据库性能调整、监控和故障排除。每项建议都附带经过生产测试的配置,您可以适应您的环境。

Longhorn 架构

了解 Longhorn 的架构对于做出有关复制、性能和故障处理的明智决策至关重要。 Longhorn 由三个核心组件组成,它们协同工作,在连接到 Kubernetes 节点的本地磁盘上提供分布式块存储。

Longhorn Manager作为 DaemonSet 在集群中的每个节点上运行。它是 Longhorn 的控制平面 — 它处理 API 调用、编排卷创建、管理复制、协调快照和备份,并与 Kubernetes API 服务器通信以管理 PersistentVolume 和 PersistentVolumeClaim 生命周期。当您创建引用 Longhorn StorageClass 的 PVC 时,Longhorn Manager 通过 CSI 驱动程序接收请求、配置卷并在可用节点上安排其副本。

Longhorn 引擎是一个按卷存储控制器,作为 Linux 用户空间进程实现(基于 Rancher Longhorn 引擎的分支)。每个卷都有自己的专用引擎进程,在该卷所附加的节点上运行。该引擎处理该卷的所有读取和写入 I/O,在确认对应用程序的写入之前将写入同步复制到所有配置的副本。这种按卷的架构意味着一个卷的引擎崩溃或挂起不会影响任何其他卷——这是生产的关键隔离属性。

副本是实际的数据存储过程。每个副本在其运行的节点的本地磁盘上存储卷数据的完整副本。默认情况下,Longhorn 为每个卷创建三个副本,分布在不同的节点(也可以选择不同的区域)。副本对快照使用写时复制机制,无论卷大小如何,都可以即时创建快照。

Longhorn 架构:管理器、引擎和副本节点 1 (worker-01)Longhorn 管理器(DaemonSet Pod)Longhorn 引擎卷:pvc-db-data-0处理 R/W I/O,同步到副本复制品 A/var/lib/longhorn/replicas/本地 NVMe/SSD:/dev/nvme0n1PostgreSQL 吊舱安装 pvc-db-data-0节点 2 (worker-02)Longhorn 管理器(DaemonSet Pod)副本 B/var/lib/longhorn/replicas/本地 NVMe/SSD:/dev/nvme1n1节点 3 (worker-03)Longhorn 管理器(DaemonSet Pod)复制品 C/var/lib/longhorn/replicas/本地 NVMe/SSD:/dev/nvme2n1同步写入同步写入管理器 (DaemonSet)引擎(每卷)副本(数据副本)应用盒本地磁盘

该架构为生产使用提供了几个关键属性。容错能力:在三个节点上具有三个副本,该卷可以承受两个同时出现的节点故障。隔离:每个卷都有自己的引擎进程,因此一个卷中的错误或挂起无法级联。简单性:没有专用存储节点,没有单独的 Ceph 或 GlusterFS 集群 — Longhorn 使用本地磁盘在与应用程序 Pod 相同的工作节点上运行。Kubernetes-native:的所有内容均通过 CRD、kubectl 和 Kubernetes CSI 接口进行管理。

在 k3s

上安装 Longhorn

Longhorn 可以通过三种方法安装在 k3s 上:Helm 图表(建议用于生产)、Rancher App Marketplace(如果您有 Rancher 管理集群)或直接 kubectl apply。安装之前,请确保您的节点满足先决条件。

先决条件

# Verify prerequisites on each node
# Required: open-iscsi (for iSCSI support)
sudo apt-get install -y open-iscsi
sudo systemctl enable iscsid
sudo systemctl start iscsid

# Required: NFSv4 client (for backup/restore to NFS targets)
sudo apt-get install -y nfs-common

# Recommended: check all prerequisites with Longhorn's environment check script
curl -sSfL https://raw.githubusercontent.com/longhorn/longhorn/v1.7.2/scripts/environment_check.sh | bash

# Verify kernel modules
lsmod | grep -E "iscsi_tcp|dm_crypt|nfs"

# On k3s specifically, local-path-provisioner is the default.
# We will make Longhorn the default StorageClass after installation.

通过 Helm 安装(推荐)

# Add the Longhorn Helm repository
helm repo add longhorn https://charts.longhorn.io
helm repo update

# Create the namespace
kubectl create namespace longhorn-system

# Install with production values
helm install longhorn longhorn/longhorn \
  --namespace longhorn-system \
  --version 1.7.2 \
  --values longhorn-values.yaml

这是具有调整默认值的生产级values.yaml:

# longhorn-values.yaml — Production configuration
persistence:
  defaultClass: true
  defaultFsType: ext4
  defaultClassReplicaCount: 3
  defaultDataLocality: best-effort
  reclaimPolicy: Retain

defaultSettings:
  backupTarget: s3://longhorn-backups@eu-west-1/
  backupTargetCredentialSecret: longhorn-backup-s3-secret
  createDefaultDiskLabeledNodes: true
  defaultDataPath: /var/lib/longhorn/
  defaultReplicaCount: 3
  defaultDataLocality: best-effort
  replicaSoftAntiAffinity: false
  replicaAutoBalance: best-effort
  storageOverProvisioningPercentage: 150
  storageMinimalAvailablePercentage: 15
  guaranteedInstanceManagerCPU: 12
  upgradeChecker: false
  autoSalvage: true
  autoDeletePodWhenVolumeDetachedUnexpectedly: true
  disableSchedulingOnCordonedNode: true
  replicaZoneSoftAntiAffinity: true
  volumeAttachmentRecoveryPolicy: wait
  snapshotDataIntegrity: fast-check
  snapshotDataIntegrityCronjob: "0 7 * * *"
  concurrentAutomaticEngineUpgradePerNodeLimit: 1

longhornManager:
  priorityClass: system-cluster-critical
  tolerations:
    - key: "node-role.kubernetes.io/storage"
      operator: "Exists"
      effect: "NoSchedule"

longhornDriver:
  priorityClass: system-cluster-critical
  tolerations:
    - key: "node-role.kubernetes.io/storage"
      operator: "Exists"
      effect: "NoSchedule"

longhornUI:
  replicas: 2

ingress:
  enabled: true
  ingressClassName: nginx
  host: longhorn.internal.example.com
  tls: true
  tlsSecret: longhorn-tls
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: longhorn-basic-auth
    nginx.ingress.kubernetes.io/auth-realm: "Longhorn UI"

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 100m
    memory: 128Mi
通过 Rancher 应用市场安装

如果 Rancher 管理您的 k3s 集群,请导航至应用程序和 应用程序。市场 → 图表 → Rancher UI 中的 Longhorn。选择您的目标命名空间 (longhorn-system),通过表单界面配置值,然后单击安装。 Rancher 自动处理 Helm 生命周期管理和升级跟踪。

通过 kubectl 安装

# Direct manifest installation
kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.7.2/deploy/longhorn.yaml

# Verify all pods are running
kubectl -n longhorn-system get pods -w

安装后:将 Longhorn 设置为默认 StorageClass

# Remove default annotation from k3s local-path
kubectl patch storageclass local-path -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'

# Verify Longhorn is now default
kubectl get storageclass
# NAME                 PROVISIONER          RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
# longhorn (default)   driver.longhorn.io   Retain          Immediate           true                   5m
# local-path           rancher.io/local-path Delete         WaitForFirstConsumer false                 30d
用于生产的

StorageClass 配置

默认的 Longhorn StorageClass 适用于开发,但生产工作负载需要针对不同用例的特定配置 - 数据库需要高复制和特定数据局部性,临时处理需要快速单副本卷,共享卷需要 RWX 支持。

# StorageClass for database workloads — maximum durability
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: longhorn-db
  annotations:
    storageclass.kubernetes.io/is-default-class: "false"
provisioner: driver.longhorn.io
allowVolumeExpansion: true
reclaimPolicy: Retain
volumeBindingMode: Immediate
parameters:
  numberOfReplicas: "3"
  staleReplicaTimeout: "2880"
  fromBackup: ""
  fsType: ext4
  dataLocality: best-effort
  recurringJobSelector: '[{"name":"db-snapshot","isGroup":true},{"name":"db-backup","isGroup":true}]'
---
# StorageClass for general workloads — balanced
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: longhorn-standard
provisioner: driver.longhorn.io
allowVolumeExpansion: true
reclaimPolicy: Delete
volumeBindingMode: Immediate
parameters:
  numberOfReplicas: "2"
  staleReplicaTimeout: "2880"
  fsType: ext4
  dataLocality: best-effort
---
# StorageClass for temporary/cache workloads — performance
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: longhorn-fast
provisioner: driver.longhorn.io
allowVolumeExpansion: true
reclaimPolicy: Delete
volumeBindingMode: Immediate
parameters:
  numberOfReplicas: "1"
  staleReplicaTimeout: "2880"
  fsType: ext4
  dataLocality: strict-local
---
# StorageClass for RWX (ReadWriteMany) shared volumes
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: longhorn-rwx
provisioner: driver.longhorn.io
allowVolumeExpansion: true
reclaimPolicy: Retain
volumeBindingMode: Immediate
parameters:
  numberOfReplicas: "3"
  nfsOptions: "vers=4.1,hard,timeo=50,retrans=3"
  staleReplicaTimeout: "2880"
  fsType: ext4

动态 PVC 扩展

Longhorn 最重要的生产功能之一是动态 PVC 扩展 — 能够在不停机、不丢失数据的情况下增加持久卷的大小,并且除了单个 kubectl 命令或清单更改之外无需手动干预。这对于数据增长不可预测并且磁盘空间不足意味着中断的数据库至关重要。

Longhorn 支持在线扩展(卷在增长时保持连接和安装)和离线扩展(首先分离卷)。在线扩展是默认且推荐的生产方法,因为它可以避免应用程序停机。

动态 PVC 扩展工作流程(在线)1用户补丁 PVCkubectl patch pvc --type merge规格.资源.请求.存储:50Gi → 100Gi2CSI 驱动程序接收请求NodeExpandVolume / ControllerExpandVolume3Longhorn 坐标管理器验证请求,指示引擎 + 副本4每个副本都扩展副本 A(节点 1):50Gi → 100Gi ✓副本 B(节点 2):50Gi → 100Gi ✓副本 C(节点 3):50Gi → 100Gi ✓5引擎扩展文件系统在线 resize2fs/xfs_growfs(无需卸载)6PVC 状态更新状态.容量.存储: 100Gi ✓零停机时间应用程序从不中断

在 StorageClass

中启用卷扩展

动态PVC扩展的关键要求是StorageClass必须具有allowVolumeExpansion: true。 Longhorn 默认 StorageClass 已包含此字段,但如果您有自定义 StorageClass,请验证此字段是否已设置。

# Verify your StorageClass supports expansion
kubectl get storageclass longhorn -o yaml | grep allowVolumeExpansion
# allowVolumeExpansion: true

# If not set, patch it
kubectl patch storageclass longhorn -p '{"allowVolumeExpansion": true}'

分步:动态扩展 PVC

# 1. Check current PVC size
kubectl get pvc pg-data-postgresql-0 -n database
# NAME                    STATUS   VOLUME       CAPACITY   ACCESS MODES   STORAGECLASS   AGE
# pg-data-postgresql-0    Bound    pvc-abc123   50Gi       RWO            longhorn-db    30d

# 2. Check current usage inside the pod
kubectl exec -n database postgresql-0 -- df -h /var/lib/postgresql/data
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/longhorn   49G   42G  7.0G  86% /var/lib/postgresql/data

# 3. Expand the PVC (online — no downtime)
kubectl patch pvc pg-data-postgresql-0 -n database --type merge -p '{
  "spec": {
    "resources": {
      "requests": {
        "storage": "100Gi"
      }
    }
  }
}'

# 4. Watch the expansion progress
kubectl get pvc pg-data-postgresql-0 -n database -w
# Wait for CAPACITY to update from 50Gi to 100Gi

# 5. Verify the filesystem expanded inside the pod
kubectl exec -n database postgresql-0 -- df -h /var/lib/postgresql/data
# Filesystem      Size  Used Avail Use% Mounted on
# /dev/longhorn   99G   42G   57G  43% /var/lib/postgresql/data

# 6. Verify via Longhorn volume status
kubectl -n longhorn-system get volumes.longhorn.io -o wide

通过警报自动执行 PVC 扩展

在生产中,您不应等到磁盘已满 86% 时才手动对其进行扩展。使用 Prometheus 警报自动触发扩展或在容量变得至关重要之前提醒待命工程师。

# PrometheusRule for PVC capacity alerts
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: pvc-capacity-alerts
  namespace: monitoring
spec:
  groups:
    - name: pvc-capacity
      rules:
        - alert: PVCCapacityWarning
          expr: |
            (kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes) > 0.80
          for: 10m
          labels:
            severity: warning
          annotations:
            summary: "PVC {{ $labels.persistentvolumeclaim }} at {{ $value | humanizePercentage }} capacity"
            runbook: "Expand the PVC using: kubectl patch pvc {{ $labels.persistentvolumeclaim }} -n {{ $labels.namespace }} --type merge -p '{\"spec\":{\"resources\":{\"requests\":{\"storage\":\"NEW_SIZE\"}}}}'"
        - alert: PVCCapacityCritical
          expr: |
            (kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes) > 0.90
          for: 5m
          labels:
            severity: critical
          annotations:
            summary: "CRITICAL: PVC {{ $labels.persistentvolumeclaim }} at {{ $value | humanizePercentage }}"
            description: "Immediate expansion required to prevent application failure"

卷复制和数据局部性

Longhorn 跨多个节点复制卷数据以防止硬件故障。复制因子和数据局部性设置控制持久性、性能和存储效率之间的权衡。

复制因子决定存在多少数据副本。默认值为 3,这意味着每次写入都存储在三个不同的节点上。对于生产数据库,3 是最小推荐值。对于不太重要的工作负载,您可以将其设置为 2 以节省存储空间,或者对于可以接受数据丢失的临时/缓存卷,将其设置为 1。

数据局部性控制 Longhorn 是否尝试将副本保留在与使用卷的 Pod 相同的节点上。共有三种模式:

  • 禁用— 副本纯粹根据可用空间和反关联性进行调度。 Pod 可能会从远程节点上的副本读取数据,从而给每个 I/O 操作增加网络延迟。
  • 尽力而为— Longhorn 尝试将一个副本放置在与消费 Pod 相同的节点上。如果本地节点空间不足或 Pod 迁移,卷仍然可以工作,但延迟可能会稍高。这是大多数工作负载的推荐设置。
  • 严格本地— 该卷只能在具有本地副本的节点上使用。如果 pod 被调度到没有本地副本的节点,则卷附加会失败。仅将其用于延迟敏感的单副本工作负载(您接受持久性权衡)。
# Change replication factor on an existing volume
kubectl -n longhorn-system patch volumes.longhorn.io pvc-abc123 \
  --type merge -p '{"spec":{"numberOfReplicas":3}}'

# Set data locality on existing volume
kubectl -n longhorn-system patch volumes.longhorn.io pvc-abc123 \
  --type merge -p '{"spec":{"dataLocality":"best-effort"}}'

# Replica auto-balancing (spreads replicas evenly across nodes)
# Set via Longhorn settings
kubectl -n longhorn-system edit settings.longhorn.io replica-auto-balance
# Set value to: best-effort

快照和备份

Longhorn 提供两种不同的数据保护机制:快照(本地、即时、用于快速回滚)和备份(远程、到对象存储、用于灾难恢复)。了解何时使用每种方法至关重要。

快照与卷副本本地存储在同一磁盘上。它们是使用写​​时复制即时创建的——在快照时不复制任何数据,只有在快照分配额外空间后进行新的写入。快照非常适合在有风险的迁移或部署之前快速回滚,但它们不能防止节点或磁盘故障,因为它们与卷位于同一存储上。

备份将卷数据复制到外部备份目标 — S3、GCS、Azure Blob 或任何 S3 兼容存储(MinIO、Wasabi)。备份在块级别是增量的:仅传输自上次备份以来更改的块。这使得定期备份变得快速且存储高效。备份可以防止整个集群丢失,因为它们是独立存在的。

配置备份目标

# Create the S3 credentials secret
kubectl create secret generic longhorn-backup-s3-secret \
  -n longhorn-system \
  --from-literal=AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE \
  --from-literal=AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY \
  --from-literal=AWS_ENDPOINTS=https://s3.eu-west-1.amazonaws.com

# Set the backup target in Longhorn settings
kubectl -n longhorn-system edit settings.longhorn.io backup-target
# Set value to: s3://longhorn-backups@eu-west-1/

kubectl -n longhorn-system edit settings.longhorn.io backup-target-credential-secret
# Set value to: longhorn-backup-s3-secret

# For GCS backup target
# value: s3://longhorn-backups@us/  (GCS is S3-compatible via interop)
# Or use the GCS JSON key:
kubectl create secret generic longhorn-backup-gcs-secret \
  -n longhorn-system \
  --from-literal=GOOGLE_APPLICATION_CREDENTIALS=/var/longhorn-backup/gcs-key.json \
  --from-file=gcs-key.json=./service-account-key.json

# For Azure Blob backup target
kubectl create secret generic longhorn-backup-azure-secret \
  -n longhorn-system \
  --from-literal=AZBLOB_ACCOUNT_NAME=prodbackupstorage \
  --from-literal=AZBLOB_ACCOUNT_KEY=base64encodedkeyhere

VolumeSnapshot 类和快照 YAML

# VolumeSnapshotClass for Longhorn
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
  name: longhorn-snapshot-vsc
driver: driver.longhorn.io
deletionPolicy: Delete
parameters:
  type: snap
---
# Create a VolumeSnapshot
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: pg-data-snap-before-migration
  namespace: database
spec:
  volumeSnapshotClassName: longhorn-snapshot-vsc
  source:
    persistentVolumeClaimName: pg-data-postgresql-0
---
# Restore a PVC from a snapshot
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pg-data-restored
  namespace: database
spec:
  storageClassName: longhorn-db
  dataSource:
    name: pg-data-snap-before-migration
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi

定期备份计划

# Recurring snapshot job — every 4 hours, retain 6
apiVersion: longhorn.io/v1beta2
kind: RecurringJob
metadata:
  name: db-snapshot-4h
  namespace: longhorn-system
spec:
  cron: "0 */4 * * *"
  task: snapshot
  retain: 6
  concurrency: 2
  groups:
    - db-volumes
  labels:
    tier: database
---
# Recurring backup job — daily at 02:00, retain 14 days
apiVersion: longhorn.io/v1beta2
kind: RecurringJob
metadata:
  name: db-backup-daily
  namespace: longhorn-system
spec:
  cron: "0 2 * * *"
  task: backup
  retain: 14
  concurrency: 2
  groups:
    - db-volumes
  labels:
    tier: database
---
# Recurring backup job — weekly full, retain 8 weeks
apiVersion: longhorn.io/v1beta2
kind: RecurringJob
metadata:
  name: db-backup-weekly
  namespace: longhorn-system
spec:
  cron: "0 3 * * 0"
  task: backup
  retain: 8
  concurrency: 1
  groups:
    - db-volumes
  labels:
    tier: database
---
# Assign recurring jobs to a volume via labels
# Label the PVC or volume with: recurring-job-group.longhorn.io/db-volumes: enabled
kubectl label pvc pg-data-postgresql-0 -n database \
  recurring-job-group.longhorn.io/db-volumes=enabled

灾难恢复

Longhorn 通过DR 卷提供内置灾难恢复机制。是辅助集群中的备用卷,持续从主集群的备份目标中提取增量备份。当灾难发生时,您激活灾难恢复卷,它会变成常规读写卷,让辅助集群接管。

使用 Longhorn进行多区域灾难恢复主 k3s 集群 (eu-west-1)PostgreSQL主数据库 PodMySQL主数据库 PodLonghorn 卷(每个 3 个副本)pg 数据:100Gi | mysql-数据:200Gi定期备份(每日 02:00 UTC)增量块级备份至 S3工人-01工人-02工人-03HEALTHY — 服务生产流量S3 / GCS备份目标跨区域复制pg 数据备份mysql 数据备份加密 AES-256版本存储桶生命周期分层日常备份DR k3s 集群 (us-east-1)DR 卷(待机模式)从备份目标自动同步上次同步:2 小时前从最新备份进行增量恢复dr-node-01dr-node-02dr-node-03STANDBY — 故障转移时激活拉恢复故障转移过程1. 检测主要故障2. 激活 DR 卷3. 在灾难恢复集群上部署应用程序4.开关DNS/流量RPO:上次备份间隔(分钟到小时)| RTO:分钟(DR 卷预同步)

设置 DR 卷

# On the DR cluster: create a DR volume from the primary's backup
# This is done via the Longhorn UI or API

# 1. Configure the DR cluster's backup target to point to the same S3 bucket
kubectl -n longhorn-system edit settings.longhorn.io backup-target
# value: s3://longhorn-backups@eu-west-1/

# 2. Create a DR volume from the latest backup
# Via Longhorn UI: Backup → Select volume → Create DR Volume
# Via kubectl:
apiVersion: longhorn.io/v1beta2
kind: Volume
metadata:
  name: pg-data-dr
  namespace: longhorn-system
spec:
  size: "107374182400"  # 100Gi in bytes
  numberOfReplicas: 3
  fromBackup: "s3://longhorn-backups@eu-west-1/?backup=backup-abc123&volume=pg-data"
  standby: true
  frontend: ""

# 3. The DR volume auto-syncs incremental backups from S3
# Monitor sync status:
kubectl -n longhorn-system get volumes.longhorn.io pg-data-dr -o jsonpath='{.status.lastBackup}'

# 4. During failover — activate the DR volume:
kubectl -n longhorn-system patch volumes.longhorn.io pg-data-dr \
  --type merge -p '{"spec":{"standby":false,"frontend":"blockdev"}}'

# 5. Create a PVC bound to the activated DR volume
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pg-data-postgresql-0
  namespace: database
spec:
  storageClassName: longhorn-db
  volumeName: pg-data-dr
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi

卷加密

Longhorn 支持使用 Linux LUKS2 的卷级加密。加密卷保护底层磁盘上的静态数据 - 即使有人获得对服务器存储的物理访问权限,如果没有加密密钥,他们也无法读取卷数据。

# Create a Kubernetes secret with the encryption passphrase
kubectl create secret generic longhorn-crypto \
  -n longhorn-system \
  --from-literal=CRYPTO_KEY_VALUE="a-very-long-and-random-passphrase-here" \
  --from-literal=CRYPTO_KEY_PROVIDER=secret \
  --from-literal=CRYPTO_KEY_CIPHER=aes-xts-plain64 \
  --from-literal=CRYPTO_KEY_HASH=sha256 \
  --from-literal=CRYPTO_KEY_SIZE=256 \
  --from-literal=CRYPTO_PBKDF=argon2i

# StorageClass with encryption enabled
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: longhorn-encrypted
provisioner: driver.longhorn.io
allowVolumeExpansion: true
reclaimPolicy: Retain
parameters:
  numberOfReplicas: "3"
  staleReplicaTimeout: "2880"
  fromBackup: ""
  encrypted: "true"
  csi.storage.k8s.io/provisioner-secret-name: longhorn-crypto
  csi.storage.k8s.io/provisioner-secret-namespace: longhorn-system
  csi.storage.k8s.io/node-publish-secret-name: longhorn-crypto
  csi.storage.k8s.io/node-publish-secret-namespace: longhorn-system
  csi.storage.k8s.io/node-stage-secret-name: longhorn-crypto
  csi.storage.k8s.io/node-stage-secret-namespace: longhorn-system

ReadWriteMany (RWX) 支持

默认情况下,Longhorn 卷是 ReadWriteOnce (RWO) — 它们可以由单个节点上的单个 Pod 挂载。对于需要跨多个 Pod 共享存储的工作负载(例如,共享媒体上传、配置文件、ML 模型工件),Longhorn 通过集成 NFS 服务器支持 ReadWriteMany (RWX)。

当 PVC 请求 RWX 访问模式时,Longhorn 会自动部署一个共享管理器 Pod,该 Pod 运行由 Longhorn 卷支持的 NFS 服务器。然后,多个 Pod 可以通过 NFS 同时挂载该卷。这比部署单独的 NFS 服务器更简单,但与直接块访问相比增加了一层网络开销。

# PVC with ReadWriteMany access mode
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: shared-media
  namespace: application
spec:
  storageClassName: longhorn-rwx
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 50Gi
Longhorn上的

数据库工作负载

在 Longhorn 上运行数据库需要仔细注意 StorageClass 参数、pod 关联性和备份集成。 Longhorn 的每卷引擎和同步复制使其非常适合数据库工作负载,但您需要正确配置它才能获得生产级的性能和可靠性。

Longhorn 存储上的数据库工作负载PostgreSQL StatefulSetpostgresql-0(主要)RWO PVC:100Gipostgresql-1(副本)RWO PVC:100Gipostgresql-2(副本)RWO PVC:100Gi3 个 Longhorn 副本 × 3 个 PG 副本MySQL StatefulSetmysql-0(主要)RWO PVC:200Gimysql-1(复制品)RWO PVC:200Gimysql-2(复制品)RWO PVC:200Gi3 个 Longhorn 副本 × 3 个 MySQL 副本MongoDB ReplicaSetmongo-0(主要)RWO PVC:150Gimongo-1(辅助)RWO PVC:150Gimongo-2(辅助)RWO PVC:150Gi3 Longhorn 副本 × 3 Mongo 成员Longhorn 分布式存储层每个 PVC3 个副本同步写复制数据局部性:尽力而为在线PVC扩展|快照| S3 备份 | DR 卷快照保护每4小时快照(保留6张) |即时回滚|牛备份到 S3/GCS/Azure每日增量 | 14 天保留 |加密|灾难恢复卷访问模式ReadWriteOnce (RWO) — 单 Pod 安装 — 所有数据库主数据库/副本ReadWriteMany (RWX) — 共享 NFS — 配置/媒体卷

PostgreSQL StatefulSet 与 Longhorn

# PostgreSQL StatefulSet using Longhorn PVC
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgresql
  namespace: database
spec:
  serviceName: postgresql
  replicas: 3
  selector:
    matchLabels:
      app: postgresql
  template:
    metadata:
      labels:
        app: postgresql
    spec:
      terminationGracePeriodSeconds: 120
      securityContext:
        fsGroup: 999
        runAsUser: 999
      containers:
        - name: postgresql
          image: postgres:16-alpine
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_DB
              value: production
            - name: POSTGRES_USER
              valueFrom:
                secretKeyRef:
                  name: pg-credentials
                  key: username
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: pg-credentials
                  key: password
            - name: PGDATA
              value: /var/lib/postgresql/data/pgdata
          resources:
            requests:
              cpu: "1"
              memory: 2Gi
            limits:
              cpu: "4"
              memory: 8Gi
          volumeMounts:
            - name: pg-data
              mountPath: /var/lib/postgresql/data
          livenessProbe:
            exec:
              command: ["pg_isready", "-U", "$(POSTGRES_USER)"]
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            exec:
              command: ["pg_isready", "-U", "$(POSTGRES_USER)"]
            initialDelaySeconds: 5
            periodSeconds: 5
  volumeClaimTemplates:
    - metadata:
        name: pg-data
        labels:
          recurring-job-group.longhorn.io/db-volumes: enabled
      spec:
        storageClassName: longhorn-db
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 100Gi

MySQL StatefulSet 与 Longhorn

# MySQL StatefulSet using Longhorn PVC
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
  namespace: database
spec:
  serviceName: mysql
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      terminationGracePeriodSeconds: 60
      containers:
        - name: mysql
          image: mysql:8.0
          ports:
            - containerPort: 3306
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-credentials
                  key: root-password
            - name: MYSQL_DATABASE
              value: production
          args:
            - "--default-authentication-plugin=mysql_native_password"
            - "--innodb-buffer-pool-size=4G"
            - "--innodb-log-file-size=1G"
            - "--innodb-flush-log-at-trx-commit=1"
            - "--sync-binlog=1"
          resources:
            requests:
              cpu: "1"
              memory: 4Gi
            limits:
              cpu: "4"
              memory: 8Gi
          volumeMounts:
            - name: mysql-data
              mountPath: /var/lib/mysql
  volumeClaimTemplates:
    - metadata:
        name: mysql-data
        labels:
          recurring-job-group.longhorn.io/db-volumes: enabled
      spec:
        storageClassName: longhorn-db
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 200Gi
针对数据库工作负载的

性能调整

Longhorn 在应用程序和物理磁盘之间添加了一个存储复制层,与直接本地磁盘访问相比,这会引入一些延迟。对于大多数工作负载来说,这种开销可以忽略不计,但具有大量写入模式的数据库工作负载需要进行调整才能实现最佳性能。

使用数据局部性:尽力而为。这可确保一个副本与数据库 Pod 位于同一节点上,这意味着读取会以 NVMe/SSD 速度命中本地磁盘。写入仍会复制到远程节点,但本地副本消除了读取的网络往返。

专用于 Longhorn 的磁盘。不要与 Longhorn 数据共享操作系统磁盘。 添加专用 NVMe 或 SSD 驱动器并将其配置为 Longhorn 磁盘。这可以防止操作系统和数据库卷之间的 I/O 争用。

# Configure dedicated disks on a node
# Via kubectl (Longhorn node CRD)
kubectl -n longhorn-system edit nodes.longhorn.io worker-01

# Add the dedicated disk under spec.disks:
spec:
  disks:
    default-disk:
      allowScheduling: false  # disable OS disk for Longhorn
      path: /var/lib/longhorn/
      storageReserved: 0
    nvme-data:
      allowScheduling: true
      path: /mnt/nvme-longhorn/
      storageReserved: 10737418240  # 10Gi reserved
      tags:
        - nvme
        - database

设置有保证的引擎管理器 CPU。Longhorn 的引擎进程使用 CPU 进行 I/O 处理和复制。guaranteedInstanceManagerCPU设置为 Longhorn 实例管理器保留一定比例的节点 CPU,以防止 CPU 在负载下饥饿。

调整副本计数。对于已经具有应用程序级复制(PostgreSQL 流复制、MySQL 组复制、MongoDB 副本集)的数据库,您可以将 Longhorn 副本数量减少到 2 个,而不是 3 个。数据库自身的复制提供了额外的数据保护层,更少的 Longhorn 副本意味着更少的写入放大和更好的写入吞吐量。

使用 ext4 而非 xfs 来实现小型随机 I/O。虽然 xfs 在大型顺序写入方面表现出色,但 ext4 通常在数据库工作负载典型的小型随机 I/O 模式方面表现更好。在您的 StorageClass 中设置fsType: ext4。

节点调度和磁盘管理

Longhorn 提供对用于卷调度的节点和磁盘的细粒度控制。这在异构集群中至关重要,其中一些节点具有快速 NVMe 存储,而其他节点具有较慢的 SATA 驱动器。

# Tag nodes for storage scheduling
kubectl label node worker-01 node.longhorn.io/storage=nvme
kubectl label node worker-02 node.longhorn.io/storage=nvme
kubectl label node worker-03 node.longhorn.io/storage=nvme
kubectl label node worker-04 node.longhorn.io/storage=sata

# Use node selector in StorageClass to target NVMe nodes
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: longhorn-nvme
provisioner: driver.longhorn.io
allowVolumeExpansion: true
parameters:
  numberOfReplicas: "3"
  nodeSelector: "node.longhorn.io/storage=nvme"
  diskSelector: "nvme,database"
  dataLocality: best-effort

使用 Prometheus 和 Grafana 进行监控

Longhorn 通过内置指标端点公开 Prometheus 指标。监控这些指标对于容量规划、性能分析和主动警报至关重要。

# ServiceMonitor for Longhorn metrics
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: longhorn-prometheus
  namespace: monitoring
  labels:
    release: prometheus
spec:
  selector:
    matchLabels:
      app: longhorn-manager
  namespaceSelector:
    matchNames:
      - longhorn-system
  endpoints:
    - port: manager
      path: /metrics
      interval: 30s
---
# PrometheusRule for Longhorn alerts
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: longhorn-alerts
  namespace: monitoring
spec:
  groups:
    - name: longhorn-storage
      rules:
        - alert: LonghornVolumeStatusCritical
          expr: longhorn_volume_robustness == 3
          for: 5m
          labels:
            severity: critical
          annotations:
            summary: "Longhorn volume {{ $labels.volume }} is Faulted"
        - alert: LonghornVolumeStatusDegraded
          expr: longhorn_volume_robustness == 2
          for: 10m
          labels:
            severity: warning
          annotations:
            summary: "Longhorn volume {{ $labels.volume }} is Degraded"
        - alert: LonghornNodeStorageWarning
          expr: |
            (longhorn_node_storage_usage_bytes / longhorn_node_storage_capacity_bytes) > 0.80
          for: 15m
          labels:
            severity: warning
          annotations:
            summary: "Longhorn node {{ $labels.node }} storage at {{ $value | humanizePercentage }}"
        - alert: LonghornBackupFailed
          expr: longhorn_backup_state == 3
          for: 5m
          labels:
            severity: critical
          annotations:
            summary: "Longhorn backup failed for volume {{ $labels.volume }}"

为 Longhorn 监控创建的关键 Grafana 仪表板面板包括:卷 IOPS(读/写)、卷吞吐量 (MB/s)、卷延迟 (p50/p95/p99)、副本重建进度、节点存储容量和使用情况、备份状态和期限以及每个卷的快照计数。

k3s 集群,具有完整的 Longhorn 存储堆栈

下图显示了 Longhorn 如何融入完整的 k3s 生产堆栈(从裸机服务器到应用程序 Pod),并具有 Rancher 管理和 Prometheus/Grafana 可观察性。

带 Longhorn 存储的 k3s 生产堆栈裸机服务器/云虚拟机(AWS EC2/Azure 虚拟机/GCP GCE/本地)NVMe SSD:/dev/nvme0n1NVMe SSD:/dev/nvme1n1NVMe SSD:/dev/nvme2n1SAS/SATA 硬盘k3s 集群控制平面k3s 服务器 (HA x3)工作器 01k3s代理+NVMe工作者 02k3s代理+NVMe工人 03k3s代理+NVMe工作者 04k3s代理+SATALonghorn 分布式块存储(CSI 驱动程序)管理器 DaemonSet引擎(每卷)跨节点的副本存储类:longhorn-db |长角牛标准 |长角牛快速 | longhorn 加密应用工作负载PostgreSQLPVC:100Gi RWOMySQLPVC:200Gi RWOMongoDBPVC:150Gi RWORedisPVC:10Gi RWO应用程序 (RWX)PVC:50Gi RWXRancher 管理集群管理、RBAC、应用程序目录Prometheus + GrafanaLonghorn 指标、PVC 容量警报Longhorn UI卷管理、备份状态云备份目标S3 / GCS / Azure Blob加密、版本化、生命周期分层灾难恢复集群从此处拉出Pod → Longhorn 引擎 → 副本 → 本地 NVMe/SSD备份 → S3/GCS/Azure(增量、加密)

与其他 Kubernetes 存储解决方案的比较

Longhorn 并不是 Kubernetes 的唯一存储选项。了解它与替代方案的比较有助于您根据您的具体要求做出正确的选择。

功能LonghornRook-CephOpenEBS (Mayastor)本地路径
复杂性低高中最小
复制内置(2–3 个副本)CRUSH 算法NVMe-oF 副本无
动态 PVC 扩展有(在线)有有无
快照COW 快照RBD 快照是否
备份到云端内置 (S3/GCS/Azure)通过 rbd 导出通过 Velero无
DR 卷本机备用卷RBD 镜像无无
RWX 支持是(基于 NFS)是(CephFS)否否
卷加密LUKS2dmcrypt无无
UI内置 Web UICeph 仪表板最小无
最小节点1(3 个用于 HA)3(专用 OSD 节点)31
资源开销低-中高中无
最适合k3s/RKE2 生产大型企业高性能 NVMe开发/单节点

Longhorn 与 Rook-Ceph:Ceph 是更强大的系统 - 它通过复杂的 CRUSH 放置算法支持对象存储、文件存储和块存储。然而,Ceph 需要至少 3 个专用 OSD 节点、大量 RAM(每个 OSD 守护进程至少 4GB)以及深厚的操作专业知识。对于具有 3-10 个节点的 k3s 集群,Longhorn 以 10% 的运营成本提供 90% 的价值。

Longhorn 与 OpenEBS Mayastor:Mayastor 使用 NVMe-over-Fabrics 进行高性能复制,实现比 Longhorn 基于 TCP 的复制更低的延迟。如果原始 IOPS 和亚毫秒延迟是您最关心的问题,并且您拥有带 RDMA 网络的 NVMe 基础设施,那么 Mayastor 可能是更好的选择。对于大多数 k3s 部署,Longhorn 的集成备份、灾难恢复和操作简单性超过了 Mayastor 的性能优势。

Longhorn 与本地路径:本地路径配置程序是 k3s 的默认存储 — 它只是在节点的本地文件系统上创建目录。零复制、零快照、零备份集成。这对于开发来说很好,但对于生产数据来说是不可接受的。

生产最佳实践

这些建议是从运行数据库工作负载的数十个生产 k3s 集群中运行 Longhorn 中提炼出来的。

1. 设置实例管理器的资源预留。Longhorn 实例管理器(引擎和副本管理器)需要有保证的 CPU 以避免节点压力期间 I/O 停顿。在 Longhorn 设置中将guaranteedInstanceManagerCPU设置为至少 12%。

2. 对数据库卷使用 Retain 回收策略。切勿将Delete用于数据库 PVC。即使 PVC 被删除,Retain策略也会保留 PV 及其数据,为您提供防止意外删除的安全网。

3. 禁用生产副本软反关联性。设置replicaSoftAntiAffinity: false以确保副本始终分布在不同节点上。通过软反亲和力,当空间紧张时,Longhorn 可能会在同一节点上安排多个副本,这违背了复制的目的。

4. 在每个节点上预留存储空间。将storageMinimalAvailablePercentage设置为至少 15%。这可以防止 Longhorn 消耗所有磁盘空间,从而导致影响所有 Pod 的节点级问题。

5. 启用自动抢救。当至少一个副本仍然正常时,autoSalvage设置会自动恢复进入故障状态的卷。这减少了节点故障期间的人工干预。

6. 将优先级设置为系统集群关键。Longhorn 的管理器和驱动程序组件在节点压力期间不应被驱逐。将它们的priorityClass 设置为system-cluster-critical以确保它们能够在 Pod 驱逐中幸存下来。

7. 为所有生产量配置重复作业。每个生产卷都应具有快照和备份重复作业。每 4 小时创建一次快照以实现快速回滚,每天进行一次备份以实现灾难恢复。

8. 定期测试 DR 卷激活。创建每月计划来激活备用集群中的 DR 卷、验证数据完整性并练习故障转移过程。从未经过测试的灾难恢复计划只是文档。

9. 主动监控卷运行状况。针对降级和故障卷、节点存储容量、备份期限和副本重建状态设置 Prometheus 警报。当用户报告数据库速度缓慢时,存储问题已经持续了几个小时。

10. 使用专用存储磁盘。将 Longhorn 数据与操作系统磁盘分开。这可以防止 I/O 争用,为您提供更清晰的容量管理,并避免使用 Longhorn 数据填充操作系统磁盘的风险。

特定于云的部署指南

AWS — 具有 NVMe 实例存储的 EC2

对于 AWS 部署,请使用附带 NVMe 实例存储的i3.xlarge或i3en.xlarge实例。这些以预配置 EBS IOPS 成本的一小部分提供原始 NVMe 性能。格式化实例存储并将其配置为 Longhorn 磁盘。

# On each EC2 i3.xlarge instance
sudo mkfs.ext4 /dev/nvme0n1
sudo mkdir -p /mnt/longhorn-nvme
sudo mount /dev/nvme0n1 /mnt/longhorn-nvme
echo '/dev/nvme0n1 /mnt/longhorn-nvme ext4 defaults,nofail 0 2' | sudo tee -a /etc/fstab

# Configure as Longhorn disk (via node CRD or UI)
# Path: /mnt/longhorn-nvme/

Azure — 具有超级磁盘

的虚拟机

在 Azure 上,使用具有本地 NVMe 存储的Standard_L8s_v3或Standard_L16s_v3VM。或者,连接超级磁盘以获得一致的亚毫秒级延迟。超级磁盘允许您独立配置 IOPS 和吞吐量。

# Attach Ultra Disk to Azure VM (Azure CLI)
az vm disk attach \
  --vm-name k3s-worker-01 \
  --resource-group k3s-cluster \
  --name longhorn-ultra-01 \
  --size-gb 512 \
  --sku UltraSSD_LRS \
  --disk-iops-read-write 10000 \
  --disk-mbps-read-write 300 \
  --new

GCP — 具有本地 SSD

的虚拟机

GCP 提供连接到n2-standard或c3-standardVM 的本地 SSD。本地 SSD 每盘提供 375 GB 容量,读取 IOPS 高达 680,000。连接多个本地 SSD 并对它们进行 RAID 以获得更大的卷。

# Create VM with local SSDs (gcloud)
gcloud compute instances create k3s-worker-01 \
  --machine-type=n2-standard-8 \
  --local-ssd=interface=NVME \
  --local-ssd=interface=NVME \
  --zone=europe-west1-b

# RAID two local SSDs for 750GB Longhorn disk
sudo mdadm --create /dev/md0 --level=0 --raid-devices=2 /dev/nvme0n1 /dev/nvme0n2
sudo mkfs.ext4 /dev/md0
sudo mkdir -p /mnt/longhorn-nvme
sudo mount /dev/md0 /mnt/longhorn-nvme

本地数据中心

对于本地部署,请使用配备 Longhorn 专用 NVMe 或 SAS SSD 驱动器的服务器。将操作系统磁盘与存储磁盘分开。 在节点之间使用 10GbE 或 25GbE 网络可确保复制流量不会成为瓶颈 — Longhorn 同步复制生成的网络流量与写入吞吐量乘以副本数量成正比。

# Typical on-premises server spec for Longhorn k3s node
# CPU: 8+ cores (Xeon or EPYC)
# RAM: 32+ GB
# OS Disk: 256GB SATA SSD (mirrored)
# Longhorn Disk: 2x 1TB NVMe (RAID-1 or individual Longhorn disks)
# Network: 2x 25GbE (bonded, one for application, one for storage)

# Configure dedicated storage network (optional but recommended)
# In Longhorn settings:
# storage-network: kube-system/storage-network-attachment

Longhorn UI 演练

Longhorn 附带内置 Web UI,提供用于管理卷、快照、备份、节点和设置的可视化界面。通过安装期间配置的 Ingress 或通过 kubectl port-forward 访问它。

# Quick access via port-forward
kubectl -n longhorn-system port-forward svc/longhorn-frontend 8080:80
# Open http://localhost:8080 in your browser

UI 提供了多个关键视图:仪表板显示集群范围的存储运行状况,包括总容量、已用空间和卷状态。卷列出所有卷及其状态(正常/降级/故障)、大小、副本计数和连接的节点。您可以直接从此视图扩展、快照、备份和还原卷。节点显示每个节点的存储配置、磁盘分配和调度状态。备份列出备份目标中存储的所有备份及其卷、大小和创建时间。设置公开所有 Longhorn 配置参数及其说明。

常见问题故障排除

降级卷

当一个或多个副本运行状况不佳但卷仍可运行时,卷将进入降级状态。常见原因包括节点故障、磁盘已满或网络分区。

# Check volume status
kubectl -n longhorn-system get volumes.longhorn.io -o wide

# Describe the volume for detailed status
kubectl -n longhorn-system describe volumes.longhorn.io pvc-abc123

# Check replica status
kubectl -n longhorn-system get replicas.longhorn.io -l longhornvolume=pvc-abc123

# If a replica is stuck in error state, delete it to trigger rebuild
kubectl -n longhorn-system delete replicas.longhorn.io pvc-abc123-r-12345

# Monitor rebuild progress
kubectl -n longhorn-system get volumes.longhorn.io pvc-abc123 \
  -o jsonpath='{.status.conditions}' | jq

卷卡在连接/拆卸

中
# Check engine status
kubectl -n longhorn-system get engines.longhorn.io -l longhornvolume=pvc-abc123

# Check for stuck VolumeAttachment objects
kubectl get volumeattachments | grep pvc-abc123

# Force detach a stuck volume (use cautiously)
kubectl -n longhorn-system patch volumes.longhorn.io pvc-abc123 \
  --type merge -p '{"spec":{"nodeID":""}}'

# If attachment is truly stuck, delete the VolumeAttachment
kubectl delete volumeattachment csi-abc123def456

空间压力

# Check node storage usage
kubectl -n longhorn-system get nodes.longhorn.io -o wide

# Identify large snapshots consuming space
kubectl -n longhorn-system get snapshots.longhorn.io -l longhornvolume=pvc-abc123

# Purge old snapshots to reclaim space
# Via Longhorn UI: Volume → Snapshots → Delete unneeded snapshots
# Old snapshots consume space because COW data cannot be freed until the snapshot is deleted

# Check for snapshot data integrity issues
kubectl -n longhorn-system get settings.longhorn.io snapshot-data-integrity

升级程序

Longhorn 升级应谨慎执行,因为存储系统支撑着所有有状态工作负载。升级前务必备份所有关键卷。

# 1. Back up all volumes before upgrade
for vol in $(kubectl -n longhorn-system get volumes.longhorn.io -o jsonpath='{.items[*].metadata.name}'); do
  echo "Backing up $vol"
  kubectl -n longhorn-system patch volumes.longhorn.io $vol \
    --type merge -p '{"spec":{"lastBackupAt":"'$(date -u +"%Y-%m-%dT%H:%M:%SZ")'"}}'
done

# 2. Check current version
kubectl -n longhorn-system get daemonset longhorn-manager -o jsonpath='{.spec.template.spec.containers[0].image}'

# 3. Upgrade via Helm
helm repo update
helm upgrade longhorn longhorn/longhorn \
  --namespace longhorn-system \
  --version 1.7.2 \
  --values longhorn-values.yaml

# 4. Monitor the rolling upgrade
kubectl -n longhorn-system rollout status daemonset/longhorn-manager
kubectl -n longhorn-system rollout status deployment/longhorn-driver-deployer

# 5. Verify all volumes are healthy after upgrade
kubectl -n longhorn-system get volumes.longhorn.io -o custom-columns=NAME:.metadata.name,STATE:.status.state,ROBUSTNESS:.status.robustness

# 6. Longhorn automatically upgrades engines — monitor progress
kubectl -n longhorn-system get engines.longhorn.io -o wide

与数据库操作员集成

现代 Kubernetes 数据库运算符(CloudNativePG、Percona Operator、Zalando Postgres Operator)与 Longhorn 无缝协作。 Operator 管理数据库生命周期,而 Longhorn 为底层存储提供复制、快照和备份。

# CloudNativePG cluster using Longhorn storage
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: production-pg
  namespace: database
spec:
  instances: 3
  storage:
    size: 100Gi
    storageClass: longhorn-db
    pvcTemplate:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 100Gi
  walStorage:
    size: 20Gi
    storageClass: longhorn-fast

  postgresql:
    parameters:
      shared_buffers: "2GB"
      effective_cache_size: "6GB"
      maintenance_work_mem: "512MB"
      wal_buffers: "64MB"
      max_connections: "200"

  backup:
    barmanObjectStore:
      destinationPath: s3://pg-backups/cnpg/
      endpointURL: https://s3.eu-west-1.amazonaws.com
      s3Credentials:
        accessKeyId:
          name: aws-creds
          key: ACCESS_KEY_ID
        secretAccessKey:
          name: aws-creds
          key: SECRET_ACCESS_KEY
      wal:
        compression: gzip
    retentionPolicy: "30d"

  resources:
    requests:
      cpu: "2"
      memory: 4Gi
    limits:
      cpu: "4"
      memory: 8Gi
# Percona XtraDB Cluster with Longhorn storage
apiVersion: pxc.percona.com/v1
kind: PerconaXtraDBCluster
metadata:
  name: production-mysql
  namespace: database
spec:
  crVersion: "1.14.0"
  pxc:
    size: 3
    image: percona/percona-xtradb-cluster:8.0
    resources:
      requests:
        cpu: "2"
        memory: 4Gi
    volumeSpec:
      persistentVolumeClaim:
        storageClassName: longhorn-db
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 200Gi
  backup:
    image: percona/percona-xtradb-cluster-operator:1.14.0-pxc8.0-backup-pxb8.0.35
    storages:
      s3-backup:
        type: s3
        s3:
          bucket: mysql-backups
          region: eu-west-1
          credentialsSecret: aws-creds
    schedule:
      - name: daily-full
        schedule: "0 2 * * *"
        keep: 14
        storageName: s3-backup

结论

Longhorn 将 k3s 从仅适用于边缘和开发的轻量级 Kubernetes 发行版转变为能够运行任务关键型有状态工作负载的生产就绪平台。其架构 — 每卷引擎、同步多节点复制、集成快照和备份到云对象存储、灾难恢复卷、卷加密和在线 PVC 扩展 — 提供企业级存储,但没有企业级复杂性。

Longhorn 在生产中取得成功的关键有三个。首先,从一开始就正确配置:使用专用存储磁盘,设置适当的复制因子和数据局部性,并为不同的工作负载类型创建专用的存储类。其次,从第一天起就将备份集成到您的架构中:用于快速回滚的定期快照、用于灾难恢复的每日备份到 S3/GCS/Azure 以及用于最坏情况的备用集群中的 DR 卷。第三,监控一切:卷健康状况、节点存储容量、备份期限和副本重建状态——存储问题在变得灾难性之前是不可见的。

动态 PVC 扩展消除了最常见的生产事故来源之一——磁盘空间不足。借助 Longhorn,只需一条 kubectl 命令即可将数据库卷从 50Gi 扩展到 500Gi,且停机时间为零。 结合容量阈值的 Prometheus 警报,您可以在卷变得关键之前主动扩展卷,或者完全自动化扩展。

无论您是在 k3s 上运行 PostgreSQL、MySQL、MongoDB 还是 Redis(在裸机服务器、AWS EC2、Azure 虚拟机、GCP 实例还是本地数据中心硬件上),Longhorn 都能提供存储基础,让您能够专注于应用程序,而不必担心数据持久性。安装它、配置它、监控它,并用您的生产数据信任它。