Kubernetes 在现有目录上挂载卷,容器内有文件

Yud*_*udi 20 mount docker kubernetes kubernetes-pod

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

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

体积

{
  "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"
  }
}
Run Code Online (Sandbox Code Playgroud)

卷挂载

{
  "mountPath": "/opt/myapplication/conf",
  "name": "cephfs-0",
  "readOnly": false
} 
Run Code Online (Sandbox Code Playgroud)

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

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

是否可以?

我浏览了 docker 文档,它提到

使用容器填充一个卷如果你启动一个创建新卷的容器,如上,并且容器在要挂载的目录中有文件或目录(如上面的/app/),目录的内容被复制到卷中. 然后容器安装并使用该卷,使用该卷的其他容器也可以访问预先填充的内容。

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

cod*_*ger 24

不幸的是,Kubernetes 的卷系统与 Docker 的卷系统非常不同,因此无法直接实现。如果只有一个文件(或少量文件),您可以像这样使用 subPath 投影:

volumeMounts:
- name: cephfs-0
  mountPath: /opt/myapplication/conf/foo.conf
  subPath: foo.conf
Run Code Online (Sandbox Code Playgroud)

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

  • @sngjuk 是的,这不是问题。这里的困难部分是 Docker 具有使用容器映像中的内容初始化持久卷的功能。Kubernetes 没有这个功能。 (3认同)

小智 5

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

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

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

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

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