Manage TLS Certificates In a Kubernetes Cluster (Authentication)

Sanket NankarSanket Nankar
4 min read

URL: https://kubernetes.io/docs/tasks/tls/certificate-issue-client-csr/

Managing TLS certificates in a Kubernetes cluster is an important part of securing communication between clients, services, and the Kubernetes API server.

Certificates are used to secure communication via mTLS (mutual TLS), encrypt traffic and establish trust between different components.

πŸ”‘ 1. Certificates in Kubernetes

Kubernetes uses TLS certificates in multiple places:

  • Kubernetes API Server – for authentication and encryption.

  • etcd – the key-value store requires TLS for secure communication.

  • Kubelet – node agent uses TLS to authenticate to the API server.

  • Controller Manager & Scheduler – also require certificates.

  • Ingress – TLS for external client access.

  • Mutual TLS Between Pods/Services – often implemented using service meshes (e.g., Istio, Linkerd).

πŸ“Œ 2. Managing Kubernetes Control Plane Certificates

The control plane certificates are usually managed by:

  • kubeadm (if the cluster was bootstrapped with kubeadm)

  • Custom CA (for enterprise setups)

  • Managed Kubernetes (EKS, AKS, GKE handle this automatically)

Checking existing certificates:

sudo kubeadm certs check-expiration

Renewing certificates:

sudo kubeadm certs renew all
sudo systemctl restart kubelet

πŸ“Œ Certificates are typically stored under:

/etc/kubernetes/pki/

πŸ“Œ 3. Managing TLS for Applications

For securing apps running in Kubernetes:

Option 1: Kubernetes Secrets

  • Store certificates and keys as Secrets:
kubectl create secret tls my-tls-secret \
  --cert=server.crt \
  --key=server.key \
  -n my-namespace
  • Reference in a Pod/Deployment:
volumes:
  - name: tls-certs
    secret:
      secretName: my-tls-secret

Option 2: Ingress + TLS

Use Ingress with TLS termination:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
spec:
  tls:
  - hosts:
    - myapp.example.com
    secretName: my-tls-secret
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-app
            port:
              number: 80

πŸ“Œ 4. Automating TLS with cert-manager

cert-manager is the standard tool for automatic certificate management in Kubernetes. It can automatically issue and renew certificates from:

  • Let’s Encrypt (ACME protocol)

  • Internal PKI / CA

  • HashiCorp Vault

Install cert-manager:

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml

Example: Let’s Encrypt certificate

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: myapp-cert
  namespace: my-namespace
spec:
  secretName: myapp-tls
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
  - myapp.example.com

πŸ“Œ 5. Managing mTLS Between Services

If you want pod-to-pod encryption:

  • Use Service Mesh (Istio, Linkerd, Consul Connect) β†’ they issue and rotate certificates automatically.

  • Alternatively, manually mount Secrets with TLS certs in Pods and configure apps for mTLS (not recommended at scale).

πŸ“Œ 6. Best Practices

βœ… Automate certificate issuance/renewal (cert-manager, Vault).

βœ… Store certs as Kubernetes Secrets, not ConfigMaps.

βœ… Rotate certificates periodically.

βœ… Use RBAC to restrict access to TLS Secrets.

βœ… For production, avoid self-signed certs unless using an internal CA.

To create a new Kubernetes user identity that authenticates with a TLS certificate.

1. Generate a private key

openssl genrsa -out myuser.key 3072

2. Generate a CSR (outside Kubernetes)

openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser"

πŸ‘‰ This produces myuser.csr.

3. Encode CSR into Base64

Kubernetes CSR YAML expects the CSR in Base64.

cat myuser.csr | base64 | tr -d "\n"

Copy this Base64 output.

4. Create csr.yaml

Example:

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: myuser
spec:
  request: <BASE64_OUTPUT_FROM_STEP3>
  signerName: kubernetes.io/kube-apiserver-client
  expirationSeconds: 86400
  usages:
  - client auth

Save it as csr.yaml.

5. Apply CSR YAML

kubectl apply -f csr.yaml

6. Approve the CSR

kubectl certificate approve myuser

7. Extract the signed certificate

Once approved:

kubectl get csr myuser -o jsonpath='{.status.certificate}' | base64 -d > myuser.crt

Now you have:

  • myuser.key β†’ private key

  • myuser.crt β†’ certificate signed by Kubernetes CA

  • Cluster CA (usually /etc/kubernetes/pki/ca.crt)

βœ… With these three, you can build a kubeconfig so myuser can authenticate to the cluster.

βœ… Learning:

  • TLS is used in Kubernetes to authenticate clients (like users or pods) securely.

  • A private key + CSR β†’ signed by Kubernetes via CertificateSigningRequest (CSR) API.

  • The CSR object requires base64 CSR, signerName, expiration time and usages (client/server).

  • An admin must approve the CSR before Kubernetes issues a certificate.

  • Certificates are short-lived (can be rotated).

  • Final output: private key and signed cert = can be used to authenticate to Kubernetes API.

0
Subscribe to my newsletter

Read articles from Sanket Nankar directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sanket Nankar
Sanket Nankar