Eine App mit Ingress und TLS veröffentlichen
Nach Ein Image mit kubectl deployen war die Demo-App nur innerhalb des Clusters erreichbar. Diese Anleitung stellt sie unter deiner eigenen Domain ins Internet, mit gültigem HTTPS-Zertifikat: ein Ingress-Controller davor, cert-manager, der Zertifikate von Let’s Encrypt holt, und ein Ingress-Objekt pro App.
Ein PaaSbox-Cluster hat den Ingress-Controller schon und bietet cert-manager als Add-on an: Folge Auf einem PaaSbox-Cluster. Auf jedem anderen Cluster folgst du Auf jedem anderen Cluster.
Was du brauchst
Abschnitt betitelt „Was du brauchst“- Die laufende Demo-App aus Ein Image mit kubectl deployen
(Namespace
demo, Servicewebauf Port 80) oder einen beliebigen Service, den du veröffentlichen willst. - Eine Domain, die dir gehört, samt Zugriff auf ihre DNS-Einträge. Diese Anleitung verwendet
demo.example.com; setz überall deine eigene ein.
Auf einem PaaSbox-Cluster
Abschnitt betitelt „Auf einem PaaSbox-Cluster“Traefik, der Ingress-Controller, den k3s mitbringt, läuft auf jedem PaaSbox-Cluster und antwortet
auf den Ports 80 und 443 des Servers; die Firewall des Clusters lässt beide von überall herein. Seine
IngressClass ist traefik. Installiere keinen zweiten Ingress-Controller wie ingress-nginx:
Traefik hält beide Ports, und der Cluster legt keine Hetzner Load Balancer an, ein zweiter Controller
bekommt also weder das eine noch das andere.
Läuft auf dem Cluster das Add-on PaaSbox Platform (im Labor gebaut, noch nicht veröffentlicht), bringt es sein eigenes cert-manager
mit, und das cert-manager-Add-on kann nicht daneben an sein. Dort fordert die SaaSApplication einer
App ihr Zertifikat selbst an: siehe Schritt 2 des Lernpfads,
Deine erste App deployen.
1. Das cert-manager-Add-on anschalten
Abschnitt betitelt „1. Das cert-manager-Add-on anschalten“Setz auf dem Reiter Add-ons des Clusters, im Abschnitt cert-manager, den Haken bei On und füll aus:
- ACME e-mail: Let’s Encrypt legt das Konto unter dieser Adresse an und schickt Ablaufwarnungen dorthin.
- Default issuer: Lass
productionstehen.stagingstellt Zertifikate aus, denen Browser nicht vertrauen, ohne die Ratenlimits von production; damit probierst du ein Setup aus. - Challenge: Lass
http01stehen. Let’s Encrypt holt ein Token von deiner Domain über Port 80, durch Traefik, und sonst ist nichts nötig.
Wähle Save. Das Add-on installiert cert-manager und zwei ClusterIssuer, letsencrypt-staging
und letsencrypt-production. In einem Labor am 2026-10-10 waren sie 21 Sekunden später bereit:
kubectl get clusterissuers2. DNS auf den Server richten
Abschnitt betitelt „2. DNS auf den Server richten“Leg bei deinem DNS-Anbieter einen A-Eintrag für deinen Hostnamen an, der auf die öffentliche IPv4-Adresse des Servers zeigt. Es ist die Adresse, auf die der API-Name des Clusters auflöst, und die Hetzner-Konsole zeigt sie beim Server:
demo.example.com. 300 IN A <the server's IPv4 address>Prüfe, dass er auflöst, bevor du weitermachst; vorher kann das Zertifikat nicht ausgestellt werden:
dig +short demo.example.comDer API-Name des Clusters ist für kubectl da, nicht für deine App: Gib der App einen eigenen Namen.
3. Den Ingress anlegen
Abschnitt betitelt „3. Den Ingress anlegen“Speichere das Folgende als ingress.yaml. Die Annotation nennt den Issuer, ingressClassName
nennt Traefik:
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: web namespace: demo annotations: cert-manager.io/cluster-issuer: letsencrypt-productionspec: ingressClassName: traefik 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 }Statt einen Issuer zu nennen, nimmt die Annotation kubernetes.io/tls-acme: "true" den
Default issuer des Add-ons.
kubectl apply -f ingress.yamlkubectl -n demo get certificate -wREADY wird True, sobald Let’s Encrypt das Token geprüft hat. Im Labor wurde ein
Staging-Zertifikat in 31 Sekunden über Traefik ausgestellt.
4. Prüfen
Abschnitt betitelt „4. Prüfen“curl https://demo.example.comcurl -vI https://demo.example.com 2>&1 | grep -E 'subject|issuer'Jede weitere App ist ein weiterer Ingress: derselbe Traefik, derselbe Issuer, ein Manifest pro Hostname.
Zum Aufräumen löschst du den Ingress und den DNS-Eintrag. Schaltest du das Add-on aus, verschwinden cert-manager und die ClusterIssuer; die Zertifikate und ihre Secrets bleiben.
Auf jedem anderen Cluster
Abschnitt betitelt „Auf jedem anderen Cluster“Diese Schritte installieren einen Ingress-Controller und cert-manager mit Helm. Schritt 1 setzt einen
Cluster bei Hetzner voraus, dessen Cloud Controller für Services vom Typ LoadBalancer Load Balancer
anlegt. Neben kubectl brauchst du helm.
1. ingress-nginx installieren
Abschnitt betitelt „1. ingress-nginx installieren“Der Ingress-Controller nimmt allen HTTP(S)-Traffic in den Cluster entgegen und leitet ihn an deine
Services weiter. Sein Service hat den Typ LoadBalancer, darum legt der Cloud Controller bei der
Installation einen Hetzner Load Balancer in deinem Projekt an:
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"=nbg1Setz die Location-Annotation auf den Standort deines Clusters (hier nbg1). Warte auf die
öffentliche IP des Load Balancers:
kubectl -n ingress-nginx get svc ingress-nginx-controller -wNach etwa einer Minute füllt sich die Spalte EXTERNAL-IP. Dein DNS-Eintrag zeigt darauf.
Der Load Balancer steht auf deiner Hetzner-Rechnung. Er liegt in deinem Hetzner-Projekt, und Hetzner rechnet ihn direkt mit dir ab. Ein Load Balancer bedient alle Apps hinter dem Ingress-Controller. Deinstallierst du den Controller (siehe Aufräumen), wird er gelö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“helm upgrade --install cert-manager cert-manager \ --repo https://charts.jetstack.io \ --namespace cert-manager --create-namespace \ --set crds.enabled=trueDann bekommt er ein Konto bei Let’s Encrypt. Speichere das Folgende als cluster-issuer.yaml und
ersetze die E-Mail-Adresse durch deine eigene:
apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata: name: letsencrypt-prodspec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: you@example.com privateKeySecretRef: name: letsencrypt-prod-account-key solvers: - http01: ingress: ingressClassName: nginxkubectl apply -f cluster-issuer.yamlDas nutzt die HTTP-01-Challenge: Let’s Encrypt holt ein Token per einfachem HTTP über deinen Ingress. DNS-Zugangsdaten brauchst du nicht, aber die Domain muss zuerst auf den Load Balancer auflösen.
3. DNS auf den Load Balancer richten
Abschnitt betitelt „3. DNS auf den Load Balancer richten“Leg einen A-Eintrag für deinen Hostnamen an, der auf die EXTERNAL-IP aus Schritt 1 zeigt, und
prüfe ihn mit dig +short demo.example.com.
4. Den Ingress anlegen
Abschnitt betitelt „4. Den Ingress anlegen“Nimm das Manifest aus Schritt 3 des PaaSbox-Abschnitts mit zwei
Änderungen: die Annotation cert-manager.io/cluster-issuer: letsencrypt-prod und
ingressClassName: nginx. Wende es an und sieh dem Zertifikat zu:
kubectl apply -f ingress.yamlkubectl -n demo get certificate -wREADY wird True, meist innerhalb von ein bis zwei Minuten. Prüfe mit
curl https://demo.example.com.
Aufräumen
Abschnitt betitelt „Aufräumen“kubectl delete -f ingress.yamlhelm -n cert-manager uninstall cert-managerhelm -n ingress-nginx uninstall ingress-nginx # deletes the Hetzner load balancerkubectl delete namespace ingress-nginx cert-managerEntferne auch den DNS-Eintrag.
Wenn das Zertifikat hängen bleibt
Abschnitt betitelt „Wenn das Zertifikat hängen bleibt“Fast immer liegt es an 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 Adresse.
kubectl -n demo describe certificaterequest und die Logs von cert-manager sagen, welche Prüfung
fehlgeschlagen ist. Korrigiere den Eintrag, und die Ausstellung läuft von selbst weiter.
Nächste Schritte
Abschnitt betitelt „Nächste Schritte“- Postgres mit CloudNativePG betreiben: Gib der App eine Datenbank.
- Eine Django-SaaS deployen: eine ganze Anwendung hinter diesem Setup.