K8S, HELM et Cie: au delà de la hype

Depuis quelques années, Kubernetes (K8S) et son écosystème deviennent l’environnement d’ exécution à la mode. Certaines personnes veulent déployer sur cet environnement en mettant en avant ses capacités de scalabilité. D’autres font du bashing (souvent) justifié sur la complexité et le coût de mise en œuvre d’une telle plateforme.
Vous l’aurez compris, cette technologie n’échappe pas au cycle du hype et à la fameuse courbe du Gartner.

Après quelques expériences sur cette plateforme ( et beaucoup sur d’autres 😀 ) je vais essayer de peser le pour et le contre qui m’apparaissent importants.
Bien évidemment, ce n’est que mon avis, j’ai sans doute omis certaines informations qui pourraient être indispensables pour d’ autres.

Pourquoi et dans quelles conditions il ne faut pas utiliser K8S ?

Avant de présenter les avantages des applications cloud, je vais essayer de réaliser l’anti thèse de mon propos.

En avez vous (vraiment) besoin ?

Vaste sujet et question délicate pour la population informaticienne qui a tendance à suivre les tendances du marché.

Avant de foncer tête baissée dans cette technologie qui est très intéressante au demeurant, il est important de se poser ces quelques questions:

  • Est-ce que mes SLO sont contraignantes?
  • Quel le cycle de déploiement de mes applications?
  • Qui gère les environnements ?

Bref, il faut savoir si le jeu en vaut la chandelle. Si vous avez une application qui doit scaler dynamiquement, encaisser les pics, et avoir du zero downtime durant les mises à jour, Kubernetes est fait pour vous. Si vous avez une application de gestion qui n’a pas d’exigences fortes si ce n’est de répondre aux besoins fonctionnels, l’utilisation de Kubernetes est discutable.

Êtes vous taillé pour ?

Kubernetes et son écosystème peuvent s’avérer complexes à appréhender. Si votre entreprise opte pour une utilisation « on premise« , c’est pire. Vous devrez avoir une équipe dédiée qui gérera cette plateforme et offrir une expertise aux équipes de développement.
Ne vous trompez pas. Si votre rôle est de développer des applications métier, il vous sera très difficile d’avoir également une expertise sur l’administration de cette plateforme. Vous pourrez l’utiliser et être à l’aise, mais l’administration d’une telle technologie est très compliquée.

Le seul conseil que je pourrais vous donner, c’est de ne partir sur Kubernetes que si vous avez une équipe support à disposition. C’est vrai si vous utilisez des services du Cloud tels que Google Cloud ou AWS. Ça l’est encore plus si vous utilisez des services « on premise » tels qu’ Openshift.

Est-ce que vos développements sont « cloud native » ?

Au delà de la plateforme, vous devrez monter en compétence sur le développement et la conception de vos applications.

Il vous faudra prendre en considération les 12 facteurs clés dans vos applications. Il n’est pas forcément la peine de passer sur des microservices. Il est également possible de faire des monolithes modulaires qui peuvent être légers et stateless. Beaucoup de ces facteurs sont communément admis comme des bonnes pratiques de développement logiciel (ex. Il faut une intégration continue).

Aussi, cela va sans dire, il faut également monter (réellement) en compétence sur les conteneurs et leurs contraintes. Si vous n’avez pas l’habitude de travailler avec des conteneurs ( construction, déploiement, disponibilité d’une registry). Il est préférable de définir une trajectoire avec des étapes intermédiaires.

Bref, tous ces sujets doivent être adressés et compris pour toutes les parties prenantes de vos équipes que ça soit les développeurs, les chefs de projet et les équipes métiers à une moindre mesure. Cette technologie représente réellement un grand pas à franchir. Si vous ne vous sentez pas de le faire, ou si vous devez gagner en maturité sur ces sujets, attendez avant de vous lancer sur Kubernetes.

On ne pourra jamais vous reprocher de ne pas opter sur Kubernetes si vous ne remplissez pas tous les pré-requis. Pour ce qui est du contraire…

Avez vous des interactions avec des services tiers qui sont compatible avec Kubernetes ?

Quand vous restez dans votre cluster Kubernetes, généralement, tout va bien. Dès que vous avez des interactions avec des services tiers, ça peut se compliquer.
En effet, généralement vous devrez vous connecter à des services tiers qui ne sont pas orienté cloud : des boitiers crypto, des passerelles de transfert, …
Il se peut que certains protocoles soient également incompatibles avec Kubernetes. Il vous faudra vous assurer que tout la galaxie de logiciels et systèmes gravitant autour de votre application sera compatible avec une telle architecture. Ceci n’est pas une mince affaire. L’aide d’une équipe support (voir ci-dessus) vous sera d’une grande utilité.

Pourquoi sauter le pas ?

La scalabilité et la résistance à la panne

