mountPath overrides the rest of the files in that same folder - kubernetes

I have a volume with a secret called config-volume. I want to have that file in the /home/code/config folder, which is where the rest of the configuration files are. For that, I mount it as this:
volumeMounts:
- name: config-volumes
- mountPath: /home/code/config
The issue is that, after deploying, in the /home/code/config I only have the secret file and the rest of them are gone
So the /home/code/config is an existing folder (not empty), I suspect that the volumeMount overwrites the folder.
Is there a way that this can be done without overwriting everything?

You can do the following, taken from this GitHub issue
containers:
- volumeMounts:
- name: config-volumes
mountPath: /home/code/config
subPath: config
volumes:
- name: config-volumes
configMap:
name: my-config
Suggested that your ConfigMapis called my-config and that you have a key config in it.

Kubernetes Secrets are mounted as a directory, with each key as a file in that directory. So in your case, the config-volumes secret is mounted to /home/code/config, shadowing whatever that directory was before.
You could specify your volume mount as:
volumeMounts:
- name: config-volumes
- mountPath: /home/code/config/config-volumes
which would provide a config-volumes directory inside the config directory with files for your secret's keys inside.

Related

How to mount a specific file within a pod folder in kubernetes

I run Jenkins in k8s, and I have mount /var/jenkins_home folder with PVC already, now I want to mount /var/jenkins_home/config.xml as a configmap, other the folder still mount with pvc.
below is my yaml file:
volumeMounts:
- mountPath: /var/jenkins_home
name: jenkins-data
subPath: jenkins
- mountPath: /var/jenkins_home/config.xml
name: configxml
subPath: config.xml
volumes:
- name: jenkins-data
persistentVolumeClaim:
claimName: shdr-jenkins-k-test
- name: configxml
configMap:
name: jenkins-k-config
ites:
- key: jenkins-configfile
path: config.xml
when I open jenkins, it says:
Also: java.nio.file.FileSystemException: /var/jenkins_home/atomic14997153162086721303tmp -> /var/jenkins_home/config.xml: Device or resource busy
at java.base/sun.nio.fs.UnixException.translateToIOException(Unknown Source)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(Unknown Source)
at java.base/sun.nio.fs.UnixCopyFile.move(Unknown Source)
at java.base/sun.nio.fs.UnixFileSystemProvider.move(Unknown Source)
at java.base/java.nio.file.Files.move(Unknown Source)
at hudson.util.AtomicFileWriter.commit(AtomicFileWriter.java:194)
java.nio.file.FileSystemException: /var/jenkins_home/config.xml: Device or resource busy
Short Answer
You need to set the mountPath of jenkins-data volume to be /var/jenkins_home/jenkins. This will correctly configure the subPath functionality.
Detailed Explanation
If I understand correctly, what you are trying to achieve is the following:
You have a ConfigMap named jenkins-k-config. This contains a single parameter config.xml with contents of your Jenkins configuration as a value.
You want to mount this ConfigMap at the path /var/jenkins_home/ in your Jenkins pod, so the pod can use the /var/jenkins_home/config.xml file.
Here's how you can do this:
You will update your pod specification to add the ConfigMap as a volume.
You will then add a volumeMount to mount that the contents of that ConfigMap into the specified mount point in your pod's container.
Since your ConfigMap only contains a single key named config.xml, you don't have to specify the items anyway. Simply mounting the ConfigMap will work. See the manifest below:
volumeMounts:
- mountPath: /var/jenkins_home/
name: configxml
subPath: config.xml
readOnly: true. #<==== Recommended, so config remains immutable.
volumes:
- name:configxml
configMap:
name: jenkins-k-config
I also noticed that when all these mistakes have been fixed, we will end up with 2 volumes (jenkins-data, configxml) attempting to mount to the same mountPoint inside the pod. This is the reason you're seeing device or resource busy error, since the mountPoint is already busy, being mounted with the jenkins-data volume.
You can change the mount point to /var/jenkins_home/jenkins. This will also put your subPath variable in affect and you will be able to mount both volumes.
jenkins-data ====> /var/jenkins_home/jenkins and
config.xml ====> /var/jenkins_home/config.xml.

Kubernetes: creating permanent folders in pod

I have a pod in which I'm running a image.
The pod is not mine but belongs to the company I work for.
Each time I mount a new image in the pod it has access to some predefined "Permanent" folders.
When I use the edit deployment command I see this:
volumeMounts:
- mountPath: /Data/logs
name: ba-server-api-dh-pvc
subPath: logs
- mountPath: /Data/ErrorAndAbortedBlobs
name: ba-server-api-dh-pvc
subPath: ErrorAndAbortedBlobs
- mountPath: /Data/SuccessfullyTransferredBlobs
name: ba-server-api-dh-pvc
subPath: SuccessfullyTransferredBlobs
- mountPath: /Data/BlobsToBeTransferred
name: ba-server-api-dh-pvc
subPath: BlobsToBeTransferred
Now I want to manually add another such mountPath so I get another folder in the pod. But when I add it to the deployment config (the one above) and try saving it I get the following error.
"error: deployments.extensions "ba-server-api-dh-deployment" is invalid"
What can I do to add another permanent folder to the POD?
kind regards
It looks like you haven't specified the volume.
Something looks like this.
...
volumeMounts:
- mountPath: /Data/BlobsToBeTransferred
name: ba-server-api-dh-pvc
subPath: BlobsToBeTransferred
...
volume:
- name: ba-server-api-dh-pvc
persistentVolumeClaim:
claimName: ba-server-api-dh-pvc
Note that you already have a PersistentVolumeClaim named ba-server-api-dh-pvc, otherwise you will have to create.

Mounting /etc/default directory problem with SOLR image

