This task was astonishingly hard to configure. In my K3S cluster I have a Traefik reverse proxy deployed. What I wanted to achieve was:

  1. Make my apps accessible from the internet
  2. Automate TLS certificate provision
  3. Protect apps with basic auth

Step 1 involved opening http and https ports to my clusters master node IP address.

Traefik was quite easily deployed through its Helm-Chart. This is my values.yaml. As Ionos is my domain hoster, I’m using their DNS challenge provider to generate Let’s Encrypt-Certificates:

additionalArguments:
  - --entrypoints.websecure.http.tls.certresolver=ionos
  - --entrypoints.websecure.http.tls.domains[0].main=mydomain.de
  - --entrypoints.websecure.http.tls.domains[0].sans=*.mydomain.de
  - --certificatesresolvers.ionos.acme.dnschallenge.provider=ionos
  - --certificatesresolvers.ionos.acme.email=mailaddress@email.com
  - --certificatesresolvers.ionos.acme.dnschallenge.resolvers=1.1.1.1
  - --certificatesresolvers.ionos.acme.storage=/data/acme.json

deployment:
  initContainers: #This is necessary or else Traefik is unable to create the acme.json file
    - name: volume-permissions
      image: traefik:v2.10.4
      command:
        [
          "sh",
          "-c",
          "touch /data/acme.json; chown 65532 /data/acme.json; chmod -v 600 /data/acme.json",
        ]
      securityContext:
        runAsNonRoot: false
        runAsGroup: 0
        runAsUser: 0
      volumeMounts:
        - name: data
          mountPath: /data

env:
  - name: IONOS_API_KEY #Store the API key it to a secret. The format is public.private
    valueFrom:
      secretKeyRef:
        key: IONOS_API_KEY
        name: ionos-api-credentials

ingressRoute:
  dashboard:
    enabled: true

persistence:
  enabled: true
  path: /data
  size: 128Mi

Now I needed to create a Traefik Middleware to request basic auth:

apiVersion: v1
kind: Secret
metadata:
  name: basicauthcredentials
  namespace: default
data:
  users: |
    dXNlcjokYXByMSQ1Y1FtYldnWiRWcXBjVTZRSTBRdnZrVlJJbGFlN0UvCgo= # created with `htpasswd -nb user password | openssl base64`
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: basicauthmiddleware
spec:
  basicAuth:
    secret: basicauthcredentials

After this, I am able to deploy an Ingress which will expose a service, provide it with a (wildcard) TLS certificate and use the basic auth middleware…voilà:

kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
  name: myapplicationingress
  namespace: default
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    traefik.ingress.kubernetes.io/router.middlewares: default-basicauthmiddleware@kubernetescrd
    traefik.ingress.kubernetes.io/router.tls: 'true'
spec:
  ingressClassName: traefik
  rules:
    - host: myapplication.mydomain.de
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: myapplication-svc
                port:
                  number: 8080