Spring Boot-Anwendungen mit Minikube ausführen

Ausführen von Spring Boot-Anwendungen mit Minikube

1. Überblick

In diesemprevious article haben wir eine theoretische Einführung über Kubernetes behandelt.

In diesem Tutorial werdenwe’ll discuss how to deploy a Spring Boot application on a local Kubernetes environment, also known as Minikube.

Im Rahmen dieses Artikels werden wir:

  • Installieren Sie Minikube auf unserem lokalen Computer

  • Entwickeln Sie eine Beispielanwendung, die aus zwei Spring Boot-Diensten besteht

  • Richten Sie die Anwendung mit Minikube auf einem Cluster mit einem Knoten ein

  • Stellen Sie die Anwendung mithilfe von Konfigurationsdateien bereit

2. Minikube installieren

Die Installation von Minikube besteht im Wesentlichen aus drei Schritten: Installation eines Hypervisors (wie VirtualBox), der CLIkubectl sowie von Minikube selbst.

Dasofficial documentation enthält detaillierte Anweisungen für jeden der Schritte und für alle gängigen Betriebssysteme.

Nach Abschluss der Installation können wir Minikube starten, VirtualBox als Hypervisor festlegen undkubectl so konfigurieren, dass es mit dem Clusterminikube kommuniziert:

$> minikube start
$> minikube config set vm-driver virtualbox
$> kubectl config use-context minikube

Danach können wir überprüfen, obkubectl korrekt mit unserem Cluster kommuniziert:

$> kubectl cluster-info

Die Ausgabe sollte folgendermaßen aussehen:

Kubernetes master is running at https://192.168.99.100:8443
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

Zu diesem Zeitpunkt halten wir die IP in der Antwort nahe (192.168.99.100 in unserem Fall). Wir werden das später alsNodeIP bezeichnen, das benötigt wird, um Ressourcen von außerhalb des Clusters aufzurufen, z. g. von unserem Browser.

Schließlich können wir den Zustand unseres Clusters überprüfen:

$> minikube dashboard

Dieser Befehl öffnet eine Site in unserem Standardbrowser, die einen umfassenden Überblick über den Status unseres Clusters bietet.

4. Demo-Anwendung

Da unser Cluster jetzt ausgeführt wird und für die Bereitstellung bereit ist, benötigen wir eine Demoanwendung.

Zu diesem Zweck erstellen wir eine einfache "Hallo Welt" -Anwendung, die aus zwei Spring Boot-Diensten besteht, die wirfrontend undbackend nennen.

Das Backend stellt einen REST-Endpunkt auf Port 8080 bereit und gibt einString zurück, das seinen Hostnamen enthält. Das Frontend ist auf Port 8081 verfügbar. Es ruft einfach den Backend-Endpunkt auf und gibt seine Antwort zurück.

Danach müssen wir aus jeder App ein Docker-Image erstellen. Alle dafür notwendigen Dateien sind auchon GitHub verfügbar.

Ausführliche Anweisungen zum Erstellen von Docker-Images finden Sie unterDockerizing a Spring Boot Application.

We have to make sure here that we trigger the build process on the Docker host of the Minikube cluster, andernfalls findet Minikube die Bilder später während der Bereitstellung nicht. Außerdem muss der Arbeitsbereich auf unserem Host in die Minikube-VM eingebunden sein:

$> minikube ssh
$> cd /c/workspace/tutorials/spring-cloud/spring-cloud-kubernetes/demo-backend
$> docker build --file=Dockerfile \
  --tag=demo-backend:latest --rm=true .

Danach können wir uns von der Minikube-VM abmelden. Alle weiteren Schritte werden auf unserem Host mit den Befehlszeilentoolskubectl undminikubeausgeführt.

5. Einfache Bereitstellung mit zwingenden Befehlen

In einem ersten Schritt erstellen wir eine Bereitstellung für unseredemo-backend-App, die nur aus einem Pod besteht. Auf dieser Grundlage werden einige Befehle erläutert, damit wir die Bereitstellung überprüfen, Protokolle überprüfen und am Ende bereinigen können.

5.1. Erstellen der Bereitstellung

Wir verwendenkubectl und übergeben alle erforderlichen Befehle als Argumente:

$> kubectl run demo-backend --image=demo-backend:latest \
  --port=8080 --image-pull-policy Never

Wie wir sehen können, erstellen wir eine Bereitstellung mit dem Namendemo-backend, which, die aus einem Image mit der Bezeichnungdemo-backend mit der Versionlatest instanziiert wird.

