Cloud Bursting – platzt die Private Cloud, ist die Public Cloud zur Stelle

Seite 3: Cross-Cluster-Kommunikation

Inhaltsverzeichnis

Anwendungen in Kubernetes lassen sich über einen internen DNS-Server eindeutig identifizieren und aufrufen. Hierfür zuständig ist die Kubernetes-Service-Ressource. Ziel der Cross-Cluster-Kommunikation ist es, diese Funktion auf mehrere Cluster auszuweiten. Eine Möglichkeit ist, ein Service Mesh einzusetzen, das alle Cluster der hybriden Cloud umspannt (s. Abb. 2) – für den Use Case kommt Istio als Multicluster-Installation in der Variante als Shared Control Plane zum Einsatz. Das hat den Vorteil, dass keine VPN-Verbindung zwischen den Clustern erforderlich ist. Die Kommunikation zwischen den Clustern geschieht jeweils über ein Gateway und ist über mutual TLS (mTLS) gesichert. In dieser Variante teilen sich beide Cluster die Istio Control Plane. Sie muss folglich immer aktiv sein und wird deshalb typischerweise in der privaten Cloud angesiedelt.

Um Probleme mit dem Multicluster-Scheduler zu vermeiden, sollte man Prometheus bei der Installation von Istio deaktivieren. Im Anschluss an die Installation von Istio gilt es, die Sidecar Injection auf Namespace-Ebene zu aktivieren. Dazu labelt man den entsprechenden Namespace in jedem Cluster folgendermaßen:

$ kubectl label namespace sample istio-injection=enabled

Damit eine Anwendung aus beiden Clustern ansprechbar ist, auch wenn sie nur in einem Cluster existiert, muss in jedem Cluster der zugehörige Service eingerichtet sein.

Abbildung 3 ist an die Istio-Beispielanwendung Bookinfo angelehnt und zeigt die Kommunikation zwischen verschiedenen Microservices, die sich über zwei Cluster verteilen. Sie besteht aus einem Frontend und zwei Backend-Services, die Details zu Büchern und Reviews bereitstellen. Der Microservice „Details“ ist in beiden Clustern vorhanden. Anfragen lassen sich so zwischen beiden Instanzen verteilen. Der Microservice „Reviews“ ist nur im privaten Cluster ausgerollt. Da die Service-Definition aber auch im öffentlichen Cluster verfügbar ist, leitet das Istio-Gateway alle Anfragen automatisch vom öffentlichen zum privaten Cluster weiter (s. Abb. 3).

Kommunikation zwischen Microservices (Abb. 3)

(Bild: doubleSlash)

Wie die Einrichtung von Istio vielleicht schon erahnen lässt, fallen viele Aufgaben bei einer hybriden Cloud mehrfach an, da sie in jedem Cluster auszuführen sind. Ziel ist es, das Anlegen von Ressourcen zu vereinheitlichen, um zum Beispiel Namespaces, Services oder Deployments zentral zu verwalten. Bei der Verwaltung mehrerer Cluster ist es dann möglich, solch redundante Aufgaben einzusparen.

Das entsprechende Kubernetes-Projekt heißt Kubernetes Cluster Federation. Es ist für den Einsatz von Cloud Bursting nicht zwingend notwendig, erleichtert Entwicklern aber die Arbeit. Der User Guide unterstützt bei der Installation.

Nach dem Installieren gibt es einen Host-Cluster, dem beliebige Cluster beitreten können. Sinnvollerweise wird der private Cluster zum Host. Im Host-Cluster können Entwickler zentral Ressourcen anlegen und dann auf ausgewählte Cluster verteilen. Zu den gebräuchlichsten Kubernetes-Objekten existiert jeweils eine Variante mit dem Präfix „Federated“.

Aus einem Service wie dem blob-storage wird dann ein FederatedService, wie die folgenden Listings veranschaulichen. Neben dem geänderten Namen ist vor allem das Attribut placement entscheidend. Durch die Auswahl von Labels oder die Auflistung von Clusternamen lässt sich hier die Verteilung auf die Cluster bestimmen. Standardmäßig legt man die Ressource in allen Clustern an. Wird der FederatedService nun also im Host-Cluster angelegt, resultiert daraus ein entsprechender Service im privaten und öffentlichen Cluster.

apiVersion: v1
kind: Service
metadata:
  name: blob-storage
spec:
  ports:
  - port: 10000
    protocol: TCP
    targetPort: 10000
  selector:
    app: blob-storage
  sessionAffinity: None
  type: ClusterIP

Listing 1: Service blob-storage

apiVersion: types.kubefed.io/v1beta1
kind: FederatedService
metadata:
 name: blob-storage
spec:
 placement:
   clusterSelector: {}
 template:
   spec:
     ports:
     - port: 10000
       protocol: TCP
       targetPort: 10000
     selector:
       app: blob-storage
     sessionAffinity: None
     type: ClusterIP

Listing 2: FederatedService blob-storage

Zusammen mit einem Istio-Multicluster-Mesh lässt sich über die Federation die Verteilung von Services vereinfachen. Das gilt insbesondere für das Betreiben von mehr als zwei Clustern, um beispielsweise verschiedene geografische Regionen abzudecken.

Da nun die Kommunikation innerhalb der hybriden Cloud sichergestellt ist, fehlt für das Cloud Bursting noch die Unterstützung eines übergreifenden Schedulers. Dieser entscheidet, in welchem Cluster das Machine Learning letztlich zur Ausführung kommt. Die Funktion steht über den Multicluster-Scheduler von admiralty.io bereit.

Nach der Installation genügt es, die Annotation multicluster.admiralty.io/elect: "" zu einem Deployment, Job oder Pod hinzuzufügen. Anschließend übernimmt der Multicluster-Scheduler und entscheidet, in welchem Cluster ein Pod zum Ausführen des Containers entsteht. Listing 3 zeigt, wie das geht:

apiVersion: batch/v1
kind: Job
metadata:
 labels:
   app: mnist-ml
 name: ml-job
spec:
 parallelism: 1
 template:
   metadata:
     annotations:
       multicluster.admiralty.io/elect: ""
     labels:
       app: mnist-ml
   spec:
     containers:
       image: smennig/ml-job:mnist
       imagePullPolicy: Always
       name: ml-job
     restartPolicy: Never
     dnsPolicy: ClusterFirst

Listing 3: Batch Job für das Multicluster-Scheduling

Aus technischer Sicht erstellt man einen so annotierten Pod wie gewohnt und lässt ihn anschließend vom Multicluster-Scheduler durch einen sogenannten Proxy Pod ersetzen, der nichts tut. Der Scheduler wählt dann einen Cluster zur Ausführung aus und erstellt darin einen sogenannten Delegate Pod. In ihm kommt die eigentliche Anwendung zur Ausführung.