Kubernetes configmap removes all the contents of existing directory - kubernetes

I have created a configmap and a pod yaml file .
I have tried multiple solutions but none worked for me .
kubectl describe cm cf3
Name: cf3
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
index.html:
----
hii im marimmo
Events: <none
pod yaml file
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: manya97/manya_tomcat:0.1
volumeMounts:
- name: config-volume
mountPath: /apache-tomcat-8.0.32/webapps/SampleWebApp/index.html
subPath: index.html
volumes:
- name: config-volume
configMap:
name: cf3
restartPolicy: Never
this was supposed to replace existing index.html file but somehow it removes all the content of SampleWebApp and places only index.html.
I dont know if have done it in correct way , I want to replace only content of index.html. Might be possible that mounting works this way I do not know .

Mounts are always directory-based. So having a mount in your yaml file tells k8s to mount the contents of the configMap (which could be one or more files) into the directory.
Whatever has been inside of the directory before the mount is gone then.
See the official documentation here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/
There is a hint saying "Caution: If there are some files in the mount directory, they will be deleted."

Related

How to create a volume that mounts a file which it's path configured in a ConfigMap

I'll describe what is my target then show what I had done to achieve it... my goal is to:
create a configmap that holds a path for properties file
create a deployment, that has a volume mounting the file from the path configured in configmap
What I had done:
ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
data:
my_properties_file_name: "my.properties"
Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-client-deployment
spec:
selector:
matchLabels:
app: my-client
replicas: 1 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: my-client
spec:
containers:
- name: my-client-container
image: {{ .Values.image.client}}
imagePullPolicy: {{ .Values.pullPolicy.client }}
ports:
- containerPort: 80
env:
- name: MY_PROPERTIES_FILE_NAME
valueFrom:
configMapKeyRef:
name: my-configmap
key: my_properties_file_name
volumeMounts:
- name: config
mountPath: "/etc/config"
readOnly: true
imagePullSecrets:
- name: secret-private-registry
volumes:
# You set volumes at the Pod level, then mount them into containers inside that Pod
- name: config
configMap:
# Provide the name of the ConfigMap you want to mount.
name: my-configmap
# An array of keys from the ConfigMap to create as files
items:
- key: "my_properties_file_name"
path: "my.properties"
The result is having a file namedmy.properties under /etc/config, BUT the content of that file is "my.properties" (as it was indicated as the file name in the configmap), and not the content of properties file as I have it actually in my localdisk.
How can I mount that file, using it's path configured in a configmap?
Put the content of the my.properties file directly inside the ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
data:
my_properties_file_name: |
This is the content of the file.
It supports multiple lines but do take care of the indentation.
Or you can also use a kubectl create configmap command:
kubectl create configmap my-configmap --from-file=my_properties_file_name=./my.properties
In either method, you are actually passing the snapshot of the content of the file on the localdisk to kubernetes to store. Any changes you make to the file on the localdisk won't be reflected unless you re-create the configmap.
The design of kubernetes allows running kubectl command against kubernetes cluster located on the other side of the globe so you can't simply mount a file on your localdisk to be accessible in realtime by the cluster. If you want such mechanism, you can't use a ConfigMap, but instead you would need to setup a shared volume that is mounted by both your local machine and the cluster for example using a NFS server.

Kubernetes mix config map and host path

Here is my deployment file and I am applying it with command kubectl apply -f deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: scan-deployment
labels:
app: scan
spec:
replicas: 1
selector:
matchLabels:
app: scan
template:
metadata:
labels:
app: scan
spec:
volumes:
- name: shared-files
configMap:
name: shared-files
containers:
- name: scan-svc
image: scan:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: shared-files
mountPath: /shared
Here I have my file test.txt file which is located in ./shared/test.txt that I have configured using configMap.
Now the thing is that I have subFolder in my local disk ./shared/xml, ./shared/report and I want to map /shared with container but not able to do it. I don't want to map config files from these subfolder. Deployed code creates report in xml and pdf format and saves it in respective folder and I want to map that to local disk.
Configmaps don't support recursive directories. When you create Configmap from ./shared directory, only the regular files in the directory are included. Sub directories are ignored.
You should create a regular volume from ./shared directory then mount it to the container.
It would be nice, if you would tell us why you are not able to do it, but I assume it overwrites your content under /shared, which is an expected behavior.
When you map your /shared; on the host with /shared in the container, it is going to be mapped correctly, but once configMap gets created, it is going to overwrite the content of the path, by whatever is in the configMap.

mount dot files in home folder of pod blowing away folder

I am building containers that are designed to build and publish things. So i need to configure the .pypirc, etc files.
I am trying to do it with a configmap. Creating a configmap with each of the dot files is easy enough, my problem is mapping it into the pod.
apiVersion: v1
kind: Pod
metadata:
generateName: jnlp-
labels:
name: jnlp
label: jnlp
spec:
containers:
- name: jnlp
image: '(redacted)/agent/cbuild-okd311-cmake3-py36:0.0.2.7'
tty: true
securityContext:
runAsUser: 1001
allowPrivilegeEscalation: false
volumeMounts:
- name: dotfiles
mountPath: "/home/jenkins"
volumes:
- name: dotfiles
configMap:
name: jenkins.user.dotfiles
heres my map (redacted)
apiVersion: v1
data:
.pypirc: |-
[distutils]
index-servers = local
[local]
repository: https://(redacted)/api/pypi/pypi
username: (redacted)
password: (redacted)
.p4config: |-
P4CLIENT=perf_pan
P4USER=(redacted)
P4PASSWD=(redacted)
P4PORT=p4proxy-pa.(redacted):1666
P4HOST=(redacted).com%
kind: ConfigMap
metadata:
name: jenkins.user.dotfiles
namespace: jenkins
im pretty sure that the mount command is blowing away everything else thats in the /home/jenkins folder. But im trying to come up with a mount that will create a dot file for each entry in my configmap.
Thanks
Your suspicion is correct. What you can use to fix that is subPath https://kubernetes.io/docs/concepts/storage/volumes/#using-subpath
But the downside is you do need a volumeMount entry for each of the dotfiles.

