Blog

Services und Ingress in Kubernetes und OpenShift 2/2

Im letzten Artikel sind wir die Grundlagen von Services durchgegangen. Diese sind bei Kubernetes und OpenShift gleich. Bei Ingress kommen einige Unterschiede zum Vorschein, aber nur in der Implementierung und bei den verwendeten Tools. Es soll aber das Gleiche erreicht werden.

Was ist Ingress?

Wie wir gesehen haben ist es unpraktisch jeden Service einzeln nach aussen bekannt zu machen. Bei Hunderten von Diensten, die im Cluster laufen sollen und auch von aussen erreichbar sein sollen, muss ein anderer Mechanismus her. Mit Ingress ist allgemein eingehender Traffic ins Cluster gemeint. Man braucht einen Ingress Controller, welches den Entrypoint ins Cluster darstellt und einzelne Ingress Api Objekte , welche beschreiben wie mit dem Traffic umzugehen ist, z.B.: SSL Offload Ja/Nein, zu welchem internen Service soll weitergeleitet werden, etc. Das Konzept klingt bestimmt vertraut. Man denke an Apache oder Nginx als Webserver und einzelne Vhosts als Konfiguration.

Und nichts anderes ist der Ingress Controller: Ein Reverse Proxy wie Nginx, HAProxy, Traefik, etc. In Kubernetes kann man eine Ingress Controller Implementierung seiner Wahl nutzen. Bei OpenShift ist standardmäßig der Ingress Controller (dort Router genannt) ein HAProxy und Ingress Objekte heissen dort Routes.

Die Installation ist recht einfach und meist mit zwei Kommandos erledigt. Beipsiel für einen Nginx Ingress Controller:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml

Dieses Kommando installiert alle notwendigen Artefakte wie einen Namespace, ConfigMaps und Nginx selbst.

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-
nginx/master/deploy/provider/cloud-generic.yaml 

Das zweite Kommando ist interessant. Betrachten wir mal den Inhalt der Yaml Datei:

kind: Service
apiVersion: v1
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  externalTrafficPolicy: Local
  type: LoadBalancer
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: https
      port: 443
      targetPort: https

---

das kennen wir schon. Es ist ein Service vom Typ LoadBalancer. Es bewirkt, dass unser Ingress Controller von aussen erreichbar wird, in dem ein cloud spezifischer LoadBalancer provisioniert wird, welches wiederum auf den Ingress Controller zeigt. Jetzt kann man jeden Service im Cluster, welches von aussen erreichbar sein soll auf die IP des Loadbalancers im DNS (A-Record) zeigen lassen und ein spezifisches Ingress Konfigurations Objekt erstellen. Dieses routet den Traffic dann basierend auf Hostnamen oder Pfad Muster etc. auf die richtigen Services im Cluster. Sehen wir uns zunächst eine Grafik an:

Die Seiten/Service www.abc.de, www.xyz.de haben im DNS einen Eintrag auf die IP 1.2.3.4, welche den vorhin provisionierten Loadbalancer repräsentiert. In einem On-Prem Enterprise Umfeld kann das auch ein bestehender Firmen Loadbalancer sein. Dann wird er nicht dynamisch provisioniert, sondern leitet traffic einfach an die IP eines Nodes und den entsprechenden NodePort weiter. Nämlich dort wo der Ingress Controller läuft. Man kann auch mehrere Instanzen (Pods) eines Ingress Controller laufen lassen. Z.B. so, dass jeder Node damit bestückt ist.

Wie auch immer, der Loadbalancer leitet traffic also auf den Ingress Controller (Nginx, HAProxy. etc.) weiter. Durch das erstellen von einzelnen Ingress Objekten kann ich jetzt dem Controller sagen an welchen internen Serivce jetzt weitergeleitet werden soll, z.B.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: name-virtual-host-ingress
spec:
  rules:
  - host: www.abc.de
    http:
      paths:
      - backend:
          serviceName: serviceabc
          servicePort: 80
  - host: www.xyz.de
    http:
      paths:
      - backend:
          serviceName: servicexyz
          servicePort: 80

Das ist ein Beispiel für Named based Virtual Hosting. Man kann verschiedene Routing Optionen nutzen, wie z.B. Http header, Pfade in der URL, usw.

In solchen Ingress Objekten kann man auch definieren, ob SSL terminiert werden soll. Dafür brauchen wir die TLS Zertifikate, welches wir als Secret einbinden. Zum Thema Zertifikate und SSL Terminierung werde ich aber einen gesonderten Artikel verfassen, weil das Thema zu umfangreich ist.

Masiar IghaniServices und Ingress in Kubernetes und OpenShift 2/2