5

I am having a config file as a secret in kubernetes and I want to mount it into a specific location inside the container. The problem is that the volume that is created inside the container is a folder instead of a file with the content of the secrets in it. Any way to fix it? My deployment looks like this:

kind: Deployment
apiVersion: apps/v1
metadata:
  name: jetty
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jetty
  template:
    metadata:
      labels:
        app: jetty
    spec:
      containers:
        - name: jetty
          image: quay.io/user/jetty
          ports:
            - containerPort: 8080
          volumeMounts:
          - name: config-properties
            mountPath: "/opt/jetty/config.properties"
            subPath: config.properties
          - name: secrets-properties
            mountPath: "/opt/jetty/secrets.properties"
          - name: doc-path
            mountPath: /mnt/storage/
          resources:
            limits:
              cpu: '1000m'
              memory: '3000Mi'
            requests:
              cpu: '750m'
              memory: '2500Mi'
      volumes:
      - name: config-properties
        configMap:
          name: jetty-config-properties
      - name: secrets-properties
        secret: 
          secretName: jetty-secrets
      - name: doc-path
        persistentVolumeClaim:
          claimName: jetty-docs-pvc
      imagePullSecrets:
      - name: rcc-quay
zozo6015
  • 557
  • 2
  • 11
  • 27
  • Did checked it it does not work with secrets. – zozo6015 Jan 20 '21 at 21:06
  • You can only mount directories. Does it work if you e.g. only mount the ConfigMap? Or are there other things on that directory already? – Jonas Jan 20 '21 at 21:27
  • I need to mount multiple config files some of then has password and hashes that are in secrets others configuration files which goes to ConfigMap. The configmaps works great with subPath however secrets does not work. – zozo6015 Jan 20 '21 at 21:41

1 Answers1

19

Secrets vs ConfigMaps

Secrets let you store and manage sensitive information (e.g. passwords, private keys) and ConfigMaps are used for non-sensitive configuration data.
As you can see in the Secrets and ConfigMaps documentation:

A Secret is an object that contains a small amount of sensitive data such as a password, a token, or a key.

A ConfigMap allows you to decouple environment-specific configuration from your container images, so that your applications are easily portable.

Mounting Secret as a file

It is possible to create Secret and pass it as a file or multiple files to Pods.
I've create simple example for you to illustrate how it works. Below you can see sample Secret manifest file and Deployment that uses this Secret:
NOTE: I used subPath with Secrets and it works as expected.

---
apiVersion: v1
kind: Secret
metadata:
  name: my-secret
data:
  secret.file1: |
    c2VjcmV0RmlsZTEK
  secret.file2: |
    c2VjcmV0RmlsZTIK
---
apiVersion: apps/v1
kind: Deployment
metadata:
...
    spec:
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: secrets-files
          mountPath: "/mnt/secret.file1"  # "secret.file1" file will be created in "/mnt" directory
          subPath: secret.file1
        - name: secrets-files
          mountPath: "/mnt/secret.file2"  # "secret.file2" file will be created in "/mnt" directory
          subPath: secret.file2
      volumes:
        - name: secrets-files
          secret:
            secretName: my-secret # name of the Secret
            

Note: Secret should be created before Deployment.

After creating Secret and Deployment, we can see how it works:

$ kubectl get secret,deploy,pod
NAME                         TYPE                                  DATA   AGE
secret/my-secret             Opaque                                2      76s

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   1/1     1            1           76s

NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-7c67965687-ph7b8   1/1     Running   0          76s

$ kubectl exec nginx-7c67965687-ph7b8 -- ls /mnt
secret.file1
secret.file2
$ kubectl exec nginx-7c67965687-ph7b8 -- cat /mnt/secret.file1
secretFile1
$ kubectl exec nginx-7c67965687-ph7b8 -- cat /mnt/secret.file2
secretFile2

Projected Volume

I think a better way to achieve your goal is to use projected volume.

A projected volume maps several existing volume sources into the same directory.

In the Projected Volume documentation you can find detailed explanation but additionally I created an example that might help you understand how it works. Using projected volume I mounted secret.file1, secret.file2 from Secret and config.file1 from ConfigMap as files into the Pod.

---
apiVersion: v1
kind: Secret
metadata:
  name: my-secret
data:
  secret.file1: |
    c2VjcmV0RmlsZTEK
  secret.file2: |
    c2VjcmV0RmlsZTIK
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
data:
  config.file1: |
    configFile1  
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: all-in-one
      mountPath: "/config-volume"
      readOnly: true
  volumes:
  - name: all-in-one
    projected:
      sources:
      - secret:
          name: my-secret
          items:
            - key: secret.file1
              path: secret-dir1/secret.file1
            - key: secret.file2
              path: secret-dir2/secret.file2
      - configMap:
          name: my-config
          items:
            - key: config.file1
              path: config-dir1/config.file1

We can check how it works:

$ kubectl exec nginx -- ls /config-volume
config-dir1
secret-dir1
secret-dir2    
$ kubectl exec nginx -- cat /config-volume/config-dir1/config.file1
configFile1
$ kubectl exec nginx -- cat /config-volume/secret-dir1/secret.file1
secretFile1
$ kubectl exec nginx -- cat /config-volume/secret-dir2/secret.file2
secretFile2

If this response doesn't answer your question, please provide more details about your Secret and what exactly you want to achieve.

matt_j
  • 4,010
  • 1
  • 9
  • 23
  • I gave up on using secrets mostly becasue it does not fit my requirement. I need to store complete configuration files in secrets and then write those configuration files out to file what I have seen I can only write the keys/values from the config files and then write them back to files each to different file while I need all of them in the same file. Ideally would've been so that I set in configMaps the keys and fill their values from secrets but that does not work either. – zozo6015 Jan 21 '21 at 11:03
  • @zozo6015 I updated my answer to be more appropriate to your case. Does it answer your question ? If not, please provide more information about your expectations/requirements. – matt_j Feb 03 '21 at 14:52
  • This doesn't work for me. I don't know whether newer version of Kubernetes behave like this or not but I keep getting error: `not a directory: unknown` and that only happens with secrets, configmaps are all fine – xbmono Apr 05 '23 at 11:12