I'm deploying a basic "solr:8.9.0" image to local Kubernetes env.
If I'm trying to mount pod's "/var/solr" directory, it works well.
I can see the files inside /var/solr in the mounted directory.
spec:
containers:
- image: solr:8.6.0
imagePullPolicy: IfNotPresent
name: solr
ports:
- name: solrport
containerPort: 8983
volumeMounts:
- mountPath: /var/solr/
name: solr-volume
volumes:
- name: solr-volume
persistentVolumeClaim:
claimName: solr-pvc
But somehow I can't mount "/etc/default/" directory. That doesn't work.
I knew there are files inside that directory but they are disappearing.
Any idea why?
Thanks!
this is because of how volumeMounts work.
A standard volumeMount mounts the volume in the suplied directory overwriting everything that is inside that directory.
You want to specify a subpath for the data you actually want to mount. By doing this the original contents of the directory won't get overridden.
see here for more information regarding the usage of subpaths.

Kubernetes copy image data to volume mounts

I need to share a directory between two containers: myapp and monitoring and to achieve this I created an emptyDir: {} and then volumeMount on both the containers.
spec:
volumes:
- name: shared-data
emptyDir: {}
containers:
- name: myapp
volumeMounts:
- name: shared-data
mountPath: /etc/myapp/
- name: monitoring
volumeMounts:
- name: shared-data
mountPath: /var/read
This works fine as the data I write to the shared-data directory is visible in both containers. However, the config file that is created when creating the container under /etc/myapp/myapp.config is hidden as the shared-data volume is mounted over /etc/myapp path (overlap).
How can I force the container to first mount the volume to /etc/myapp path and then cause the docker image to place the myapp.config file under the default path /etc/myapp except that it is the mounted volume thus allowing the config file to be accessible by the monitoring container under /var/read?
Summary: let the monitoring container read the /etc/myapp/myapp.config file sitting on myapp container.
Can anyone advice please?
Can you mount shared-data at /var/read in an init container and copy config file from /etc/myapp/myapp.config to /var/read?
Consider using ConfigMaps with SubPaths.
A ConfigMap is an API object used to store non-confidential data in
key-value pairs. Pods can consume ConfigMaps as environment variables,
command-line arguments, or as configuration files in a volume.
Sometimes, it is useful to share one volume for multiple uses in a
single pod. The volumeMounts.subPath property specifies a sub-path
inside the referenced volume instead of its root.
ConfigMaps can be used as volumes. The volumeMounts inside the template.spec are the same as any other volume. However, the volumes section is different. Instead of specifying a persistentVolumeClaim or other volume type you reference the configMap by name. Than you can add the subPath property which would look something like this:
volumeMounts:
- name: shared-data
mountPath: /etc/myapp/
subPath: myapp.config
Here are the resources that would show you how to set it up:
Configure a Pod to Use a ConfigMap: official docs
Using ConfigMap SubPaths to Mount Files: step by step guide
Mount a file in your Pod using a ConfigMap: supplement

Kubernetes Persisent Volume

Could anyone clarify on the Persistent Volume in Kubernetes?
In this below example, the /my-test-project is in the persistent volume.Then, why I need these mounts as technically my entire directory /my-test-project is persisted? How these mountpath and subpath would help if entire directory is persisted.Thanks!
volumeMounts:
- name: empty-dir-volume
mountPath: /my-test-project/data-cache
subPath: data-cache
- name: empty-dir-volume
mountPath: /my-test-project/user-cache
subPath: user-cache
volumes:
- name: empty-dir-volume
emptyDir: {}
Your /my-test-project entire directory is not persisted.
mountPath or path in host /my-test-project/data-cache is persisted in empty-dir-volume in path data-cache
mountPath /my-test-project/user-cache is persisted in empty-dir-volume in path user-cache
Which mean when you create files inside /my-test-project/data-cache, it will be persisted in data-cache(subpath) inside emtpy-dir-volume. Similarly for user-cache. Whenever you create files inside /my-test-project/ it wont be persisted. Lets say you create /my-test-project/new-dir, now new-dir will not be persisted.
For better explaination, lets take the below example(two containers sharing the volume, but in different mounthPath):
apiVersion: v1
kind: Pod
metadata:
name: share-empty-dir
spec:
containers:
- name: container-1
image: alpine
command:
- "bin/sh"
- "-c"
- "sleep 10000"
volumeMounts:
- name: empty-dir-volume
mountPath: /my-test-project/data-cache
subPath: data-cache-subpath
- name: empty-dir-volume
mountPath: /my-test-project/user-cache
subPath: user-cache-subpath
- name: container-2
image: alpine
command:
- "bin/sh"
- "-c"
- "sleep 10000"
volumeMounts:
- name: empty-dir-volume
mountPath: /tmp/container-2
volumes:
- name: empty-dir-volume
emptyDir: {}
In container-1:
mountPath /my-test-project/user-cache is persisted in empty-dir-volume in path user-cache-subpath
mountPath /my-test-project/data-cache is persisted in empty-dir-volume in path data-cache-subpath
In container-2:
mountPath /tmp/container-2 is persisted in empty-dir-volume in path "" (which means "/")
Observations:
touch /my-test-project/user-cache/a.txt. we can see this file in container-2 at /tmp/container-2/user-cache-subpath/a.txt and reverse will work
touch /my-test-project/data-cache/b.txt. we can see this file in container-2 at /tmp/container-2/data-cache-subpath/a.txt and reverse will work
touch /tmp/container-2/new.txt, we can never this file in container-1 as the base path we are have specified subPaths in container-1
Play around similarly for even better understanding
Note: Just to be clear, you are using emptyDir type volume, which means whenever pod gets deleted, data will be lost. This type is used only to share the data between containers.