一、
首先说原理,参考docker数据的覆盖问题, 是没错的。
- 第一条原则:如果挂载一个空的数据卷到容器中的一个非空目录中,那么这个目录下的文件会被复制到数据卷中。
- 第二条原则:如果挂载一个非空的数据卷到容器中的一个目录中,那么容器中的目录中会显示数据卷中的数据。如果原来容器中的目录中有数据,那么这些原始数据会被隐藏掉。
二、但关键是怎么解读。
1、先解读第一句话: “如果挂载一个非空的数据卷到容器中的一个目录中”,有三种使用方式:
-
方式1:采用configmap的话,configmap相当于一个主机上的数据卷,而且是文件。 所以挂载到容器后,就会覆盖容器文件。 为了只覆盖容器里面的指定文件,就可以和subpath结合。
-
方式2:采用主机文件, 所以挂载到容器后,就会覆盖容器文件。 为了只覆盖容器里面的指定文件,就可以和subpath结合。
-
方式3:采用主机目录, 所以挂载到容器后,就会覆盖容器目录。 为了只覆盖容器里面的指定目录,就可以和subpath结合。
2、再解读第二句话:“如果挂载一个空的数据卷到容器中的一个非空目录中”, 也是最容易出现问题情况。
很多人启动一个容器运行中间件,为了备份中间件配置文件等原因,就想着把容器里面的配置文件挂载到主机上面去。 但出现了诸如“挂载到主机了,但是变成了一个目录”、“ Check if the specified host path exists and is the expected type.”、“ no such file or directory”等问题。
例如启动一个nginx容器,假如此时主机还没这个nginx.conf文件,你配置了nginx容器启动后把nginx.con文件挂载到主机上。 但挂载之后,发现主机上出现的不是nginx.conf文件,而是一个nginx.conf目录, 且报错“ Check if the specified host path exists and is the expected type”。
针对上面的问题,于是有人说先在主机上创建一个空的nginx.conf文件,这样做确实是可以挂载为nginx.conf文件。 但这个时候就会认为主机上有数据了,就变成“第一条原则了”,所以会覆盖容器,即主机上空的nginx.conf,覆盖了容器里面的nginx.conf, 导致nginx没配置了文件,就启动失败了。
最终推荐做法是:
步骤1:先不挂载nginx.conf文件,先启动nginx容器,使得在容器里面生成nginx.conf文件。
步骤2:然后拷贝nginx.conf到主机上。
步骤3:然后挂载主机nginx.conf到容器,并且启动容器,就可以了。