kubernetes - K8s 1.16:将镜像中的现有目录挂载到pv

标签 kubernetes storage pv

tl; dr:我们如何将 pods 中的现有目录安装到PV,从而使我们能够持久化将要生成的数据?
目前,我们正在运行具有Azure Disk和Azure File集成的K8s 1.16.7。我们有一个镜像,其中包含一些我们希望存储在PV上以保持持久性的目录。在Docker中,这很容易处理,因为容器会将数据写入主机安装中。有谁知道如何在Kubernetes中解决此问题?现在,当我们执行此操作时,容器将启动,但是目录(例如:/etc/nginx/conf.d/作为装入PV的目录)为空,并且pod崩溃了。
例:
在下面的容器中,/ usr / src / app充满了hello-world应用程序。在下面的文件部署之后,容器由于无法在/ usr / src / app中找到任何内容而崩溃(由于PV安装,目录为空)。

---
apiVersion: v1
kind: Namespace
metadata:
  name: testwebsite
  labels:
    environment: development
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: normal
  namespace: testwebsite
provisioner: disk.csi.azure.com
parameters:
  storageaccounttype: Standard_LRS
  kind: Managed
  resourceGroup: resourcegroup
  cachingmode: None
mountOptions:
  - dir_mode=0777
  - file_mode=0777
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-azurefile
  namespace: testwebsite
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: normal
---
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:
      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
目标:将容器内/ usr / src / app中的数据写入PV。
提前谢谢!

最佳答案

据我了解,您的要求是,每次创建Pod时,您都希望它的/usr/src/app包含应用程序到目前为止生成并永久存储在PersistentVolume中的数据,以及/usr/src/app的原始内容是您的paulbouwer/hello-kubernetes:1.8图片,可在/usr/src/app目录下找到。
您可以使用init container kubernetes 中实现该功能,该操作会将/usr/src/app启动过程中Pod目录的原始内容复制到可能已经包含某些数据的PersistentVolume中,该数据先前由您的应用生成。在进行这样的卷初始化之后,主容器将挂载PersistentVolume,其中包含您的应用先前生成的数据(如果有)以及镜像中/usr/src/app目录的原始内容。
您的Deployment可能如下所示:

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
为了从/usr/src/app/图像的paulbouwer/hello-kubernetes:1.8获取原始数据,您的init容器也必须基于该图像。
一个警告: paulbouwer/hello-kubernetes:1.8图像必须包含cp二进制文件才能执行该操作。
如您所见,这不是一个非常“优雅”的解决方案。好吧,实际上不是。这就是为什么不建议将PersistentVolume挂载在已经包含一些重要文件的目录下,应用程序需要该文件才能正常运行。但是无法将卷安装在特定的安装点下并同时保留其原始内容。在Linux或其他基于nix的系统中,它根本无法通过这种方式工作。您要么装载整个卷,要么根本不装载它,并保留特定目录的原始内容。原始内容甚至都不会被覆盖。它仍然在那里。当此特定路径用作其他卷的安装点时,它仍然完全不可用。

关于kubernetes - K8s 1.16:将镜像中的现有目录挂载到pv,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62997427/

相关文章:

networking - 当 pod 通过目标 pod 在同一主机上的服务与 pod 通信时,kubernetes 是否使用两次 conntrack?

android - 如何在Flutter中访问Android的内部存储

sh - 通过命令 "pv"压缩的文件与普通压缩文件不同

ffmpeg - 通过命名 PIPE 以有限的 "channel"带宽流式传输视频

Linux 管道查看器,如何拆分管道

kubernetes - NGINX Ingress 上的全局静态 IP 名称

azure - azure 上的 kudeadm k8s 集群

amazon-web-services - `aws eks list-nodegroups`和 `eksctl get nodegroups`结果不一致

hadoop - hadoop 的分布式替代品

javascript - Node.js 生态系统中在哪里存储大量媒体文件?