Zum Inhalt springen

Deine App mit Ingress und TLS veröffentlichen

Nach Deine erste App deployen war die Demo-App nur innerhalb des Clusters erreichbar. Dieser Guide bringt sie ins öffentliche Internet – mit echter Domain und gültigem HTTPS-Zertifikat: ein Ingress-Controller davor, cert-manager, der Zertifikate von Let’s Encrypt holt, und ein Ingress-Objekt pro App. Das Muster funktioniert auf jedem konformen Kubernetes-Cluster; als Beispiel dient ein PaaSbox-Cluster.

  • Die laufende Demo-App aus Deine erste App deployen (Namespace demo, Service web auf Port 80) – oder ein beliebiger Service, den du veröffentlichen willst.
  • helm lokal installiert, zusätzlich zu kubectl.
  • Eine Domain, die dir gehört, samt Zugriff auf ihre DNS-Einträge. Wir verwenden demo.example.com – ersetze sie überall durch deine eigene.

Der Ingress-Controller ist die zentrale Eingangstür für allen HTTP(S)-Traffic in den Cluster. Sein Service hat den Typ LoadBalancer, deshalb provisioniert der cloud-controller-manager bei der Installation automatisch einen Hetzner Load Balancer in deinem Projekt:

Terminal-Fenster
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace \
--set controller.service.annotations."load-balancer\.hetzner\.cloud/location"=nbg1

Setze die Location-Annotation auf die Region deines Clusters (hier nbg1). Warte, bis der Load Balancer eine öffentliche IP bekommt:

Terminal-Fenster
kubectl -n ingress-nginx get svc ingress-nginx-controller -w

Nach etwa einer Minute füllt sich die Spalte EXTERNAL-IP. Notiere dir die IP – dein DNS-Eintrag zeigt darauf.

Dieser Load Balancer erscheint auf deiner Hetzner-Rechnung. Wie deine Worker-Nodes lebt er in deinem eigenen Hetzner-Projekt, und Hetzner rechnet ihn direkt mit dir ab – er gehört zur Aufteilung in zwei Rechnungen, nicht zur PaaSbox-Gebühr. Ein Load Balancer bedient alle Apps hinter dem Ingress-Controller, du zahlst also nicht pro App. Löschst du den Service (siehe Aufräumen), wird der Load Balancer mitgelöscht und die Kosten enden.

2. cert-manager und einen Let’s-Encrypt-Issuer installieren

Abschnitt betitelt „2. cert-manager und einen Let’s-Encrypt-Issuer installieren“

cert-manager beobachtet deine Ingress-Objekte und sorgt für durchgehend gültige Zertifikate – Ausstellung und Verlängerung laufen automatisch:

Terminal-Fenster
helm upgrade --install cert-manager cert-manager \
--repo https://charts.jetstack.io \
--namespace cert-manager --create-namespace \
--set crds.enabled=true

Dann bekommt er ein Konto bei Let’s Encrypt. Speichere das Folgende als cluster-issuer.yamlersetze die E-Mail-Adresse durch deine eigene (Let’s Encrypt schickt Ablauf-Hinweise dorthin, auch wenn cert-manager lange vor Ablauf erneuert):

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: you@example.com
privateKeySecretRef:
name: letsencrypt-prod-account-key
solvers:
- http01:
ingress:
ingressClassName: nginx
Terminal-Fenster
kubectl apply -f cluster-issuer.yaml

Das nutzt die HTTP-01-Challenge: Let’s Encrypt prüft, dass die Domain dir gehört, indem es ein Token per einfachem HTTP über deinen neuen Ingress abruft. Zugangsdaten für deinen DNS-Provider brauchst du nicht – aber die Domain muss zuerst auf deinen Load Balancer auflösen, und das ist Schritt 3.

Lege bei deinem DNS-Provider einen A-Eintrag für deinen Hostnamen an, der auf die Load-Balancer-IP aus Schritt 1 zeigt:

demo.example.com. 300 IN A <EXTERNAL-IP>

Prüfe, dass er auflöst, bevor du weitermachst – vorher kann das Zertifikat nicht ausgestellt werden:

Terminal-Fenster
dig +short demo.example.com

Der Ingress führt alles zusammen: Er routet demo.example.com zum Service web und überlässt cert-manager das Zertifikat. Speichere als ingress.yaml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
namespace: demo
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts: [demo.example.com]
secretName: web-tls
rules:
- host: demo.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port: { number: 80 }
Terminal-Fenster
kubectl apply -f ingress.yaml

cert-manager erkennt die Annotation, führt die HTTP-01-Challenge durch und legt das ausgestellte Zertifikat im Secret web-tls ab. Sieh live zu:

Terminal-Fenster
kubectl -n demo get certificate -w

READY springt auf True – typischerweise innerhalb von ein bis zwei Minuten.

Zertifikat hängt in Pending? Fast immer DNS: Der Eintrag löst öffentlich noch nicht auf (frische Einträge und Negative Caching können ein paar Minuten dauern) oder er zeigt auf die falsche IP. kubectl -n demo describe certificaterequest und die cert-manager-Logs sagen dir genau, welche Prüfung fehlgeschlagen ist. Korrigiere den Eintrag, und die Ausstellung läuft von selbst weiter.

Terminal-Fenster
curl https://demo.example.com

Eine Antwort der App, über HTTPS, mit gültigem Zertifikat – prüf das Schloss-Symbol im Browser oder:

Terminal-Fenster
curl -vI https://demo.example.com 2>&1 | grep -E 'subject|issuer'

Ab hier ist jede weitere App nur ein zusätzliches Ingress-Objekt: gleicher Controller, gleicher Load Balancer, gleicher Issuer – ein Manifest pro Hostname.

War das nur ein Experiment, lösche in umgekehrter Reihenfolge:

Terminal-Fenster
kubectl delete -f ingress.yaml # releases the certificate secret
helm -n cert-manager uninstall cert-manager
helm -n ingress-nginx uninstall ingress-nginx # deletes the Hetzner load balancer
kubectl delete namespace ingress-nginx cert-manager

Das Deinstallieren von ingress-nginx entfernt den LoadBalancer-Service, und der cloud-controller-manager löscht damit auch den Hetzner Load Balancer – dieser Posten verschwindet von deiner Hetzner-Rechnung. Denk daran, auch den DNS-Eintrag zu entfernen.