使用 configmap volume mount 将文件挂载(添加)到现有目录

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

我有一个包含多个文件的 ConfigMap,我想将这些文件添加到一个已经存在的目录中。但这里棘手的部分是,文件名(密钥)可以更改。所以我不能尝试使用 subPath 单独安装它们。

有什么方法可以从部署清单中实现吗?

配置图:

config-files-configmap
└── newFile1.yml
└── newFile2.yml

从 configmap 添加文件后的现有目录:

config/
└── existingFile1.yml
└── existingFile2.yml
└── newFile1.yml
└── newFile2.yml

PS: 我已经尝试将 configmap 安装为目录,这将覆盖目录的现有内容。

谢谢

您可以将 init 容器configmap 一起用作 volume 装载。

不确定实际的部署架构。

我建议将 configmap 文件注入另一个目录并在主容器启动时复制和粘贴。

使用初始化容器POD的生命周期钩子。

因为我们不能使用 subpath,我现在看到的是这个选项。

来自 RabbitMQ 的示例 helm 模板

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 }}

示例参考:https://github.com/GoogleCloudPlatform/click-to-deploy/blob/master/k8s/rabbitmq/chart/rabbitmq/templates/statefulset.yaml