六个 Chrome 容器打崩存储 NAS:CPU 软解 WebGL、Btrfs D 状态死锁与核显架构迁移

· 3 分钟 · 运维架构 dockersynologybtrfsgpuchromeunraidcdp

失去响应的集中存储设备

故障最初表现为网络边缘服务的集体超时:部署在一台 DS1821+ NAS 上的管理后台与私有网盘页面打不开。外部 HTTPS 握手瞬间完成、证书完全匹配,但一旦反代向后端发起请求,连接便无休止地转圈挂起。

通过 SSH 登录宿主机终端,看到的资源消耗状况令人震惊:

# uptime
 09:42:15 up 42 days, 18:22,  1 user,  load average: 27.42, 25.18, 22.04

# free -m
               total        used        free      shared  buff/cache   available
Mem:            7842        7410         112         340         320         180
Swap:           4096        3980         116

对于一台搭载 AMD Ryzen V1500B(4 核 4 线程)嵌入式处理器的机器来说,超过 27 的 Load Average 意味着有二十多个进程在排队抢夺算力,或者卡在不可中断的内核休眠中。物理内存占用高达 94%,4GB 的 Swap 分区几乎彻底告罄。

资源消耗大户是 6 个常驻的桌面版 Chrome 容器(lscr.io/linuxserver/chrome),用于跑生图预览、自动化审计与网页渲染。

Btrfs 内核 D 状态死锁剖析

这台 NAS 芯片没有集成核显。现代 Web 应用——尤其是富媒体界面、交互看板与视频画布——高度依赖 WebGL 渲染管线。在没有透传图形加速设备(/dev/dri)的环境下,Chromium 会静默降级为 CPU 软件光栅化(SwiftShader 或 llvmpipe)。

这种硬件特质与软件需求的错配,引发了三级连环雪崩:

  1. 算力被软解耗尽:6 个浏览器容器同时用 CPU 计算像素,把 4 颗物理核心全部顶死在 100%。
  2. 内存溢出与磁盘颠簸:随着渲染进程申请图形缓冲区,系统内存见底,内核被迫高频将内存页换出到机械阵列(/volume1)的 Swap 分区,引入天量 I/O Wait。
  3. 存储事务挂起:当容器守护进程尝试删除一个废弃的临时探针容器时,触发了 btrfs subvolume delete。在磁盘队列彻底堵死的极端压力下,Btrfs 的全局删除事务陷入了内核不可中断睡眠(D-state)。

由于 Btrfs 全局锁未能释放,宿主机上依赖文件写入的其它核心进程(包括本地元数据库、日志记录器与反代工作线程)在发起同步系统调用时全部被锁死在等待队列中,整机因而瘫痪。

架构迁移:将负载剥离至 Intel 核显计算节点

彻底的解法是将“存储节点”与“图形化自动化算力”在物理层面上做隔离。

浏览器集群被全量迁移至配备 Intel Core i9-13900K 且具备 Intel UHD Graphics 770 的专用 unRaid 计算节点上。

🔍 docker-compose.yml — 核显硬件加速 Chrome 容器配置(17 行)
services:
  chrome-worker:
    image: lscr.io/linuxserver/chrome:latest
    container_name: chrome-worker
    devices:
      - /dev/dri/renderD128:/dev/dri/renderD128
      - /dev/dri/card0:/dev/dri/card0
    environment:
      - CHROME_CLI=--remote-debugging-port=9222 --user-data-dir=/config/profile --enable-features=VaapiVideoDecodeLinuxGL --ignore-gpu-blocklist --use-gl=angle --use-angle=gl
    deploy:
      resources:
        limits:
          memory: 3072M
    restart: "no"

透传 /dev/dri/renderD128 让渲染和硬件解码直接跑在处理器的核显执行单元上,彻底解放了 CPU。此外,容器策略从 restart: unless-stopped 改为按需启停模型:在未执行任务时保持 Stopped 状态,实现 0% CPU 与 0 MB 内存的真正零驻留。

结果

架构调整后,存储宿主机立刻恢复了健康弹性:

🛡️ 生产级基础设施与系统架构

服务器频繁异常重启、云账单过高,或缺一位能穿透内核日志的架构师?

真正的生产环境稳定性,靠的是穿透表象抓出根因。我独立管理着跨 3 台物理/云主机、162 个容器的高可用自托管生产网络。

Lee Teong Hoe

Lee Teong Hoe · Mr Hoelee

Full-stack developer & DevOps engineer based in Malaysia. I run my own production infrastructure and build web systems for small businesses — this blog is the living record.

Hiring? Profile & stack · Malaysian SME? Website design & development ↗ · All posts