Setting up LetsEncrypt SSL/TLS for a domain in MicroK8s

Prerequisites:

  1. Forward ports 80 & 443 to your server. Set up a domain name that point to your server.
  2. Ngnix Ingress Controller

Installing MicroK8s:

Here, we are using MicroK8s version 1.21 and for the letsencrypt SSL/TLS certificate we use a cert-manager.

To install MicroK8s,

snap install microk8s –classic –channel=1.21/stable

Now, enable the MicroK8s add-ons ‘dns’ and ‘ingress’.

sudo microk8s enable dns ingress

 

Deployment and Service file

A test webserver is created using an nginx image and a service is also associated with it. We are creating them in a namespace ‘dev’.

Create the namespace using the command,

microk8s kubectl create ns dev

Following is the deployment and service file ( webserver-depl-svc.yaml ).

 

apiVersion: apps/v1

kind: Deployment

metadata:

  name: webserver-depl

spec:

  selector:

    matchLabels:

      app: webserver-app

  template:

    metadata:

      labels:

        app: webserver-app

    spec:

      containers:

        – name: webserver-app

          image: nginx:1.8

apiVersion: v1

kind: Service

metadata:

  name: webserver-svc

spec:

  selector:

    app: webserver-app

  ports:

  – name: webserver-app

    protocol: TCP

    port: 80

    targetPort: 80

 

Apply the file using,

sudo microk8s kubectl apply -f webserver-depl-svc.yaml –n dev

 

Setting up an Nginx Ingress Controller

All the manifests used in this documentation are taken from the official Nginx community repo.

git clone https://github.com/Keyshelltechs/nginx-ingress-controller.git

 

Here is the one-liner to deploy all the objects.

microk8s kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/cloud/deploy.yaml

 

Install cert-manager

To install, cert-manager use the following command.

sudo microk8s kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.3.1/cert-manager.yaml

 

To check if the cert-manager is installed and running successfully,

sudo microk8s kubectl get pods -n=cert-manager ( You should see 3 pods running ).

 

Certificate Issuer config

Next, we have to create a certificate issuer config. Apply the following 2 yaml files for that.

letsencrypt-staging.yaml:

 

apiVersion: cert-manager.io/v1

kind: ClusterIssuer

metadata:

  name: letsencrypt-staging

spec:

  acme:

#change to your email

    email: youremail@gmail.com

    server: https://acme-staging-v02.api.letsencrypt.org/directory

    privateKeySecretRef:

      name: letsencrypt-staging

    solvers:

    – http01:

        ingress:

          class: public

 

letsencrypt-prod.yaml:

 

apiVersion: cert-manager.io/v1

kind: ClusterIssuer

metadata:

  name: letsencrypt-prod

spec:        

  acme:

    server: https://acme-v02.api.letsencrypt.org/directory

#change to your email

    email: youremail@gmail.com

    privateKeySecretRef:

       name: letsencrypt-prod

    solvers:

    – http01:

        ingress:

          class: public

 

Apply both files,

sudo microk8s kubectl apply -f letsencrypt-staging.yaml

sudo microk8s kubectl apply -f letsencrypt-prod.yaml

 

Create an ingress object

Create an ingress object to access our nginx welcome page using a DNS. An ingress object is nothing but a setup of routing rules. The ingress controller pod connects to the Ingress API to check for rules and it updates its nginx.conf accordingly.

To configure the ingress object, we use the following file ( ingress-routes.yaml ).

For the staging certificate, use the following ingress object.

 

apiVersion: networking.k8s.io/v1beta1

kind: Ingress

metadata:

  name: ingress-routes

  annotations:

    cert-manager.io/cluster-issuer: “letsencrypt-staging”

spec:

  tls:

  – hosts:

#change to your domain

    – yourdomain.com

    secretName: tls-secret

  rules:

#change to your domain

  – host: yourdomain.com

    http:

      paths:

        – path: /

        pathType: Prefix

        backend:

          service:

            name: webserver-svc

            port:

              number: 80

 

Apply it using,

sudo microk8s kubectl apply -f ingress-routes.yaml –n dev

sudo microk8s kubectl get certificate  ( Check if the state Ready=True)

 

Change the same ingress-routes.yaml file with the following content for production certificate.

 

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

  name: ingress-routes

  annotations:

    cert-manager.io/cluster-issuer: “letsencrypt-prod”

spec:

  tls:

  – hosts:

#change to your domain

    – yourdomain.com

    secretName: tls-secret

  rules:

#change to your domain

  – host: yourdomain.com

    http:

      paths:

        – path: /

        pathType: Prefix

        backend:

          service:

            name: webserver-svc

            port:

              number: 80

 

Apply and check the state using,

sudo microk8s kubectl apply -f ingress-routes.yaml –n dev

sudo microk8s kubectl get certificate

To verify if the certificate was issued,

sudo microk8s kubectl describe certificate tls-secret

 

Now, visit your domain to check if the SSL/TLS has been enabled.

 

Any SSL certificate already purchased from an authority

You can use the same deployment and service file for this case. For the certificate, you have to generate a secret and pass it to the ingress object from where the ingress controller will take it.

 

To create the secret, go to the directory where the certificates are saved or mention the absolute path to the files in the command,

microk8s kubectl create secret tls hello-app-tls –namespace dev –key server.key –cert server.cert

Now, you can use the following ingress-routes.yaml file and apply it.

 

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

  name: ingress-routes

  namespace: dev

spec:

  ingressClassName: nginx

  tls:

  – hosts:

#change to your domain

    – yourdomain.com

    secretName: hello-app-tls

  rules:

#change to your domain

  – host: ” yourdomain.com “

    http:

      paths:

        – pathType: Prefix

          path: “/”

          backend:

            service:

              name: webserver-svc

              port:

                number: 80

 

sudo microk8s kubectl apply -f ingress-routes.yaml

If needed you can forcefully apply the deployment file using,

sudo microk8s kubectl apply –f  webserver-depl-svc.yaml –force

 

Access the domain in browser and check if the certificate is applied.