skip to content
Sebastien Maintrot

Accessing Kubernetes Secrets Using Volumes

/ 5 min read

In Kubernetes, managing sensitive data like API keys, passwords, and certificates is a crucial aspect of building secure applications. One of the most secure ways to expose Secrets to a container is by using Volumes. This approach allows the Secret to be mounted as files inside the container, ensuring limited exposure and making it easier to handle sensitive information securely.

In this article, we’ll focus exclusively on accessing Kubernetes Secrets using Volumes. We will go over the basic concept, advantages of using Volumes for Secrets, and the various syntaxes available for configuring them.

Why Use Volumes to Access Secrets?

When using Volumes to access Kubernetes Secrets, the sensitive data is stored as files on the container’s filesystem, rather than exposed as environment variables. This method offers several advantages:

  • Better security: Since files can be read with more fine-grained access control than environment variables, you can make Secrets accessible only to specific parts of your application.
  • Read-only access: By default, Secrets mounted as volumes are read-only, reducing the risk of accidental modification.
  • Automatic updates: If a Secret is updated, the mounted volume will reflect the new value without needing to restart the Pod (except when using Subpath).

Let’s dive into the different ways you can configure Secrets using Volumes.

Mounting Secrets as Volumes: Basic Syntax

The most straightforward way to mount a Secret as a volume in a Pod is by defining a volume that references the Secret and a volumeMount in the container to map it to a specific directory in the filesystem.

Here’s the basic syntax for doing this:

basic.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-volume-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: secret-volume
mountPath: '/etc/secret' # Directory inside the container where the Secret will be mounted
readOnly: true # Ensure the Secret is mounted read-only
volumes:
- name: secret-volume
secret:
secretName: my-secret # The name of the Secret object

How This Works:

  • The volumeMounts section defines where the Secret should be mounted in the container (/etc/secret).
  • The volumes section references the Kubernetes Secret (my-secret) and exposes it through the volume.

In this configuration, the keys in the Secret (username and password) will be mounted as files under /etc/secret/username and /etc/secret/password, respectively. Each file contains the Secret’s value as its content.

Specifying Specific Keys from a Secret

Sometimes you may only want to mount specific keys from a Secret instead of all keys. You can do this using the items field in the volume definition.

Here’s how you can mount specific keys from the Secret:

specific-keys.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-volume-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: secret-volume
mountPath: '/etc/secret'
volumes:
- name: secret-volume
secret:
secretName: my-secret
items:
- key: username # Specify the key to be mounted
path: my-app-username # Custom filename for the key
- key: password
path: my-app-password # Custom filename for the key

How This Works:

  • In the items field, you specify which keys from the Secret to include. In this case, the username and password keys are mounted.
  • You can customize the file names under which the keys are stored inside the container (my-app-username and my-app-password).

Mounting Secrets as SubPaths

In some cases, you may need to mount a Secret to a specific sub-directory or file path within the container without affecting other contents in the directory. This is where the subPath option comes in handy.

Here’s an example:

subpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-subpath-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: secret-volume
mountPath: '/etc/app-config' # Mount target directory
subPath: username # Mount only this specific key
volumes:
- name: secret-volume
secret:
secretName: my-secret

How This Works:

  • The subPath option ensures that only the username key from the Secret is mounted to /etc/app-config/username. This approach prevents overwriting other contents in the /etc/app-config directory.

⚠️ Warning ⚠️

SubPaths are not automatically updated when a Secret is modified. If the Secret is updated you will have to restart the Pod to load the latest version.

Example with Multiple Containers Using the Same Secret

You can also use the same Secret across multiple containers in a single Pod, each mounting the Secret in different paths. This is useful when multiple containers need to share credentials or other sensitive data.

multiple-containers.yaml
apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
spec:
containers:
- name: app-container-1
image: nginx
volumeMounts:
- name: secret-volume
mountPath: '/etc/app1-secret'
- name: app-container-2
image: nginx
volumeMounts:
- name: secret-volume
mountPath: '/etc/app2-secret'
volumes:
- name: secret-volume
secret:
secretName: my-secret

How This Works:

  • The same Secret is mounted to different paths (/etc/app1-secret and /etc/app2-secret) in two separate containers within the same Pod.

Customizing File Permissions for Secrets

By default, Kubernetes mounts Secrets with 644 permissions (i.e., readable by everyone). If your application requires more restrictive file permissions, you can modify the default file permissions using the defaultMode field.

custom-permission.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-permission-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: secret-volume
mountPath: '/etc/secret'
volumes:
- name: secret-volume
secret:
secretName: my-secret
defaultMode: 0400 # Set file permissions to read-only for the owner

How This Works:

  • The defaultMode: 0400 ensures that only the owner (root, in this case) has read access to the files containing the Secret values.

Best Practices for Mounting Secrets as Volumes

  1. Use Least Privilege: Only mount the specific keys from Secrets that your application needs to access.
  2. Set Proper File Permissions: Ensure that file permissions are appropriately set to prevent unauthorized access to the Secrets.
  3. Rotate Secrets Regularly: Update your Secrets periodically, and leverage Kubernetes’ ability to automatically propagate changes to mounted Secrets.
  4. Avoid Storing Secrets in Logs: Ensure that your application doesn’t inadvertently log the contents of Secret files.

Conclusion

Mounting Kubernetes Secrets as Volumes is a powerful and secure method for managing sensitive data in your applications. This approach allows you to control access, securely expose only the necessary data, and maintain compliance with security best practices. With the various syntaxes available—whether it’s mounting all keys, specific keys, or setting custom permissions—you have a flexible way to handle Secrets in your Pods while minimizing security risks.