容器内mount bind绑定目录后变更无法同步到宿主机问题
问题根因
核心原因是Docker卷默认的挂载传播属性为rprivate(私有递归),该属性下容器内对已挂载卷路径做的嵌套挂载操作(比如你执行的mount --bind),挂载事件不会向上同步到宿主机的挂载命名空间。
你启动容器时把宿主机/hostdir挂到容器内/hostdir后,在容器内部又执行bind把/container_dir挂到/hostdir,相当于在容器的命名空间里把这个路径的挂载点替换成了容器内部的目录,但宿主机侧感知不到这个替换,看到的还是最开始挂载进去的原始空目录,自然找不到你写入的hello.txt。
正确实现方法
两种方案都能满足需求,按需选择即可:
方案1:保留容器内bind操作,开启共享挂载传播
如果必须保留容器内执行mount --bind的操作逻辑,启动容器时显式开启双向挂载传播即可:
- 先在宿主机给目标目录设置共享挂载属性,否则Docker启动会抛出参数错误:
mkdir -p /hostdir mount --make-rshared /hostdir - 启动容器时给卷加上
rshared传播参数:docker run -itd --privileged --name ubuntu -v /hostdir:/hostdir:z,rshared ubuntu - 后续进入容器执行你原来的bind、写文件操作,所有写入内容都会直接同步到宿主机/hostdir目录。
方案2:跳过容器内bind操作,直接挂载到目标路径(最简便)
如果没有强制要求必须在容器内做bind挂载,根本不需要多此一举,启动容器时直接把宿主机目录挂载到你要使用的容器内路径即可:
mkdir -p /hostdir docker run -itd --privileged --name ubuntu -v /hostdir:/container_dir:z ubuntu
这种方式下容器内/container_dir目录本身就是直接映射宿主机/hostdir的,所有写入操作原生就会双向同步,完全不会遇到挂载传播的问题,稳定性更高。
注意事项
使用rshared传播属性时,该路径下的所有挂载事件会双向同步,不要在对应路径下执行无意义的高危挂载操作,避免污染宿主机挂载表。
内容的提问来源于stack exchange,提问作者Hackaholic
相关产品推荐
相关产品推荐

