The Hotel Hero

Notes by a Sysadmin


Cluster | Philosophy | Stack

K3s Helm Traefik + LetsEncrypt

March 31, 2022 | Cluster

By default Traefik is deployed in K3s. So, in production we would like automating valid wildcard certificate creation. In this case there are two main approaches to generate and store certificates; cert-manager and traefik acme. On it's own Traefik acme can be used to create and store the certificate, but to get HA this way is only supported on the Enterprice version of Traefik. I'll try to use Cert-manager to handle the certificates, which I also consider a better solution for control and isolation of the Certificates and the added bonus of HA.

The Cert-manager way

You should allready have Cert-manager up and running, before continuing. When that's done Cert-manager have a Issuer/ClusterIssuer which will represent the CA. The deployment looks like this:

# Staging
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
  namespace: cert-manager
spec:
  acme:
    email: ...
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-staging-key
    solvers:
       # An empty 'selector' means that this solver matches all domains
       - selector: { }
         http01:
             ingress: { }

---
# And Production would look something like this
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
  namespace: cert-manager
spec:
  acme:
    email: ...
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-prod-key
    solvers:
       # An empty 'selector' means that this solver matches all domains
       - selector: { }
         http01:
             ingress: { }
# DNS challange something like this
#    - dns01:
#       digitalocean:
#         tokenSecretRef:
#            name: digitalocean-dns
#            key: access-token

Deploy the above ClusterIssuer

To create a certificate, for a domain/subdomain apply the following:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: yourdomain-cert
  namespace: your-namespace
spec:
  commonName: '*.yourdomain.com'
  secretName: yourdomain-cert
  dnsNames:
    - yourdomain.com
    - '*.yourdomain.com'
    # or [sub]. instead of wildcard (*)
  issuerRef:
    name: letsencrypt-staging
    kind: ClusterIssuer

Apply the two and se if a staging cert has been generated.

kubectl describe certificate my-app-com

and for troubleshooting:

kubectl describe certificaterequest selfsigned-cert-2gd9x

Traefik IngressRoute

Last apply the IngressRoute:

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: my-ingress
spec:
  entryPoints:
    - web
    - websecure
  routes:
    - match: Host(`yourdomain.com`)
      kind: Rule
      services:
        - name: my-app-svc
          port: 3000
  tls:
    # Reference the Secret
    secretName: yourdomain-cert


About

I'm a Sysadmin, network manager and cyber security entusiast. The main purpose of this public "notebook" is for referencing repetitive tasks, but it might as well come in handy to others. Windows can not be supported! But all other OS compliant with the POSIX-standard can (with minor adjustments) apply the configs on the site. It is Mac OSX, RHEL and all the Fedora based distros and Debian based (several 100's of OS's), all the BSD distros, Solaris, AIX and HP-UX.

Links