在 Ubuntu Server 下使用 LVM + LUKS 全盘加密时,是什么原因导致我的系统停顿/冻结/损坏数据?

在 Ubuntu Server 下使用 LVM + LUKS 全盘加密时,是什么原因导致我的系统停顿/冻结/损坏数据?

问题摘要

在启用 Ubuntu 安装程序中的 LUKS / dm-crypt 全盘加密选项后,磁盘 I/O 性能非常糟糕。写入磁盘会导致系统停滞/冻结。从磁盘读取的数据似乎已损坏。

如果我不使用 LUKS / dm-crypt,那么我就不会遇到任何问题。一切都非常稳定且性能出色。我知道加密会影响性能。我期望性能降低,而不是长达数分钟的系统冻结和数据损坏。

我以前从未在完全干净的 Ubuntu 安装中遇到过这么多问题。我不在乎出错。我只想让我的东西正常工作!

下面列出的两个系统都受到此问题的影响。所有实验都在 Ryzen 系统上进行。i5 两年来基本没有做任何事情,所以我直到现在才注意到这个问题。

系统 #1(运行约 2 年,大部分时间处于闲置状态)

  • Ubuntu Server 20.04.3 LTS
  • 英特尔 i5-3570
  • 8GB RAM,非 ECC
  • 金士顿 120GB A400 SATA 固态硬盘
  • Memtest86+ 或 Prime95 没有报告任何错误

系统 #2(新系统,首次发现问题的地方)

  • Ubuntu 服务器 22.04 LTS
  • AMD 锐龙 5 5600
  • 32GB 内存,ECC
  • 金士顿 120GB A400 SATA 固态硬盘
  • Memtest86+ 或 Prime95 没有报告任何错误

重现步骤

  • 安装 Ubuntu 20.04 LTS 或 22.04 LTS
  • 在安装过程中,设置磁盘时,选择以下选项
  • 使用整个磁盘
  • 将此磁盘设置为 LVM 组
  • 使用 LUKS 加密 LVM 组
  • 扩展包含以下内容的分区/,使其占用 LVM 组中的所有可用空间
  • 安装并启动后,使用 SSH/samba/USB/其他方式将大文件传输到操作系统磁盘

期待

  • 将大文件(大于~6GB)写入磁盘,系统不会冻结
  • 从磁盘读回文件并确保它们不被损坏

现实

所有这些问题都是在 Ryzen 系统上发现的。我在 i5 系统上测试了重度 I/O 负载一次并能够重现该问题。我不敢继续推进,否则我会损坏操作系统磁盘并不得不重建它。

  • 写入大文件会使系统冻结到只有控制台回显可以工作的程度。命令无法运行。甚至ls不会返回任何内容。SSH 传输停滞、超时并失败。
  • iotop 表示至少有一个 kcryptd 工作线程达到 99% 的 IO 负载,然后挂在那里几分钟(感觉像 2-3 分钟)
  • 从磁盘读回的大文件似乎已损坏。我移动了一个 VM 映像,但由于内部文件系统损坏,它无法运行超过几秒钟,否则就会崩溃。几次重启后,apt开始抱怨软件包损坏。网络连接停止。最终系统出现内核崩溃,我放弃了。
  • 奇怪的是,它reboot实际上并没有重新启动。关闭操作系统后,系统将挂起并出现黑屏。灯和风扇保持打开状态。底盘重置按钮在此状态下不起作用。我必须将电源线从墙上拔下来才能让一切恢复正常。

请注意,如果操作系统没有安装 LUKS / dm-crypt,则不会出现这些问题。这包括挂起重启的奇怪问题。

另请注意,我尝试在 Ryzen 系统上运行 Windows 10 + BitLocker,没有任何问题。

附加信息