Mit–port geben wir an, dass die Bereitstellung Port 8080 für ihre Pods öffnet (da unseredemo-backend-App Port 8080 abhört).

Das Flag–image-pull-policy Never stellt sicher, dass Minikube nicht versucht, das Image aus einer Registrierung abzurufen, sondern es stattdessen vom lokalen Docker-Host übernimmt.

5.2. Überprüfen der Bereitstellung

Jetzt können wir überprüfen, ob die Bereitstellung erfolgreich war:

$> kubectl get deployments

Die Ausgabe sieht folgendermaßen aus:

NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
demo-backend   1         1         1            1           19s

Wenn wir uns die Anwendungsprotokolle ansehen möchten, benötigen wir zuerst die Pod-ID:

$> kubectl get pods
$> kubectl logs 

5.3. Erstellen eines Dienstes für die Bereitstellung

Um den REST-Endpunkt unserer Backend-App verfügbar zu machen, müssen wir einen Service erstellen:

$> kubectl expose deployment demo-backend --type=NodePort

–type=NodePort stellt den Dienst von außerhalb des Clusters zur Verfügung. Es wird bei<NodeIP>:<NodePort> verfügbar sein, d.h. e. Der Dienst ordnet alle bei<NodePort> eingehenden Anforderungen dem Port 8080 seiner zugewiesenen Pods zu.

Wir verwenden den Befehl expose, sodassNodePort vom Cluster automatisch festgelegt wird (dies ist eine technische Einschränkung). Der Standardbereich ist 30000-32767. Um einen Port unserer Wahl zu erhalten, können wir eine Konfigurationsdatei verwenden, wie wir im nächsten Abschnitt sehen werden.

Wir können überprüfen, ob der Dienst erfolgreich erstellt wurde:

$> kubectl get services

Die Ausgabe sieht folgendermaßen aus:

NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
demo-backend   NodePort    10.106.11.133           8080:30117/TCP   11m

Wie wir sehen können, haben wir einen Dienst namensdemo-backend vom TypNodePort, der unter der clusterinternen IP 10.106.11.133 verfügbar ist.

Wir müssen uns die Spalte PORT (S) genauer ansehen: Da Port 8080 im Deployment definiert wurde, leitet der Service den Datenverkehr an diesen Port weiter. Wenn wir jedochdemo-backend von unserem Browser aus aufrufen möchten, müssen wir Port 30117 verwenden, der von außerhalb des Clusters erreichbar ist.

5.4. Den Service anrufen

Jetzt können wir erstmals unseren Backend-Service anrufen:

$> minikube service demo-backend

Dieser Befehl startet unseren Standardbrowser und öffnet<NodeIP>:<NodePort>.. In unserem Beispiel wäre dieshttp://192.168.99.100:30117.

5.5. Bereinigen von Service und Bereitstellung

Danach können wir Service und Deployment entfernen:

$> kubectl delete service demo-backend
$> kubectl delete deployment demo-backend

6. Komplexe Bereitstellung mithilfe von Konfigurationsdateien

Für komplexere Setups sind Konfigurationsdateien die bessere Wahl, anstatt alle Parameter über Befehlszeilenargumente zu übergeben.

Konfigurationsdateien sind eine hervorragende Möglichkeit, unsere Bereitstellung zu dokumentieren, und sie können versioniert werden.

6.1. Service Definition für unsere Backend App

Definieren wir unseren Service für das Backend mithilfe einer Konfigurationsdatei neu:

kind: Service
apiVersion: v1
metadata:
  name: demo-backend
spec:
  selector:
    app: demo-backend
  ports:
  - protocol: TCP
    port: 8080
  type: ClusterIP

Wir erstellen einService mit dem Namendemo-backend, angezeigt durch das Feldmetadata: name.

Es zielt auf den TCP-Port 8080 auf jedem Pod mit der Bezeichnungapp=demo-backendab.

Schließlich gibttype: ClusterIP an, dass es nur innerhalb des Clusters verfügbar ist (da wir den Endpunkt dieses Mal von unsererdemo-frontend-App aus aufrufen möchten, jedoch nicht mehr direkt von einem Browser aus, wie im vorherigen Beispiel ).

6.2. Bereitstellungsdefinition für die Backend-App

Als Nächstes können wir die tatsächliche Bereitstellung definieren:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-backend
spec:
  selector:
      matchLabels:
        app: demo-backend
  replicas: 3
  template:
    metadata:
      labels:
        app: demo-backend
    spec:
      containers:
        - name: demo-backend
          image: demo-backend:latest
          imagePullPolicy: Never
          ports:
            - containerPort: 8080