Personnellement, la première fonctionnalité qui m’a intéressé c’est la gestion de la scalabilité. Si vous avez des objectifs de 99.9% de disponibilité. Kubernetes sera une plus value indéniable dans votre architecture. Après quelques jours heures à batailler avec les fichiers YAML, vous pourrez gérer automatiquement la scalabilité en fonction de plusieurs indicateurs qu’ils soient techniques (ce sont les plus faciles à gérer) ou un peu plus métier en utilisant Prometheus – et oui encore une technologie supplémentaire à connaître.

En effet, au lieu de vous en soucier une fois arrivé en production, vous aurez lors du développement l’obligation de prendre en considération l’observabilité de votre application. Par exemple, vous aurez à renseigner si votre application est prête et/ou disponible pour traiter les requêtes. Ces indicateurs vous permettront de scaler automatiquement et de re-créer si nécessaire un POD en cas de panne.

J’ai trouvé que cette pratique était vertueuse. Bien évidemment, pas besoin d’être sur Kubernetes pour avoir de l’observabilité dans des applications. Par contre, ici, c’est obligatoire et implémenté dès le développement.

La scalabilité automatique est aussi très intéressante. On a souvent vu des serveurs en production qui n’étaient pas suffisamment utilisés. Ici vous n’aurez que les instances nécessaires pour votre cas d’utilisation.
La contrainte que l’on peut voir à cette fonctionnalité et qu’on ne maitrise pas complètement le nombre d’instances disponibles. C’est Kubernetes qui s’en charge en prenant en compte le paramétrage que vous aurez renseigné dans vos templates HELM.

Le déploiement

Avant de déployer (dans la vraie vie), vous aurez à mettre en place un pipeline CI/CD qui orchestre les différents déploiements sur tous vos environnements. Attention, ce n’est pas une mince affaire 🙂 !

Une fois réalisé, vous verrez automatiquement le gain. Vos déploiements seront réellement fluides. Bon OK, on peut le faire sur des VMS standards. Mais on peut améliorer la procédure de déploiement pour mettre en place du zero downtime pour ne pas interrompre le service lors d’un déploiement.

strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0

L’Infrastructure As Code

Quand on pense à Kubernetes, et au cloud, on ne pense pas trop à l’Infrastructure As Code au début. Cependant, cette pratique est pour moi l’une des plus utiles.

En effet, avoir votre système décrit dans des fichiers, versionnés vous permet de le tester dès le développement. Ça évite ( dans la majorité des cas ) les erreurs lors des installations d’environnement. La mise à jour des logiciels est largement accélérée.

Bien évidemment, il existe Terraform et Ansible pour le provisionning des environnements. Ici je trouve qu’on pousse le concept encore plus loin. L’automatisation est à mon avis poussé à paroxysme.
Prenons par exemple la gestion des systèmes d’exploitation. La mise à jour sur des serveurs physiques ou virtuels peut prendre énormément de temps et générer des erreurs. Avec de l’infra as code, ceci est testé et validé automatiquement via des tests unitaires dès l’environnement de développement.
On peut suivre la gestion des environnements via un gestionnaire de sources et la promotion vers les autres environnements (recette[1-n], pré-production, production) est grandement accélérée.

Conclusion

Bon, vous l’aurez peut être compris, cette galaxie de technologies est intéressante et peut vous aider dans vos projets. Avant d’arriver à l’utiliser sereinement, il vous faudra sans doute définir une trajectoire et appréhender plusieurs sujets avant d’arriver à déployer vos applications sur un cloud interne ou externe.
J’espère que cet article vous aura permis de mettre en évidence les pour et contre d’une telle technologie et le cas échéant vous donnera envie de franchir le pas.

Utiliser des GITHUB Actions pour déployer dans Google Kubernetes Engine

A mes heures perdues, je travaille sur un « POC/side project qui n’aboutira pas et je m’en fiche » basé sur Quarkus. J’ ai choisi d’utiliser les langages et composants suivants :

Oui, tant qu’à faire, autant aller dans la hype …

Mon projet est sur GITHUB. Pour automatiser certaines actions et, disons-le, par fierté personnelle, j’ai choisi d’automatiser certaines actions par la mise en œuvre de pipelines CI/CD.
Depuis peu, GITHUB a intégré un mécanisme de pipeline : GITHUB Actions.

Ça permet, entre autres, de lancer des processus automatisé sur un push ou sur une action pour un commit GIT.

La force de l’outil est, selon moi, de facilement s’intégrer avec beaucoup de services du cloud ( sonarcloud, google cloud, heroku,…). On aime ou on n’aime pas, mais chez Microsoft, l’intégration ils savent faire.

Par exemple, si on veut lancer une compilation lors d’un push, on peut placer un fichier .github/workflows/build.xml avec le contenu :

name: CI

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 11
        uses: actions/setup-java@v1
        with:
          java-version: 11
      - name: Build with Gradle without testing
        run: ./gradlew build -x test

Coté GITHUB, vous verrez l’exécution sur un écran dédié