我在装有 Ubuntu 22.04 LTS 的新 Ryzen 系统上完成了所有这些操作。

  • 我尝试设置cryptsetup --allow-discards --perf-no_read_workqueue --perf-no_write_workqueue --persistent refresh,认为这是由廉价 SSD 的一些异常引起的。它有助于提高写入性能,但读取仍然出现损坏。
  • 我尝试了完全干净的重新安装,没有安装任何额外的应用程序。只有基本操作系统和 iotop。没有更新。问题仍然存在。
  • 我将金士顿 SSD 换成了已知良好的 7200RPM 旋转硬盘。SATA 2.5 英寸 320GB 非 SMR。完全全新重新安装。问题仍然存在。
  • 我将金士顿 SSD 换成了已知良好的 NVMe 驱动器三星 SSD 970 EVO Plus。完全全新安装。问题仍然存在。
  • 我更换了 SATA 电缆,尽管没有加密一切正常。问题仍然存在。
  • 所有涉及此问题的驱动器均已通过坏块和 SMART 测试。

此时,我正在认真考虑回到 Windows 10 + BitLocker,因为我不知道还能做什么。

链接

答案1

事实证明有两个问题共同导致了我的生活变得困难。

第一期:Ubuntu / Fedora / Linux 概述

Ubuntu 附带启用了 dm-crypt 工作 I/O 队列。显然这些队列写得不太好。内核会等到它们已满或接近已满后才尝试将它们转储到磁盘,由于多个队列都在争夺磁盘访问权限,磁盘会在负载下死机,系统会锁定。

但是“Reeeeeee!”,你会说,“事情不是这样的,队列很完美,没有什么可以写入的”别在意,我不是内核开发人员,我所知道的只是我在 iotop 中看到的内容,以及当我将大量内容写入磁盘时系统会严重锁定的事实。当系统在没有加密的情况下运行时,不会发生这种情况。dm-crypt 队列已损坏。故事结束。

如果您不同意我的观点,那么您可以阅读 Cloudflare 对此的看法。https://blog.cloudflare.com/speeding-up-linux-disk-encryption/

无论如何,禁用队列“解决”了这个问题。您可以在上面的原始帖子中看到我用来执行此操作的命令。

第二期:VirtualBox

此票:https://www.virtualbox.org/ticket/10031?cversion=0&cnum_hist=14

... 已经开放了 10 多年。根据这些信息,我猜测 VBox 对 I/O 延迟的容忍度不高,如果访问主机存储的时间过长,最终会放弃。VBox 模拟器/虚拟机管理程序/无论它是什么,都会返回到客户虚拟机并说“抱歉,我无法读取或写入磁盘”。

VM 如何处理充当有缺陷硬盘的虚拟化 I/O 层?它无法处理。它会立即爆炸成原子,就像超级英雄在灭霸的打击下失败了一样。

我通过放弃 VirtualBox 并切换到 KVM 来“解决”这个问题。我现在使用 SSH 上的 virt-manager 和 X-forwarder 来做我的事情。KVM 似乎对慢速主机 I/O 的容忍度更高,这使其与 LUKS 完美匹配。

切换到 KVM

VirtualBox .vdi 文件可轻松转换为 .qcow2 格式。关于如何执行此操作的教程数不胜数。

在启用 x-forwarding 的情况下,virt-manager UI 在 SSH 上运行良好。

USB 直通到客户虚拟机也很好用。如果您的权限设置不正确,您可能需要编辑 udev 规则。同样,通过 Google 可以轻松找到大量有关此信息。

如果您希望从 VirtualBox 进行同样的操作,但希望客户虚拟机上的桥接网络适配器直接连接到网络(就像我一样),那么您需要相应地更改 netplan 设置。这是我自己的配置文件中的一个示例:

network:
    version: 2
    renderer: networkd
    ethernets:
        eno1:
            match:
                name: eno1
            dhcp4: no
            optional: yes
    bridges:
        br0:
            macaddress: 74:46:a0:b4:39:b9
            dhcp4: yes
            interfaces:
                - eno1

如果您不想弄乱 DHCP 静态映射,请将桥接 MAC 设置为物理 NIC 的 MAC。

相关内容