LetEncrypt SSL certificates for your Kubernetes

|Edit on GitHub

If you are working with Kubernetes probably did you faced the situation when you need to use SSL certificates for your ingress domains. Here we take a look at how we can do it for free and automatically.

Prerequisites

First of all, we have to install some tools locally:

  • Helm 3 - for managing dependencies on your Kubernetes cluster.
  • Kubernetes cluster - if you don't have an own cluster I advise you to take a look at my previous post "How to create your own cluster for development?"
  • Kubectl - for managing your cluster.

Step 0: Preparation

I recommend to create independent Kubernetes namespace where will be running certificate manager:

kubectl create namespace cert-manager

Next, via HELM we will install the tool which is responsible for managing certificates. Let's add the needed Helm Repository:

helm repo add jetstack https://charts.jetstack.io

And now we are ready to install the cert-manager.

helm install certmanager --namespace cert-manager jetstack/cert-manager \ 
         --set ingressShim.defaultIssuerName=issuer-letsencrypt \
         --set ingressShim.defaultIssuerKind=ClusterIssuer
helm list -n cert-manager

NAME           NAMESPACE   	 STATUS  	  CHART                  APP VERSION
certmanager    cert-manager	 deployed	  cert-manager-v0.12.0   v0.12.0

cert-manager is a Kubernetes add-on to automate the management and issuance of TLS certificates. By simple words, cert-manager will manage all certificates automatically for all of our domain names.

Above, we installed cert-manager to cert-manager namespace using two custom parameters:

ingressShim.defaultIssuerName = issuer-letsencrypt - it defines the name of an issuer for managing certificates automatically, later we will look for a more detail sample.

ingressShim.defaultIssuerKind = ClusterIssuer - defines a kind of issuer.

There are two types of IssuerKind:

  • Issuer - manages certain namespace where it was created. It is not possible to issue certificates from an Issuer in a different namespace.
  • ClusterIssuer - manages a whole cluster independent of the namespace. For getting a certificate we just need to add an annotation to the Ingress and cert-manager automatically issues the certificate.

Step 1. Create an Issuer

First of all, we have to create an issuer which was defined above as ingressShim.defaultIssuerName with name issuer-letsencrypt:

Use Case #1

If we want to manage the whole cluster through one issuer. Here we have to use a kind ClusterIssuer and store it to cert-manager kubernetes namespace.

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: issuer-letsencrypt
  namespace: cert-manager
spec:
  acme:
    email: [your email address here]
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: issuer-letsencrypt
    solvers:
      - http01:
          ingress:
            class: nginx

Use Case #2

If we want to manage certain namespace. Here we have to use a kind Issuer and store it to the same namespace that your ingresses use (for instance: staging).

apiVersion: cert-manager.io/v1alpha2
kind: Issuer
metadata:
  name: issuer-letsencrypt
  namespace: staging
spec:
  acme:
    email: [your email address here]
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      # Secret resource used to store the account's private key.
      name: issuer-letsencrypt
    # Add a single challenge solver, HTTP01 using nginx
    solvers:
      - http01:
          ingress:
            class: nginx

Two of these use cases have the same structure:

  • metadata.name = issuer-letsencrypt - name which was defined as defaultIssuerName .
  • spec.acme.email - uses for issuing certificates.
  • spec.acme.server - there are two servers production and staging:

    We highly recommend testing against our staging environment before using our production environment. This will allow you to get things right before issuing trusted certificates and reduce the chance of your running up against rate limits.

You could read more detail documentation about Cert-Manager setup ACME guide here.

Step 2. Let's use an Issuer

Bellow a real sample of using Issuer was an important term to use an annotation:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: issuer-letsencrypt
  name: [some-ingress-name]
  namespace: staging
spec:
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          serviceName: [some-service-name]
          servicePort: 8080
        path: /
  tls:
  - hosts:
    - example.com
    secretName: [tls secret name]

But for clarity, I described the same thing, but without additional information, and left that really make sense:

metadata:
  annotations:
    cert-manager.io/cluster-issuer: issuer-letsencrypt
		# OR in case when we are using kind Issuer
    cert-manager.io/issuer: issuer-letsencrypt
spec:
  tls:
  - hosts:
    - example.com
    secretName: [TLS secret name]

Defined an annotation of issuer kind, and provided information of TLS host based on that will generate certificate and store to secret with name [TLS secret name].

Enjoy!

Will see in the next post 👋

Email News

Get an update when something new comes out by signing up below!

Subscribe