# liens utiles
Le mot de passe, c'est toujours **p4tate** et le user **admin**.
+ https://compassionate-lamport.100do.se/
+ https://consul-compassionate-lamport.100do.se/
+ https://nomad-compassionate-lamport.100do.se/
+ https://traefik.compassionate-lamport.100do.se/
+ https://prometheus.compassionate-lamport.100do.se/
+ https://grafana.compassionate-lamport.100do.se/
+ https://jaeger.compassionate-lamport.100do.se/
# Intro
Le but de ce projet était de développer une infrastructure scalable, robuste et observable (monitoring). Nous devons mettre à disposition une application web permettant à des utilisateurs de charger des images et de pouvoir les récupérer en différentes tailles proposées. Cela, avec différentes ressources mises à disposition par notre fournisseur *Cloud*.
Le rapport se divise en trois parties :
1) [**Description de l'infrastructure**](#Description-de-l’infrastructure)
2) [**Difficultés rencontrées**](#Difficultés-rencontrées)
3) [**Question/Réponse**](#Question-réponse)
# Description de l'infrastructure
Nous disposons de deux VMs qui sont des clients des serveurs [Consul](https://consul-compassionate-lamport.100do.se/) et [Nomad](https://nomad-compassionate-lamport.100do.se/). Elles hébèrgent les différents services répartits par *Nomad*. Nous disposons d'une **adresse IP flottante** que nous mettons à disposition des deux VMs à travers le service [keepalived](https://keepalived.readthedocs.io/en/latest/introduction.html).
Nous avons implémenté une architecture classique :
- Répartiteur de charge : Traefik
- Frontend : Site web (scalable horizontalement)
- Backend : Application python/flask (scalable horizontalement)
- File d'attente de messages : RabbitMQ
- Workers : Application python/celery (scalable horizontalement)
- Stockage S3 : Minio
- Monitoring : Prometheus/Grafana, Jaeger
## Représentation des différents services et de leurs interactions

## Exemple de répartition des différents services sur les VM (sans les services de monitoring)

## Répartiteur de charge
Nous avons choisi d'utiliser le répartiteur de charge **Traefik**. Car il offre une bonne intégration avec le catalogue de service Consul en permettant de découvrir automatiquement de nouveaux services avec l'utilisation de tags. Il permet aussi l'utilisation de *middlewares*, par exemple, nous l'utilisons pour ajouter une phase d'authentification pour accéder au [*dashboard*](https://traefik.compassionate-lamport.100do.se/) de Traefik. Traefik nous permet aussi d'exporter des metrics vers [Prometheus](https://prometheus.compassionate-lamport.100do.se/) et des traces vers [Jaeger](https://jaeger.compassionate-lamport.100do.se/) assez simplement.
## Frontend
Le frontend, sous forme d'**interface web**, permet aux utilisateurs de charger des images et de les récupérer dans différentes tailles. L'interface web est disponible à l'adresse : https://compassionate-lamport.100do.se/
Le frontend et scalable horizontalement. Il se situe derrière un répartiteur de charge Traefik capable de découvrir les instances des frontends grâce à Consul.
## Backend
Le backend remplit deux tâches principales :
- sauvegarder les images téléversées
- servir les images hébergées
Il prend la forme d'une **API web** qui est accessible sans passer par le frontend. Il est écrit en python flask et a été modifié pour remonter des traces OpenTelemetry à Jaeger. Il est scalable horizontalement. Traefik répartit automatiquement la charge entre les différentes instances du backend découvertes à l'aide de Consul.
## File de messages
Nous utilisons la file de messages **RabbitMQ** mise à disposition par le fournisseur Cloud. La file de messages est utilisée par les Backends pour distribuer le travail aux workers.
## Worker
Un worker est une **application python celery** qui a pour rôle de redimensionner les images envoyées à l'API puis de les stocker dans le bucket S3.
## Stockage S3
Notre fournisseur Cloud nous donne accès à **une instance de Minio**, un service de stockage compatible S3. L'instance est partagée mais nous avons accès à plusieurs buckets.
## Monitoring
**Prometheus** récupère les métriques de Traefik et des nodes Nomad.
**Grafana** affiche les métriques de Prometheus.
**Jaeger** récupère des traces de Traefik et du Backend.
Ces applications ne disposent pas de stockage persistant ce qui est un promblème. Dans l'idée on devrait mettre en place un stockage distribué (comme ceph) pour sauvegarder les données de monitoring.
Pour se simplifier la vie on aurait pu utiliser une solution comme Datadog mais dans un but pédagogique nous avons choisi de tout auto-héberger.
# Difficultés rencontrées
Notre plus grand dificulté a été les caprices de gitlab. En effet ,le gitlab de l'université a fait des caprices. Le push d'image était impossible pendant un moment puis la ci ne pouvait pas push d'image sur la registry du dépôt.
Nous avons donc improvisé et décidé d'utiliser la **registry d'un répertoire gitlab .com** et comme on avait pas envie de mettre notre carte de crédit sur gitlab pour vérifier notre identité on a gardé la **CI sur le git de l'université**. C'est pas très propre mais on a fait comme on a pu.
# Question réponse
## Comment se passerait le déploiement d’une nouvelle version de l’application ?
Quand on fait un commit sur le git, la **CI** s'occupe de build l'image docker avec **kaniko** et les jobs nomad seront automatiquement mis à jour et deployés avec **levant**.
(Voir stages *build* et *deploy* du fichier gitlab-ci.yml)
## Quelle est la procédure pour effectuer une maintenance planifiée d’un nœud ?
Un noeud peut tomber ou être indisponible à n'importe quel moment. Si l'adresse IP flottante lui était attribuée, elle sera attribuée au prochain noeud de priorité la plus grande dans *keepalived*. On peut donc faire la maintenance d'un noeud sans coupure de service. Lorsque le noeud sera de nouveau opérationnel et qu'il aura lancé le service *keepalived*, il récuperera l'adresse IP flottante si son niveau de priorité est toujours le plus haut.
Le seul problème est la quantité de ressources disponible sur un nœud. Il faudra peut être réduire le nombre de task dans certains jobs (web, api, worker) ou désactiver des jobs dédiés au monitoring comme prometheus, grafana ou jaeger.
## Les étapes pour ajouter ou supprimer un nœud de l'infrastructure
Ajouter un noeud :
1) Installer les serives Consul, Nomad, Keepalived
2) Appliquer les fichiers de configuration Consul, Nomad, Keepalived qui se trouvent dans le dossier [client-config](https://git.unistra.fr/avogel/projet-cloud-virt/-/tree/main/) du repertoire git, puis lancer ces services
3) Ajuster manuellement le nombre de tasks par job
4) Ajuster manuellement le nombre de tasks par job Traefik pour coller au nombre de client nomad
Supprimer un noeud :
1) Ajuster manuellement le nombre de tasks par job
Remarque : L'application ne fait pas de *"scalabilitée"* horizontale automatiquement, il faudra donc ajuster manuellement le nombre de tasks par job.
## Impact de différents scénarios de panne sur l'infrastructure ?
### Plantage d'une VM
L'**adresse IP flottante** est attribuée par défaut à l'une des deux VMs (désignée "Master"). Si le master tombe en panne, l'autre VM sera prévenue par keepalived (protocole [VRRP](https://en.wikipedia.org/wiki/Virtual_Router_Redundancy_Protocol)) et s'attribuera l'adresse IP flottante. Nomade remontera les services sur l'autre noeud.
### Plantage d'un Frontend, Backend ou Worker
Nomad le redémarrera et traefik répartira la charge sur les autres instances du service.