是否可以覆盖或隐藏 Docker 容器中已挂载的文件

是否可以覆盖或隐藏 Docker 容器中已挂载的文件

我有一个包含两个配置文件的 Docker 镜像,并根据sed入口点脚本中传递的环境变量合并它们。为了简化此合并步骤,您可以假设类似

if [ -n $MERGE ]; then
    sed -i s/a/b/ /config.json
fi

config.json编写此入口点脚本的人没有考虑挂载到容器中的主要用例。在这种情况下,此脚本会产生错误消息

sed: cannot rename ./sedahi0e3: Device or resource busy

因为sed将其更改写入临时文件并覆盖原始文件。正如我所说,这是对我实际问题的简化,因此大多数解决方法都不起作用。我只想知道是否有可能以某种方式挂载config.json到容器中并允许其被覆盖、删除或隐藏。主机文件系统上的原始文件会发生什么并不重要。在最好的情况下,它不会被修改,但我可以接受它被删除或修改。如果不可能,我必须以一种复杂且容易出错的方式修改脚本,这可能会破坏一些我不知道的配置边缘情况。

我是否可以将文件挂载到 Docker 容器中,以便可以在容器内覆盖、删除或隐藏该文件?该镜像基于 Alpine Linux。主机是 Debian 或 RHEL。

要重现该问题,您可以创建一个文件config.json。使用以下命令启动 Alpine 容器

docker run -v $PWD/config.json:/config.json -it --rm alpine sh

复制文件

cp /config.json /config2.json

并尝试使用副本覆盖已安装的文件

mv /config2.json /config.json

这与sed入口点脚本中的合并类似,并产生相同的错误。

答案1

如果文件以 rw 方式挂载(默认),您可以替换其内容(这将修改主机上的文件):

$ cat config.json 
{
  "key": "value1"
}

$ docker run -v "$(pwd)/config.json:/config.json" --rm -it alpine sh
/ # cp /config.json /config2.json
/ # vi config2.json 
/ # cat config2.json >config.json
/ # cat config.json
{
  "key": "value2"
}
/ # exit

$ cat config.json 
{
  "key": "value2"
}

另一个值得考虑的选项是将镜像内的文件设为可以指向绑定挂载位置的符号链接。然后,您将符号链接更改为容器文件系统内的文件,而不是尝试替换绑定挂载。

对于更复杂的图像,一种常见的技术是在容器中有一个/config.d/由应用程序合并在一起的多个配置组成的目录,在这些情况下,您不需要修改绑定挂载,但可能会创建一个更高优先级的配置来覆盖您需要更改的任何设置。

任何试图更改绑定挂载的 inode 的操作都将不起作用。其中包括mvsed -i

相关内容