Der Nginx Ingress Controller gehört zu den am häufigsten genutzten Ingress-Lösungen für Kubernetes. Er verwendet Nginx als Reverse Proxy und Load Balancer, um externe Anfragen sicher an die internen Dienste im Cluster weiterzuleiten. Als zentraler Zugriffspunkt bietet er Funktionen wie SSL/TLS-Beendigung, Lastverteilung, Sitzungsverwaltung und pfadbasierte Weiterleitung für Anwendungen innerhalb von Kubernetes.
In dieser Anleitung richtest du den Nginx Ingress Controller mit SSL-Zertifikaten in einem Kubernetes Engine Cluster ein. Du wirst zwei Beispielanwendungen bereitstellen und sie mit Let’s Encrypt-Zertifikaten absichern, die durch Cert Manager verwaltet werden. Außerdem wird gezeigt, wie du kommerzielle SSL-Zertifikate für TLS-Verschlüsselung integrieren kannst.
Voraussetzungen
Bevor du beginnst, stelle sicher, dass du Folgendes vorbereitet hast:
- Einen laufenden Kubernetes-Cluster mit mindestens zwei Nodes.
- Das Tool Kubectl ist installiert, um deinen Cluster zu verwalten.
- Der Paketmanager Helm ist auf deinem System eingerichtet.
- Eine gültige Domain, beispielsweise example.com.
Passende Infrastruktur bei centron
Vom Container zum Cluster: Managed Kubernetes mit cStack gibt es ab 29,99 € im Monat – Control Plane, AutoScaler und Traffic inklusive. Managed Kubernetes ansehen →
Nginx Ingress Controller installieren
Füge zunächst das Nginx Ingress Helm-Repository hinzu.
$ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginxAktualisiere anschließend die Helm-Repositories, um die neuesten Charts zu laden.
$ helm repo updateInstalliere nun den Nginx Ingress Controller in deinem Kubernetes-Cluster.
$ helm install ingress-nginx ingress-nginx/ingress-nginxNach der Installation wird dem Cluster automatisch ein LoadBalancer-Service hinzugefügt.
$ kubectl get services ingress-nginx-controllerBeispielausgabe:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.101.22.249 <pending> 80:31915/TCP,443:30217/TCP 106s
Je nach Cloud-Anbieter kann es einige Minuten dauern, bis der Dienst eine EXTERNAL-IP erhält.
Cert Manager installieren
Installiere die neueste Version des Cert Managers mit folgendem Befehl:
$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.2/cert-manager.yamlÜberprüfe regelmäßig die offizielle Cert Manager-Release-Seite, um sicherzustellen, dass du die aktuellste Version nutzt.
Kontrolliere anschließend die Cert Manager-Ressourcen im Namespace cert-manager:
$ kubectl get all -n cert-managerDu solltest nun mehrere Pods, Services, ReplicaSets und Deployments sehen, die mit dem Cert Manager zusammenhängen.
Backend-Anwendungen bereitstellen
Als Nächstes werden zwei Beispielanwendungen — app1 und app2 — bereitgestellt, um die Ingress-Konfiguration zu testen. Beide verwenden das Image hashicorp/http-echo, das einen einfachen Text auf einer HTML-Seite ausgibt.
Deployment für App1 erstellen
$ nano app1-deploy.yamlFüge die folgende Konfiguration ein:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app1
spec:
replicas: 1
selector:
matchLabels:
app: app1
template:
metadata:
labels:
app: app1
spec:
containers:
- name: app1
image: hashicorp/http-echo
args: ["-text=Hello from App1"]
ports:
- containerPort: 5678Deployment für App2 erstellen
$ nano app2-deploy.yamlFüge diesen Inhalt hinzu:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app2
spec:
replicas: 1
selector:
matchLabels:
app: app2
template:
metadata:
labels:
app: app2
spec:
containers:
- name: app2
image: hashicorp/http-echo
args: ["-text=Hello from App2"]
ports:
- containerPort: 5678Wende beide Deployment-Manifeste an:
$ kubectl apply -f app1-deploy.yaml
$ kubectl apply -f app2-deploy.yamlÜberprüfe, ob die Deployments erfolgreich ausgeführt werden:
$ kubectl get deploymentsService-Manifeste erstellen
Service für App1
$ nano app1-svc.yamlFüge die folgende YAML-Konfiguration hinzu:
apiVersion: v1
kind: Service
metadata:
name: app1-svc
spec:
ports:
- name: http
port: 80
targetPort: 8080
selector:
app: app1Service für App2
$ nano app2-svc.yamlFüge diese Konfiguration hinzu:
apiVersion: v1
kind: Service
metadata:
name: app2-svc
spec:
ports:
- name: http
port: 80
targetPort: 8080
selector:
app: app2Stelle anschließend beide Services bereit:
$ kubectl apply -f app1-svc.yaml
$ kubectl apply -f app2-svc.yamlÜberprüfe, ob alle Services korrekt ausgeführt werden:
$ kubectl get servicesDNS-Einträge konfigurieren
Melde dich bei deinem DNS-Provider an und öffne die Domainverwaltung. Erstelle einen A-Record für app1, der auf die externe IP-Adresse deines LoadBalancers verweist. Wiederhole den Vorgang für app2 mit derselben IP-Adresse.
Anwendungen über den Nginx Ingress Controller bereitstellen
Erstelle nun Ingress-Ressourcen, um deine Backend-Anwendungen öffentlich zugänglich zu machen.
Ingress für App1
$ nano app1-ingress.yamlFüge diesen Inhalt ein:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-app1
annotations:
cert-manager.io/issuer: letsencrypt-nginx
spec:
ingressClassName: nginx
rules:
- host: app1.example.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: app1-svc
port:
number: 80Ingress für App2
$ nano app2-ingress.yamlVerwende den folgenden YAML-Inhalt:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-app2
annotations:
cert-manager.io/issuer: letsencrypt-nginx
spec:
ingressClassName: nginx
rules:
- host: app2.example.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: app2-svc
port:
number: 80Wende beide Ingress-Manifeste an:
$ kubectl apply -f app1-ingress.yaml
$ kubectl apply -f app2-ingress.yamlÜberprüfe, ob die Ingress-Ressourcen verfügbar sind:
$ kubectl get ingressEs sollten sowohl ingress-app1 als auch ingress-app2 angezeigt werden. Warte, bis in der Spalte ADDRESS die IP deines LoadBalancers erscheint.
SSL-Zertifikate für Nginx Ingress aktivieren
Um HTTPS zu aktivieren, kannst du den Cert Manager so konfigurieren, dass er SSL-Zertifikate automatisch verwaltet. Cert Manager erweitert Kubernetes um benutzerdefinierte Ressourcen für die Ausstellung und Verwaltung von Zertifikaten durch vertrauenswürdige Zertifizierungsstellen wie Let’s Encrypt.
- Issuer: Definiert die Konfiguration eines Zertifikatsausstellers, etwa den Typ (ACME) und die Validierungsmethode (DNS01 oder HTTP01) innerhalb eines Namespaces.
- ClusterIssuer: Funktioniert wie der Issuer, kann jedoch Zertifikate für den gesamten Cluster ausstellen – ideal bei mehreren Namespaces.
- Certificate: Enthält Informationen über die Domainnamen, das zugehörige Secret und den gewählten Issuer.
Liste die verfügbaren CRDs für den Cert Manager auf:
$ kubectl get crd -l app.kubernetes.io/name=cert-managerDie Ausgabe sollte Ressourcen wie issuers.cert-manager.io, certificates.cert-manager.io und clusterissuers.cert-manager.io enthalten, was bestätigt, dass die CRDs erfolgreich installiert wurden.
Let’s Encrypt-Zertifikate einrichten
Erstelle ein neues Issuer-Manifest namens cert-issuer.yaml, um Let’s Encrypt zu konfigurieren.
$ nano cert-issuer.yamlFüge diese YAML-Konfiguration ein:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-nginx
spec:
acme:
email: hello@example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-nginx-prod
solvers:
- http01:
ingress:
class: nginxDiese Konfiguration erstellt einen ACME-Issuer mit folgenden Parametern:
- email: Die Kontaktadresse des ACME-Kontos. Verwende keine
@example.com-Adresse, da der Issuer sonst inaktiv bleibt. - server: Die API-URL des Let’s Encrypt-ACME-Dienstes.
- privateKeySecretRef: Gibt das Secret an, in dem der private Schlüssel des ACME-Kontos gespeichert wird.
- solvers: Definiert die Validierungsmethode, meist
http01, außer bei Wildcard-Zertifikaten.
Ersetze die Beispiel-E-Mail-Adresse durch deine eigene und speichere die Datei.
Wende den Issuer im Cluster an:
$ kubectl apply -f cert-issuer.yamlÜberprüfe, ob der Issuer korrekt erstellt und initialisiert wurde:
$ kubectl get issuerBeispielausgabe:
NAME READY AGE
letsencrypt-nginx False 4s
Der Status READY zeigt zunächst False an und wechselt nach kurzer Zeit zu True.
Ingress-Ressourcen für TLS konfigurieren
Verknüpfe nun deine Ingress-Ressourcen mit den Let’s Encrypt-Zertifikaten.
Überprüfe zuerst den aktuellen Status deiner Ingress-Ressourcen:
$ kubectl get ingressBearbeite anschließend die Datei app1-ingress.yaml, um eine TLS-Sektion hinzuzufügen:
$ nano app1-ingress.yamlErgänze den folgenden Abschnitt unterhalb von spec:
tls:
- hosts:
- app1.example.com
secretName: letsencrypt-nginx-app1Das vollständige Manifest sieht wie folgt aus:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-app1
annotations:
cert-manager.io/issuer: letsencrypt-nginx
spec:
ingressClassName: nginx
rules:
- host: app1.example.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: app1-svc
port:
number: 80
tls:
- hosts:
- app1.example.com
secretName: letsencrypt-nginx-app1Füge denselben TLS-Abschnitt auch in die Datei app2-ingress.yaml ein:
tls:
- hosts:
- app2.example.com
secretName: letsencrypt-nginx-app2Wende anschließend die geänderten Manifeste an, um TLS für beide Hosts zu aktivieren:
$ kubectl apply -f app1-ingress.yaml
$ kubectl apply -f app2-ingress.yamlPrüfe, ob deine Ingress-Ressourcen jetzt auch Port 443 aktiviert haben:
$ kubectl get ingressBeispielausgabe:
NAME CLASS HOSTS ADDRESS PORTS AGE
app1-ingress nginx app1.example.com 192.0.2.1 80,443 10m
app2-ingress nginx app2.example.com 192.0.2.1 80,443 10m
Zertifikatsressourcen prüfen
Überprüfe, ob die SSL-Zertifikate erfolgreich erstellt wurden:
$ kubectl get certificatesBeispielausgabe:
NAME READY SECRET AGE
letsencrypt-app1 True letsencrypt-nginx-app1 5m
letsencrypt-app2 True letsencrypt-nginx-app2 5m
Wenn die Spalte READY True anzeigt, wurden die Zertifikate erfolgreich ausgestellt. Falls sie False bleibt, überprüfe deine Ingress-Konfiguration und führe die Manifeste erneut aus, um neue Zertifikate anzufordern.
SSL-Konfiguration testen
Sobald die Zertifikate aktiv sind, teste die HTTPS-Verbindung im Browser:
Wenn du die Hosts über HTTP aufrufst, leitet der Ingress Controller automatisch auf HTTPS um.
Kommerzielle SSL-Zertifikate importieren
Wenn du ein SSL-Zertifikat von einer kommerziellen Zertifizierungsstelle erworben hast, kannst du dieses manuell importieren. Wandle dafür sowohl das Zertifikat als auch den privaten Schlüssel in Base64 um.
$ base64 -w 0 /path/ssl-certificate.pem
$ base64 -w 0 /path/cert-private-key.pemErsetze /path durch den tatsächlichen Pfad deiner Zertifikatsdateien.
Erstelle anschließend ein Kubernetes-Secret-Manifest:
$ nano ssl-secret.yamlFüge folgende YAML-Konfiguration hinzu:
apiVersion: v1
kind: Secret
metadata:
name: prod-ssl-secret
type: kubernetes.io/tls
data:
tls.crt:
tls.key: Stelle sicher, dass:
- tls.crt das Base64-kodierte SSL-Zertifikat enthält.
- tls.key den Base64-kodierten privaten Schlüssel beinhaltet.
Speichere die Datei und wende sie an. Anschließend kannst du in deinem Ingress-Manifest unter spec.tls.secretName auf dieses Secret verweisen, um das kommerzielle SSL-Zertifikat zu aktivieren.
Fehlerbehebung
- Nginx 502 Gateway Error: Überprüfe deine Ingress-Konfiguration und stelle sicher, dass die referenzierten Services verfügbar und erreichbar sind.
- Let’s Encrypt-Zertifikate werden nicht generiert (READY = False): Kontrolliere deine Issuer- und Zertifikatseinstellungen, verwende eine gültige E-Mail-Adresse und prüfe die Logs des Issuers für weitere Hinweise.
Fazit
In dieser Anleitung hast du den Nginx Ingress Controller mit SSL-Zertifikaten auf einem Kubernetes Engine Cluster eingerichtet. Deine Umgebung kann nun eingehenden Datenverkehr sicher über HTTPS an die Cluster-Services weiterleiten – sowohl mit Let’s Encrypt- als auch mit kommerziellen SSL-Zertifikaten.
Testen Sie Ihr Setup auf ccloud³
Registrieren Sie sich in der ccloud³ und erhalten Sie 200 € Startguthaben für Ihr Projekt – z. B. für eine PostgreSQL-VM mit automatischen Backups.