Working with Projected Volumes
1. Understanding Projected Volumes
Projected volumes in Kubernetes allow you to mount multiple existing volumes, config maps, or secrets into a single directory within a Pod. They are particularly useful for sharing data across multiple containers in the same Pod or providing configuration data to applications without exposing sensitive information directly.
| Property | Description | Values |
|---|---|---|
| sources | List of sources to project into the volume | Array of objects (secret, configMap, downwardAPI, serviceAccountToken) |
| defaultMode | Permission mode for projected files | Integer (e.g., 420 = 0644) |
Example: Projecting a ConfigMap and Secret
apiVersion: v1
kind: Pod
metadata:
name: projected-volume-pod
spec:
containers:
- name: app-container
image: nginx
volumeMounts:
- name: projected-volume
mountPath: /etc/projected
volumes:
- name: projected-volume
projected:
sources:
- configMap:
name: app-config
- secret:
name: app-secret
Note: Projected volumes can only be mounted as read-only and cannot be used for persistent storage.
2. Projecting Secrets
| Field | Description | Example |
|---|---|---|
| secret.name | Name of the Secret object to project | my-secret |
| secret.items.key | Key within the Secret to project | password |
| secret.items.path | Path in the volume where the key is projected | credentials/password |
| secret.items.mode | Permissions for the projected file | 0644 |
Example: Projecting a Secret
apiVersion: v1
kind: Pod
metadata:
name: secret-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: secret-volume
mountPath: /etc/secret
volumes:
- name: secret-volume
projected:
sources:
- secret:
name: my-secret
Note: Projected volumes can combine multiple sources including secrets, config maps, and service account tokens.
3. Projecting ConfigMaps
| Field | Description | Example |
|---|---|---|
| configMap.name | Name of the ConfigMap to project | my-config |
| configMap.items.key | Key from the ConfigMap to project | database-url |
| configMap.items.path | Path in the volume where the key is projected | config/database-url |
| configMap.items.mode | Permissions for the projected file (octal) | 0644 |
Example: Projecting a ConfigMap
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
projected:
sources:
- configMap:
name: my-config
Note: ConfigMaps must exist in the same namespace as the Pod.
4. Projecting Service Account Tokens
| Field | Description | Default |
|---|---|---|
| projected.sources | List of sources to project into the volume | None |
| projected.sources[].serviceAccountToken | Source for service account token | None |
| projected.sources[].serviceAccountToken.audience | Optional audience for the token | API server's default audience |
| projected.sources[].serviceAccountToken.expirationSeconds | Expiration time in seconds | 3600 (1 hour) |
| projected.sources[].serviceAccountToken.path | Path in the volume to write the token | token |
Example: Configuring Service Account Token Projection
apiVersion: v1
kind: Pod
metadata:
name: token-test-pod
spec:
containers:
- name: token-container
image: nginx
volumeMounts:
- name: token-volume
mountPath: /token
readOnly: true
volumes:
- name: token-volume
projected:
sources:
- serviceAccountToken:
path: token
expirationSeconds: 7200
audience: api
Note: The projected token is automatically rotated by the API server before expiration.
Warning: Ensure that the audience matches your service's expectations to avoid authentication issues.
5. Projecting Downward API
| Field | Description | Example |
|---|---|---|
| downwardAPI | Enables projection of downward API values into the pod | |
Example: Projecting Pod Name
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "downward-api-pod"
},
"spec": {
"containers": [
{
"name": "downward-api-container",
"image": "nginx",
"volumeMounts": [
{
"name": "pod-info",
"mountPath": "/etc/pod-info"
}
]
}
],
"volumes": [
{
"name": "pod-info",
"downwardAPI": {
"items": [
{
"path": "pod-name",
"fieldRef": {
"fieldPath": "metadata.name"
}
}
]
}
}
]
}
}
Example: Projecting Pod Namespace
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "downward-api-pod"
},
"spec": {
"containers": [
{
"name": "downward-api-container",
"image": "nginx",
"volumeMounts": [
{
"name": "pod-info",
"mountPath": "/etc/pod-info"
}
]
}
],
"volumes": [
{
"name": "pod-info",
"downwardAPI": {
"items": [
{
"path": "pod-namespace",
"fieldRef": {
"fieldPath": "metadata.namespace"
}
}
]
}
}
]
}
}
Example: Projecting Pod Labels
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "downward-api-pod",
"labels": {
"app": "web"
}
},
"spec": {
"containers": [
{
"name": "downward-api-container",
"image": "nginx",
"volumeMounts": [
{
"name": "pod-info",
"mountPath": "/etc/pod-info"
}
]
}
],
"volumes": [
{
"name": "pod-info",
"downwardAPI": {
"items": [
{
"path": "pod-labels",
"fieldRef": {
"fieldPath": "metadata.labels"
}
}
]
}
}
]
}
}
6. Configuring Token Expiration
| Field | Description | Default Value | Notes |
|---|---|---|---|
| expirationSeconds | Duration in seconds for which the token will be valid | 3600 (1 hour) | Must be between 60 and 86400 seconds |
| audience | Intended audience for the token | API server's hostname | Optional; used for audience validation |
Example: Using Token Expiration in a Projected Volume
apiVersion: v1
kind: Pod
metadata:
name: projected-volume-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: projected-volume
mountPath: /etc/projected
volumes:
- name: projected-volume
projected:
sources:
- serviceAccountToken:
path: token
expirationSeconds: 7200
audience: api
Note: The
expirationSeconds field is only supported for serviceAccountToken in projected volumes. It does not apply to secret or configMap sources.
7. Setting Token Audience
| Field | Description | Values |
|---|---|---|
| audience | Specifies the intended audience for the token | string |
Example: Configuring Token Audience in ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: example-sa
namespace: default
secrets:
- name: example-sa-token
annotations:
kubernetes.io/service-account.name: example-sa
kubernetes.io/service-account.uid: "12345678-1234-1234-1234-123456789012"
kubernetes.io/service-account.token.audience: "api-server"
Note: The
audience field is used to set the intended audience for tokens issued by the ServiceAccount. This helps in validating the token's purpose and ensures that it is used only for the intended service or API endpoint.8. Combining Multiple Sources
Example: ConfigMap and Secret in One Projected Volume
apiVersion: v1
kind: Pod
metadata:
name: combined-volume-pod
spec:
containers:
- name: app-container
image: nginx
volumeMounts:
- name: combined-volume
mountPath: /config
volumes:
- name: combined-volume
projected:
sources:
- configMap:
name: app-config
- secret:
name: app-secret
| Source Type | Properties | Description |
|---|---|---|
| configMap | name, items |
Maps ConfigMap keys to files or directories in the projected volume |
| secret | name, items |
Maps Secret keys to files or directories in the projected volume |
| downwardAPI | items |
Exposes Pod and Container fields to projected volume files |
| serviceAccountToken | path, audience, expirationSeconds |
Mounts a service account token to the projected volume |
Note: When combining multiple sources, each source's keys are merged into the same projected volume namespace. Keys with the same name from different sources will overwrite each other.
9. Using Projected Volumes for mTLS
Projected volumes in Kubernetes allow you to mount multiple volume sources into a single directory. This feature is particularly useful for implementing mutual Transport Layer Security (mTLS) in applications by combining secrets and config maps into a single volume.
| Field | Description | Example Value |
|---|---|---|
| projected.sources | Array of volume sources to be projected | [{secret: {...}}, {configMap: {...}}] |
| projected.sources[].secret | Reference to a secret resource | {name: "mtls-secret"} |
| projected.sources[].configMap | Reference to a config map resource | {name: "mtls-config"} |
Example: mTLS Configuration
apiVersion: v1
kind: Pod
metadata:
name: mtls-pod
spec:
containers:
- name: app-container
image: myapp:latest
volumeMounts:
- name: mtls-volume
mountPath: /etc/mtls
volumes:
- name: mtls-volume
projected:
sources:
- secret:
name: client-cert-secret
- configMap:
name: mtls-configmap
Note: Ensure that the secrets and config maps used in projected volumes contain the necessary TLS certificates and configurations for mTLS to function correctly.
Warning: Projected volumes do not support
readOnly flag, so all mounted content is writable by default. Be cautious with sensitive data.
| Component | Type | Description |
|---|---|---|
| client-cert-secret | Secret | Contains client certificate and key for mTLS handshake |
| mtls-configmap | ConfigMap | Configuration parameters for mTLS behavior (e.g., trust store paths) |
10. Debugging Projected Volumes
| Step | Action | Description |
|---|---|---|
| 1 | kubectl describe pod <pod-name> |
Inspect volume mounts and events for errors |
| 2 | kubectl exec -it <pod-name> |
Enter the pod to verify volume contents |
| 3 | kubectl logs <pod-name> |
Check for volume-related errors in logs |
Note: Ensure the projected volume source (like ConfigMap or Secret) exists and is correctly referenced in the Pod spec.