DEV Community

Pascal Widdershoven
Pascal Widdershoven

Posted on • Originally published at pascalw.me on

k3s HTTPS with Let’s Encrypt

K3s is a Certified Kubernetes distribution designed for production workloads in unattended, resource-constrained, remote locations or inside IoT appliances.
It provides a ready to go Kubernetes instance packaged a single binary.

This guide will show you how to easily set up k3s with HTTPS via Let’s Encrypt.

(READMORE)

K3s comes with Traefik out of the box. Traefik itself supports automatic HTTPS via Let’s Encrypt, but setting this up with k3s turned out to be pretty cumbersome. Instead using the excellent cert-manager add-on, it's a breeze!

0: Setup k3s.

This guide assumes you have a working k3s instance and kubectl configured to talk to your k3s instance. If you haven't already just follow the docs and you'll be up and running in minutes.

1. Install Helm

Helm is a package manager for Kubernetes. It consists of a local client and a server component.
Installing Helm is quite straightfoward.

Install the client:

$ brew install kubernetes-helm 

Create the service account so Helm can interact with your k3s instance:

$ kubectl create serviceaccount tiller --namespace=kube-system 

Grant it admin privileges:

$ kubectl create clusterrolebinding tiller-admin --serviceaccount=kube-system:tiller --clusterrole=cluster-admin 

Note: granting admin privileges to Helm might not be a good idea depending on how your cluster is setup. Read here for more details.

Install Helm on k3s:

$ helm init --service-account=tiller 

2. Install cert-manager

Alright, so now we have Helm installed let's move on to installing cert-manager.
cert-manager is a Kubernetes add-on to automate the management and issuance of TLS certificates from various issuing sources, amongst which Let’s Encrypt.

Start with installing cert-managers CRDs:

$ kubectl apply -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml 

Add the cert-manager Helm repo:

$ helm repo add jetstack https://charts.jetstack.io && helm repo update 

Install cert-manager:

$ helm install \ --name cert-manager \ --namespace cert-manager \ --version v0.8.1 \ jetstack/cert-manager 

This might take a minute or so. Verify the installation by checking all cert-manager pods are running:

$ kubectl get all -n cert-manager 

3. Configure cert-manager

With cert-manager installed we need to configure it to use Let’s Encrypt, by creating a certificate issuer:

$ cat <<EOF > letsencrypt-prod-issuer.yaml apiVersion: certmanager.k8s.io/v1alpha1 kind: Issuer metadata: name: letsencrypt-prod spec: acme: # The ACME server URL server: https://acme-v02.api.letsencrypt.org/directory # Email address used for ACME registration, update to your own. email: user@example.com # Name of a secret used to store the ACME account private key privateKeySecretRef: name: letsencrypt-prod # Enable the HTTP-01 challenge provider http01: {} EOF 

And apply it:

$ kubectl apply -f letsencrypt-prod-issuer.yaml 

By now, cert-manager is ready to provision Let’s Encrypt certificates as we need it.

4. Deploy a service with automatic HTTPS

To try this out let's deploy a simple service. You should have a DNS name pointed to your k3s cluster for this to work. The example below uses bootcamp.k3s.example.org, be sure to update this to your own hostname!

Create the manifest:

$ cat <<EOF > k8s-bootcamp.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: k8s-bootcamp namespace: default spec: replicas: 1 selector: matchLabels: app: k8s-bootcamp template: metadata: labels: app: k8s-bootcamp spec: containers: - name: k8s-bootcamp image: gcr.io/google-samples/kubernetes-bootcamp:v1 --- apiVersion: v1 kind: Service metadata: name: k8s-bootcamp namespace: default spec: ports: - name: http targetPort: 8080 port: 80 selector: app: k8s-bootcamp --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: k8s-bootcamp annotations: kubernetes.io/ingress.class: "traefik" certmanager.k8s.io/issuer: "letsencrypt-prod" certmanager.k8s.io/acme-challenge-type: http01 spec: tls: - hosts: # Change this to your own hostname - bootcamp.k3s.example.org secretName: bootcamp-k3s-example-org-tls rules: # Change this to your own hostname - host: bootcamp.k3s.example.org http: paths: - path: / backend: serviceName: k8s-bootcamp servicePort: http EOF 

And apply it:

$ kubectl apply -f k8s-bootcamp.yaml 

Wait a minute or so and your endpoint should become available with a Let’s Encrypt certificate! 🎉

Top comments (0)