---
title: Automated SSL certs for Kubernetes with letsencrypt and cert-manager
description: If you are running Kubernetes in production, then cert-manager is a must have. Here's a kubernetes cert manager tutorial to get you started!
---

[Fairwinds | Blog ](https://www.fairwinds.com/blog)

# [Automated SSL certs for Kubernetes with letsencrypt and cert-manager](https://www.fairwinds.com/blog/automated-ssl-certs-for-kubernetes-with-letsencrypt-and-cert-manager)

 Written by [Jess Grebenschikov](https://www.fairwinds.com/blog/author/jess-grebenschikov) | Jun 5, 2018 5:34:00 PM

Did you ever dream of the day where there would be free TLS certs that were automatically created and renewed when a new service shows up? Well that day has arrived. If you’ve jumped on the cool train and are running Kubernetes in production, then `cert-manager` is a must have. `cert-manager` is a service that automatically creates and manages TLS certs in Kubernetes and it is as cool as its sounds.

Here's a kubernetes cert manager tutorial to get things up and running.

**Overview to setup cert-manager**

To get this setup in a kubernetes cluster, there are 3 main moving pieces:

1. the cert-manager service which ensures TLS certs are valid, up to date, and renew them when needed.
2. the clusterIssuer resource which defines what Certificate Authority to use
3. the certificate resource which defines the certificate that should be created

The following steps assume [nginx-ingress controller](https://github.com/kubernetes/charts/tree/master/stable/nginx-ingress) is running in the kubernetes cluster and there is a way to create DNS records. Additionally, assumes [Helm](https://helm.sh/) is installed.

**Here is a Kubernetes**`cert-manger`** tutorial to get things up and running in a Kubernetes cluster.**

1. launch cert-manager from the [official helm chart](https://github.com/kubernetes/charts/tree/master/stable/cert-manager)
2. create a letsencrypt CA [clusterIssuer](https://omidraha.com/en/latest/src/kubernetes/cert_manager.html) k8s resource
3. launch an app (with an ingress) in the kubernetes cluster to be access at a TLS endpoint.
4. create a certificate object that describes how to create a TLS cert for the test app

## **Details to set up cert-manager**

Here are the more detailed steps:

1. Deploy the `cert-manager`[ helm chart](https://github.com/kubernetes/charts/tree/master/stable/cert-manager). Create the [values.yaml](https://github.com/JessicaGreben/example-nodejs/blob/master/deploy/cert-manager-setup/cert-manager-values.yaml) file then run: `helm-install --name my-release -f cert-manager-values.yaml cert-manager`. cert-manager can be configured to automatically provision TLS certificates for Ingress resources via annotations on your Ingresses. This is how I set up cert-manager and therefore, I added a two settings to the values.yaml file`ingressShim.defaultIssuerName` and `ingressShim.defaultIssuerKind`. Read more about [ingressShim here](https://cert-manager.io/docs/usage/ingress/). See my values file [here](https://github.com/JessicaGreben/example-nodejs/blob/master/deploy/cert-manager-setup/cert-manager-values.yaml).
2. Create the [letsencrypt CA cluster issuer](https://github.com/JessicaGreben/example-nodejs/blob/master/deploy/cert-manager-setup/letsencrypt-clusterissuer-staging.yaml). Here I used the letsencrypt staging ACME server just for testing, once this worked, I will switch over to letsencrypt production server. I created the following file by running: `kubectl create -f letsencryp-clusterissuer-staging.yaml`.

```
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    # The ACME server URL
    server: https://acme-staging.api.letsencrypt.org/directory    # Email address used for ACME registration    email: myemail@gmail.com    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
    name: letsencrypt-staging
    # Enable the HTTP-01 challenge provider
    http01: {}
```

3. Create a test app configured with TLS. Create the kubernetes manifest files (I created a helm chart [here](https://github.com/JessicaGreben/example-nodejs/tree/master/deploy/charts/example-nodejs)) including a [deployment](https://github.com/JessicaGreben/example-nodejs/blob/master/deploy/charts/example-nodejs/templates/deployment.yaml), [service](https://github.com/JessicaGreben/example-nodejs/blob/master/deploy/charts/example-nodejs/templates/service.yaml), and [ingress](https://github.com/JessicaGreben/example-nodejs/blob/master/deploy/charts/example-nodejs/templates/ingress.yaml). The ingress needs [annotations](https://github.com/JessicaGreben/example-nodejs/blob/master/deploy/charts/example-nodejs/templates/ingress.yaml#L8) that tell cert-manager what CA to use to create TLS certificates. The domain`example-nodejs.mydomain.com` must have a DNS record that is configured to send traffic to the nginx ingress controller load balancer.

```
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    certmanager.k8s.io/cluster-issuer: letsencrypt-staging
spec:
  tls:
  - hosts:
    - example-nodejs.mydomain.com
    secretName: example-nodejs-crt
rules:
- host: example-nodejs.mydomain.com
  http:
    paths:
    - path: /
      backend:
        serviceName: example-nodejs
        servicePort: 8080
```

4. Create the `certificate` resource with [acme http challenge](https://ietf-wg-acme.github.io/acme/draft-ietf-acme-acme.html#rfc.section.8.3) configured.

```
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
  name: example-nodejs-crt
spec:
  secretName: example-nodejs-crt
  dnsNames:
  - example-nodejs.mydomain.com
  acme:
    config:
    - http01:
        ingressClass: nginx
      domains:
      - example-nodejs.mydomain.com
  issuerRef:
    name: letsencrypt-staging
    kind: ClusterIssuer
```

Once this resource is created, there should be a tls cert that is created. If not, then check the logs of the cert-manger service for errors.

Once all these pieces are setup, you will still get an error when trying to access the app in the browser since the certificate was created with the [staging letsencrypt server](https://github.com/JessicaGreben/example-nodejs/blob/master/deploy/cert-manager-setup/letsencrypt-clusterissuer-staging.yaml#L8) however this still shows that the cert *was* successfully created.

Once this is setup successfully, then create a [production cluster-issuer](https://github.com/JessicaGreben/example-nodejs/blob/master/deploy/cert-manager-setup/letsencrypt-clusterissuer-prod.yaml) and replace all the references to the `letsencrypt-staging` clusterissuer with the `letsencrypt-prod` clusterissuer.

**Extra background info for fun if you are interested:**

**What is letsencrypt? **Letsencrypt is a Certificate Authority that issues free TLS certificates. It was launch in 2016 and its purpose is to try to make a safer internet by making it easier and cheaper to use TLS.

**What is the**[** ACME protocol**](https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment)**?** ACME stands for Automated Certificate Management Environment. It is a protocol for automating interactions between [certificate authorities](https://en.wikipedia.org/wiki/Certificate_authority) and their users’ web servers, allowing the automated deployment of [public key infrastructure](https://en.wikipedia.org/wiki/Public_key_infrastructure) at very low cost. It was designed by the [Internet Security Research Group](https://en.wikipedia.org/wiki/Internet_Security_Research_Group)(ISRG) for their [Let’s Encrypt](https://en.wikipedia.org/wiki/Let%27s_Encrypt) service.

**Resources:**

- [Letsencrypt How It Works](https://letsencrypt.org/how-it-works/)
- [cert-manager](https://github.com/jetstack/cert-manager)
- [my app example](https://github.com/JessicaGreben/example-nodejs) and helm charts for this blog post

[View full post](https://www.fairwinds.com/blog/automated-ssl-certs-for-kubernetes-with-letsencrypt-and-cert-manager)

```json
{
  "@context" : "http://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Jess Grebenschikov"
  },
  "dateModified" : "2024-02-20T14:57:24.244Z",
  "datePublished" : "2018-06-05T17:34:00Z",
  "headline" : "Automated SSL certs for Kubernetes with letsencrypt and cert-manager",
  "image" : {
    "@type" : "ImageObject",
    "height" : 591,
    "url" : "https://cdn2.hubspot.net/hubfs/2184645/standard_banner.png",
    "width" : 2000
  },
  "mainEntityOfPage" : "https://www.fairwinds.com/blog/automated-ssl-certs-for-kubernetes-with-letsencrypt-and-cert-manager",
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "height" : 60,
      "url" : "/hs/hsstatic/content_shared_assets/static-1.4092/img/default-amp-logo.png",
      "width" : 60
    },
    "name" : "Fairwinds | Blog"
  }
}
```