To simplify data management within your pods, you can use projected volumes to map multiple configuration sources, such as secrets and config maps, into a single directory. By using a single directory, you make it easier for your applications to access sensitive information and environment metadata easier.
You can use projected volumes to map any combination of the volume sources into a single directory, allowing the user to perform the following actions:
-
Automatically populate a single volume with the keys from multiple secrets, config maps, and with downward API information,
so that you can synthesize a single directory with various sources of information.
-
Populate a single volume with the keys from multiple secrets, config maps, and with downward API information,
explicitly specifying paths for each item, so that you can have full control over the contents of that volume.
|
|
When the RunAsUser permission is set in the security context of a Linux-based pod, the projected files have the correct permissions set, including container user ownership. However, when the Windows equivalent RunAsUsername permission is set in a Windows pod, the kubelet is unable to correctly set ownership on the files in the projected volume.
Therefore, the RunAsUsername permission set in the security context of a Windows pod is not honored for Windows projected volumes running in OKD.
|
The following general scenarios show how you can use projected volumes.
- Config map, secrets, Downward API
-
Projected volumes allow you to deploy containers with configuration data that includes passwords.
An application using these resources could be deploying OpenStack on Kubernetes. The configuration data might have to be assembled differently depending on if the services are going to be used for production or for testing. If a pod is labeled with production or testing, the downward API selector metadata.labels can be used to produce the correct OpenStack configs.
- Config map + secrets
-
Projected volumes allow you to deploy containers involving configuration data and passwords.
For example, you might execute a config map with some sensitive encrypted tasks that are decrypted using a vault password file.
- ConfigMap + Downward API
-
Projected volumes allow you to generate a config including the pod name (available via the metadata.name selector). This application can then pass the pod name along with requests to easily determine the source without using IP tracking.
- Secrets + Downward API
-
Projected volumes allow you to use a secret as a public key to encrypt the namespace of the pod (available via the metadata.namespace selector).
This example allows the Operator to use the application to deliver the namespace information securely without using an encrypted transport.
The following are examples of Pod specs for creating projected volumes.
Pod with a secret, a Downward API, and a config map
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: container-test
image: busybox
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
volumes:
- name: all-in-one
projected:
defaultMode: 0400
sources:
- secret:
name: mysecret
items:
- key: username
path: my-group/my-username
- downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "cpu_limit"
resourceFieldRef:
containerName: container-test
resource: limits.cpu
- configMap:
name: myconfigmap
items:
- key: config
path: my-group/my-config
mode: 0777
spec.containers.volumeMounts
-
Specifies a section for each container that needs the secret.
spec.containers.volumeMounts.mountPath
-
Specifies a path to an unused directory where the secret will appear.
spec.containers.volumeMounts.readOnly
-
When true, specifies that the volume mount is readOnly.
spec.containers.volumes
-
Specifies a volumes block to list each projected volume source.
spec.containers.volumes.name
-
Specifies a name for the volume.
spec.containers.volumes.projected.defaultMode
-
Specifies the execute permission on the files.
spec.containers.volumes.projected.sources.secret.name
-
Specifies a secret. Enter the name of the secret object. Each secret you want to use must be listed.
spec.containers.volumes.projected.sources.secret.items.path
-
Specifies the path to the secrets file under the mountPath. Here, the secrets file is in /projected-volume/my-group/my-username.
spec.containers.volumes.projected.defaultMode.downwardAPI
-
Specifies a Downward API source.
spec.containers.volumes.projected.defaultMode.configMap
-
Specifies a ConfigMap source.
spec.containers.volumes.projected.defaultMode.configMap.items.mode
-
Specifies the mode for the specific projection.
|
|
If there are multiple containers in the pod, each container needs a volumeMounts section, but only one volumes section is needed.
|
Pod with multiple secrets with a non-default permission mode set
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: container-test
image: busybox
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
volumes:
- name: all-in-one
projected:
defaultMode: 0755
sources:
- secret:
name: mysecret
items:
- key: username
path: my-group/my-username
- secret:
name: mysecret2
items:
- key: password
path: my-group/my-password
mode: 511
|
|
The defaultMode can only be specified at the projected level and not for each
volume source. However, as illustrated above, you can explicitly set the mode
for each individual projection.
|
- Pathing Considerations
-
-
Collisions Between Keys when Configured Paths are Identical. If you configure any keys with the same path, the pod spec will not be accepted as valid.
In the following example, the specified path for mysecret and myconfigmap are the same:
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: container-test
image: busybox
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: mysecret
items:
- key: username
path: my-group/data
- configMap:
name: myconfigmap
items:
- key: config
path: my-group/data
Consider the following situations related to the volume file paths.
-
Collisions Between Keys without Configured Paths. The only run-time validation that can occur is when all the paths are known at pod creation, similar to the above scenario. Otherwise, when a conflict occurs the most recent specified resource overwrites anything preceding it
(this is true for resources that are updated after pod creation as well).
-
Collisions when One Path is Explicit and the Other is Automatically Projected. If there is a collision due to a user-specified path matching data that is automatically projected,
the latter resource overwrites anything preceding it as before.