简体   繁体   中英

Mount (add) files to existing directory using configmap volume mount

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM