Skip to main content
RunBook Academy

KubernetesCXIV · Certificate and TLS OperationsCertificate and TLS operations

Internal CA — the cert-manager CA injector and self-signed CAs

Advanced⏱ ~16 minkubectlcfsslcert-manager

What you'll learn

  • Create an internal CA for Kubernetes
  • Use the cert-manager CA injector to mount certificates into Pods
  • Issue certificates from the internal CA
  • Apply the operational discipline of internal CA management

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.

Internal CA provides certificates for private services within a cluster. This lesson walks creating the CA, the cert-manager CA injector, issuing certificates, and the discipline.

Creating an internal CA

# Generate the CA key and certificate with cfssl
cfssl gencert -initca -config ca-config.json -ca-key ca-key.pem \
  | cfssljson -bare ca
# Or with openssl
openssl genrsa -out ca-key.pem 4096
openssl req -new -x509 -days 3650 -key ca-key.pem -out ca.pem \
  -subj "/CN=Kubernetes Internal CA"

The CA is a self-signed certificate with a long validity (10 years). Store the key and cert as a Kubernetes Secret:

apiVersion: v1
kind: Secret
metadata:
  name: internal-ca-key-pair
  namespace: cert-manager
type: Opaque
data:
  tls.crt: <base64-encoded-ca.pem>
  tls.key: <base64-encoded-ca-key.pem>

The Secret stores the CA material; cert-manager uses it to sign issued certificates.

The internal CA issuer

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: internal-ca
  namespace: prod-app
spec:
  ca:
    secretName: internal-ca-key-pair

The internal CA issuer:

  • ca. The Secret containing the CA’s certificate and private key.
  • cert-manager signs issued certificates with this CA.

A certificate from the CA

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: myapp-cert
  namespace: prod-app
spec:
  secretName: myapp-tls
  dnsNames:
    - myapp.prod-app.svc.cluster.local
    - myapp.internal
  issuerRef:
    name: internal-ca
    kind: Issuer
    group: cert-manager.io
  duration: 720h  # 30 days
  renewBefore: 240h  # renew 10 days before

The certificate is signed by the internal CA. The TLS material is stored in the myapp-tls Secret.

The CA injector (CSI driver)

flowchart LR
    A[Pod] --> B["Volume mount: csi.cert-manager.io"]
    B --> C[cert-manager csi-driver]
    C -->|fetch cert| D[cert-manager]
    D -->|sign with CA| E[Internal CA]
    E -->|return cert| C
    C -->|mount| B

The cert-manager CSI driver (formerly CA injector) mounts certificates directly into Pods without storing them in Secrets.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      containers:
        - name: app
          image: myapp
          volumeMounts:
            - name: myapp-tls
              mountPath: /etc/tls
              readOnly: true
      volumes:
        - name: myapp-tls
          csi:
            driver: csi.cert-manager.io
            volumeAttributes:
              certManagerNamespace: prod-app
              issuerName: internal-ca
              duration: 720h

The Pod’s volume is backed by cert-manager’s CSI driver. The driver issues the certificate and mounts it into the Pod.

The use cases

flowchart LR
    A[Use cases] --> B[Private services]
    A --> C[mTLS between services]
    A --> D[Internal PKI]
    A --> E[Service mesh certificates]

The use cases:

  • Private services. Internal services that need TLS but don’t need a public certificate.
  • mTLS. Mutual TLS between services; both ends have certificates signed by the same CA.
  • Internal PKI. The cluster has its own PKI, separate from public PKIs.
  • Service mesh certificates. Istio, Linkerd, Consul use certificates for service identity.

Quiz

Knowledge check · 4 questions

  1. Q1. What must be distributed to clients when using an internal CA for in-cluster TLS?

  2. Q2. A CA's private key must be distributed to clients for certificate verification.

  3. Q3. Fix a client that rejects a server certificate issued by the cluster's own internal CA.

    Two services in prod-app both hold certificates issued by the internal-ca Issuer. The client fails every connection with `x509: certificate signed by unknown authority`. The server's Secret myapp-tls contains tls.crt, tls.key and ca.crt. The client Deployment mounts the Secret at /etc/tls but its TLS configuration points only at /etc/tls/tls.crt and it has no trust store entry for the internal CA.

  4. Q4. Which three keys does cert-manager write into a Secret issued by a CA Issuer, and which of them must the client be configured to trust?

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

The operational discipline

Internal CA in production rests on five non-negotiable elements:

  • Protect the CA private key. The entire chain depends on it.
  • Use the CSI driver for sensitive certs. Avoids Secret storage.
  • Document the CA hierarchy. Root CA, intermediate CAs, end-entity certificates.
  • Monitor certificate expiry. Alert on certificates expiring soon.
  • Test renewal. Quarterly: verify cert-manager renews certificates before expiry.

Internal CA is production PKI. The discipline is to protect the CA, use the CSI driver, and monitor renewals.