Longhorn 加密存储:从配置到验证,彻底阻断宿主机越权访问
在云原生环境中,存储安全是至关重要的一环。本文详细记录了我一次部署和验证 Longhorn 加密存储的完整过程,旨在解决一个核心安全问题:即便获得宿主机 root 权限,也无法访问 Kubernetes 集群中的敏感数据。文章不仅涵盖了标准的配置步骤,更复盘了一次由 `StorageClass` 配置不完整引发的 `FailedMount` 故障排查,详细介绍了不同 Linux 发行版的前置依赖准
Longhorn 加密存储:从配置错误到最终验证,亲手打造安全的云原生数据防线
摘要:在云原生环境中,存储安全是至关重要的一环。本文详细记录了我一次部署和验证 Longhorn 加密存储的完整过程,旨在解决一个核心安全问题:即便获得宿主机 root 权限,也无法访问 Kubernetes 集群中的敏感数据。文章不仅涵盖了标准的配置步骤,更复盘了一次由 StorageClass 配置不完整引发的 FailedMount 故障排查,详细介绍了不同 Linux 发行版的前置依赖准备,最终通过在宿主机层面直接验证加密效果,为 Longhorn 加密功能的有效性提供了确凿证据。
一、 背景与目标
在我的 Kubernetes 集群日常运维中,我常常面临一个安全挑战:拥有宿主机 root 权限的用户,理论上可以访问该节点上存储的所有数据,包括容器的持久化存储卷。这对于需要高数据安全性的应用来说,是一个巨大的潜在风险。
Longhorn 作为一款优秀的云原生分布式块存储系统,提供了静态加密(at-rest encryption)和传输中加密(in-transit encryption)的功能。本次实践的目标是:
- 在我的 Longhorn 集群中,启用并部署加密存储功能。
- 亲自验证即便以宿主机 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-secret 和 node-publish-secret 相关的参数,而**缺少了 node-stage-secret 的定义,这个目前网络上的很多教程没有提及这个,可能是因为我用的是k3s 1.33 版本的原因,但是在加上 **。
CSI的挂载流程分为 NodeStageVolume 和 NodePublishVolume 两个主要阶段。前者负责在节点上进行全局性的准备(如格式化、挂载到临时目录),后者则负责将准备好的设备绑定挂载到具体的 Pod 目录。如果加密卷的解密操作发生在 NodeStage 阶段,而 StorageClass 中又没有提供该阶段所需的 Secret,就会导致 missing passphrase 错误。
解决方案就是补全 StorageClass 的 parameters 部分,确保 provisioner、node-stage 和 node-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可读的硬盘格式就行,都可以验证为已经加密
这个结果表明:
- 该文件被正确识别为 LUKS 加密容器,而不是 ext4 等任何可以直接挂载的文件系统。
- 任何直接的
mount尝试都会因“文件系统类型错误”而失败。 - 作为宿主机 root 用户,在没有密钥的情况下,我面对的只是一堆无法解读的、加密后的二进制数据。
六、总结
通过本次实战,我不仅成功部署了 Longhorn 的加密存储,还深入经历了一次有价值的排错过程。最终的宿主机验证,直观且有力地证明了 Longhorn 加密功能可以有效抵御来自宿主机层面的越权数据访问。
我的关键 takeaways:
- 依赖先行:在配置前,务必确保所有相关节点都已安装
cryptsetup等软件包,并加载了dm_crypt内核模块。 - 配置要完整:
StorageClass中关于 Secret 的三个阶段 (provisioner,node-stage,node-publish) 都应配置齐全,避免因流程阶段遗漏导致挂载失败。 - 验证是标准:不要想当然,通过
file命令在宿主机上进行验证,是检验加密是否生效的“金标准”。
在安全日益重要的今天,正确利用 Longhorn 这类云原生存储提供的加密功能,是我构建稳固数据防线的关键一步。
更多推荐


所有评论(0)