Docker 绑定安装目录中的文件未更新

Files within Docker bind mount directory not updating

我正在使用 docker 绑定挂载来映射由 Ubuntu 生成的主机 /dev/serial/ 文件夹(其中包含指向串行设备的识别符号链接,例如 /dev/ttyUSB0)。我使用的完整 docker 容器 运行 命令是

docker run -d --restart always --privileged=true -v /dev/serial:/dev/serial DOCKER_IMAGE_NAME

这起初工作正常 运行,但是如果串行设备断开连接并重新连接,符号链接将重新创建。此更改不会传播到 docker 容器中,而是 docker 容器找到一个空的 /dev/serial 文件夹。我测试了在主机上和此目录中的 docker 容器中手动创建一个文件,奇怪的是,在这两种情况下,一个文件的更改没有在另一个文件中更新。

成交量显示为

{
    "Type": "bind",
    "Source": "/dev/serial",
    "Destination": "/dev/serial",
    "Mode": "",
    "RW": true,
    "Propagation": "rprivate"
}

编辑:Ubuntu 在 /dev/serial 文件夹下的两个目录 by-pathby-id 中创建符号链接。

绑定挂载是基于 inode 的,当文件被删除并重新创建时,绑定挂载就会被破坏。在容器重新启动之前,这些更改不会传播到绑定安装,因此它会选择新的 inode。

这种情况(文件被删除并重新创建)的解决方案是挂载父目录,因此在您的情况下,您可以使用 -v /dev:/dev 挂载。当然这会将 /dev 暴露给容器,因此请小心处理。

Docker 的早期版本存在此问题。 Sebastian Van

已经清楚地解释了同样的原因

This looks like a race condition; the problem here is that, when using the -v : option, docker will automatically create if the path does not exist. This functionality was marked for deprecation at some point (exactly because of these issues), but it was considered too much of a breaking change to change (see moby/moby#21666, and issues linked from that issue).

Docker for Windows (when running Linux containers) runs the docker daemon in a VM. Files/directories shared from your local (Windows) machine are shared with the VM using a shared mount, and I suspect that mount is not yet present when the container is started.

Because of that, the %USERPROFILE%/docker_shared directory is not found inside the VM, so the daemon creates that path (as an empty directory). Later, when the shared mount (from the Windows host) is present, it's mounted "on top" of the %USERPROFILE% directory inside the VM, but at that point, the container is already started.

Restarting (docker stop, docker start) resolves the situation because at that point, the shared mount is available, and the container will mount the correct path.

关注主题:https://github.com/docker/for-win/issues/1192 以获得更好的理解。此问题已在 Docker 版本 2.0.4.0(Edge Channel)和更高版本的稳定版本中得到解决。