0

I'm trying to mount a secret as a file

apiVersion: v1
data:
  credentials.conf: >-
    dGl0bGU6IHRoaYWwpCg==
kind: Secret
metadata:
  name: address-finder-secret
type: Opaque
kind: DeploymentConfig
    apiVersion: v1
    metadata:
      name: app-sample
    spec:
      replicas: 1
      selector:
        app: app-sample
      template:
        metadata:
          labels:
            app: app-sample
        spec:
          volumes:
            - name: app-sample-vol
              configMap:
                name: app-sample-config
            - name: secret
              secret:
                secretName: address-finder-secret
          containers:
            - name: app-sample
              volumeMounts:
                - mountPath: /config
                  name: app-sample-vol
                - mountPath: ./secret/credentials.conf
                  name: secret
                  readOnly: true
                  subPath: credentials.conf

I need to add the credentials.conf file to a directory where there are already other files. I'm trying to use subPath, but I get 'Error: failed to create subPath directory for volumeMount "secret" of container "app-sample"' If I remove the subPath, I will lose all other files in the directory.

Where did I go wrong?

Violetta
  • 509
  • 4
  • 12

1 Answers1

3

Hello, Hope you are enjoying your kubernetes journey !

It would have been better if you have given your image name to try it out but however, i decided to create on custom image.

I created a simple file named file1.txt and copied it to the image, here is my dockefile:

FROM nginx

COPY file1.txt /secret/

I built it simply with:

❯ docker build -t test-so-mount-file .

I just checked if my file were here before going further:

❯ docker run -it test-so-mount-file bash
root@1c9cebc4884c:/# ls
bin                   etc    mnt   sbin    usr
boot                  home   opt   secret  var
dev                   lib    proc  srv
docker-entrypoint.d   lib64  root  sys
docker-entrypoint.sh  media  run   tmp
root@1c9cebc4884c:/# cd secret/
root@1c9cebc4884c:/secret# ls
file1.txt
root@1c9cebc4884c:/secret#

perfect. now lets deploy it on kubernetes.

For this test, since i'm using kind (kubernetes in docker) I just used this command to upload my image to the cluster:

❯ kind load docker-image test-so-mount-file --name so-cluster-1

It seems that you are deploying on openshift regarding to your "Deploymentconfig" kind. however, once my image has been added to my cluster i modified your deployment with it :

first without volumes, to check that the file1 is in the container:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-sample
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-sample
  template:
    metadata:
      labels:
        app: app-sample
    spec:
      containers:
        - name: app-sample
          image: test-so-mount-file
          imagePullPolicy: Never
          # volumeMounts:

yes it is:

❯ k exec -it app-sample-7b96558fdf-hn4qt -- ls /secret
file1.txt

Before going further, when i tried to deploy your secret i got this:

Error from server (BadRequest): error when creating "manifest.yaml": Secret in version "v1" cannot be handled as a Secret: illegal base64 data at input byte 20

This is linked to your base64 string that actually contains illegal base64 data, here it is:

❯ base64 -d <<< "dGl0bGU6IHRoaYWwpCg=="
title: thi���(base64: invalid input

No pb, I used another string in b64:

❯ base64 <<< test
dGVzdAo=

and added it to the secret. since I want this data to be in a file, i replaced the '>-' by a '|-' (What is the difference between '>-' and '|-' in yaml?),however it works, with or without it. Now, lets add the secret to our deployment. I replaced the "./secret/credentials.conf" by "/secret/credentials.conf" (it works with or without but i prefer to remove the "."). since I don't have your confimap datas, I commented out this part. However, Here is the deployment manifest of my file manifest.yaml:

apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: address-finder-secret
data:
  credentials.conf: |-
    dGVzdAo=

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-sample
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-sample
  template:
    metadata:
      labels:
        app: app-sample
    spec:
      containers:
        - name: app-sample
          image: test-so-mount-file
          imagePullPolicy: Never
          volumeMounts:
            # - mountPath: /config
            #   name: app-sample-vol
            - mountPath: /secret/credentials.conf
              name: secret
              readOnly: true
              subPath: credentials.conf
      volumes:
        # - name: app-sample-vol
        #   configMap:
        #     name: app-sample-config
        - name: secret
          secret:
            secretName: address-finder-secret

Lets deploy this:

❯ kaf manifest.yaml
secret/address-finder-secret created
deployment.apps/app-sample created



❯ k get pod
NAME                                READY   STATUS    RESTARTS   AGE
app-sample-c45ff9d58-j92ct          1/1     Running   0          31s



❯ k exec -it app-sample-c45ff9d58-j92ct -- ls /secret
credentials.conf  file1.txt



❯ k exec -it app-sample-c45ff9d58-j92ct -- cat /secret/credentials.conf
test

It worked perfectly, Since I havent modified big things from you manifest, i think the pb comes from the deploymentConfig, I suggest you to use deployment instead of deploymentConfig, That way it will works (I hope) and if someday you decide to migrate from openshift to another kubernetes cluster your manifest will be compatible.

bguess

Bguess
  • 1,700
  • 1
  • 11
  • 24