浏览器、数据库、多进程程序在容器里莫名崩溃,往往因为 /dev/shm 只有 64 MiB。这篇实测默认大小、写满时 dd 与 mmap 的不同表现(报错与 SIGBUS)、它算不算容器的内存、以及怎么在容器之间共享。
默认:/dev/shm 大小 64 MiB;挂载选项 rw,nosuid,nodev,noexec,relatime,size=65536k --shm-size 256m:/dev/shm 大小 256 MiB;挂载选项 rw,nosuid,nodev,noexec,relatime,size=262144k --shm-size 1g:/dev/shm 大小 1024 MiB;挂载选项 rw,nosuid,nodev,noexec,relatime,size=1048576k docker inspect 的 HostConfig.ShmSize(默认容器) = 67108864 字节
默认 64 MiB,--shm-size 可以改,单位 b/k/m/g。挂载选项带 noexec。
默认 64 MiB,写 100 MiB:65+0 records in | 64+0 records out | 67108864 bytes (64.0MB) copied, 0.130363 seconds, 490.9MB/s | 67108864 --shm-size 128m,写 100 MiB:100+0 records in | 100+0 records out | 104857600 bytes (100.0MB) copied, 0.166911 seconds, 599.1MB/s | 104857600
用 write 写满返回 ENOSPC:dd 只写进 64 MiB,第 65 个块写不下。
默认 64 MiB,共享内存 100 MiB:退出码 135;输出:ftruncate 成功,大小 100 MiB(稀疏,还没占用) --shm-size 128m,共享内存 100 MiB:退出码 0;输出:ftruncate 成功,大小 100 MiB(稀疏,还没占用) | 所有页都写完了
用 mmap 的程序(Python 的 shared_memory、浏览器、很多数据库)在创建时不会报错,写到没空间的页时才被 SIGBUS 杀死,退出码 135,很难一眼看出原因。
往 /dev/shm 写 80 MiB:memory.current 5.2 → 85.7 MiB(增加 80.5 MiB) --memory 64m、--shm-size 200m,往 /dev/shm 写 120 MiB:docker run 退出码 0;输出:dd 之后的退出码 0 | Killed;容器 ExitCode=0 OOMKilled=True
/dev/shm 是内存文件系统,写进去的内容算在容器的内存里;--memory 比 --shm-size 小的话,先触发的是 OOM,不是 No space left(与 c24 的 tmpfs 一致)。
b 通过 --ipc container:a 加入 a 的 IPC 命名空间后,能读到 a 写在 /dev/shm 的文件吗?from-a 两者的 IPC 命名空间相同吗?True
/dev/shm 属于 IPC 命名空间,--ipc shareable 加 --ipc container:名字 让两个容器共用同一个 /dev/shm。