Exécution d’applications Spring Boot avec Minikube

Exécution d'applications de démarrage Spring avec Minikube

1. Vue d'ensemble

Dans ceprevious article, nous avons couvert une introduction théorique sur Kubernetes.

Dans ce didacticiel,we’ll discuss how to deploy a Spring Boot application on a local Kubernetes environment, also known as Minikube.

Dans le cadre de cet article, nous allons:

  • Installer Minikube sur notre machine locale

  • Développer un exemple d'application comprenant deux services Spring Boot

  • Configurer l'application sur un cluster à un nœud à l'aide de Minikube

  • Déployer l'application à l'aide de fichiers de configuration

2. Installer Minikube

L'installation de Minikube se compose essentiellement de trois étapes: l'installation d'un hyperviseur (comme VirtualBox), la CLIkubectl, ainsi que Minikube lui-même.

Leofficial documentation fournit des instructions détaillées pour chacune des étapes et pour tous les systèmes d'exploitation courants.

Une fois l'installation terminée, nous pouvons démarrer Minikube, définir VirtualBox comme hyperviseur et configurerkubectl pour parler au cluster appeléminikube:

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

Après cela, nous pouvons vérifier quekubectl communique correctement avec notre cluster:

$> kubectl cluster-info

Le résultat devrait ressembler à ceci:

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

À ce stade, nous conserverons l'adresse IP dans la réponse close (192.168.99.100 dans notre cas). Nous appellerons plus tard celaNodeIP, qui est nécessaire pour appeler des ressources de l'extérieur du cluster, e. g. depuis notre navigateur.

Enfin, nous pouvons inspecter l’état de notre cluster:

$> minikube dashboard

Cette commande ouvre un site dans notre navigateur par défaut, qui fournit une vue d'ensemble détaillée de l'état de notre cluster.

4. Application de démonstration

Notre cluster étant maintenant opérationnel et prêt à être déployé, nous avons besoin d'une application de démonstration.

À cette fin, nous allons créer une simple application «Hello world», composée de deux services Spring Boot, que nous appelleronsfrontend etbackend.

Le backend fournit un point de terminaison REST sur le port 8080, renvoyant unString contenant son nom d'hôte. L'interface est disponible sur le port 8081; il suffit d'appeler le point d'extrémité principal et de renvoyer sa réponse.

Après cela, nous devons créer une image Docker à partir de chaque application. Tous les fichiers nécessaires pour cela sont également disponibleson GitHub.

Pour obtenir des instructions détaillées sur la création d'images Docker, jetez un œil àDockerizing a Spring Boot Application.

We have to make sure here that we trigger the build process on the Docker host of the Minikube cluster, sinon, Minikube ne trouvera pas les images plus tard lors du déploiement. De plus, l’espace de travail de notre hôte doit être monté sur la VM Minikube:

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

Après cela, nous pouvons nous déconnecter de la VM Minikube, toutes les étapes suivantes seront exécutées sur notre hôte à l'aide des outils de ligne de commandekubectl etminikube.

5. Déploiement simple à l'aide des commandes impératives

Dans un premier temps, nous allons créer un déploiement pour notre applicationdemo-backend, composé d'un seul pod. Sur cette base, nous discuterons de certaines commandes afin que nous puissions vérifier le déploiement, inspecter les journaux et le nettoyer à la fin.

5.1. Création du déploiement

Nous utiliseronskubectl, en passant toutes les commandes requises comme arguments:

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

Comme nous pouvons le voir, nous créons un déploiement appelédemo-backend, which qui est instancié à partir d'une image également appeléedemo-backend, avec la versionlatest.

Avec–port, nous spécifions que le déploiement ouvre le port 8080 pour ses pods (car notre applicationdemo-backend écoute le port 8080).

L'indicateur–image-pull-policy Never garantit que Minikube n'essaye pas d'extraire l'image d'un registre, mais la prend à la place de l'hôte Docker local.

5.2. Vérification du déploiement

Maintenant, nous pouvons vérifier si le déploiement a réussi:

$> kubectl get deployments

La sortie ressemble à ceci:

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

Si nous voulons consulter les journaux de l'application, nous avons d'abord besoin de l'ID du pod:

$> kubectl get pods
$> kubectl logs 

5.3. Création d'un service pour le déploiement

Pour rendre le point de terminaison REST de notre application backend disponible, nous devons créer un service:

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

–type=NodePort rend le service disponible depuis l'extérieur du cluster. Il sera disponible à<NodeIP>:<NodePort>, i. e. le service mappe toute demande entrante à<NodePort> au port 8080 de ses pods attribués.

