Mit Hilfe eines Ingress ist es relativ einfach, eine Webanwendung in Kubernetes öffentlich erreichbar zu machen. Für den Zugriff mittels HTTPS wird allerdings ein Zertifikat (inkl. privatem Schlüssel) benötigt, denn das im Ingress Controller angebotene selbstsignierte Standard-Zertifikat reicht vielleicht für erste Gehversuche, nicht aber für professionelle Einsätze. Man könnte nun manuell ein Zertifikat erstellen, es von einer Certificate Authority signieren lassen, und es dann in einem Secret bereitzustellen, das in der Ingress-Konfiguration referenziert wird.
Es gibt aber ein bessere Möglichkeit: Mit Hilfe von cert-manager können Zertifikate automatisch erstellt und in dem erwähnten Secret eingetragen werden. cert-manager kennt dazu sog. Issuer, die wie eine Art Adapter für die eigentliche Zertifikatsausgabestelle fungieren. Im folgenden nutzen wir den Issuer für Let’s Encrypt.
Zur Installation von cert-manager
im Kubernetes Cluster kann ein Helm Chart verwendet werden:
helm repo add jetstack https://charts.jetstack.io --force-update
helm upgrade -i -n cert-manager cert-manager jetstack/cert-manager --set installCRDs=true --wait --create-namespace
Der erwähnte Issuer für Let’s Encrypt wird dann durch das folgende Objekt beschrieben:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@gedoplan.de
privateKeySecretRef:
name: letsencrypt
solvers:
- http01:
ingress:
class: nginx
Hier wird ein ClusterIssuer
definiert, der Cluster-weit in allen Namespaces genutzt werden kann; ein einfacher Issuer
wäre Namespace-gebunden.
Let’s Encrypt prüft mit einer sog. Challenge, ob der Dienst, für den das Zertifikat angefordert wird, tatsächlich mit dem im Ingress angegebenen Hostnamen erreichbar ist. Im Beispiel wird die sog. Acme Challenge benutzt und vorausgesetzt, dass der Ingress Controller ein Nginx ist.
Ab jetzt läuft die Zertifikatserstellung automatisch, wenn ein Ingress im Kubernetes Cluster eingespielt wird:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: somename
annotations:
cert-manager.io/cluster-issuer: letsencrypt
spec:
rules:
- host: somename.gedoplan.de
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: somename
port:
name: someport
tls:
- hosts:
- somename.gedoplan.de
secretName: somename-gedoplan-de-tls
Mit der Annotation cert-manager.io/cluster-issuer
wird der oben definierte Issuer referenziert. Beim ersten Mal existiert das angegebene Secret noch nicht, was zur Anforderung eines neuen Zertifikats von Let’s Ecrypt führt. cert-manager
kümmert sich auch automatisch um die regelmäßige Erneuerung des Zertifikats (bei Let’s Encrypt alle 3 Monate).
Bei Let’s Encrypt ist zu beachten, dass nur eine limitierte Anzahl Zertifikate innerhalb einer bestimmen Zeitspanne ausgegeben werden. Es gibt daher auch einen Staging-Dienst von Let’s Encrypt, der diese Einschränkung nicht hat, aber auch keine offiziell signierten Zertifikate ausgibt. Er kann genutzt werden, solange man sich noch nicht sicher ist, ob alles wie gewünscht funktioniert.