Longhorn 加密存储:从配置错误到最终验证,亲手打造安全的云原生数据防线

摘要:在云原生环境中,存储安全是至关重要的一环。本文详细记录了我一次部署和验证 Longhorn 加密存储的完整过程,旨在解决一个核心安全问题:即便获得宿主机 root 权限,也无法访问 Kubernetes 集群中的敏感数据。文章不仅涵盖了标准的配置步骤,更复盘了一次由 StorageClass 配置不完整引发的 FailedMount 故障排查,详细介绍了不同 Linux 发行版的前置依赖准备,最终通过在宿主机层面直接验证加密效果,为 Longhorn 加密功能的有效性提供了确凿证据。

一、 背景与目标

在我的 Kubernetes 集群日常运维中,我常常面临一个安全挑战:拥有宿主机 root 权限的用户,理论上可以访问该节点上存储的所有数据,包括容器的持久化存储卷。这对于需要高数据安全性的应用来说,是一个巨大的潜在风险。

Longhorn 作为一款优秀的云原生分布式块存储系统,提供了静态加密(at-rest encryption)和传输中加密(in-transit encryption)的功能。本次实践的目标是:

  1. 在我的 Longhorn 集群中,启用并部署加密存储功能。
  2. 亲自验证即便以宿主机 root 身份,也无法读取加密卷中的明文数据。
二、核心原理与节点前置准备

Longhorn 的加密功能基于 Linux 内核的标准加密框架 LUKS (Linux Unified Key Setup)。在深入配置之前,必须确保所有将要承载存储卷的节点都满足依赖条件。这包括内核模块的支持和必要的软件包。

1. 内核模块 dm_crypt

这是执行加密操作的核心内核模块。

  • 临时加载模块:可以使用 modprobe 命令立即加载该模块,使其在本次系统启动周期内生效。
    sudo modprobe dm_crypt
    
  • 永久加载模块:为确保节点重启后模块依然可用,需要将其添加到启动加载配置中。在大多数 Linux 发行版中,可以在 /etc/modules-load.d/ 目录下创建一个配置文件。
    # 创建配置文件并写入模块名
    echo dm_crypt | sudo tee /etc/modules-load.d/longhorn-crypto.conf
    

2. 必要的软件包

Longhorn 在后端与存储交互,或提供加密功能时,依赖于一些用户空间的工具集。

功能 软件包 (Debian/Ubuntu) 软件包 (CentOS/RHEL) 用途说明
加密 cryptsetup cryptsetup 管理 LUKS 加密卷的核心工具集。启用加密功能必须安装
iSCSI open-iscsi iscsi-initiator-utils Longhorn 卷本质上是 iSCSI Target,节点需要 iSCSI 启动器来连接它们。
NFS (用于备份) nfs-common nfs-utils 如果您使用 NFS 作为 Longhorn 的备份目标 (Backup Target),则必须安装。

综合安装命令:

  • 对于 Debian/Ubuntu 系统:
    sudo apt-get update
    sudo apt-get install -y open-iscsi nfs-common cryptsetup
    
  • 对于 CentOS/RHEL 系统:
    sudo yum install -y iscsi-initiator-utils nfs-utils cryptsetup
    
三、配置加密存储

现在,我将演示如何为整个 Longhorn 集群配置加密存储。这个配置将允许任何满足前置条件的节点承载加密卷。

第一步:创建用于存储密钥的 Secret

longhorn-system 命名空间下,我创建了一个 Secret 用于存放加密密码。注意stringData 中的键名必须是 CRYPTO_KEY_VALUE

# longhorn-crypto-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: longhorn-crypto-secret
  namespace: longhorn-system
stringData:
  CRYPTO_KEY_VALUE: "your-super-secret-and-strong-passphrase"
``````bash
kubectl apply -f longhorn-crypto-secret.yaml

第二步:创建专用的加密 StorageClass

这是整个配置的核心。我创建了一个新的 StorageClass,用于动态创建加密卷。

