Ingress
Das Ingress System von Kubernetes bietet die Möglichkeit externe HTTP oder HTTPS Requests in den Cluster zu leiten. Es besteht dabei aus der Ingress Ressource und einem sogenannten Ingress Controller, welcher die notwendige Logik implementiert. Wir haben uns dazu entschieden, den Nginx Ingress Controller als Standard Ingress Controller in nine Managed GKE zu verwenden. Die einzelnen Features dieses Controllers können mittels Annotations in der Ingress Ressource gesteuert werden.
Details
Der Nginx Ingress Controller erlaubt es externen HTTP/HTTPS Verkehr zu bestimmten Services welche im nine Managed GKE Cluster laufen, zu routen.
Verfügbarkeit
Der Nginx Ingress Controller ist standardmässig Teil von nine Managed GKE.
Nutzung
Die grundlegende Struktur und Nutzung der Ingress Ressource wird in der offiziellen Kubernetes Dokumentation erklärt. Um für die TLS Terminierung ein automatisch generiertes Lets Encrypt Zertifikat zu nutzen, folgen Sie bitte den Instruktionen für "Automatisierte SSL Zertifikate".
DNS Setup
Wildcard DNS domain
Wir stellen eine automatisch generierte Wildcard DNS Domain zur Verfügung. Sie kann für Tests oder in der Entwicklung genutzt werden. Sie können einfach einen beliebigen Hostnamen aus dieser Wildcard Domain nehmen und ihn in Ihrer Ingress Ressource als Hostname nutzen. DNS ist bereits fertig konfiguriert. Die notwendigen Angaben zur Domain finden Sie auf runway unter den Infos zu Nginx Ingress.
Ingress DNS
Um eigene DNS Hostnamen konfigurieren zu können, stellen wir einen DNS Eintrag zur Verfügung, welcher immer auf die öffentliche IP des Nginx Ingress Controllers zeigt. Erstellen Sie einfach in Ihrer eigenen Domain einen CNAME Eintrag welcher auf den von uns bereitgestellten DNS Eintrag zeigt. Die notwendigen Angaben können Sie auch hier auf runway unter den Infos zu Nginx Ingress finden.
IngressClass
Um unseren Ingress Controller zu nutzen kann das Feld ingressClassName
in
der Ingress
resource auf nginx
gesetzt werden. Alternativ kann das Feld
auch weggelassen werden, weil diese bereits als Standard gesetzt ist.
Access Logs
Um die Access Logs der Ingress Requests können Sie in Grafana in der Loki
Explore-Ansicht anschauen. The Ingress Logs sind unter dem Label
app_kubernetes_io_name="ingress-nginx"
verfügbar. Um die Logs einer
spezifischen Ingress-Insanz anzuzeigen, können Sie nach dem zusätzlichen Label
ingress
filtern. Das Label hat das Schema
<namespace>-<ingress-name>-<backend-port>
. Hier ein Beispiel Query um alle
Logs anzuzeigen vom Ingress frontend
mit dem Port 80
im Namespace
shop-prod
:
{app_kubernetes_io_name="ingress-nginx", ingress="shop-prod-frontend-80"}
Zusätzlich können die Ingress Logs nach diesen Labels gefiltert werden:
method
die HTTP-Methode des Requestsstatus
den HTTP-Status des Requests
Mehr Informationen zur Benutzung von Loki finden Sie im spezifischen Support Artikel.
Spezifische Features
Der Nginx Ingress Controller bringt einige Features wie bspw. rate limiting, IP white listing, custom default backends, temporäre und permanente Weiterleitungen, etc mit. Alle zur Steuerung dieser Features verfügbaren Annotations sind in der offiziellen Nginx Ingress Controller Dokumentation zu finden. Sie wenden diese Annotations direkt auf Ihr bereits erstelltes Ingress Objekt an.
Nachfolgend finden Sie Dokumentation zu den meist verwendeten Features.
Basic Authentifizierung
Sie können auf einfache Weise basic Authentifizierung zu ihren Ingress Ressourcen hinzufügen. Folgen Sie dazu einfach den folgenden Schritten:
-
Setzen Sie ein paar Umgebungsvariablen
USERNAME=<IHR GEWÜNSCHTER NUTZERNAME>
SECRET_NAMESPACE=<NAMESPACE IN WELCHEM DIE ZUGANGSDATEN ABGELEGT WERDEN SOLLEN>
INGRESS_NAMESPACE=<DER NAME DES NAMESPACES IN DEM SICH IHRE INGRESS RESOURCE BEFINDET>
INGRESS=<DER NAME IHRER INGRESS RESOURCE> -
Erstellen Sie ein Kubernetes Secret welche Ihre Zugangsdaten beinhaltet. Sie benötigen das Tool
mkpasswd
, welches man bspw. imwhois
Paket in Debian oder Ubuntu findet. Das Secret muss dabei nicht zwingend im selben Namespace wie die Ingress Ressource selbst angelegt werden.kubectl create secret generic basic-auth-secret --namespace=$SECRET_NAMESPACE --from-literal=auth=$USERNAME:$(mkpasswd -m sha-512)
-
Konfigurieren Sie die Ingress Ressource so, dass Ihr erstelltes Secret genutzt wird
kubectl --namespace=$INGRESS_NAMESPACE annotate ingress $INGRESS nginx.ingress.kubernetes.io/auth-type=basic
kubectl --namespace=$INGRESS_NAMESPACE annotate ingress $INGRESS nginx.ingress.kubernetes.io/auth-secret=$SECRET_NAMESPACE/basic-auth-secret
kubectl --namespace=$INGRESS_NAMESPACE annotate ingress $INGRESS nginx.ingress.kubernetes.io/auth-realm='Authentication required'
Rate limiting
Es stehen einige Möglichkeiten zur Verfügung, gewisse rate limits auf ihre Ingress Ressource anzuwenden. Alle verfügbaren Optionen finden Sie in der offiziellen Dokumentation.
Temporäre und permanente Weiterleitungen
Um eine temporäre Weiterleitung in Ihrer Ingress Ressource einzurichten nutzen Sie einfach die folgende Annotation:
nginx.ingress.kubernetes.io/temporal-redirect: <IHRE URL>
Temporäre Weiterleitungen nutzen den HTTP Status Code 302.
Möchten Sie dauerhaft auf eine andere URL weiterleiten so nutzen Sie:
nginx.ingress.kubernetes.io/permanent-redirect: <IHRE URL>
HTTPS Weiterleitung
Sobald Ihre Ingress Ressource für TLS konfiguriert ist, findet eine automatische Weiterleitung auf die HTTPS URL des Ingress Objektes statt. Möchten Sie dies verhindern, so nutzen Sie die folgende Annotation:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
IP whitelisting
Um nur bestimmte IP Bereiche zu erlauben, welche auf Ihre Ingress Ressource zugreifen dürfen, können Sie mit Komma getrennte CIDR Blöcke in der folgenden Annotation verwenden:
nginx.ingress.kubernetes.io/whitelist-source-range: <IHRE CIDR BLÖCKE>
Caching
Der Nginx Ingress Controller unterstützt eine einfache Form von Content Caching, welche nützlich sein kann, um zum Beispiel statischen Inhalt schneller auszuliefern.
Sie können das Caching pro Ingress Ressource aktivieren, indem Sie folgende Annotations in Ihrer Ingress Definition setzen (unter metadata.annotations
):
nginx.ingress.kubernetes.io/proxy-buffering: "on"
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_cache static-cache;
proxy_cache_valid 10m;
proxy_cache_use_stale error timeout updating http_404 http_500 http_502 http_503 http_504;
proxy_cache_bypass $http_x_purge;
add_header X-Cache-Status $upstream_cache_status;
In diesem Beispiel werden die Antworten mit den Status Codes 200, 301 und 302 für 10 Minuten gecached. Falls ein anderes Verhalten gewünscht sein sollte, kann die proxy_cache_valid
Option auch mit Status Code vor der Zeit gesetzt werden:
proxy_cache_valid 404 1m;
Diese Option cached 404 Antworten für eine Minute. Ausserdem haben Sie die Möglichkeit, den Spezialcode "any" zu nutzen, welcher alle Antworten cached.
Weiterhin können mehrere proxy_cache_valid
Optionen kombiniert werden, um verschiedene Cache-Zeiten für verschiedene Status Codes zu haben.
Die Cache-Grösse ist 100MB per default. Sollten Sie andere Anforderungen haben, können Sie uns gerne kontaktieren.
Um zu überprüfen, ob das Caching funktioniert, kann cURL
verwendet werden. Führen Sie den folgenden Befehl zwei mal aus, um im zweiten Output den Cache-Status zu kontrollieren:
curl --head <URL>
Dies sollte den HTTP-Header x-cache-status: HIT
anzeigen.
Falls Sie Caching nur für einen ausgewählten Unterpfad nutzen wollen (zum Beispiel ein Endpunkt unter /static
), muss dazu eine separate Ingress Ressource erstellt werden.
Das Caching kann weiter konfiguriert werden über die proxy_cache
Optionen welche gültig sind innerhalb von location
Blöcken. Diese Optionen können hier gefunden werden.
Eigenes Standard Backend
Falls der Nginx Ingress Controller Anfragen erhält welche nicht durch Regeln in den Ingress Ressourcen abgedeckt sind, so beantwortet er diese mit einer HTTP 404 Fehler Seite welche vom Standard Backend bereitgestellt wird. Diese Seite kann den eigenen Bedürfnissen angepasst werden indem ein eigenes Standard Backend zur Verfügung gestellt wird. Anschliessend wird in der Ingress Ressource auf das eigene Standard Backend verwiesen.
Das Standard Backend muss lediglich 2 Bedingungen erfüllen:
- es muss eine 404 Fehler Seite (bzw. einen 404 HTTP Fehler Code) auf dem "/" Pfad ausliefern
- es muss auf dem Pfad "/healthz" mit dem HTTP Code 200 antworten
Die Implementation des Standard Backends welches mit dem Nginx Ingress Controller ausgeliefert wird kann man hier anschauen. Dies kann als Beispiel für eigene Implementationen genutzt werden.
Sobald man sein eigenes Standard Backend im selben Namespace wie die Ingress Ressource zur Verfügung gestellt hat, kann man mit folgender Annotation in der Ingress Ressource darauf verweisen:
nginx.ingress.kubernetes.io/default-backend: <SERVICE NAME DES STANDARD BACKENDS>
Zusätzliche benutzerdefinierte Fehler Seiten
Um zusätzlich noch weitere spezielle benutzerdefinierte Fehler Seiten auf dem Standard Backend anzeigen zu lassen (bspw. eine benutzerdefinierte Seite falls die Applikation auf welche der Ingress zeigt nicht verfügbar ist) kann die folgende zusätzliche Annotation verwendet werden:
nginx.ingress.kubernetes.io/custom-http-errors: <HTTP FEHLER CODES> # bspw. "404,415,503"
Der Nginx Ingress Controller wird Fehler Informationen via HTTP Header zum Standard Backend weiterleiten. Die dort laufenden Applikation kann anhand dieser Header spezielle Webseiten ausliefern, welche den aufgetretenen Fehler am Besten darstellen. Mehr Informationen zu diesem Feature kann in der offiziellen Dokumentation gefunden werden. Eine Beispielapplikation, welche die HTTP Header Informationen auswertet und benutzerdefinierte Fehler Seiten anzeigt, kann man hier finden. Diese kann auch als Inspiration für eigene Implementationen dienen.
SLI Probe
Um die Funktionalität des Ingress Controllers sicherzustellen, nutzen wir einen Service, welcher unter sli-probe.apps-customer.<domain>.ninegcp.ch
verfügbar ist.