This task was astonishingly hard to configure. In my K3S cluster I have a Traefik reverse proxy deployed. What I wanted to achieve was:
- Make my apps accessible from the internet
- Automate TLS certificate provision
- 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