Vous pouvez créer autant de workflows que vous souhaitez (si votre projet est en libre accès).
Pour chaque workflow, on peut définir et utiliser des jobs. Les logs d’exécution sont disponibles dans ce même écran:

Worflows implémentés

J’ai choisi d’implémenter les workflows suivants:

  • CI: Build sur la feature branch
  • CD: Build sur master branch et déploiement

On obtient donc dans mon cas:

Ce n’est pas parfait. Loin de là. Dans la « vraie vie », pour une équipe de dev, je l’améliorerai sans doute par un build docker dans les features branches, une validation formelle et bloquante de l’analyse sonar, etc.
Pour un dev perso ça suffit largement. Le contenu de la branche master est compilé et une image docker est crée pour être déployée automatiquement dans GKE.

Analyse SONAR

J’ai choisi d’utiliser sonarcloud pour analyser mon code. C’est gratuit pour les projets opensource. L’analyse se fait simplement:

  sonarCloudTrigger:
    name: SonarCloud Trigger
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 11
        uses: actions/setup-java@v1
        with:
          java-version: 11
      - name: SonarCloud Scan
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        run: ./gradlew jacocoTestReport sonarqube

Dans ce job j’utilise deux secrets. Ce sont des tokens qui permettent de ne pas stocker en dur les données dans les repos GITHUB.

Création d’une image Docker et déploiement dans le registry GITHUB

Ici aussi, ça se fait simplement. La preuve :

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 11
        uses: actions/setup-java@v1
        with:
          java-version: 11
      - name: Build in JVM Mode with Gradle without testing
        run: ./gradlew quarkusBuild  [1]
      - name: Branch name
        run: echo running on branch ${GITHUB_REF##*/}
      - name: Build the Docker image Quarkus JVM
        run: docker build -f src/main/docker/Dockerfile.jvm -t docker.pkg.github.com/${GITHUB_REPOSITORY}/music-quote-jvm:latest .  [2]
      - name: Login against github docker repository
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: docker login -u ${GITHUB_ACTOR} -p ${GITHUB_TOKEN}  docker.pkg.github.com   [3]
      - name: Publish the Docker image Quarkus JVM
        run: docker push docker.pkg.github.com/${GITHUB_REPOSITORY}/music-quote-jvm:latest  [4]
  1. Création du binaire
  2. Création de l’image docker en utilisant la commande docker et le Dockerfile fourni par Quarkus
  3. Identification sur la registry Docker de GITHUB
  4. Déploiement de l’image

Pour plus de détails sur la variable GITHUB_TOKEN, vous pouvez lire cet article de la documentation.

Déploiement dans Google Kubernetes Engine

Mon application est pour l’instant architecturée comme suit (attention c’est compliqué):

Pour la déployer dans Google Kubernetes Engine, j’ai besoin d’ implémenter cette « architecture » par les objets Kubernetes suivants:

J’utilise les objets suivants:

  • Des services pour exposer la base de données ainsi que l’application
  • Un deployment pour l’application
  • Des pods car à un moment, il en faut…
  • Un statefulset pour la base de données

Vous pourrez trouver la définition de tous ces objets au format yaml via ce lien. J’ai fait très simple. Logiquement j’aurai du créer un volume pour les bases de données ou utiliser une base de données en mode PAAS.

Pour lancer le déploiement, il faut au préalable créer un secret ( fait manuellement pour ne pas stocker d’objet yaml dans le repository GITHUB) pour se connecter au repo GITHUB via la commande suivante:

kubectl create secret docker-registry github-registry --docker-server=docker.pkg.github.com --docker-username=USER--docker-password=PASSWORD --docker-email=EMAIL

On peut faire pareil pour les connexions base de données. J’ai mis dans un configmap pour ne pas trop me prendre la tête…

Après le déploiement via le pipeline se fait assez simplement:

      [...]
      - uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
        with:
          version: '286.0.0'
          service_account_email: ${{ secrets.GKE_SA_EMAIL }}
          service_account_key: ${{ secrets.GKE_SA_KEY }}
          project_id: ${{ secrets.GKE_PROJECT }}
      # Get the GKE credentials so we can deploy to the cluster
      - run: |-
          gcloud container clusters get-credentials "${{ secrets.GKE_CLUSTER }}" --zone "${{ secrets.GKE_ZONE }}"
      # Deploy the Docker image to the GKE cluster
      - name: Deploy
        run: |-
          kubectl apply -f ./k8s     

J’utilise les « actions » fournies par Google.

Conclusion

Pour que ça marche il y a pas mal d’étapes préalables ( des tokens à générer, un utilisateur technique, …).
J’ai essayé de les référencer dans le README du projet.
Si vous voulez tester l’intégration Kubernetes dans le cloud google, sachez que vous pouvez disposer d’un crédit de 300€ valable un an. Attention, avec ce genre d’architecture, ça part vite…