DEV Community

Cover image for Cert-manager: automate certificate management on kubernetes
Ashok Nagaraj
Ashok Nagaraj

Posted on

Cert-manager: automate certificate management on kubernetes

Secure HTTP communication is popularly achieved through TLS certificates. These certificates can be to validate the server ( or both parties involved in the communication ( and which is commonly known as Mutual TLS (mTLS). mTLS is not common in web browsers but is used in service-to-service communication models.
To keep things secure, these certificates have a life-time and needs renewal upon expiry

In kubernetes for example kublet authenticates with kube-api-server through mTLS. The certificates come from within kubernetes control plane itself and a new one is issued for every new node that joins. For it's internal purposes there is a CertificateSigningRequest object provided, but it is not flexible enough to be used by workloads themselves.


Cert-manager is a general purpose x509 certificate management tool for Kubernetes.

  • It can be used as a standard Certificate Authority (CA).
  • It can also work with other well known CAs like Hashicorp Vault and LetsEncrypt.
  • It can generate self-signed certificates
  • It can inject certificates into workloads automatically through annotations
  • It can handle certificate rotation
❯ helm repo add jetstack
"jetstack" has been added to your repositories
❯ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "jetstack" chart repository
Update Complete. ⎈Happy Helming!⎈
❯ helm install \
  cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.9.1 \
  --set installCRDs=true
NAME: cert-manager
LAST DEPLOYED: Mon Sep 19 08:45:10 2022
NAMESPACE: cert-manager
STATUS: deployed
cert-manager v1.9.1 has been deployed successfully!

❯ kubectl get all -n cert-manager
NAME                                           READY   STATUS    RESTARTS   AGE
pod/cert-manager-85f68f95f-k9f6q               1/1     Running   0          2m19s
pod/cert-manager-cainjector-7d9668978d-lrtgn   1/1     Running   0          2m19s
pod/cert-manager-webhook-66c8f6c75-hq7lj       1/1     Running   0          2m19s

NAME                           TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
service/cert-manager           ClusterIP   <none>        9402/TCP   2m19s
service/cert-manager-webhook   ClusterIP    <none>        443/TCP    2m19s

NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/cert-manager              1/1     1            1           2m19s
deployment.apps/cert-manager-cainjector   1/1     1            1           2m19s
deployment.apps/cert-manager-webhook      1/1     1            1           2m19s

NAME                                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/cert-manager-85f68f95f               1         1         1       2m19s
replicaset.apps/cert-manager-cainjector-7d9668978d   1         1         1       2m19s
replicaset.apps/cert-manager-webhook-66c8f6c75       1         1         1       2m19s
Enter fullscreen mode Exit fullscreen mode
  • Issuer Objects representing CAs that generate certificates as requested through Certificate Signing Requests (CSRs). It is a namespace scoped resource - can issue certifcates valid in the operating namespace scope
  • ClusterIssuer Issuer with cluster scope - can issue certificate valid throughout the cluster
  • Certificate an object defining a X.509 certificate. This certificate is issued, kept up-to-date through renewal with cert-manager. A certificate issued through Issuer is namespace scoped, while the one issued through ClusterIssuer is valid through the cluster
  • CertificateRequest a namespaced resource used to request certificate from Issuer. It contains a base-64 encoded CSR sent to Issuer. Upon success, it will return a valid, signed certificate based on the CSR more info

cert-manager supports requesting certificates from ACME servers, including from Let's Encrypt, with use of the ACME Issuer. These certificates are typically trusted on the public Internet by most computers. To successfully request a certificate, cert-manager must solve ACME Challenges which are completed in order to prove that the client owns the DNS addresses that are being requested.

  • Order are resources used by the ACME issuer to manage the lifecycle of an ACME 'order' for a signed TLS certificate. It represents a single CSR.
  • Challenge are resources are used by the ACME issuer to manage the lifecycle of an ACME 'challenge' that must be completed in order to complete an 'authorization' for a single DNS name/identifier. It is created and managed by the challenge-controller more info
  • cainjector helps fetch CA certificates for webhooks and other API services. It populates the caBundle field of four API types: ValidatingWebhookConfiguration, MutatingWebhookConfiguration CustomResourceDefinition and APIService. It copies CA data from one of three sources: a Kubernetes Secret, a cert-manager Certificate, or from the Kubernetes API server CA certificate. Note: If the source is a Kubernetes Secret, that resource MUST also have an "true" annotation.
Example with a self-signed certificate
# assumption: cert-manager is installed and configured as described above

# Prepare a namespace
❯ kubectl create ns demo-ns
namespace/demo-ns created

# Prepare an issuercat issuer.yaml
kind: Issuer
  name: selfsigned-issuer
  namespace: demo-ns
  selfSigned: {}

# Create
❯ kubectl create -f issuer.yaml created

# Verify
❯ kubectl get -n demo-ns
NAME                READY   AGE
selfsigned-issuer   True    17s

# Create a Certificate objectcat certificate.yaml
kind: Certificate
  name: sample-certificate
  namespace: demo-ns
  secretName: sample-certificate
  - sample.demo-ns
    name: selfsigned-issuer

# Request for certificate
❯ kubectl create -f certificate.yaml created

# Verify 
❯ kubectl get certificate -n demo-ns
NAME                 READY   SECRET               AGE
sample-certificate   True    sample-certificate   10s

# Describe the secret
❯ kubectl get secrets/sample-certificate -n demo-ns -o yaml | cut -c -80
apiVersion: v1
kind: Secret
  annotations: sample.demo-ns sample-certificate "" "" "" Issuer selfsigned-issuer ""
  name: sample-certificate
  namespace: demo-ns

# Inject secret to a validation webhookcat val-webhook.yaml
kind: ValidatingWebhookConfiguration
  name: test-webhook
  annotations: demo-ns/sample-certificate
- name:
  - v1
      name: test-webhook
      namespace: demo-ns
      path: /validate
      port: 443
  sideEffects: None

# Instantiate assuming test-webhook is a valid service in demo-ns pointing to port 443 to validate on /validate route
❯ kubectl create -f val-webhook.yaml created

# Verify 
❯ kubectl get
NAME                   WEBHOOKS   AGE
cert-manager-webhook   1          137m
test-webhook           1          6s

Enter fullscreen mode Exit fullscreen mode

Top comments (0)