Skip to main content

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
{
  "downwardAPI": {
    "items": [
      {
        "path": "pod-name",
        "fieldRef": {
          "fieldPath": "metadata.name"
        }
      }
    ]
  }
}

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

Example: Check Volume Mounts in Pod

kubectl exec -it <pod-name> -- ls -la /mounted/path
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.

Was this article helpful?