18

How can I mount a 'single' file from a secret?

I've created a secret with:

kubectl create secret generic oauth \
        --from-file=./.work-in-progress/oauth_private.key \
        --from-file=./.work-in-progress/oauth_public.key \

How can I mount the oauth_private.key file as a single file, rather than overriding the entire path with a directory that ONLY contains the two files (and potentially removing files that existed on the container initially)?

Chris Stryczynski
  • 30,145
  • 48
  • 175
  • 286
  • https://stackoverflow.com/questions/57104822/kubernetes-secret-items-not-mounted-as-file-path – nicole Nov 30 '19 at 07:05

2 Answers2

26

You can do as bellow:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      items:
      - key: username
        path: my-group/my-username

Suppose mysecret contains username and password. Above yaml will mount only username in /etc/foo/my-group/my-username directory.

For more details check this: Using Secrets as Files from a Pod

Emruz Hossain
  • 4,764
  • 18
  • 26
  • 3
    I assume this mounts /etc/foo as a new empty volume - which overrides the existing files in the container? So it has an unintended effect unfortunately. – Chris Stryczynski Nov 14 '18 at 08:57
  • 7
    `subPath` might help in this case. Check answers from this question: https://stackoverflow.com/questions/33415913/whats-the-best-way-to-share-mount-one-file-into-a-pod – Emruz Hossain Nov 14 '18 at 09:07
3

Providing an answer after I've wasted some good hour pulling my hair out, it is extremely important to create secret in k8s namespace where your deployment is running as secrets are tied to namespaces and all examples just use default namespace but your deployments are likely not!

Secret can be created in various ways, I'll show two common ones:

  1. From literal string
kubectl create secret generic my-secret --from-literal some_key='some_value' --namespace my-namespace
  1. From file content
kubectl create secret generic my-secret --from-file myfile --namespace my-namespace

Note that file name essentially becomes what "some_key" is with --from-literal and it's important to get it right because it will appear in your k8s configs!

You can now debug how it inflated:

kubectl describe secrets my-secret --namespace my-namespace

Note how secret can store multiple key value pairs, and in the Deployment example above I'm only going to mount one individual key.

Now that we have secret created in the right namespace, we can mount it as file.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test
  namespace: my-namespace
spec:
  selector:
    matchLabels:
      app: test
  replicas: 1
  template:
    metadata:
      labels:
        app: test
    spec:
      volumes:
        - name: my-secret
          secret:
            secretName: my-secret
            items:
              - key: my_key
                path: my_key
      containers:
        - name: test
          image: ubuntu:jammy
          volumeMounts:
            - name: my-secret
              mountPath: "/tmp/my_key"
              subPath: my_key
              readOnly: true

This will mount the secret as a single file to /tmp/my_key without overriding entire dir.

Artem Zinnatullin
  • 4,305
  • 1
  • 29
  • 43