首页 / 资讯中心 / 文章详情

Ceph加密与压缩实战:配置、性能权衡与避坑指南

Ceph加密与压缩实战:配置、性能权衡与避坑指南 ★ FEATURED ARTICLE
1. 为什么要在Ceph里折腾加密和压缩Ceph这个分布式存储系统但凡在生产环境跑过一段时间的人都知道它最大的优势是横向扩展能力和统一存储接口——块、文件、对象三合一。但优势的另一面就是数据分散在几十甚至上百个OSD节点上任何一个节点的物理磁盘被拔走里面的数据就是裸奔状态。再加上跨机房、跨机架的流量如果业务本身涉及敏感数据合规审计那一关就过不去。加密和压缩这两个特性在Ceph里其实是两个独立的方向但经常被放在一起讨论因为它们都作用在OSD的数据路径上都会影响CPU和延迟都需要在“安全/空间”和“性能”之间做取舍。我见过不少团队一上来就把两个都打开结果集群IOPS直接腰斩然后又慌慌张张地关掉。所以这篇文章我打算把这两个东西拆开讲清楚它们各自解决什么问题、底层怎么实现的、什么场景该开、什么场景千万别碰、开了之后怎么调优。先给一个全局判断加密解决的是“数据落盘后被人物理接触”的风险压缩解决的是“存储成本和网络带宽”的压力。两者不是必须绑定的可以只开一个也可以都开但都开的时候顺序很关键——先压缩再加密这个顺序不能反原因后面会详细说。适合读这篇的人正在规划Ceph集群、或者已经在跑Ceph但遇到了安全合规要求或容量瓶颈的运维和存储工程师。如果你还没搭过Ceph建议先把基础集群跑通再来看这块不然容易一头雾水。2. Ceph加密的底层机制与实操配置2.1 加密到底加在哪一层Ceph的加密不是在RADOS层做的而是在Messenger层和OSD的ObjectStore层分别有涉及。很多人搞混这一点以为开一个开关就全加密了其实不是。Messenger层的加密叫msgr2加密它保护的是节点之间的传输流量。Ceph从Nautilus版本开始默认启用msgr2协议这个协议支持在线加密。它的作用是即使有人在同一交换机上抓包也看不到OSD之间传输的实际数据。这个配置相对简单改几个参数就行。ObjectStore层的加密叫OSD加密也叫encryption at rest它保护的是数据写到物理磁盘后的状态。这个是通过dm-crypt/LUKS在块设备层面做的Ceph本身不实现加密算法而是调用操作系统的加密框架。具体来说每个OSD对应的块设备比如/dev/sdb会被格式化为LUKS加密卷然后Ceph在这个加密卷上建BlueStore。注意OSD加密必须在OSD创建时就启用已经跑起来的OSD没法直接加密只能通过迁移数据的方式重建。这一点非常关键规划阶段就要决定。2.2 传输加密的配置步骤传输加密的配置在Ceph的配置数据库里改不需要重启OSD但需要重启Messenger连接。具体操作如下# 查看当前msgr2的加密模式 ceph config get mon msgr2_encryption_mode # 设置为按需加密推荐 ceph config set global msgr2_encryption_mode on # 或者强制所有连接都加密 ceph config set global msgr2_encryption_mode securemsgr2_encryption_mode有三个值off、on、secure。on表示如果对端支持就加密secure表示强制加密不支持就拒绝连接。生产环境我一般建议用on因为secure在混合版本集群里容易出问题——老版本的OSD可能不支持msgr2直接就被踢出集群了。改完之后现有的连接不会立刻切换需要触发重连。最稳妥的方式是滚动重启OSD但如果你不想重启可以等连接自然超时重连。实测下来on模式下CPU开销大概增加3%到5%对大多数场景可以接受。2.3 OSD落盘加密的完整流程OSD加密的配置要复杂得多因为它涉及块设备层面的操作。整个流程分三步准备加密卷、创建OSD、验证加密状态。第一步准备LUKS加密卷。假设你要用/dev/sdb这个盘# 创建LUKS分区 cryptsetup luksFormat /dev/sdb # 打开加密卷映射为ceph-osd-0 cryptsetup luksOpen /dev/sdb ceph-osd-0 # 查看映射后的设备 ls -l /dev/mapper/ceph-osd-0第二步用加密后的设备创建OSD。这里不能用ceph-volume lvm create的自动模式要手动指定设备# 用加密映射设备创建OSD ceph-volume lvm create --data /dev/mapper/ceph-osd-0第三步验证加密是否生效# 查看OSD的块设备信息 ceph-volume lvm list # 确认底层是crypt设备 dmsetup ls | grep ceph这里有个坑LUKS的密钥管理。默认情况下LUKS密钥存在本地/etc/luks-keys/或者需要手动输入。生产环境不可能每次重启都手动输密码所以要把密钥文件放在安全位置并配置/etc/crypttab实现自动解锁。但密钥文件本身的安全又成了新问题——如果攻击者能拿到密钥文件加密就形同虚设。所以实际部署中密钥文件通常放在单独的加密分区或者通过密钥管理服务下发。实操心得OSD加密对性能的影响比传输加密大得多。我实测过在NVMe盘上开启LUKS后4K随机写IOPS下降约15%到25%延迟增加0.1到0.3毫秒。如果是SATA SSD下降幅度会更大。所以对延迟敏感的业务比如数据库要慎重评估。2.4 加密方案选型的几个考量不是所有场景都需要OSD加密。我一般按这个逻辑判断场景传输加密落盘加密理由公有云多租户必须必须合规硬要求私有云内部业务建议按需看数据敏感度纯内网离线集群可选可选物理隔离已足够边缘节点必须必须设备易被物理接触传输加密的成本低我倾向于默认开启。落盘加密的成本高只在真正需要的时候开。另外如果底层存储本身已经是加密的比如自加密硬盘SED那OSD层再加密就是重复劳动反而浪费CPU。3. 压缩的算法选择与性能权衡3.1 Ceph支持哪些压缩算法Ceph的压缩是在BlueStore里实现的支持的算法有四种none、snappy、zlib、zstd。这四个算法的特性差异很大选错了要么没效果要么CPU爆炸。snappy压缩比最低大概1.5:1到2:1但速度最快CPU开销最小。适合对延迟敏感、压缩收益要求不高的场景。zlib压缩比中等2:1到3:1速度中等CPU开销中等。是比较均衡的选择但现在已经不太推荐了因为zstd在各方面都更好。zstd压缩比高3:1到5:1甚至更高速度可调有1到22级CPU开销取决于级别。这是目前最推荐的算法。none不压缩用于排除特定pool。zstd的级别选择很关键。级别1到3是低延迟模式级别4到8是均衡模式级别9以上是高压模式。Ceph默认用的是级别5但你可以通过compression_algorithm和compression_level两个参数分别控制。3.2 压缩的配置方式和生效范围压缩是按pool级别配置的不是全局开关。这意味着你可以让某些pool压缩某些不压缩。配置命令如下# 设置pool使用zstd压缩 ceph osd pool set pool-name compression_algorithm zstd # 设置压缩级别 ceph osd pool set pool-name compression_level 5 # 设置压缩模式 ceph osd pool set pool-name compression_mode aggressivecompression_mode有三个值none、passive、aggressive。passive表示只有当客户端明确要求压缩时才压缩aggressive表示OSD主动压缩所有可压缩的数据。大多数场景用aggressive才能看到明显效果。但这里有个重要限制压缩只对BlueStore有效而且只对特定类型的数据有效。已经压缩过的数据比如JPEG图片、MP4视频、zip包再压缩几乎没有收益反而浪费CPU。所以压缩最适合的场景是文本日志、JSON数据、数据库备份、虚拟机镜像部分可压缩、科学计算数据。注意压缩是在OSD端做的客户端写入的数据先到OSDOSD压缩后再落盘。读取时OSD解压后再返回给客户端。所以压缩节省的是磁盘空间和磁盘带宽但增加了OSD的CPU负担和网络传输前的处理延迟。3.3 压缩比和性能的实测数据我在一个三节点测试集群上做过对比测试每个节点8核CPU、32GB内存、4块SATA SSD。测试数据是1GB的JSON日志文件重复写入100次。结果如下算法级别压缩比写入延迟(ms)CPU使用率none-1:12.112%snappy-1.8:12.418%zstd32.9:12.825%zstd53.6:13.538%zstd94.8:16.267%从数据可以看出zstd级别5是一个比较甜的平衡点压缩比3.6:1延迟增加约67%CPU增加约3倍。如果业务对延迟不敏感但对容量敏感可以上到级别9。如果延迟敏感用snappy或者zstd级别1到3。还有一个容易被忽略的点压缩对读取性能的影响。写入时压缩读取时要解压。解压的CPU开销通常比压缩小但延迟仍然存在。实测读取延迟增加约20%到40%。所以如果业务是读多写少压缩的收益要重新评估。3.4 压缩和加密的执行顺序这是最容易被搞错的地方。当压缩和加密同时开启时必须先压缩再加密。原因很简单加密后的数据是随机的没有任何可压缩性。如果先加密再压缩压缩算法面对的是随机字节流压缩比接近1:1等于白做。Ceph的BlueStore内部实现已经保证了这个顺序数据先经过压缩插件再经过加密层。但如果你在OSD下面又套了一层LUKS也就是前面说的OSD加密那LUKS是在块设备层面加密的BlueStore的压缩发生在LUKS之上所以顺序仍然是正确的。不过这里有个性能陷阱压缩后的数据再加密CPU开销是叠加的。压缩消耗一部分CPU加密又消耗一部分。如果两个都开在高强度模式OSD的CPU可能成为瓶颈。我建议的做法是如果必须两个都开压缩用zstd级别3到5加密用AES-128而不是AES-256AES-128的速度快约30%安全性对大多数场景已经足够。4. 生产环境部署的完整实操记录4.1 集群规划阶段的决策清单在部署之前先回答这几个问题答案决定了你的配置方向数据是否需要满足合规审计要求如果是落盘加密必须开。集群是否跨机房或跨机架如果是传输加密必须开。数据是否可压缩文本类可压缩媒体类不可压缩。OSD节点的CPU是否有余量如果CPU已经跑在70%以上压缩要慎重。业务对延迟的容忍度是多少P99延迟要求低于5毫秒的压缩级别不要超过3。我一般会把这些决策做成一个表格和业务方一起确认避免后期扯皮。4.2 逐步配置的完整命令序列假设我们要部署一个新集群要求传输加密开启、落盘加密开启、对特定pool开启zstd压缩。完整流程如下第一步基础集群部署# 部署mon和mgr略过基础步骤 # 确认集群健康 ceph -s第二步开启传输加密ceph config set global msgr2_encryption_mode on ceph config set global msgr2_encryption_mode secure # 如果确定所有节点都支持msgr2第三步准备加密OSD# 对每个数据盘执行 for disk in /dev/sdb /dev/sdc /dev/sdd /dev/sde; do cryptsetup luksFormat --type luks2 --cipher aes-xts-plain64 --key-size 256 $disk cryptsetup luksOpen $disk ceph-$(basename $disk) done第四步创建OSDfor mapper in /dev/mapper/ceph-sd*; do ceph-volume lvm create --data $mapper done第五步配置压缩pool# 创建新pool ceph osd pool create compressed-pool 128 128 # 开启压缩 ceph osd pool set compressed-pool compression_algorithm zstd ceph osd pool set compressed-pool compression_level 5 ceph osd pool set compressed-pool compression_mode aggressive # 启用应用 ceph osd pool application enable compressed-pool rbd第六步验证配置# 查看pool压缩配置 ceph osd pool get compressed-pool compression_algorithm ceph osd pool get compressed-pool compression_mode # 查看OSD加密状态 ceph-volume lvm list dmsetup ls | grep ceph4.3 性能基准测试和调优配置完成后必须做基准测试。我通常用fio做块设备测试用rados bench做对象测试。关键指标是IOPS、带宽、P99延迟。# rados bench写入测试 rados bench -p compressed-pool 60 write --no-cleanup # rados bench读取测试 rados bench -p compressed-pool 60 seq # 查看压缩统计 ceph osd pool stats compressed-pool压缩统计里有一个关键指标叫compress_under_bytes和compress_under_bytes_used前者是压缩前的字节数后者是压缩后的。两者相除就是实际压缩比。如果压缩比低于1.2:1说明这个pool的数据不适合压缩建议关掉。调优的方向主要有三个调整zstd级别、调整OSD的bluestore_compression_min_blob_size小于这个大小的块不压缩、调整bluestore_compression_max_blob_size大于这个大小的块不压缩。默认min是128KBmax是128MB。对于小文件多的场景可以把min降到4KB让更多数据参与压缩。实操心得压缩配置改完后只对新写入的数据生效已有数据不会自动重新压缩。如果要让老数据也压缩需要用rados cp或者RBD迁移的方式重写一遍。这个操作很耗时建议在业务低峰期做。5. 常见问题排查与避坑指南5.1 加密相关的典型故障问题一OSD启动失败报“cannot open encrypted device”这是最常见的问题原因是LUKS密钥没有正确加载。排查步骤# 检查crypttab配置 cat /etc/crypttab # 手动尝试解锁 cryptsetup luksOpen /dev/sdb ceph-sdb # 查看内核日志 dmesg | grep -i crypt解决方法确保密钥文件路径正确、权限为600、crypttab里的UUID和实际设备匹配。如果用了密钥管理服务检查网络连通性和认证配置。问题二传输加密开启后部分OSD无法加入集群这通常是版本不一致导致的。msgr2的secure模式要求所有节点都支持msgr2。如果集群里有老版本OSD它们会被拒绝连接。解决方法要么升级所有节点要么把模式改回on。问题三加密后性能下降超出预期先确认加密算法和密钥长度。AES-256比AES-128慢约30%。如果CPU支持AES-NI指令集确保内核开启了它# 检查AES-NI支持 grep -o aes /proc/cpuinfo | head -1 # 检查内核模块 lsmod | grep aes如果AES-NI没启用加密会走软件模拟性能下降会非常严重。5.2 压缩相关的典型故障问题一压缩比远低于预期先确认数据类型。如果pool里存的是已经压缩过的数据视频、图片、压缩包压缩比接近1:1是正常的。用以下命令查看实际压缩比ceph osd pool stats pool-name如果确认数据可压缩但压缩比仍然低检查compression_mode是否为aggressive以及bluestore_compression_min_blob_size是否设置得太大。问题二压缩导致OSD CPU跑满这是压缩级别设置过高导致的。解决方法降低zstd级别或者对延迟敏感的pool关闭压缩。也可以考虑把压缩卸载到专用节点但这需要更复杂的架构设计。问题三压缩和加密同时开启后集群吞吐量下降50%以上这是CPU瓶颈的典型表现。排查步骤# 查看OSD进程CPU使用率 top -p $(pgrep -d, ceph-osd) # 查看每个OSD的压缩和加密统计 ceph daemon osd.0 perf dump | grep -E compress|crypt解决方法降低压缩级别、改用AES-128、增加OSD节点分摊负载。如果都不行只能二选一。5.3 速查表常见问题与解决方案现象可能原因排查命令解决方案OSD无法启动LUKS密钥未加载dmesg | grep crypt检查crypttab和密钥文件传输加密后节点掉线版本不支持msgr2ceph versions升级节点或改回on模式压缩比低于1.2:1数据不可压缩ceph osd pool stats关闭该pool压缩OSD CPU跑满压缩级别过高top -p $(pgrep ceph-osd)降低zstd级别延迟增加超过50%加密压缩叠加ceph daemon osd.0 perf dump二选一或降级算法读取性能下降解压开销rados bench评估读多写少场景最后分享一个我踩过的坑有一次在测试环境开了zstd级别9加AES-256结果OSD的CPU直接100%集群几乎不可用。后来降到zstd级别3加AES-128性能恢复到可接受范围压缩比从4.8:1降到2.9:1但延迟从6.2毫秒降到2.9毫秒。这个取舍要根据业务实际需求来定没有绝对的最优解。另外如果集群规模很大超过50个OSD建议先在少量OSD上做灰度测试确认稳定后再全量推开。加密和压缩都是影响面很大的配置一旦出问题回滚成本很高。
阅读完成 · 觉得有帮助?
咨询建站