# longhorn-encrypted-sc.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: longhorn-encrypted
provisioner: driver.longhorn.io
allowVolumeExpansion: true
reclaimPolicy: Delete
volumeBindingMode: Immediate
parameters:
  numberOfReplicas: "3"
  encrypted: "true"
  
  # --- 关键:关联加密密钥 ---
  csi.storage.k8s.io/provisioner-secret-name: "longhorn-crypto-secret"
  csi.storage.k8s.io/provisioner-secret-namespace: "longhorn-system"
  csi.storage.k8s.io/node-stage-secret-name: "longhorn-crypto-secret"  # 注意这个,问题四的修复方案
  csi.storage.k8s.io/node-stage-secret-namespace: "longhorn-system"		# 注意这个,问题四的修复方案
  csi.storage.k8s.io/node-publish-secret-name: "longhorn-crypto-secret"
  csi.storage.k8s.io/node-publish-secret-namespace: "longhorn-system"``````bash
kubectl apply -f longhorn-encrypted-sc.yaml
四、问题排查实录:StorageClass 配置不完整引发的 FailedMount

在创建 PVC 并尝试挂载到一个测试 Pod 后,我遇到了典型的 FailedMount 错误。Events 部分显示:

Warning  FailedMount  ...  MountVolume.MountDevice failed ... desc = missing passphrase for encrypted volume 

错误信息 missing passphrase 直指密钥问题。经过一番检查,我发现最初的 StorageClass 配置存在疏漏。我只包含了 provisioner-secretnode-publish-secret 相关的参数,而**缺少了 node-stage-secret 的定义,这个目前网络上的很多教程没有提及这个,可能是因为我用的是k3s 1.33 版本的原因,但是在加上 **。

CSI的挂载流程分为 NodeStageVolumeNodePublishVolume 两个主要阶段。前者负责在节点上进行全局性的准备(如格式化、挂载到临时目录),后者则负责将准备好的设备绑定挂载到具体的 Pod 目录。如果加密卷的解密操作发生在 NodeStage 阶段,而 StorageClass 中又没有提供该阶段所需的 Secret,就会导致 missing passphrase 错误。

解决方案就是补全 StorageClassparameters 部分,确保 provisionernode-stagenode-publish 三个阶段的 Secret 参数都已正确提供。在删除旧的 PVC 并使用修正后的 StorageClass 重建后,卷成功挂载!

五、终极验证:在宿主机层面直面数据

现在,我以宿主机 root 用户的身份,直接访问 Longhorn 副本文件,以验证其加密效果。

我登录到承载副本的节点,并使用 file 命令来识别副本文件的类型:

# 进入副本所在目录
cd /var/lib/longhorn/replicas/pvc-xxxxxxxx/

# 使用 file 命令检查
sudo file volume-head-000.img

得到的输出是决定性的:

volume-head-000.img: LUKS encrypted file, ver 2, header size 16384, 

或者是data、application/xxx等等,不是linux可读的硬盘格式就行,都可以验证为已经加密

这个结果表明:

  1. 该文件被正确识别为 LUKS 加密容器,而不是 ext4 等任何可以直接挂载的文件系统。
  2. 任何直接的 mount 尝试都会因“文件系统类型错误”而失败。
  3. 作为宿主机 root 用户,在没有密钥的情况下,我面对的只是一堆无法解读的、加密后的二进制数据。
六、总结

通过本次实战,我不仅成功部署了 Longhorn 的加密存储,还深入经历了一次有价值的排错过程。最终的宿主机验证,直观且有力地证明了 Longhorn 加密功能可以有效抵御来自宿主机层面的越权数据访问

我的关键 takeaways:

  • 依赖先行:在配置前,务必确保所有相关节点都已安装 cryptsetup 等软件包,并加载了 dm_crypt 内核模块。
  • 配置要完整StorageClass 中关于 Secret 的三个阶段 (provisioner, node-stage, node-publish) 都应配置齐全,避免因流程阶段遗漏导致挂载失败。
  • 验证是标准:不要想当然,通过 file 命令在宿主机上进行验证,是检验加密是否生效的“金标准”。

在安全日益重要的今天,正确利用 Longhorn 这类云原生存储提供的加密功能,是我构建稳固数据防线的关键一步。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