Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Vers des environnements de développement cloud-native [Partie 2 — Comment]

By Yarel MamanJun 18, 202110 min read

Cette page est également disponible en English, Deutsch, Español, Italiano, 日本語 et Português.

Parfait ! Si vous êtes ici, c'est probablement que vous avez lu la Partie 1 (Le Pourquoi) et que vous souhaitez en savoir plus sur la mise en place d'environnements de développement cloud-native. Excellent !

Prenons l'exemple d'une équipe projet existante et voyons comment améliorer son workflow de développement.

Ce guide a été rédigé avec GCP (Google Cloud Platform) en tête, mais les mêmes concepts s'appliquent également à AWS.

Photo de Jason Richard sur Unsplash

📖 Étude de cas

Une entreprise nommée MajesticFantastic propose plusieurs produits liés au paiement 💸

L'équipe du projet billing pilote le développement d'une application de facturation.

Elle se compose des éléments suivants :

  • Quelques microservices déployés sous forme de conteneurs dans GKE 🛳
  • Services cloud GCP utilisés : Pub/Sub, Cloud SQL (PostgreSQL), Cloud Monitoring, Container Registry.
  • Environnements actuels : Dev, Prod.
  • Une équipe de 2 développeurs : David et Martha. Très bientôt, un développeur nommé Ezekiel et plusieurs autres rejoindront l'équipe, l'entreprise étant en pleine phase de croissance. Une période passionnante ! 🚀

Preuve de concept

Nous allons introduire un nouveau type d'environnement, que nous appellerons l'environnement personnel.

Pour cet environnement personnel, notre POC se composera de :

  • Un projet GCP qui jouera le rôle de projet Host. Il hébergera le cluster GKE, l'instance Cloud SQL et les images de conteneur dans GCR.
  • Plusieurs projets personnels GCP — un par développeur. Chaque projet contiendra des ressources non partagées, propres à chaque développeur. Dans notre cas d'usage, par exemple, il hébergera les topics et abonnements Pub/Sub.
  • Un Shared VPC. Son host sera le projet Host, et chaque projet personnel agira comme projet de service du Shared VPC.

Cluster GKE multi-tenant

Nous allouerons un namespace K8s par environnement (par exemple, l'environnement de David recevra le namespace david-env, celui de Martha sera martha-env, et ainsi de suite).

Chaque environnement accédera uniquement à son propre namespace, sans dépendre de ressources situées dans les namespaces d'autres environnements.

Note : nous n'imposerons rien sur le plan de la sécurité pour l'instant. Des mesures de sécurité pourront être mises en place ; nous y reviendrons à la fin de cet article.

Cloud SQL multi-tenant

Cloud SQL prend en charge les Users et les Databases, ce qui nous permet d'allouer un User et une Database par environnement (à noter : nous utilisons une seule instance Cloud SQL et ne sommes facturés que pour celle-ci !).

Nous allons créer une instance Cloud SQL privée unique et la rattacher à notre Shared VPC via private service access.

Place à la pratique ! 👩‍🔧

Le repo developer-envs contient tout le code IaC et GitOps utile.

Infrastructure-as-Code (IaC)

Pas besoin de tout faire à la main. Nous allons utiliser Terraform comme outil d'Infrastructure-as-Code pour amorcer le tout. Montrez-moi le code !

Nous utiliserons le Terraform Kubernetes Provider pour créer un namespace K8s par environnement, ainsi que des ConfigMaps généraux contenant les paramètres liés à l'infra (par exemple, le nom du topic Pub/Sub, l'ID du projet GCP, etc.).

J'ai utilisé les Terraform Modules de Google dans le cadre du Cloud Foundation Toolkit tout au long de la solution, et je les ai trouvés très simples à prendre en main. Ils intègrent par ailleurs certaines bonnes pratiques de Google : ça vaut vraiment le détour.

Recourir à un outil d'infra-as-code (tel que Terraform) est essentiel à ce concept — l'objectif étant de réduire et d'automatiser les tâches répétitives sources d'erreurs humaines, et de garder toutes les configurations alignées au fil de la montée en charge. Un peu plus de travail aujourd'hui pour beaucoup moins demain.

GitOps

Nous utiliserons ensuite ArgoCD pour piloter et déployer nos différents environnements dans K8s. ArgoCD est un outil de livraison continue GitOps populaire qui, à mon sens, se prête bien à notre cas d'usage multi-tenant. Montrez-moi le code !

Nous définirons la plupart de nos ressources K8s sous forme de fichiers YAML, et nous utiliserons Kustomize pour personnaliser notre configuration.

