Is there a way to share existing data between containers in a pod?

7/16/2019

I have 2 containers in a pod. 1. Webapp 2. Nginx I would like to share the data from Webapp container /var/www/webapp/ with the nginx container. /var/www/html

/var/www/webapp ( folder structure )
index.php
└───folder1
│   │   service1.php
│   │   
│   └───subfolder1
│       │   app.php
└───folder2
service2.php  

The folder is mounted properly but all the files are missing.

apiVersion: apps/v1
kind: Deployment
    spec:
      volumes:
      - name: webapp-data
        persistentVolumeClaim:
          claimName: webapp-data
      containers:
      - name: webapp
        image: webapp
        imagePullPolicy: Always 
        volumeMounts:
        - name: webapp-data
          mountPath: /var/www/webapp/
       - name: nginx
        imagePullPolicy: Always
        image: nginx
        volumeMounts:
        - name: webapp-data
          mountPath: /var/www/html/
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: webapp-data
spec:
  storageClassName: local
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

When mounting a volume under docker all the folders and files from within the container are available but not in k8s.

-- Khaliq
kubernetes
kubernetes-pvc
persistent-volumes

2 Answers

7/17/2019

Kubernetes will not automatically populate an empty volume with contents from an image. (This is a difference from docker run.) Your application needs to figure out how to set up the shared-data directory itself, if it's empty.

For standard database containers this doesn't really matter since they typically start off with some sort of initdb type call which will create the required file structure. Similarly, if you're using a persistent volume as a cache or upload space, it doesn't matter.

For the use case you're describing where you want one container to just have a copy of files from the other, you don't really need a persistent volume. I'd use an emptyDir volume that can be shared between the two containers, and then an init container to copy data into the volume. Do not mount anything over the application content.

This would roughly look like (in reality use a Deployment):

apiVersion: v1
kind: Pod
metadata:
  name: ...
spec:
  volumes:
    - name: webapp-data
      emptyDir: {}
  initContainers:
    - name: populate
      image: webapp
      volumeMounts:
        - name: webapp-data
          mountPath: /data
      command: [cp, -a, /var/www/webapp, /data]
  containers:
    - name: webapp
      image: webapp
      # no volumeMounts; default command
    - name: nginx
      image: nginx
      volumeMounts:
        - name: webapp-data
          mountPath: /var/www/html

With this setup there's also not a hard requirement that the two containers run in the same pod; you could have one deployment that runs the back-end service, and a second deployment that runs nginx (starting up by copying data from the back-end image).

(The example in Configure Pod Initialization in the Kubernetes docs is very similar, but fetches the nginx content from an external site.)

-- David Maze
Source: StackOverflow

7/16/2019

Probably just a mistake but you are referring to the volume with the name blinger-main in one of the containers. Use this:

apiVersion: apps/v1
kind: Deployment
    spec:
      volumes:
      - name: webapp-data
        persistentVolumeClaim:
          claimName: webapp-data
      containers:
      - name: webapp
        image: webapp
        imagePullPolicy: Always 
        volumeMounts:
        - name: webapp-data
          mountPath: /var/www/webapp/
       - name: nginx
        imagePullPolicy: Always
        image: nginx
        volumeMounts:
        - name: webapp-data
          mountPath: /var/www/html/
-- cookiedough
Source: StackOverflow