tmpfs 挂载
卷(Volumes)和绑定挂载(bind mounts)允许您在宿主机和容器之间共享文件,以便即使在容器停止后数据也能持久化。
如果您在 Linux 上运行 Docker,您还有第三个选择:tmpfs 挂载。当您创建一个带有 tmpfs 挂载的容器时,该容器可以在其可写层之外创建文件。
与卷和绑定挂载不同,tmpfs 挂载是临时的,并且只保存在宿主机的内存中。当容器停止时,tmpfs 挂载会被移除,写入其中的文件不会被持久化。
当您不希望数据在宿主机或容器内持久化时,最适合使用 tmpfs 挂载。这可能是出于安全原因,或者当您的应用程序需要写入大量非持久性状态数据时,为了保护容器的性能。
重要Docker 中的 tmpfs 挂载直接映射到 Linux 内核中的 tmpfs。因此,临时数据可能会被写入交换文件(swap file),从而持久化到文件系统中。
覆盖现有数据挂载
如果您在容器中已存在文件或目录的路径上创建了一个 tmpfs 挂载,那么预先存在的文件将被该挂载所遮盖。这类似于您在 Linux 主机上将文件保存到 /mnt,然后将一个 USB 驱动器挂载到 /mnt。在 USB 驱动器被卸载之前,/mnt 的内容将被 USB 驱动器的内容所遮盖。
对于容器,没有直接的方法可以移除挂载以再次显示被遮蔽的文件。最好的选择是重新创建没有该挂载的容器。
tmpfs 挂载的局限性
- 与卷和绑定挂载不同,您不能在容器之间共享 tmpfs 挂载。
- 此功能仅在您于 Linux 上运行 Docker 时可用。
- 在 tmpfs 上设置权限可能会导致它们在容器重启后重置。在某些情况下,设置 uid/gid 可以作为一种变通方法。
语法
要使用 docker run 命令挂载 tmpfs,您可以使用 --mount 或 --tmpfs 标志。
$ docker run --mount type=tmpfs,dst=<mount-path>
$ docker run --tmpfs <mount-path>
通常情况下,推荐使用 --mount。主要区别在于 --mount 标志更明确。另一方面,--tmpfs 更简洁,并允许您设置更多的挂载选项,从而提供更大的灵活性。
--tmpfs 标志不能用于 swarm 服务。您必须使用 --mount。
--tmpfs 的选项
--tmpfs 标志由两个字段组成,以冒号 (:) 分隔。
$ docker run --tmpfs <mount-path>[:opts]
第一个字段是要挂载到 tmpfs 的容器路径。第二个字段是可选的,允许您设置挂载选项。--tmpfs 的有效挂载选项包括:
| 选项 | 描述 |
|---|---|
ro | 创建一个只读的 tmpfs 挂载。 |
rw | 创建一个读写的 tmpfs 挂载(默认行为)。 |
nosuid | 在执行期间阻止 setuid 和 setgid 位生效。 |
suid | 允许在执行期间 setuid 和 setgid 位生效(默认行为)。 |
nodev | 可以创建设备文件,但无法使用(访问会导致错误)。 |
dev | 可以创建设备文件并且功能齐全。 |
exec | 允许在挂载的文件系统中执行可执行二进制文件。 |
noexec | 不允许在挂载的文件系统中执行可执行二进制文件。 |
sync | 对文件系统的所有 I/O 操作都同步进行。 |
async | 对文件系统的所有 I/O 操作都异步进行(默认行为)。 |
dirsync | 文件系统内的目录更新同步进行。 |
atime | 每次访问文件时更新文件访问时间。 |
noatime | 访问文件时不更新文件访问时间。 |
diratime | 每次访问目录时更新目录访问时间。 |
nodiratime | 访问目录时不更新目录访问时间。 |
size | 指定 tmpfs 挂载的大小,例如 size=64m。 |
mode | 指定 tmpfs 挂载的文件模式(权限)(例如,mode=1777)。 |
uid | 指定 tmpfs 挂载所有者的用户 ID(例如,uid=1000)。 |
gid | 指定 tmpfs 挂载所有者的组 ID(例如,gid=1000)。 |
nr_inodes | 指定 tmpfs 挂载的最大 inode 数量(例如,nr_inodes=400k)。 |
nr_blocks | 指定 tmpfs 挂载的最大块数(例如,nr_blocks=1024)。 |
$ docker run --tmpfs /data:noexec,size=1024,mode=1777
并非所有 Linux mount 命令中可用的 tmpfs 挂载特性都受 --tmpfs 标志支持。如果您需要高级的 tmpfs 选项或特性,您可能需要使用特权容器或在 Docker 之外配置挂载。
警告使用
--privileged运行容器会授予提升的权限,并可能使主机系统面临安全风险。仅在绝对必要且在受信任的环境中使用此选项。
$ docker run --privileged -it debian sh
/# mount -t tmpfs -o <options> tmpfs /data
--mount 选项
--mount 标志由多个键值对组成,用逗号分隔,每个键值对由一个 <key>=<value> 元组构成。键的顺序不重要。
$ docker run --mount type=tmpfs,dst=<mount-path>[,<key>=<value>...]
--mount type=tmpfs 的有效选项包括:
| 选项 | 描述 |
|---|---|
destination, dst, target | 要挂载到 tmpfs 的容器路径。 |
tmpfs-size | tmpfs 挂载的大小(以字节为单位)。如果未设置,tmpfs 卷的默认最大大小为主机总 RAM 的 50%。 |
tmpfs-mode | tmpfs 的文件模式(八进制)。例如,700 或 0770。默认为 1777 或全局可写。 |
$ docker run --mount type=tmpfs,dst=/app,tmpfs-size=21474836480,tmpfs-mode=1770
在容器中使用 tmpfs 挂载
要在容器中使用 tmpfs 挂载,请使用 --tmpfs 标志,或者使用带有 type=tmpfs 和 destination 选项的 --mount 标志。tmpfs 挂载没有 source。以下示例在 Nginx 容器中的 /app 处创建了一个 tmpfs 挂载。第一个示例使用 --mount 标志,第二个示例使用 --tmpfs 标志。
$ docker run -d \
-it \
--name tmptest \
--mount type=tmpfs,destination=/app \
nginx:latest
通过查看 docker inspect 输出中的 Mounts 部分,验证该挂载是否为 tmpfs 挂载:
$ docker inspect tmptest --format '{{ json .Mounts }}'
[{"Type":"tmpfs","Source":"","Destination":"/app","Mode":"","RW":true,"Propagation":""}]
$ docker run -d \
-it \
--name tmptest \
--tmpfs /app \
nginx:latest
通过查看 docker inspect 输出中的 Mounts 部分,验证该挂载是否为 tmpfs 挂载:
$ docker inspect tmptest --format '{{ json .Mounts }}'
{"/app":""}
停止并移除容器
$ docker stop tmptest
$ docker rm tmptest