Kustomize est un outil de configuration qui permet de définir une configuration de base et de superposer plusieurs overlays par-dessus, le tout partageant la configuration de base (une sorte d'héritage du pauvre). Idéal lorsque vous avez plusieurs environnements et que vous voulez qu'ils partagent tous une configuration commune.

Heureusement pour nous, notre solution de CD, ArgoCD, prend en charge Kustomize en tant qu'intégration.

Je trouve Kustomize simple et facile à utiliser, mais vous pouvez bien entendu opter pour un autre outil (comme Helm).

Exemples de microservices

Nous allons déployer deux microservices assez simples et minimalistes écrits en Go.

Le microservice env-producer publiera périodiquement des événements de paiement sur un topic Pub/Sub toutes les 10 secondes.

Le microservice env-consumer consommera les messages d'événements de paiement depuis Pub/Sub et persistera ces événements dans une table PostgreSQL.

L'élément clé concernant ces services, c'est que notre configuration multi-environnement leur reste transparente, puisque nous exposons les détails de l'environnement via des variables d'environnement. Séparer la configuration du code est une pratique clé du Twelve-Factor bonne à connaître.

En somme, ces microservices s'exécuteront séparément dans chaque environnement, en s'intégrant uniquement aux ressources propres à cet environnement.

Mise en route 🏃🏻‍♂️

Pour démarrer, clonez le repo d'exemple et suivez les instructions du README.md.

La console ArgoCD devrait alors ressembler à ceci.

C'est l'endroit où vous pouvez suivre tous vos environnements depuis un seul dashboard. Vous voudrez sans doute y ajouter aussi vos autres environnements (comme dev et prod), éventuellement dans un autre projet ArgoCD.

Notez la présence d'une application appelée argocd-config, chargée de synchroniser elle-même la configuration et les fichiers d'installation d'ArgoCD, ainsi que 2 applications supplémentaires — une par développeur.

Comment déployer des modifications dans votre environnement

Vous avez modifié l'un des services et souhaitez déployer ce changement dans votre environnement. Quelles sont vos options ?

Option 1 : créer une image personnalisée

Vous pouvez modifier le code source, puis créer une nouvelle image de conteneur. Une rapide modification du tag d'image dans votre application sur ArgoCD permettra ensuite de déployer la nouvelle image en un clin d'œil.

Informations de l'application dans ArgoCD où un développeur peut modifier un tag d'image et cliquer sur Save.

Cela peut se faire manuellement ou automatiquement via une pipeline CI ou des scripts personnalisés. (ArgoCD dispose également d'une CLI pour automatiser tout cela.)

Option 2 : l'exécuter en local

Attendez… Quoi ? N'est-ce pas l'inverse de ce que nous cherchons à faire ?

Place à Telepresence. Telepresence est l'un des outils les plus chouettes que j'aie découverts ces derniers temps. Je l'ai utilisé à de nombreuses reprises, et il a clairement boosté ma productivité de développeur.

Difficile de résumer son fonctionnement en une phrase, mais je vais essayer. Voici une description tirée de leur site :

Telepresence remplace votre pod habituel exécuté dans le cluster Kubernetes par un proxy réseau bidirectionnel. Ce pod relaie les données de votre environnement Kubernetes (par exemple, les connexions TCP, les variables d'environnement, les volumes) vers le processus local. Le réseau du processus local est redirigé de manière transparente afin que les appels DNS et les connexions TCP soient acheminés via le proxy vers le cluster Kubernetes distant.

En termes plus simples : il vous permet d'exécuter votre service en local, sur votre machine, tout en relayant les connexions entrantes et sortantes, les variables d'environnement et les volumes vers le cluster K8s. Plutôt sympa ! 👍

Imaginons que vous ayez modifié le microservice env-consumer et que vous vouliez tester votre changement. Vous lancez :

Et en quelques secondes, c'est déployé et exécuté avec votre nouvelle modification.

Concrètement, il remplace le pod de votre service par un pod proxy, puis exécute votre service en local en dialoguant avec ce pod proxy.

Le plus génial ici, c'est que vous exécutez une application locale, tout en étant réellement connecté à PubSub et à Cloud SQL (PostgreSQL) à distance !

Et tout cela sans modifier le code de l'application ni configurer de certificats ou de clés secrètes. Le même code dans l'environnement personnel qu'en production !

Quand j'ai terminé, je tape Ctrl+C et l'image revient à son état initial. Que demander de plus ! 🤩

Une démo de l'exécution de notre service d'exemple avec Telepresence.

Imaginez maintenant que vous corrigez un bug, que vous lancez Telepresence, que vous attendez quelques secondes, et que vous découvrez que vous avez fait planter le service. Eh oui… vous corrigez à nouveau. La boucle de feedback est plutôt rapide ! 😁

Notez que je n'ai construit aucune image Docker ici. Je compile le code source modifié et j'exécute le binaire en local. Vous pouvez aussi lui faire construire l'image Docker et la remplacer à la place.

Environnements personnels et onboarding

Ezekiel vient de rejoindre l'équipe en tant que développeur ! Bienvenue ! Il a reçu son ordinateur portable et quelques goodies. Youpi ! 🥳

Dans le cadre de son onboarding, on vous demande de préparer un environnement personnel pour Ezekiel afin qu'il puisse explorer l'application, l'infrastructure, et éventuellement faire de petites modifications pour en mesurer l'impact.

Voici comment procéder :

  1. Modifiez le fichier tf/personal.tfvars et ajoutez Ezekiel à la liste des tenants :

2. Appliquez la modification en exécutant terraform apply -f personal.tfvars

3. Ajoutez une application ArgoCD pour l'environnement d'Ezekiel en insérant le snippet suivant dans argo/apps/applications.yaml, puis commitez et poussez la modification.

Et voilà ! Comme ArgoCD est synchronisé pour suivre le dossier apps, il détectera automatiquement l'ajout de ezekiel-env et préparera l'environnement. Ezekiel sera ravi, j'en suis sûr.

Environnements personnels et offboarding

Oh non ! David quitte l'équipe pour explorer d'autres horizons !

Dommage, il va nous manquer. ⭐️ 😩

Mais bon, c'est l'occasion de voir à quel point il est facile de nettoyer son environnement personnel. 😌

Rendez-vous simplement dans argo/apps/applications.yaml, supprimez la définition de l'application david-env, commitez et poussez. Comme ArgoCD est synchronisé pour suivre le dossier apps, il détectera automatiquement la suppression de david-env et supprimera l'environnement.

Ensuite, supprimez l'infra de l'environnement en retirant david de la liste des tenants dans tf/personal.tfvars, puis exécutez terraform apply -f personal.tfvars.

Et voilà ! Aucune trace de David 💀

👣 Étapes suivantes

Si vous souhaitez adapter cela à votre organisation, n'hésitez pas. Vous devrez toutefois prendre en compte d'autres aspects, parmi lesquels :

Ce n'est qu'un POC

Comme indiqué, il s'agit d'un POC conçu à des fins d'exemple et de démarrage. Certaines parties de l'implémentation ont été simplifiées par souci de concision. Ne considérez pas cette implémentation comme une référence de bonnes pratiques, et n'hésitez pas à l'adapter à vos besoins et préférences.

Sécurité

Comme évoqué dans le chapitre précédent, la sécurité peut être un sujet de préoccupation avec cette solution. Plusieurs approches permettent d'améliorer la sécurité et l'isolation à partir de cette solution (par exemple, RBAC, Network Policies, Resource Quotas, Pod anti-affinity. Consultez cette page pour en savoir plus).

Multi-tenancy

Les exemples de multi-tenancy donnés ici concernent des services cloud comme GKE, Pub/Sub et Cloud SQL ; vous pouvez toutefois adapter ces concepts à d'autres services cloud.

Projet GCP par développeur

La portée actuelle du projet GCP par développeur est assez réduite. Elle constitue une base pour étendre et enrichir ce périmètre. Vous pouvez par exemple configurer le routage des logs et métriques propres à un namespace pour qu'ils soient envoyés vers un projet GCP de développeur dédié. Autre exemple : le projet GCP du développeur peut servir à lancer des ressources personnalisées hors de la mainline du projet, afin de vérifier que tout fonctionne comme prévu. Le projet GCP par développeur n'est pas une exigence mais plutôt une piste à explorer ; vous pouvez donc l'omettre si vous le souhaitez.

Shared VPC

Nous utilisons un Shared VPC, qui permet à vos différents projets personnels GCP de partager le même réseau VPC. Cela implique certains prérequis IAM à prendre en compte. Par exemple, l'utilisateur IAM de votre développeur doit disposer du rôle compute.networkUser dans le projet Host pour pouvoir créer des ressources dans le Shared VPC.

Solutions alternatives

Les alternatives suivantes visent à apporter une réponse au problème. Certaines sont payantes. Il semble qu'aucune ne propose de solution full-stack permettant d'aligner l'infrastructure sur la configuration de déploiement comme dans notre POC (à ma connaissance). Elles ciblent principalement la partie Kubernetes. Chacune a ses avantages et ses inconvénients selon votre contexte ; à prendre en compte donc.

Voilà ! J'espère que cela vous a plu 🙂

Chez DoiT International, nos Architects et Engineers cherchent en permanence à rapprocher l'infrastructure et le développement logiciel, persuadés que ces deux mondes partagent un objectif commun : la productivité et la fiabilité.

Merci de votre lecture ! Pour rester en contact, suivez-nous sur le DoiT Engineering Blog, le DoiT Linkedin Channel, et le DoiT Twitter Channel. Pour découvrir nos opportunités de carrière, rendez-vous sur https://careers.doit-intl.com.