Portfolio de Dasek Joiakim - Semestre 4
Semestre 4
B2

B2

⚠️

Je tiens à informer que durant ce semestre, je considère avoir atteint le niveau hautement spécialisé de la compétence B2. J'ai travaillé sur plusieurs projets qui m'ont permis de mettre en pratique ces différents concepts. J'ai également effectué des lectures individuelles et des labs qui m'ont permis de renforcer mes compétences dans ces domaines. Je suis convaincu que j'ai acquis une expérience significative, c'est d'ailleurs un point qui a été relevé lors de l'intervention d'un expert du domaine lors de la dernière session de formation sur DevSecOps pour le projet Koloka. Vous pouvez explorer les différentes preuves dans cette section ou encore dans mon notion (opens in a new tab).

Maîtriser la programmation concurrente. Maîtriser la programmation distribuée. Connaitre les concepts de développement logiciel DevSecOps. Être capable de concevoir et d’exploiter des ressources, services et fonctionnalités d’une infrastructure virtuelle (cloud,…).

Maîtriser la programmation concurrente

Projets

La programmation concurrente est un paradigme de programmation qui permet d'exécuter plusieurs tâches en parallèle. Cela permet d'optimiser les performances d'un programme en utilisant au mieux les ressources matérielles disponibles.

Koloka

Lors du projet Koloka, j'ai mis en place un système de notifications en temps réel pour informer les utilisateurs des nouveaux messages entre futurs colocataires. Pour cela, j'ai utilisé la bibliothèque WebSocket pour établir une connexion en temps réel entre le serveur et le client. J'ai par ailleurs optimisé les requêtes pour le backend qui sont envoyées en parallèle à la base de données pour réduire le temps de réponse et améliorer les performances de l'application.

Voici un exemple de code qui illustre cela :

Next.js Promise all

AKTS

Dans le projet AKTS, il fallait un moment donné envoyer un ensemble de requête vers un serveur pour enregistrer celles-ci. C'est une application mobile, sachant que les données sont envoyées en arrière-plan, il fallait donc que les requêtes soient envoyées en parallèle pour optimiser le temps de réponse mais aussi ne pas bloquer l'interface utilisateur. Il a fallu comprendre le principe des threads et comment les utiliser pour envoyer les requêtes en parallèle.

/*
* This function is executed in the isolate to push the data to the server
* @param params: The parameters of the function of DeviceLogger
*/
void isolatePushDataFunction(Map<String, dynamic> params) async {
  // Get the parameters
  List<String> deviceLoggersIds = params['deviceLoggersIds'];
  SendPort spPushFeedbackUI = params['sendPort'];
  String username = params['username'];
  String password = params['password'];
  String token = params['token'];
 
  // Create the queue
  var pushDataTaskQueue = <Function>[];
 
  // Add the push data task to the queue
  for (int i = 0; i < deviceLoggersIds.length; i++) {
    pushDataTaskQueue.add(() => pushDataTask(
        deviceLoggersIds[i], spPushFeedbackUI, username, password, token));
  }
 
  // Execute the queue of tasks in the event loop model
  while (pushDataTaskQueue.isNotEmpty) {
    var pushDataTask = pushDataTaskQueue.removeAt(0);
 
    // Run the task in the queue
    await Future.delayed(const Duration(seconds: 2), () async {
      await pushDataTask();
    });
  }
 
  if (kDebugMode) {
    print("All tasks are completed");
  }
 
  spPushFeedbackUI.send({
    'messageCode': 'ALLTASKCOMPLETE',
  });
}
 
/*
* This function pushes the data to the server (task)
* @param deviceLoggerdentifier: The identifier of the deviceLogger
* @param spPushFeedbackUI: The send port to send messages to the UI
*/
void pushDataTask(String deviceLoggerdentifier, SendPort spPushFeedbackUI,
    String username, String password, String token) async {
  int result = 0;
 
  // Execute code (Terence) to push to MQTT
  result = await pushData(deviceLoggerdentifier, username, password, token);
 
  if (kDebugMode) {
    print("Result de datatask : $result");
  }
 
  // Send a message to update the UI
  spPushFeedbackUI.send({
    'messageCode': 'TASKCOMPLETE',
    'deviceLoggerId': deviceLoggerdentifier,
    'result': result,
  });
}

Maîtriser la programmation distribuée

La programmation distribuée est un paradigme de programmation qui permet de faire communiquer des programmes qui s'exécutent sur des machines différentes. Cela permet de répartir la charge de travail sur plusieurs machines et d'optimiser les performances d'un programme.

Projets / Labs

Emerging technologies

Dans le premier topic du projet Emerging technologies :

En travaillant sur ce projet, j'ai démontré ma capacité à maîtriser la programmation distribuée grâce à une série d'activités et de compétences clés :

Situation actuelle

Une entreprise possédant un système de load balancing localisé souhaite évoluer vers une architecture de microservices et tirer parti des capacités d'Istio pour analyser les métriques et optimiser l'utilisation des ressources. Cette transition vers une architecture plus moderne et distribuée m'a permis de mettre en œuvre des solutions complexes et avancées, prouvant ainsi ma maîtrise de la programmation distribuée.

Objectif

Mon objectif principal était de créer un environnement de test permettant de :

  • Tester la nouvelle fonctionnalité d'Istio (Locality Load Balancing) en version bêta.
  • Évaluer les capacités d'analyse des métriques d'Istio.
Fonctionnement

Pour atteindre cet objectif, j'ai conçu et mis en place une infrastructure où les requêtes sont redirigées en fonction de leur origine géographique simulée. Voici un résumé du processus de la requête :

  1. Le proxy Caddy ajoute un tag 'x-region' à la requête.
  2. La requête passe par l'Ingress Gateway d'Istio.
  3. Elle est redirigée vers le Hono Gateway.
  4. La VirtualService décide vers quel service (America ou Europe) la requête sera envoyée.
  5. Le service transmet la requête aux pods appropriés.

Cette configuration démontre ma capacité à orchestrer et à gérer des services distribués dans un environnement de microservices, utilisant les capacités avancées d'Istio pour le routage basé sur les régions.

Technologies utilisées

Pour mettre en œuvre cette architecture distribuée, j'ai utilisé plusieurs technologies de pointe :

  • Terraform : pour définir et provisionner des ressources d'infrastructure, garantissant une infrastructure reproductible et évolutive.
  • Kubernetes : pour l'orchestration des conteneurs, permettant de gérer efficacement les services déployés.
  • hono : un framework web rapide pour créer des API, essentiel pour le développement des microservices.
  • Istio : une plateforme de service mesh pour la gestion, la sécurisation et la surveillance des microservices, offrant des fonctionnalités cruciales pour la programmation distribuée.

Koloka

Dans le projet Koloka, j'ai mis en place toute la migration de AWS à Infomaniak Jelastic, un service de cloud computing. J'ai aussi mis en place toute l'infrastructure avec Kubernetes, un orchestrateur de conteneurs, pour déployer les services de l'application. J'ai créer toute la pipeline CI/CD pour automatiser le déploiement des services et des applications. J'ai aussi mis en place un système de monitoring pour surveiller les performances de l'application. J'ai implémenter les principes de continuity business et disaster recovery pour garantir la disponibilité du service.

Voici les images qui illustre mon travail :

Koloka system design

Koloka CI/CD

Koloka CI/CD

Kafka Lab

Lors de la lecture indviduelle qui était axée sur la mise en place d'un serveur Kafka distribué, j'ai pu mettre en place Kafka qui consomme des données de Telegram et qui peut faire du traitement sur celles-ci, il les stoquent et c'est un système qui assure l'intégrité des données. J'ai pu comprendre comment fonctionne un serveur Kafka distribué et comment il peut être utilisé pour stocker des données en temps réel.

