I have a ConfigMap with multiple files, and want to add these files to an already existing directory. But the tricky part here is, the filenames(keys) can change. So I can't try to mount them individually using subPath.
Is there any way this can be achieved from Deployment manifest?
Configmap:
config-files-configmap
└── newFile1.yml
└── newFile2.yml
Existing directory after adding files from configmap:
config/
└── existingFile1.yml
└── existingFile2.yml
└── newFile1.yml
└── newFile2.yml
PS: I have tried mounting the configmap as directory, which will override existing contents of the directory.
Thanks
CodePudding user response:
You can use the init container with configmap as a volume mount.
Not sure about the actual deployment architecture.
i would suggest injecting the configmap files to another directory and copying and pasting at starting of the main container.
Using life cycle hook of POD of init container.
As we can not go with subpath, this one option i am seeing as of now.
Example helm template from RabbitMQ
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ .Release.Name }}-rabbitmq
labels: &RabbitMQDeploymentLabels
app.kubernetes.io/name: {{ .Release.Name }}
app.kubernetes.io/component: rabbitmq-server
spec:
selector:
matchLabels: *RabbitMQDeploymentLabels
serviceName: {{ .Release.Name }}-rabbitmq-discovery
replicas: {{ .Values.rabbitmq.replicas }}
updateStrategy:
# https://www.rabbitmq.com/upgrade.html
# https://cloud.google.com/kubernetes-engine/docs/how-to/updating-apps
type: RollingUpdate
template:
metadata:
labels: *RabbitMQDeploymentLabels
spec:
serviceAccountName: {{ .Values.rabbitmq.serviceAccount }}
terminationGracePeriodSeconds: 180
initContainers:
# This init container copies the config files from read-only ConfigMap to writable location.
- name: copy-rabbitmq-config
image: {{ .Values.rabbitmq.initImage }}
imagePullPolicy: Always
command:
- /bin/bash
- -euc
- |
# Remove cached erlang cookie since we are always providing it,
# that opens the way to recreate the application and access to existing data
# as a new erlang will be regenerated again.
echo ${RABBITMQ_ERLANG_COOKIE} > /var/lib/rabbitmq/.erlang.cookie
chmod 600 /var/lib/rabbitmq/.erlang.cookie
# Copy the mounted configuration to both places.
cp /rabbitmqconfig/rabbitmq.conf /etc/rabbitmq/rabbitmq.conf
# Change permission to allow to add more configurations via variables
chown :999 /etc/rabbitmq/rabbitmq.conf
chmod 660 /etc/rabbitmq/rabbitmq.conf
cp /rabbitmqconfig/enabled_plugins /etc/rabbitmq/enabled_plugins
volumeMounts:
- name: configmap
mountPath: /rabbitmqconfig
- name: config
mountPath: /etc/rabbitmq
- name: {{ .Release.Name }}-rabbitmq-pvc
mountPath: /var/lib/rabbitmq
env:
- name: RABBITMQ_ERLANG_COOKIE
valueFrom:
secretKeyRef:
name: {{ .Release.Name }}-rabbitmq-secret
key: rabbitmq-erlang-cookie
containers:
- name: rabbitmq
image: "{{ .Values.rabbitmq.image.repo }}:{{ .Values.rabbitmq.image.tag }}"
imagePullPolicy: Always
resources:
requests:
cpu: 100m
memory: 100Mi
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: RABBITMQ_USE_LONGNAME
value: 'true'
- name: RABBITMQ_NODENAME
value: 'rabbit@$(MY_POD_NAME).{{ .Release.Name }}-rabbitmq-discovery.{{ .Release.Namespace }}.svc.cluster.local'
- name: K8S_SERVICE_NAME
value: '{{ .Release.Name }}-rabbitmq-discovery'
- name: K8S_HOSTNAME_SUFFIX
value: '.{{ .Release.Name }}-rabbitmq-discovery.{{ .Release.Namespace }}.svc.cluster.local'
# User name to create when RabbitMQ creates a new database from scratch.
- name: RABBITMQ_DEFAULT_USER
value: '{{ .Values.rabbitmq.user }}'
# Password for the default user.
- name: RABBITMQ_DEFAULT_PASS
valueFrom:
secretKeyRef:
name: {{ .Release.Name }}-rabbitmq-secret
key: rabbitmq-pass
ports:
- name: clustering
containerPort: 25672
- name: amqp
containerPort: 5672
- name: amqp-ssl
containerPort: 5671
- name: prometheus
containerPort: 15692
- name: http
containerPort: 15672
volumeMounts:
- name: config
mountPath: /etc/rabbitmq
- name: {{ .Release.Name }}-rabbitmq-pvc
mountPath: /var/lib/rabbitmq
livenessProbe:
exec:
command:
- rabbitmqctl
- status
initialDelaySeconds: 60
timeoutSeconds: 30
readinessProbe:
exec:
command:
- rabbitmqctl
- status
initialDelaySeconds: 20
timeoutSeconds: 30
lifecycle:
postStart:
exec:
command:
- /bin/bash
- -c
- |
# Wait for the RabbitMQ to be ready.
until rabbitmqctl node_health_check; do
sleep 5
done
# By default, RabbitMQ does not have Highly Available policies enabled,
# using the following command to enable it.
rabbitmqctl set_policy ha-all "." '{"ha-mode":"all", "ha-sync-mode":"automatic"}' --apply-to all --priority 0
{{ if .Values.metrics.exporter.enabled }}
- name: prometheus-to-sd
image: {{ .Values.metrics.image }}
ports:
- name: profiler
containerPort: 6060
command:
- /monitor
- --stackdriver-prefix=custom.googleapis.com
- --source=rabbitmq:http://localhost:15692/metrics
- --pod-id=$(POD_NAME)
- --namespace-id=$(POD_NAMESPACE)
- --monitored-resource-type-prefix=k8s_
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
{{ end }}
volumes:
- name: configmap
configMap:
name: {{ .Release.Name }}-rabbitmq-config
items:
- key: rabbitmq.conf
path: rabbitmq.conf
- key: enabled_plugins
path: enabled_plugins
- name: config
emptyDir: {}
volumeClaimTemplates:
- metadata:
name: {{ .Release.Name }}-rabbitmq-pvc
labels: *RabbitMQDeploymentLabels
spec:
accessModes:
- ReadWriteOnce
storageClassName: {{ .Values.rabbitmq.persistence.storageClass }}
resources:
requests:
storage: {{ .Values.rabbitmq.persistence.size }}
Example reference : https://github.com/GoogleCloudPlatform/click-to-deploy/blob/master/k8s/rabbitmq/chart/rabbitmq/templates/statefulset.yaml