Ubuntu下使用shutil.rmtree删除Docker绑定挂载目录后挂载失效问题
问题根因
- 该行为差异是Linux绑定挂载的底层机制导致,和shutil库、Docker本身逻辑无关:
Linux原生的绑定挂载是将宿主机目录的inode与容器内挂载点绑定,当你执行shutil.rmtree删除宿主机的/tmp/mount_dir时,该目录对应的原始inode会被标记为已释放,后续os.mkdir创建的同名目录是全新的inode对象。容器内挂载的仍然是已经被删除的旧inode对应的空目录,所以执行ls /app看不到新写入的文件。 - MacOS上的Docker Desktop默认使用gRPC FUSE/osxfs实现跨系统文件共享,这类共享文件系统是基于路径而非inode做映射,删除原路径后重建同名路径,共享映射仍然能匹配到新的目录,所以表现正常。
可行解决方案
方案1:保留挂载根目录,仅删除目录内内容(最推荐)
不要删除整个挂载根目录,只清空目录下的所有子文件和子目录,保留根目录的inode不变,容器内的挂载就不会失效,Python代码示例如下:
import os import shutil mount_dir = "/tmp/mount_dir" # 遍历清空目录内容,保留目录本身 for entry in os.scandir(mount_dir): if entry.is_file() or entry.is_symlink(): os.remove(entry.path) elif entry.is_dir(): shutil.rmtree(entry.path) # 后续直接在原有目录下创建新内容即可 os.mkdir(os.path.join(mount_dir, "test_one"))
方案2:删除重建目录后重启容器
如果业务逻辑必须删除整个挂载根目录,删除重建完成后重启对应容器即可,容器重新启动时会绑定新目录的inode,挂载恢复正常。
方案3:调整挂载层级
如果需要频繁重建挂载目录,可以将挂载层级上移一级,比如挂载/tmp到容器的/host_tmp,容器内访问/host_tmp/mount_dir即可,即使重建mount_dir容器也能正常看到最新内容。
内容的提问来源于stack exchange,提问作者Ilya Zlatkin
相关产品推荐
相关产品推荐

