Blog ENI : Toute la veille numérique !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Quarkus
  3. Conteneurisation et Kubernetes
Extrait - Quarkus Développer des applications microservices en Java pour le cloud et Kubernetes
Extraits du livre
Quarkus Développer des applications microservices en Java pour le cloud et Kubernetes Revenir à la page d'achat du livre

Conteneurisation et Kubernetes

Conteneurisation

1. Utilisation d’images fournies à la création d’un projet

Comme évoqué dans le chapitre Quarkus : carte d’identité, section Les piliers de Quarkus, ce dernier a été pensé pour fonctionner dans un conteneur.

Docker est un outil qui permet de créer des images de conteneur à partir d’un fichier de descripteur appelé Dockerfile. Il fournit aussi un démon (dockerd) pour faire tourner les conteneurs et une ligne de commande (docker) pour interagir avec ce démon.

L’Open Container Initiative (OCI) a standardisé le format des images et le lancement des conteneurs. Docker et d’autres outils sont compatibles OCI.

À la génération d’un projet Quarkus, quatre fichiers de type Dockerfile sont générés dans le répertoire src/main/docker. Ils peuvent être utilisés pour créer une image Docker de votre application :

  • Dockerfile.jvm : pour créer une image Docker lançant l’application en mode JVM (depuis un JAR).

  • Dockerfile.legacy-jar : pour créer une image Docker lançant l’application en mode JVM mais utilisant l’ancien format de JAR (legacy JAR).

  • Dockerfile.native : pour créer une image Docker lançant l’application comme une image native GraalVM. Il utilise comme image de base ubi-minimal

  • Dockerfile.native-micro : pour créer une image Docker lançant l’application comme une image native GraalVM. Il utilise comme image de base quarkus-micro qui est optimisée pour une taille d’image réduite.

Le plus souvent, on choisit Dockerfile.jvm pour les déploiements JVM et Dockerfile.native pour les déploiements en image native GraalVM.

Lors du packaging d’une application pour la JVM, quatre répertoires sont créés. Le fichier Dockerfile.jvm va tirer parti de cela pour créer quatre layers (couches en français) dans l’image Docker créée :

COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/ 
COPY --chown=185 target/quarkus-app/*.jar /deployments/ 
COPY --chown=185 target/quarkus-app/app/ /deployments/app/ 
COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/ 

Ceci permet d’optimiser l’image...

Génération de ressources Kubernetes et OpenShift

1. Génération de ressources Kubernetes

Quarkus permet la génération automatique de ressources Kubernetes via l’outil Dekorate. Ceci est réalisé grâce à l’extension Kubernetes qui va se reposer sur l’extension Container Images, si elle est présente, pour récupérer les informations de l’image du conteneur à utiliser lors de la génération des ressources Kubernetes.

On appelle ressources Kubernetes les objets qui seront créés dans Kubernetes pour contrôler ses fonctionnalités d’orchestration. Kubernetes offre de nombreuses ressources parmi lesquelles on trouve :

  • Les ressources de type Pod qui permettent de démarrer un ou plusieurs conteneurs et s’assurer de leur fonctionnement.

  • Les ressources de type Deployment qui permettent de s’assurer qu’un certain nombre d’instances de pod existent sur le cluster et gèrent la mise à jour de ces pods.

  • Les ressources de type Service qui permettent d’exposer un pod au sein du cluster.

  • Les ressources de type Ingress qui permettent d’exposer un pod à l’extérieur du cluster.

Pour ajouter l’extension Kubernetes à votre application, vous pouvez utiliser :

  • la CLI Quarkus :

quarkus extension add kubernetes 
  • le plugin Maven :

mvn quarkus:add-extension -Dextensions="kubernetes" 

Ceci va ajouter la dépendance Maven suivante :

<dependency> 
  <groupId>io.quarkus</groupId> 
  <artifactId>quarkus-kubernetes</artifactId> 
</dependency> 

Par défaut, Quarkus va générer une ressource Deployment et une ressource Service dans le répertoire target/kubernetes, dans un fichier unique kubernetes.yml (il existe aussi une version JSON du fichier).

Voici son contenu pour l’application exemple de ce chapitre (les annotations ont été supprimées pour gain de place) :

--- 
apiVersion: apps/v1 
kind: Deployment 
metadata: 
  labels: 
    app.kubernetes.io/name: chapitre-09 
    app.kubernetes.io/version: 1.0.0-SNAPSHOT 
  name: chapitre-09 
spec: 
  replicas:...

Déploiement dans Kubernetes

Comme évoqué dans le chapitre Quarkus : carte d’identité, section Les piliers de Quarkus, ce dernier a été pensé pour fonctionner dans un conteneur et être déployé dans Kubernetes ou OpenShift.

L’extension Kubernetes vue dans la section précédente permet la génération des ressources nécessaires au déploiement d’une application dans Kubernetes ou OpenShift. Cependant, que vous l’utilisiez ou non, quelques points spécifiques à un déploiement dans Kubernetes sont à prendre en compte.

1. Configuration des ressources des conteneurs

Il est important de toujours configurer les ressources CPU et mémoire utilisées par un conteneur dans Kubernetes pour ne pas risquer qu’un conteneur utilise trop de ressources, ou pas assez si le cluster a des valeurs par défaut faibles.

Quarkus a une faible empreinte mémoire, il peut donc fonctionner sans problème avec une demande minimale en mémoire assez basse. De même, Quarkus va se servir du CPU de manière efficiente, surtout si des extensions réactives sont utilisées ; il peut donc fonctionner sans souci avec une demande minimale en CPU assez basse.

En revanche, même si Quarkus démarre vite, une application Java déployée dans une JVM va tirer parti d’une limite maximum de CPU élevée au démarrage et pendant les premières minutes de fonctionnement ; c’est ce que l’on appelle la phase de chauffe de l’application (warm up en anglais). Pendant cette phase, le compilateur JIT (Just In Time Compiler) va compiler et optimiser le code de l’application, ce qui nécessite beaucoup de CPU. Si vous pouvez vous le permettre, configurer la limite en termes de CPU à 1 ou 2 permettra une phase de chauffe de votre application plus rapide qui atteindra sa performance en pic plus vite.

Bien sûr, chaque application a des besoins en mémoire et CPU qui sont liés à ce qu’elle réalise et à la charge qu’elle veut pouvoir supporter ; il n’y a pas de valeur magique. Mais gardez en mémoire que pour un démarrage et une phase de chauffe plus rapides, il est conseillé d’allouer des ressources...

ConfigMap, Secret et Service Binding

1. ConfigMap et Secret

Une ConfigMap est un type de ressources Kubernetes qui permet de stocker des données en clé/valeur. Un pod peut ensuite consommer ces ConfigMap comme variable d’environnement, ou comme fichier de configuration via un volume.

Comme vu dans le chapitre Développement d’applications avec Quarkus, section Bases : configuration, logs, injection de dépendances et tests, Quarkus permet la configuration d’une application via un fichier externe dont la localisation est configurée via la propriété de configuration quarkus.config.locations.

Une ConfigMap peut être montée dans un conteneur comme un répertoire contenant un fichier par entrée ; elle peut donc être utilisée pour créer un fichier de configuration qui sera ensuite lu par Quarkus.

Par exemple, la commande kubectl suivante va créer une ConfigMap depuis un répertoire contenant un ou plusieurs fichiers de configuration additionnels :

kubectl create configmap chapitre-09 \ 
    --from-file chapitre-09/config 

On peut ensuite configurer le pod pour monter un volume dans le répertoire /etc/config ; ce répertoire contiendra un fichier par entrée de la ConfigMap :

spec: 
  containers: 
  - name: chapitre-09 
    volumeMounts: 
    - name: config 
      mountPath: "/etc/config" 
      readOnly: true 
  volumes: 
  - name: config 
    configMap: 
      name: config 

Il faudra ensuite configurer Quarkus pour charger le ou les fichiers de configuration.

Par exemple, si le répertoire contient le fichier additional-config.properties, on devra ajouter la propriété de configuration suivante :

quarkus.config.locations=/etc/config/additional-config.properties 

Les Secret fonctionnent de la même manière, sauf que leur contenu est encodé en Base64 au sein du cluster Kubernetes.

Si l’extension...

Interagir avec un cluster Kubernetes

Il est possible d’interagir avec un cluster Kubernetes grâce à l’extension Kubernetes Client qui va fournir une instance du client Kubernetes de Fabric8

L’extension Quarkus Kubernetes Client peut être ajoutée à votre application via :

  • la CLI Quarkus :

quarkus extension add kubernetes-client 
  • le plugin Maven :

mvn quarkus:add-extension -Dextensions="kubernetes-client" 

Ceci va ajouter la dépendance Maven suivante :

<dependency> 
  <groupId>io.quarkus</groupId> 
  <artifactId>quarkus-kubernetes-client</artifactId> 
</dependency> 

Cette dépendance va permettre l’injection d’un objet de type KubernetesClient pour interagir avec un cluster Kubernetes.

L’exemple ci-dessous crée un endpoint KubernetesResource qui va permettre d’accéder à la version du cluster Kubernetes ainsi qu’à la liste des ressources de type Deployment :

@Path("/k8s") 
public class KubernetesResource { 
    @Inject 
    KubernetesClient kubernetesClient; 
 
    @GET 
    @Path("/version") 
    public VersionInfo getKubernetesVersion() { 
        return kubernetesClient.getKubernetesVersion(); 
    } 
 
    @GET 
    @Path("/apps") 
    public DeploymentList apps() { ...