我的Docker容器(ubuntu:18.04)中有一个VPN客户端。

客户端必须执行以下操作:

mv /etc/resolv.conf /etc/resolv.conf.orig

然后,客户端应使用其DNS服务器创建新的/etc/resolv.conf。但是,移动失败并出现错误:
mv: cannot move '/etc/resolv.conf' to '/etc/resolv.conf.orig': Device or resource busy

这个可以解决吗?谢谢你提前。

附注:我无法更改VPN客户端代码。

最佳答案

在Docker容器中,/etc/resolv.conf文件不是普通的常规文件。 Docker以一种特殊的方式对其进行管理:容器引擎将特定于容器的配置写入容器外部的文件中,并将其绑定(bind)安装到容器内部的/etc/resolv.conf中。

当您的VPN客户端运行mv /etc/resolv.conf /etc/resolv.conf.orig时,事情归结为rename(2) syscall(或来自该家族的类似调用),并且根据此syscall的联机帮助页,由于多种原因(包括当出现以下情况时,会返回EBUSY(Device or resource busy)错误)原始文件是一个安装点:



尽管有种说法是不能保证在这种情况下会产生该错误,但似乎总是会向绑定(bind)安装目标触发该错误(我想这可能会发生here):

$ touch sourcefile destfile
$ sudo mount --bind sourcefile destfile
$ mv destfile anotherfile
mv: cannot move 'destfile' to 'anotherfile': Device or resource busy

因此,类似地,您不能在容器内移动/etc/resolv.conf,因为它是绑定(bind)安装,并且没有直接的解决方案。

鉴于/etc/resolv.conf的绑定(bind)安装是读写安装,而不是只读安装,仍然可以覆盖此文件:

$ mount | grep resolv.conf
/dev/sda1 on /etc/resolv.conf type ext4 (rw,relatime)

因此,可能的解决方法是尝试将此文件复制到.orig备份,然后重写原始文件,而不是重命名原始文件然后重新创建。

不幸的是,这不符合您的限制(I can 't change the VPN client code.),所以我敢打赌,您在这里很不幸。

07-27 14:00