现有目录上的 Kubernetes 挂载卷,其中包含容器内的文件

Kubernetes mount volume on existing directory with files inside the container

我正在使用 1.11 版的 k8s 和 CephFS 作为存储。

我正在尝试将在 CephFS 上创建的目录挂载到 pod 中。为了达到同样的目的,我编写了以下卷和卷安装配置 在部署配置中

音量

{
  "name": "cephfs-0",
  "cephfs": {
    "monitors": [
      "10.0.1.165:6789",
      "10.0.1.103:6789",
      "10.0.1.222:6789"
    ],
    "user": "cfs",
    "secretRef": {
      "name": "ceph-secret"
    },
    "readOnly": false,
    "path": "/cfs/data/conf"
  }
}

volumeMounts

{
  "mountPath": "/opt/myapplication/conf",
  "name": "cephfs-0",
  "readOnly": false
} 

挂载正常。我可以看到 ceph 目录,即 /cfs/data/conf 挂载在 /opt/myapplication/conf 上,但以下是我的问题。

我的配置文件已经作为 docker 图像的一部分存在于位置 /opt/myapplication/conf。当部署尝试挂载 ceph 卷时,位于 /opt/myapplication/conf 位置的所有文件都会消失。我知道这是挂载操作的行为,但是有什么方法可以将容器中已经存在的文件保留在我正在挂载的卷上,以便其他正在挂载相同卷的 pod 可以访问配置文件。也就是说,已经存在于位置 /opt/myapplication/conf 的 pod 中的文件应该可以在 CephFS 上的位置 /cfs/data/conf.

上访问

可能吗?

我浏览了 docker 文档,其中提到

Populate a volume using a container If you start a container which creates a new volume, as above, and the container has files or directories in the directory to be mounted (such as /app/ above), the directory’s contents are copied into the volume. The container then mounts and uses the volume, and other containers which use the volume also have access to the pre-populated content.

这符合我的要求,但如何使用 k8s 卷实现它?

不幸的是,Kubernetes 的卷系统与 Docker 的卷系统非常不同,所以这不可能直接进行。如果只有一个文件(或少量文件),您可以像这样使用子路径投影:

volumeMounts:
- name: cephfs-0
  mountPath: /opt/myapplication/conf/foo.conf
  subPath: foo.conf

对每个文件重复该操作。但是,如果您有很多文件,或者它们可能会有所不同,那么您必须在运行时处理它或使用模板工具。通常这意味着将它安装在其他地方并在主进程启动之前设置符号链接。

我也遇到了这个非常小众的问题,无法将文件夹安装到包含我构建的映像内容的特定路径。这最终是空的。

但是我的解决方法是在 de dockerfile 中使用 ENTRYPOINT 引用运行命令的 shellscript 来初始化 DB 或对影响已安装目标文件夹的文件执行某些操作。

因此入口点似乎在 kubernetes 挂载卷之后运行。

我曾尝试在入口点脚本中对路径进行符号链接,但没有成功。

我可以通过让我的 ENTRYPOINT 成为一个 bash 脚本来解决这个问题,mv 我想将我的配置文件安装到正确的位置。似乎 this device or resource is busy 发生了错误,因为文件尚未安装。

很简单!你必须在这里使用 init 容器。使用 init 容器使用与您的应用程序相同的部署映像。 假设您的容器路径是 /opt/myapplication/conf 您的初始容器将共享 cephfs PVC

  1. 使用 init 容器定义卷安装在 /opt/data
  2. 在初始容器配置中 运行 命令 mv 将现有数据移动到已安装的卷路径 /opt/data。

使用主应用程序容器,将卷安装在正确的位置,即 /opt/myapplication/conf

现在当您部署应用程序时,

  • 您的 init 容器装载 cephfs pv 并将容器路径数据移动到卷。
  • 现在您的主应用程序启动并将卷挂载到正确的路径上,现在挂载时的卷也有数据。