Im IT-Kontext bedeutet **Ingress** allgemein: > „Eingehender Datenverkehr in ein System, Netzwerk oder einen Dienst.“ Je nach Kontext wird der Begriff etwas unterschiedlich verwendet: # Allgemein ### 1. Netzwerk / Security In klassischen Netzwerken und Firewalls unterscheidet man: - **Ingress-Traffic**: Datenverkehr, der **von außen nach innen** in ein Netzwerk oder System hineinkommt (z. B. HTTP-Anfragen aus dem Internet an Ihren Webserver). - **Egress-Traffic**: Datenverkehr, der **von innen nach außen** geht (z. B. Ihr Server ruft eine externe API im Internet auf). Typische Themen rund um Ingress in diesem Kontext: - **Ingress-Filterung**: Regeln, die festlegen, welcher eingehende Traffic erlaubt ist (z. B. Firewall-Regeln). - **Ingress-Schutz**: Maßnahmen gegen Angriffe von außen (DDoS-Schutz, WAF, Rate Limiting). ### 2. Kubernetes (Spezialfall „Ingress“ Resource) In Kubernetes ist **Ingress** ein eigener Begriff und bezeichnet eine **API-Ressource**, die regelt, wie externe Requests in den Cluster hinein zu den internen Services geleitet werden. Kurz gesagt: - Ein **Ingress** ist eine Art **Reverse Proxy / Routing-Regel** auf Layer 7 (HTTP/HTTPS). - Er definiert z. B.: - Welche Domain (`host`) auf welchen Service zeigt - Welche Pfade (`/api`, `/app`) zu welchen Services geroutet werden - SSL/TLS-Termination (HTTPS) Beispielhafte Ingress-Definition in Kubernetes: ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-app-ingress spec: rules: - host: myapp.example.com http: paths: - path: /api pathType: Prefix backend: service: name: my-api-service port: number: 80 ``` Hier sorgt der Ingress dafür, dass Anfragen an `https://myapp.example.com/api` in den Cluster gehen und beim Service `my-api-service` landen. --- Im Kubernetes-Kontext ist „Ingress“ etwas spezieller als nur „eingehender Traffic“. Es gibt drei eng zusammenhängende Dinge: 1. **Ingress-Ressource** (YAML-Objekt, das Routing-Regeln beschreibt) 2. **Ingress-Controller** (Software/Pod, der diese Regeln umsetzt) 3. **(Optional) IngressClass** (welcher Controller für welches Ingress zuständig ist) Ich gehe der Reihe nach durch. --- # Kubernetes ## 1. Warum braucht man Ingress überhaupt? Ohne Ingress hast du im Wesentlichen drei Möglichkeiten, Dienste nach außen verfügbar zu machen: - `ClusterIP` (Standard): nur intern im Cluster erreichbar - `NodePort`: öffnet einen Port auf jedem Node; eher low-level / unkomfortabel - `LoadBalancer`: Cloud-Loadbalancer vor einem Service (oft pro Service ein eigener LB) Nachteile: - Viele externe IPs / Loadbalancer, wenn du viele Services hast - Keine zentrale Layer‑7-Logik (z. B. Routing per Hostname/URL-Pfad, TLS-Termination) **Ingress** löst genau das: > Ein (oder wenige) externe Einstiegspunkte, die per Hostname und Pfad auf viele interne Services routen können, inkl. HTTPS/TLS, Auth, Rate-Limiting (je nach Controller). --- ## 2. Ingress-Ressource (das YAML-Objekt) Die Ingress-Ressource beschreibt **Deklarativ**, wie Anfragen von außen zu Services im Cluster geroutet werden sollen: - Auf Basis von **Hostname** (`host`, z. B. `api.example.com`) - Auf Basis von **Pfad** (`path`, z. B. `/api`, `/app`) - Verknüpft mit einem **Backend-Service** (`Service` + Port) - Optional: **TLS**-Konfiguration (Zertifikate) Beispiel: ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-app-ingress namespace: default annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: nginx tls: - hosts: - myapp.example.com secretName: myapp-tls-secret rules: - host: myapp.example.com http: paths: - path: /api pathType: Prefix backend: service: name: my-api-service port: number: 80 - path: /app pathType: Prefix backend: service: name: my-frontend-service port: number: 80 ``` Was hier passiert: - Alle Anfragen an `https://myapp.example.com/api...` → Service `my-api-service` - Alle Anfragen an `https://myapp.example.com/app...` → Service `my-frontend-service` - TLS-Zertifikat liegt in `Secret myapp-tls-secret` - `ingressClassName: nginx` sagt: „Dieser Ingress ist für den Ingress-Controller mit Klasse `nginx` gedacht“ Wichtige Felder: - `rules[].host`: auf welchen Host gilt die Regel? - `rules[].http.paths[].path`: URL-Pfad - `pathType`: - `Prefix` → „beginnt mit diesem Pfad“ - `Exact` → „genau dieser Pfad“ - (früher gab es noch `ImplementationSpecific`) - `backend.service.name` / `port`: zu welchem Service leiten? --- ## 3. Ingress-Controller (die „Engine“ dahinter) Die YAML-Ressource alleine macht noch nichts. Es braucht einen **Ingress-Controller**: - Läuft als Pod/Deployment im Cluster - Beobachtet (watch) Ingress-Ressourcen im API-Server - Übersetzt die Regeln in eine konkrete Konfiguration (z. B. [[NGINX]], Envoy, Traefik …) - Lauscht auf einem (oder mehreren) Node-Ports/LoadBalancer-IPs und routet Traffic in die passende Services Typische Implementierungen: - **[[NGINX]] Ingress Controller** - **Traefik** - **HAProxy Ingress** - **Envoy-basierte** Controller - Cloud-spezifische: - GCE/GLBC (GKE HTTP(S) Load Balancing) - AWS ALB Ingress Controller - Azure Application Gateway Ingress Wichtig: Du kannst mehrere Ingress-Controller im Cluster haben, z. B. einen für öffentliche, einen für interne Services. --- ## 4. IngressClass (Zuordnung Controller ↔ Ingress) Mit `IngressClass` kann man genau definieren, **welcher** Ingress-Controller für welche Ingress-Ressourcen zuständig ist. Beispiel IngressClass: ```yaml apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: name: nginx spec: controller: k8s.io/ingress-nginx ``` Im Ingress verknüpfst du das mit: ```yaml spec: ingressClassName: nginx # ... ``` Somit: - Nur der Ingress-Controller, der sich als `k8s.io/ingress-nginx` registriert, reagiert auf diesen Ingress. - Andere Controller ignorieren ihn. Früher wurde das oft über **Annotations** geregelt (`kubernetes.io/ingress.class`), `ingressClassName` ist der neuere, bevorzugte Weg. --- ## 5. Request-Flow: Wie läuft eine Anfrage technisch? Typischer Ablauf (z. B. mit [[NGINX]] Ingress Controller in einer Cloud): 1. Benutzer ruft im Browser `https://myapp.example.com/api/users` auf. 2. DNS zeigt `myapp.example.com` auf die externe IP eines Cloud-Loadbalancers. 3. Der Cloud-Loadbalancer leitet die Anfrage an einen Node/Port, auf dem der Ingress-Controller erreichbar ist. 4. Der Ingress-Controller (Pod) erhält die HTTP(S)-Anfrage. 5. Er vergleicht Host (`myapp.example.com`) und Pfad (`/api/users`) mit seinen Ingress-Regeln: - Host passt zu `myapp.example.com` - Pfad passt zum Prefix `/api` 6. Er leitet die Anfrage intern an den Kubernetes-Service `my-api-service:80` weiter. 7. Kubernetes-Service verteilt die Anfrage per kube-proxy/IPVS/iptables auf einen Pod (`my-api`-Pod). 8. Antwort geht den Weg zurück und landet beim Benutzer. --- ## 6. Typische Features (Controller-abhängig) Je nach Ingress-Controller gibt es zusätzliche Möglichkeiten, meist über **Annotations** oder spezifische CRDs: - **TLS-Termination** und optional TLS-Passthrough - **HTTP → HTTPS Redirect** - **Path-Rewrites**, z. B. `/api` außen → `/` im Backend - **Authentifizierung** (z. B. OAuth2, Basic Auth) - **Rate Limiting**, IP-Whitelist/Blacklist - **Canary-Deployments / Traffic-Splitting** - **gRPC-Support**, WebSockets, etc. Beispiel (nginx Spezifische Annotation für Redirect): ```yaml metadata: annotations: nginx.ingress.kubernetes.io/force-ssl-redirect: "true" ``` --- ## 7. Grenzen von Ingress & Gateway API Die klassische Ingress-API ist bewusst relativ simpel (Host, Pfad, Backend, TLS). Für komplexere Szenarien (multi-tenant, umfangreiche Routing-Logik, mehrere Gateways) gibt es inzwischen die **Gateway API** (Ressourcen wie `Gateway`, `HTTPRoute` etc.), die Ingress langfristig ergänzen/teilweise ablösen soll. Dennoch ist Ingress aktuell (2024) in vielen Clustern der Standardweg, HTTP/HTTPS-Traffic von außen hereinzubringen. --- Wenn du möchtest, kann ich als Nächstes: - ein konkretes Setup „von Null an“ durchgehen (z. B. Minikube + [[NGINX]] Ingress + Beispiel-App), oder - spezifisch auf Annotations/Features eines bestimmten Ingress-Controllers eingehen (etwa nginx oder Traefik).