bigywater.tech
Docker · 29

tmpfs 挂载:内存文件系统的大小限制和数据去向

tmpfs 挂载的数据放在哪里?默认能写多少?写满了会怎样?容器内存限制和它是什么关系?这篇逐项实测。

3967 MiB
没指定 size 的 --tmpfs 的大小,正好是 MemTotal(7934 MiB)的一半
+100.4 MiB
往 tmpfs 写 100 MiB,容器 cgroup 的内存用量增加
137 / OOMKilled
内存限制 64m 时往 200m 的 tmpfs 写 150 MiB 的结果

默认大小

实测 · 本机执行输出
  /t1:挂载类型与选项 = tmpfs rw,nosuid,nodev,noexec,relatime;df 显示总大小 3967 MiB
  /t2:挂载类型与选项 = tmpfs rw,nosuid,nodev,noexec,relatime,size=10240k;df 显示总大小 10 MiB
  虚拟机(容器看到的)MemTotal = 7934 MiB;/t1 默认大小 = 其一半吗?True

--tmpfs /t1 不带 size,df 显示 3967 MiB,等于容器看到的内存(7934 MiB)的一半;带 size=10m 就是 10 MiB。挂载选项默认带 noexec,不能在上面直接执行程序(本文没有演示)。

写满

实测 · 本机执行输出
  dd 写 20 MiB 到 /t2(size=10m):dd 退出码 1 | dd: error writing '/t2/big': No space left on device | 11+0 records in | 10+0 records out | 10485760

写满后报的是 No space left on device,文件停在正好 10 MiB。

重启

实测 · 本机执行输出
  docker restart 之后:可写层里的 /layer.txt = layer;/t1 里的文件数 = 0

tmpfs 里的数据在 docker restart 后没了,可写层里的文件还在。

占内存

实测 · 本机执行输出
  写入前 5.9 MiB → 写入 100 MiB 后 106.3 MiB(增加 100.4 MiB)
  删掉文件后 8.3 MiB
  对比:同样 100 MiB 写到容器可写层 /layer.bin:8.9 → 111.2 MiB(增加 102.3 MiB;页缓存也会计入)

往 tmpfs 写 100 MiB,容器的 memory.current 增加了 100.4 MiB,删掉文件后回落;写到可写层同样会增加(页缓存),但那部分在内存紧张时可以回收,tmpfs 的数据不行——这一点我没有实验,是对机制的理解。

配合内存限制

实测 · 本机执行输出
  --memory 64m、tmpfs size=200m,往里写 150 MiB:docker run 退出码 0;输出:dd 退出码 137;容器 ExitCode OOMKilled = 0 true

容器内存上限 64m 而 tmpfs 允许 200m 时,写 150 MiB 到一半,dd 被内核 OOM 杀死(退出码 137),OOMKilled 为 true,但容器因为 shell 还活着,ExitCode 是 0。看容器的退出码不一定能发现内存被打爆,要看 OOMKilled(详见后面的 OOM 一篇)。

--mount 写法

实测 · 本机执行输出
  --mount type=tmpfs,destination=/m1 → 目录权限 drwxrwxrwt
  --mount type=tmpfs,destination=/m2,tmpfs-mode=0700,tmpfs-size=5m → 目录权限 drwx------

--mount type=tmpfs,destination=… 的目录默认是 1777;tmpfs-mode 和 tmpfs-size 可以调整。

分步演示

tmpfs 挂载
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Docker Desktop(Engine 29.8.2,容器跑在 Docker Desktop 自带的 Linux 虚拟机里,内核与宿主机的 macOS 不同);镜像为 linux/arm64;需要看虚拟机内部时用特权容器 + nsenter;计时用 time / date +%s%N,数字每次运行会有小幅抖动。容器的 MemTotal 7934 MiB(Docker Desktop 虚拟机内存);memory.current 取自容器内的 /sys/fs/cgroup/memory.current;每个场景只运行一次(OOM 和写满都是确定性的现象,数值有 ±几 MiB 抖动);实验后已删除容器
    • 没有验证:noexec 的实际影响、tmpfs 与 swap 的关系、Linux 宿主机上的 tmpfs 默认大小、tmpfs 在 docker commit / docker cp 里的表现、Kubernetes 的 emptyDir medium: Memory
    京ICP备2026067502号-1京公网安备11010502063487号