Voici un exemple de l'architecture du serveur Kafka distribué :

Kafka distributed

Redis Lab

Lors de la lecture individuelle sur la mise en place d'un serveur Redis. J'ai pu comprendre à quoi cela pourrait servir mais aussi quelles types de données il était possible de stocker. J'ai mis en place un serveur Redis distribué pour stocker des données en mémoire et les consommer. Il peut servir notamment de cache pour stocker des données fréquemment utilisées et réduire le temps de réponse de l'application. Je me suis intéressé de mon côté sur comment invalider aussi le cache qui est un élément important pour garantir la cohérence des données.

Voici un exemple de l'architecture du serveur Redis distribué :

Redis distributed

Connaitre les concepts de développement logiciel DevSecOps

DevSecOps est une approche de développement logiciel qui intègre la sécurité dès la phase de développement. Cela permet de réduire les risques de sécurité et de garantir la qualité du code.

Ce semestre, j'ai eu l'occasion de travailler sur plusieurs projets qui m'ont permis de mettre en pratique les concepts de DevSecOps :

Projets

Koloka

Dans le projet Koloka, j'ai mis en place toute la pipeline CI/CD pour automatiser le déploiement des services et des applications. J'ai utilisé des outils comme GitHub Actions pour automatiser les tests et le déploiement des services. J'ai également mis en place des outils de sécurité comme SonarQube/Snyk pour analyser le code et détecter les vulnérabilités. J'ai implémenté et configuré Kubernetes sur Jelastic de Infomaniak pour déployer les services de l'application. J'ai aussi mis en place un système de monitoring pour surveiller les performances de l'application.

Je détaille ici les différentes étapes de la pipeline CI/CD : Images

Voici les détails de cette pipeline et en quoi elle est conforme aux principes de DevSecOps :

  1. Intégration continue (CI) et Livraison continue (CD)
  • CI : Les étapes commentées montrent l'intention d'intégrer des tests de linting, de dépendances et de tests unitaires, ce qui est crucial pour la qualité et la sécurité du code. Les étapes comme "Install Next.js dependencies" et "Run Strapi lint test" sont des pratiques de CI courantes.
  • CD : Les étapes pour vérifier les changements, créer des fichiers .env, construire et déployer des images Docker, et déployer sur Kubernetes et Vercel montrent une mise en place de livraison continue. Cela permet de déployer fréquemment des petites modifications, réduisant les risques de grandes mises à jour.
  1. Sécurité intégrée (Security)
  • Gestion des secrets : Utilisation des secrets GitHub pour gérer les informations sensibles comme les clés d'API, les mots de passe de base de données, etc. Cela empêche l'exposition des secrets dans le code.
- name: Create .env file for Strapi
  run: |
    echo "ADMIN_JWT_SECRET=${{ secrets.ADMIN_JWT_SECRET }}" >> strapi/.env
    echo "API_TOKEN_SALT=${{ secrets.API_TOKEN_SALT }}" >> strapi/.env
    ...
  • Vérification des modifications : L'étape "Check if Strapi Docker build is needed" utilise tj-actions/changed-files pour identifier les fichiers modifiés, garantissant que seules les parties pertinentes du projet sont reconstruites et déployées, réduisant ainsi la surface d'attaque.