No such file or directory error on --audit-policy-file flag

I'm trying to enable audit option on my kubeadm based k8s. (v1.11.2)
but after I added --audit-policy-file flag on /etc/kubernetes/manifests/kube-apiserver.yaml, It won't start and print no such file or directory error.
This is my kube-apiserver.yaml file.
apiVersion: v1
kind: Pod
metadata:
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ""
creationTimestamp: null
labels:
component: kube-apiserver
tier: control-plane
name: kube-apiserver
namespace: kube-system
spec:
containers:
- command:
...
- --audit-policy-file=/etc/kubernetes/audit-policy.yaml
- --audit-log-path=/var/log/kubernetes
image: k8s.gcr.io/kube-apise...
...
and my error printed.
error: loading audit policy file: failed to read file path "/etc/kubernetes/audit-policy.yaml": open /etc/kubernetes/audit-policy.yaml: no such file or directory
I double checked the path and it was all fine.
Is this some kind of bug of kubeadm? I need your help.
Thanks.
Move your audit-policy.yaml file to the root path of the master node and then edit the given path in audit-policy-file also.
- --audit-policy-file=audit-policy.yaml
Create a volume and mounts for your audit policy file location in your kube-api manifest.
Something like this.
volumeMounts:
- mountPath: /var/lib/k8s_audit/
name: data
volumes:
- hostPath:
path: /var/lib/k8s_audit
type: DirectoryOrCreate
name: data

How to mount data file in kubernetes via pvc?

I want to persistent data file via pvc with glusterfs in kubernetes, I mount the diretory and it'll work, but when I try to mount the file, it'll fail, because the file was mounted to the directory type, how can I mount the data file in k8s ?
image info:
how can I mount the data file in k8s ?
This is often application specific and there are several ways to do so, but mainly you want to read about subPath.
Generally, you can chose to:
use subPath to separate config files.
Mount volume/path as directory at some other location and then link file to specific place within pod (in rare cases that mixing with other config files or directory permission in same dir is presenting an issue, or boot/start policy of application prevents files from being mounted at the pod start but are required to be present after some initialization is performed, really edge cases).
Use ConfigMaps (or even Secrets) to hold configuration files. Note that if using subPath with configMap and Secret pod won't get updates there automatically, but is more common way of handling configuration files, and your conf/interpreter.json looks like a fine example...
Notes to keep in mind:
Mounting is "overlaping" underlying path, so you have to mount file up to the point of file in order to share its folder with other files. Sharing up to a folder would get you folder with single file in it which is usually not what is required.
If you use ConfigMaps then you have to reference individual file with subPath in order to mount it, even if you have a single file in ConfigMap. Something like this:
containers:
- volumeMounts:
- name: my-config
mountPath: /my-app/my-config.json
subPath: config.json
volumes:
- name: my-config
configMap:
name: cm-my-config-map-example
Edit:
Full example of mounting a single example.sh script file to /bin directory of a container using ConfigMap.
This example you can adjust to suit your needs of placing any file with any privilege in any desired folder. Replace my-namespace with any desired (or remove completely for default one)
Config map:
kind: ConfigMap
apiVersion: v1
metadata:
namespace: my-namespace
name: cm-example-script
data:
example-script.sh: |
#!/bin/bash
echo "Yaaaay! It's an example!"
Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: my-namespace
name: example-deployment
labels:
app: example-app
spec:
selector:
matchLabels:
app: example-app
strategy:
type: Recreate
template:
metadata:
labels:
app: example-app
spec:
containers:
- image: ubuntu:16.04
name: example-app-container
stdin: true
tty: true
volumeMounts:
- mountPath: /bin/example-script.sh
subPath: example-script.sh
name: example-script
volumes:
- name: example-script
configMap:
name: cm-example-script
defaultMode: 0744
Full example of mounting a single test.txt file to /bin directory of a container using persistent volume (file already exists in root of volume).
However, if you wish to mount with persistent volume instead configMap, here is another example of mounting in much the same way (test.txt is mounted in /bin/test.txt)... Note two things: test.txt must exist on PV and that I'm using statefulset just to run with automatically provisioned pvc, and you can adjust accordingly...
apiVersion: apps/v1
kind: StatefulSet
metadata:
namespace: my-namespace
name: ss-example-file-mount
spec:
serviceName: svc-example-file-mount
replicas: 1
selector:
matchLabels:
app: example-app
template:
metadata:
labels:
app: example-app
spec:
containers:
- image: ubuntu:16.04
name: example-app-container
stdin: true
tty: true
volumeMounts:
- name: persistent-storage-example
mountPath: /bin/test.txt
subPath: test.txt
volumeClaimTemplates:
- metadata:
name: persistent-storage-example
spec:
storageClassName: sc-my-storage-class-for-provisioning-pv
accessModes: [ ReadWriteOnce ]
resources:
requests:
storage: 2Gi