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.
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.)
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/