- name: Check if Strapi Docker build is needed
  id: strapi-changes
  uses: tj-actions/changed-files@v44.5.1
  with:
    files: |
      strapi/**
      !strapi/build/**
      !strapi/.strapi/**
      ...
  1. Automatisation
  • Automatisation des tests et des déploiements : L'automatisation des étapes de test et de déploiement garantit que les tests de sécurité et les déploiements sont exécutés de manière cohérente et sans intervention humaine, réduisant les erreurs humaines et améliorant la sécurité.
- name: Build Strapi Docker image
  if: steps.strapi-changes.outputs.any_changed == 'true'
  run: |
    cd strapi
    docker build -t ghcr.io/${{ env.OWNER_LC }}/strapi:latest -f ./Dockerfile.dev .
  1. Observabilité et Monitoring
  • Mise en place de Kubernetes : Le déploiement sur Kubernetes (K8s) avec Helm pour la gestion des configurations et des versions des déploiements permet une meilleure observabilité et monitoring des applications déployées.
- name: Deploy helm chart to k8s
  uses: wahyd4/kubectl-helm-action@master
  env:
    KUBE_CONFIG_DATA: ${{ secrets.KUBE_CONFIG_DATA }}
  with:
    args: |
      helm repo add cnpg https://cloudnative-pg.github.io/charts
      helm upgrade --install cnpg ...
  1. Responsabilisation et Collaboration
  • Pipeline GitHub Actions : L'utilisation de GitHub Actions permet une meilleure collaboration entre les équipes de développement, de sécurité et d'opérations. Chaque modification de code déclenche la pipeline, assurant ainsi que les équipes sont informées des changements et des déploiements en cours.
  1. Gestion des risques et des vulnérabilités
  • IAST (SAST/DAST) : L'utilisation de SonarQube et Snyk pour l'analyse statique et dynamique du code permet de détecter les vulnérabilités et les erreurs de sécurité avant le déploiement, réduisant ainsi les risques de sécurité.

Koloka CI/CD

En conclusion, cette pipeline GitHub Actions est conforme aux principes DevSecOps en intégrant la sécurité dès le début du processus de développement, en automatisant les tests et les déploiements, en gérant efficacement les secrets, et en utilisant des outils de CI/CD modernes pour garantir des déploiements sécurisés et fiables.

Interview

Pour l'interview j'ai mis en place une pipeline de build de l'image docker pour le modèle de transcription de la voix. J'ai utilisé GitHub Actions pour automatiser le build de l'image docker et le push sur le registre docker.

Voici un exemple de la pipeline de build :

Interview CI/CD

Interview CI/CD

J'ai déployé l'application sur le PaaS Vercel et le modèle de transcription de la voix sur le PaaS Railway. J'ai utilisé des stratégies pour que le modèle soit en mode hybernation pour réduire les coûts.

Interview CI/CD

Session de formation

J'ai au cours des sessions de formations partie 1 et partie 2 pu apprendre les concepts de DevSecOps. J'ai pu comprendre comment intégrer la sécurité dès le début du développement, comment automatiser les tests et les déploiements, comment gérer les secrets et comment utiliser des outils de CI/CD modernes pour garantir des déploiements sécurisés et fiables. J'ai notamment posé des questions sur les bonnes pratiques de DevSecOps et comment les mettre en place dans un projet.

J'ai aussi montré comment j'ai mis en place ces concepts dans les différents projets sur lesquels j'ai travaillé ! C'éatit très constructif et j'ai pu apprendre beaucoup de choses.

Être capable de concevoir et d’exploiter des ressources, services et fonctionnalités d’une infrastructure virtuelle (cloud, ...)

Les infrastructures virtuelles permettent de déployer des ressources, des services et des fonctionnalités sur des machines virtuelles. Cela permet de réduire les coûts d'infrastructure et d'optimiser les performances d'un programme.

Durant les quatres semestres j'ai utilisé plusieurs IaaS et PaaS différents comme :

AWS (RDS, S3, EC2, EKS, CloudFront, Route 53, ...)

AWS - S3

Vercel (CDN, Firewall, ...)

Vercel - Dashboard

Railway (Containers, Redis, Postgres, ...)

Railway - Dashboard

Infomaniak Jelastic (Cloud computing, Kubernetes, CI/CD, Monitoring, ...)

Railway - Dashboard

Mes tâches liées à cette compétence