k3s HTTPS with Let’s Encrypt
Pascal Widdershoven
Posted on July 5, 2019
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-manager
s 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! 🎉
Posted on July 5, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.