Skip to main content
RunBook Academy

KubernetesCXIV · Certificate and TLS OperationsCertificate and TLS operations

Application TLS secrets — using TLS material in Pods

Advanced⏱ ~16 minkubectlcert-manager

What you'll learn

  • Use kubernetes.io/tls Secrets for application TLS
  • Mount Secrets as volumes or environment variables
  • Use the CSI driver for direct certificate mounting
  • Apply the operational discipline of application TLS

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

Application TLS secrets are how applications consume certificates. This lesson walks the kubernetes.io/tls Secret type, mounting as volumes or environment variables, the CSI driver, and the discipline.

The kubernetes.io/tls Secret type

apiVersion: v1
kind: Secret
metadata:
  name: myapp-tls
  namespace: prod-app
type: kubernetes.io/tls
data:
  tls.crt: <base64-encoded-cert>
  tls.key: <base64-encoded-key>

The kubernetes.io/tls Secret:

  • tls.crt. The certificate (PEM-encoded).
  • tls.key. The private key (PEM-encoded).
  • Both are base64-encoded in the data field.

This is the standard Secret type for TLS material. kubectl knows the type and validates the format.

Mounting as a volume

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      containers:
        - name: app
          image: myapp
          volumeMounts:
            - name: tls
              mountPath: /etc/tls
              readOnly: true
      volumes:
        - name: tls
          secret:
            secretName: myapp-tls

The Pod sees:

  • /etc/tls/tls.crt — the certificate.
  • /etc/tls/tls.key — the private key.

The application reads the files from the mount path. This is the standard pattern for TLS material.

Mounting as environment variables

env:
  - name: TLS_CRT
    valueFrom:
      secretKeyRef:
        name: myapp-tls
        key: tls.crt
  - name: TLS_KEY
    valueFrom:
      secretKeyRef:
        name: myapp-tls
        key: tls.key

Environment variables:

  • The application reads the certificate and key from environment variables.
  • The values are base64-encoded (decoded by the container).
  • Less common than volume mounts; some applications require files.

The CSI driver (preferred)

flowchart LR
    A[Pod] -->|csi.cert-manager.io| B[CSI driver]
    B -->|fetch cert| C[cert-manager]
    C -->|sign with CA| D[CA]
    D -->|return cert| C
    C -->|mount| B
    B -->|/etc/tls/tls.crt| A

The cert-manager CSI driver mounts certificates directly into Pods without storing them as Secrets:

volumes:
  - name: tls
    csi:
      driver: csi.cert-manager.io
      volumeAttributes:
        certManagerNamespace: prod-app
        issuerName: internal-ca
        duration: 720h

The CSI driver issues the certificate on demand and mounts it. The certificate is on the Pod’s filesystem but not in etcd.

The rotation

flowchart LR
    A[Secret updated] -->|kubelet sync| B[Pod volume updated]
    C[CSI driver] -->|new cert| B
    D -->|periodic refresh| B

The rotation:

  • Secret-backed volume. The kubelet syncs the Secret; the Pod’s volume is updated (eventually consistent).
  • CSI driver. The CSI driver periodically refreshes the certificate; the Pod’s volume is updated.

The application may need to reload the certificate. Many TLS libraries support hot-reload; some do not.

The application patterns

# Reading from files
with open('/etc/tls/tls.crt', 'r') as f:
    cert = f.read()
with open('/etc/tls/tls.key', 'r') as f:
    key = f.read()

# Reading from env vars
import os
cert = os.environ['TLS_CRT']
key = os.environ['TLS_KEY']

# Hot reload on file change
import watchdog
class ReloadHandler(watchdog.events.FileSystemEventHandler):
    def on_modified(self, event):
        reload_tls()

The application patterns:

  • Files. Most common; load once or on signal.
  • Env vars. Less common; values are strings.
  • Hot reload. Watch the file; reload on change.

Quiz

Knowledge check · 4 questions

  1. Q1. Why is mounting TLS material as a volume preferred over environment variables?

  2. Q2. A Secret mounted as a volume is updated in the container when the Secret changes.

  3. Q3. Explain why an application still presents an expired certificate after cert-manager renewed it, and restore correct service.

    cert-manager renewed myapp-tls four days ago and `kubectl get certificate myapp-cert -n prod-app` shows READY True. Clients still receive an expired certificate from the application. The Deployment mounts the Secret as a volume at /etc/tls, and its Pods have an age of 51 days. The application reads /etc/tls/tls.crt once during start-up.

  4. Q4. Which two keys does a kubernetes.io/tls Secret require, and why does a certificate consumed through env.valueFrom.secretKeyRef never pick up a renewal?

Passing score: 75%. Answers are checked in this browser.

The operational discipline

Application TLS secrets in production rest on five non-negotiable elements:

  • Use kubernetes.io/tls Secret type. Standard format; kubectl validates.
  • Mount as volume, not env. Files are easier to hot-reload.
  • Consider the CSI driver. More secure for sensitive material.
  • Support hot reload. The application reloads certificates without restart.
  • Document the rotation procedure. The runbook describes the renewal.

Application TLS secrets are how applications consume certificates. The discipline is to choose the right mounting mechanism, support rotation, and document the procedure.