aethercert
Documentation

How to change Certificate on Kubernetes

Learn how to manually replace a kubernetes.io/tls Secret, manage full-chain PEM data, restart workloads when needed, verify rollout, and avoid downtime.

Kubernetes applications commonly consume a kubernetes.io/tls Secret containing tls.crt and tls.key. Updating the Secret changes stored data, but the Ingress controller or workload decides when that data becomes active.

Before you begin

Identify the cluster context, namespace, Secret name, Ingress/Gateway/workload references, controller behavior, replica count, PodDisruptionBudget, and current Secret backup. Use least-privilege credentials. Prepare a PEM full chain and matching PEM private key.

Understand TLS Secrets

The tls.crt value normally contains the leaf followed by intermediate certificates; tls.key contains its private key. The API checks that both keys exist for the Secret type but does not fully validate their cryptographic content. Secret data is base64 encoding, not encryption; protect API/RBAC and enable encryption at rest where required.

Step-by-step certificate replacement

  1. Back up metadata and encrypted secret handling without committing decoded key data:

    kubectl -n <namespace> get secret <secret> -o yaml > <protected-backup.yaml>
  2. Validate the files, then update declaratively:

    kubectl -n <namespace> create secret tls <secret> `
      --cert=fullchain.pem --key=private.key `
      --dry-run=client -o yaml | kubectl apply -f -

    Preserve labels/annotations managed by GitOps, Helm, or another controller; ideally update that source of truth instead of making an out-of-band live change.

  3. Determine activation behavior. Many Ingress controllers watch Secrets and reload automatically. A normal Secret volume is updated eventually, but an application may read it only at process start; environment-variable consumers never update in place. Restart only workloads that require it:

    kubectl -n <namespace> rollout restart deployment/<deployment>
    kubectl -n <namespace> rollout status deployment/<deployment> --timeout=10m
  4. Repeat only for separate clusters/namespaces/Secrets. A Secret is namespace-scoped.

Product-specific considerations

Do not delete/recreate a Secret when an in-place apply is sufficient; deletion creates an avoidable gap and existing Pods can retain a mount to the deleted object. Rolling restart availability depends on replica count, readiness probes, surge/unavailable settings, and disruption budgets. Immutable Secrets require a new named Secret and a workload reference change.

Verify the new certificate

Inspect the Secret's leaf certificate without printing the key, check controller and Pod events/logs, watch rollout status, then query the actual Ingress/Gateway hostname:

kubectl -n <namespace> get secret <secret> -o jsonpath='{.data.tls\.crt}' |
  base64 -d | openssl x509 -noout -subject -issuer -dates -fingerprint -sha256
openssl s_client -connect app.example.com:443 -servername app.example.com -showcerts </dev/null

Rollback

Reapply the protected previous Secret or revert the GitOps/Helm source, then repeat the required controller/workload activation. Watch the rollout and network endpoint.

Common problems

  • tls.crt contains only the leaf and omits intermediates.
  • Secret updated in the wrong context or namespace.
  • GitOps immediately restores the old Secret.
  • Application reads the Secret only at startup and no rollout occurs.
  • Broad RBAC permits unrelated workloads/users to read private-key data.

Automating certificate replacement with aethercert

The aethercert Kubernetes target creates or patches a kubernetes.io/tls Secret through the API and can trigger rolling restarts for explicitly listed Deployments in the same namespace.

See Deploy targets for the fields this preset takes, what it needs on the host, and how far it has been verified.

Sources

On this page