Nous utilisons la commande exposer, doncNodePort sera automatiquement défini par le cluster (c'est une limitation technique), la plage par défaut est 30000-32767. Pour obtenir un port de notre choix, nous pouvons utiliser un fichier de configuration, comme nous le verrons dans la section suivante.

Nous pouvons vérifier que le service a été créé avec succès:

$> kubectl get services

La sortie ressemble à ceci:

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

Comme nous pouvons le voir, nous avons un service appelédemo-backend, de typeNodePort, qui est disponible à l'adresse IP interne du cluster 10.106.11.133.

Nous devons examiner de plus près la colonne PORT (S): comme le port 8080 a été défini dans le déploiement, le service transfère le trafic à ce port. Cependant, si nous voulons appeler ledemo-backend  depuis notre navigateur, nous devons utiliser le port 30117, qui est accessible depuis l'extérieur du cluster.

5.4. Appeler le service

Maintenant, nous pouvons appeler notre service backend pour la première fois:

$> minikube service demo-backend

Cette commande démarrera notre navigateur par défaut, ouvrant<NodeIP>:<NodePort>. Dans notre exemple, ce seraithttp://192.168.99.100:30117.

5.5. Nettoyage du service et déploiement

Par la suite, nous pouvons supprimer le service et le déploiement:

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

6. Déploiement complexe à l'aide de fichiers de configuration

Pour les configurations plus complexes, les fichiers de configuration constituent un meilleur choix, au lieu de transmettre tous les paramètres via des arguments de ligne de commande.

Les fichiers de configuration constituent un excellent moyen de documenter notre déploiement. Ils peuvent être contrôlés par version.

6.1. Définition de service pour notre application backend

Redéfinissons notre service pour le backend à l'aide d'un fichier de configuration:

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

Nous créons unService nommédemo-backend, indiqué par le champmetadata: name.

Il cible le port TCP 8080 sur n'importe quel pod avec l'étiquetteapp=demo-backend.

Enfin,type: ClusterIP indique qu'il n'est disponible que depuis l'intérieur du cluster (car nous voulons appeler le point de terminaison depuis notre applicationdemo-frontend cette fois, mais plus directement depuis un navigateur, comme dans l'exemple précédent ).

6.2. Définition de déploiement pour l'application backend

Ensuite, nous pouvons définir le déploiement réel:

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

Nous créons unDeployment nommédemo-backend, indiqué par le champmetadata: name.

Le champspec: selector définit comment le déploiement trouve les pods à gérer. Dans ce cas, nous sélectionnons simplement sur une étiquette définie dans le modèle de pod (app: demo-backend).

Nous voulons avoir trois pods répliqués, que nous indiquons par le champreplicas.

Le champ de modèle définit le pod actuel:

  • Les pods sont étiquetés commeapp: demo-backend

  • Le champtemplate: spec indique que chaque réplication de pod exécute un conteneur,demo-backend, avec la versionlatest

  • Les pods ouvrent le port 8080

6.3. Déploiement de l'application backend

Nous pouvons maintenant déclencher le déploiement:

$> kubectl create -f backend-deployment.yaml

Vérifions que le déploiement a réussi:

$> kubectl get deployments

La sortie ressemble à ceci:

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

Nous pouvons également vérifier si le service est disponible:

$> kubectl get services

La sortie ressemble à ceci:

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

Comme nous pouvons le voir, le service est de typeClusterIP, et il ne fournit pas de port externe dans la plage 30000-32767, différent de notre exemple précédent dans la section 5.

6.4. Déploiement et définition de service pour notre application frontend

Après cela, nous pouvons définir Service et déploiement pour le client:

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

Le frontend et le backend sont presque identiques,the only difference between backend and frontend is the spec of the Service:

Pour le frontend, nous définissons le type commeNodePort  (car nous voulons rendre le frontend disponible à l'extérieur du cluster). Le backend ne doit être accessible qu'à partir du cluster, par conséquent, letype étaitClusterIP.

Comme indiqué précédemment, nous spécifions égalementNodePort manuellement, en utilisant le champnodePort.

6.5. Déploiement de l'application Frontend

Nous pouvons maintenant déclencher ce déploiement de la même manière:

$> kubectl create -f frontend-deployment.yaml

Vérifions rapidement que le déploiement a réussi et que le service est disponible:

$> kubectl get deployments
$> kubectl get services

Après cela, nous pouvons enfin appeler le point de terminaison REST de l'application frontale:

$> minikube service demo-frontend

Cette commande redémarrera notre navigateur par défaut, ouvrant<NodeIP>:<NodePort>, qui esthttp://192.168.99.100:30001 pour cet exemple.

6.6. Nettoyage des services et des déploiements

En fin de compte, nous pouvons nettoyer en supprimant Services et déploiements:

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

7. Conclusion

Dans cet article, nous avons brièvement expliqué comment déployer une application Spring Boot «Hello world» sur un cluster Kubernetes local à l'aide de Minikube.

Nous avons discuté en détail comment:

  • Installer Minikube sur notre machine locale

  • Développer et construire un exemple composé de deux applications Spring Boot

  • Déployez les services sur un cluster à un nœud, en utilisant des commandes impératives aveckubectl ainsi que des fichiers de configuration

Comme toujours, le code source complet des exemples est disponibleover on GitHub.