Kubernetes K8s 1.16:将映像中的现有目录装载到pv

Kubernetes K8s 1.16:将映像中的现有目录装载到pv,kubernetes,storage,persistent-volumes,Kubernetes,Storage,Persistent Volumes,tl;dr:我们如何将pod中的现有目录挂载到PV上,从而使我们能够持久保存将生成的数据 目前我们正在运行K8s 1.16.7,它集成了Azure磁盘和Azure文件。我们有一个映像,其中包含一些我们希望存储在PV上以实现持久性的目录。在Docker中,这很容易处理,因为容器会将数据写入hostmount。有人知道如何在库伯内特斯解决这个问题吗?当我们现在这样做时,容器会引导,但目录(例如:/etc/nginx/conf.d/作为PV的挂载)是空的,因此pod会崩溃 例如: 在下面的容器中,/u

tl;dr:我们如何将pod中的现有目录挂载到PV上,从而使我们能够持久保存将生成的数据

目前我们正在运行K8s 1.16.7,它集成了Azure磁盘和Azure文件。我们有一个映像,其中包含一些我们希望存储在PV上以实现持久性的目录。在Docker中,这很容易处理,因为容器会将数据写入hostmount。有人知道如何在库伯内特斯解决这个问题吗?当我们现在这样做时,容器会引导,但目录(例如:/etc/nginx/conf.d/作为PV的挂载)是空的,因此pod会崩溃

例如:

在下面的容器中,/usr/src/app中填充了helloworld应用程序。部署下面的文件后,容器崩溃,因为它无法在/usr/src/app中找到任何内容(由于PV mount,目录为空)

目标:将容器中/usr/src/app中的数据写入PV


提前谢谢

据我所知,每次创建
Pod
时,您都希望其
/usr/src/app
包含这两个数据,迄今为止由您的应用程序生成并永久存储在
PersistentVolume
中,以及
/usr/src/app
的原始内容,是您的
paulbouwer/hello kubernetes:1.8
图像的组成部分,可在
/usr/src/app
目录下获得

您可以在kubernetes中通过使用来实现它,它将在
Pod
启动过程中将
/usr/src/app
目录的原始内容复制到
PersistentVolume
中,该目录可能已经包含了应用程序先前生成的一些数据。在该卷初始化之后,主容器将装入
PersistentVolume
,其中包含应用程序先前生成的数据(如果有)以及图像中
/usr/src/app
目录的原始内容

您的
部署可能如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes
  namespace: testwebsite
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-kubernetes
  template:
    metadata:
      labels:
        app: hello-kubernetes
    spec:
      initContainers:
      - name: init-hello-kubernetes
        image: paulbouwer/hello-kubernetes:1.8
        command: ['sh', '-c', 'cp -a /usr/src/app/* /mnt/pv-content/']
        volumeMounts:
         - name: azurefile01
           mountPath: "/mnt/pv-content"
      containers:
      - name: hello-kubernetes
        image: paulbouwer/hello-kubernetes:1.8
        ports:
        - containerPort: 8080
        volumeMounts:
          - name: azurefile01
            mountPath: "/usr/src/app"
      volumes:
      - name: azurefile01
        persistentVolumeClaim:
          claimName: pvc-azurefile
为了从
paulbouwer/hello kubernetes:1.8
映像的
/usr/src/app/
中获取原始数据,您的init容器也必须基于该映像

一个警告:
paulbouwer/hello kubernetes:1.8
图像必须包含
cp
二进制才能执行该操作


正如你所看到的,这不是一个非常“优雅”的解决方案。其实不是。这就是为什么不建议将您的
PersistentVolume
装载到已包含一些重要文件的目录下,这些文件是您的应用程序正常运行所必需的。但无法在特定装入点下装入卷,同时保留其原始内容。在Linux或其他基于nix的系统中,它根本不能以这种方式工作。您可以装载整个卷,也可以根本不装载,并保留特定目录的原始内容。原始内容甚至没有被覆盖。它还在那里。当此特定路径用作不同卷的装载点时,它仍然不可用。

据我所知,每次创建
Pod
时,您都希望它的
/usr/src/app
包含这两个数据,迄今为止由您的应用程序生成并永久存储在
PersistentVolume
中,以及
/usr/src/app
的原始内容,是您的
paulbouwer/hello kubernetes:1.8
图像的组成部分,可在
/usr/src/app
目录下获得

您可以在kubernetes中通过使用来实现它,它将在
Pod
启动过程中将
/usr/src/app
目录的原始内容复制到
PersistentVolume
中,该目录可能已经包含了应用程序先前生成的一些数据。在该卷初始化之后,主容器将装入
PersistentVolume
,其中包含应用程序先前生成的数据(如果有)以及图像中
/usr/src/app
目录的原始内容

您的
部署可能如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-kubernetes
  namespace: testwebsite
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-kubernetes
  template:
    metadata:
      labels:
        app: hello-kubernetes
    spec:
      initContainers:
      - name: init-hello-kubernetes
        image: paulbouwer/hello-kubernetes:1.8
        command: ['sh', '-c', 'cp -a /usr/src/app/* /mnt/pv-content/']
        volumeMounts:
         - name: azurefile01
           mountPath: "/mnt/pv-content"
      containers:
      - name: hello-kubernetes
        image: paulbouwer/hello-kubernetes:1.8
        ports:
        - containerPort: 8080
        volumeMounts:
          - name: azurefile01
            mountPath: "/usr/src/app"
      volumes:
      - name: azurefile01
        persistentVolumeClaim:
          claimName: pvc-azurefile
为了从
paulbouwer/hello kubernetes:1.8
映像的
/usr/src/app/
中获取原始数据,您的init容器也必须基于该映像

一个警告:
paulbouwer/hello kubernetes:1.8
图像必须包含
cp
二进制才能执行该操作


正如你所看到的,这不是一个非常“优雅”的解决方案。其实不是。这就是为什么不建议将您的
PersistentVolume
装载到已包含一些重要文件的目录下,这些文件是您的应用程序正常运行所必需的。但无法在特定装入点下装入卷,同时保留其原始内容。在Linux或其他基于nix的系统中,它根本不能以这种方式工作。您可以装载整个卷,也可以根本不装载,并保留特定目录的原始内容。原始内容甚至没有被覆盖。它还在那里。当此特定路径用作其他卷的装载点时,它仍然不可用。

感谢您的回答Mario!我记得Docker(而不是kubernetes)在容器中安装了一个hostdirectory。容器会将原始数据写入已装载的主机路径,以便在移除容器后保留数据。遗憾的是,在K8s中,这不可能以优雅的方式实现:-(感谢您的回答Mario!我记得Docker(而不是kubernetes)在容器中装入hostdirectory时这样做的。容器会将原始数据写入装入的hostpath中,以便在移除容器后保留数据。遗憾的是,在K8s中,这不可能以优雅的方式实现-(