Wir erstellen einDeployment mit dem Namendemo-backend, angezeigt durch das Feldmetadata: name.

Das Feldspec: selectordefiniert, wie die Bereitstellung ermittelt, welche Pods verwaltet werden sollen. In diesem Fall wählen wir lediglich ein Etikett aus, das in der Pod-Vorlage definiert ist (app: demo-backend).

Wir möchten drei replizierte Pods haben, die wir durch das Feldreplicasangeben.

Das Vorlagenfeld definiert den tatsächlichen Pod:

  • Die Pods sind alsapp: demo-backend gekennzeichnet

  • Das Feldtemplate: spec gibt an, dass auf jeder Pod-Replikation ein Containerdemo-backend mit der Versionlatest ausgeführt wird

  • Die Pods öffnen den Port 8080

6.3. Bereitstellung der Backend-App

Wir können jetzt die Bereitstellung auslösen:

$> kubectl create -f backend-deployment.yaml

Überprüfen wir, ob die Bereitstellung erfolgreich war:

$> kubectl get deployments

Die Ausgabe sieht folgendermaßen aus:

NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
demo-backend   3         3         3            3           25s

Wir können auch prüfen, ob der Service verfügbar ist:

$> kubectl get services

Die Ausgabe sieht folgendermaßen aus:

NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
demo-backend    ClusterIP   10.102.17.114           8080/TCP         30s

Wie wir sehen können, ist der Dienst vom TypClusterIP und bietet keinen externen Port im Bereich 30000-32767, anders als in unserem vorherigen Beispiel in Abschnitt 5.

6.4. Bereitstellung und Service-Definition für unsere Frontend-App

Danach können wir Service und Deployment für das Frontend definieren:

kind: Service
apiVersion: v1
metadata:
  name: demo-frontend
spec:
  selector:
    app: demo-frontend
  ports:
  - protocol: TCP
    port: 8081
    nodePort: 30001
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-frontend
spec:
  selector:
      matchLabels:
        app: demo-frontend
  replicas: 3
  template:
    metadata:
      labels:
        app: demo-frontend
    spec:
      containers:
        - name: demo-frontend
          image: demo-frontend:latest
          imagePullPolicy: Never
          ports:
            - containerPort: 8081

Sowohl Frontend als auch Backend sind nahezu identisch,the only difference between backend and frontend is the spec of the Service:

Für das Frontend definieren wir den Typ alsNodePort  (da wir das Frontend außerhalb des Clusters verfügbar machen möchten). Das Backend muss nur innerhalb des Clusters erreichbar sein, daher wartypeClusterIP.

Wie bereits erwähnt, geben wirNodePort auch manuell über das FeldnodePort an.

6.5. Bereitstellung der Frontend-App

Wir können diese Bereitstellung jetzt auf die gleiche Weise auslösen:

$> kubectl create -f frontend-deployment.yaml

Lassen Sie uns schnell überprüfen, ob die Bereitstellung erfolgreich war und der Service verfügbar ist:

$> kubectl get deployments
$> kubectl get services

Danach können wir endlich den REST-Endpunkt der Frontend-Anwendung aufrufen:

$> minikube service demo-frontend

Dieser Befehl startet unseren Standardbrowser erneut und öffnet<NodeIP>:<NodePort>, in diesem Beispielhttp://192.168.99.100:30001.

6.6. Bereinigen von Diensten und Bereitstellungen

Am Ende können wir aufräumen, indem wir Dienste und Bereitstellungen entfernen:

$> kubectl delete service demo-frontend
$> kubectl delete deployment demo-frontend
$> kubectl delete service demo-backend
$> kubectl delete deployment demo-backend

7. Fazit

In diesem Artikel haben wir einen kurzen Einblick in die Bereitstellung einer Spring Boot-App "Hello world" auf einem lokalen Kubernetes-Cluster mit Minikube erhalten.

Wir haben ausführlich besprochen, wie man:

  • Installieren Sie Minikube auf unserem lokalen Computer

  • Entwickeln und erstellen Sie ein Beispiel, das aus zwei Spring Boot-Apps besteht

  • Stellen Sie die Dienste in einem Cluster mit einem Knoten bereit, indem Sie zwingende Befehle mitkubectl sowie Konfigurationsdateien verwenden

Wie immer ist der vollständige Quellcode der Beispieleover on GitHub verfügbar.