Commit f61a51df authored by marmous's avatar marmous

Gramar and syntax checks

parent e3230464
J’ai commencé ce projet en novembre 2017. J’ai terminé la conteneurisation de l’application Efficient et des deux services Agent et Autotask fin juillet 2018. Il s’est étalé dans la durée pour plusieurs raisons.
\par
Premièrement, je n’ai pas pu y dédier tout mon temps professionnel. Mes tâches sont variées et conséquentes. Leur priorité change sans cesse en fonction des circonstances. Deuxièmement, la jeunesse des conteneurs Windows implique des bugs, des fonctionnalités manquantes et une documentation légère. Cela m’a fait perdre énormément de temps notamment pour différencier une mauvaise compréhension et un bug ou une fonctionnalité manquante.
Premièrement, je n’ai pas pu dédier tout mon temps professionnel à ce projet. Mes tâches sont variées et conséquentes. Leur priorité change sans cesse en fonction des circonstances. Deuxièmement, la jeunesse des conteneurs Windows implique des bugs, des fonctionnalités manquantes et une documentation légère. Cela m’a fait perdre énormément de temps notamment pour différencier une mauvaise compréhension et un bug ou une fonctionnalité manquante.
Troisièmement, il y a mille et une manières d’utiliser Docker et de conteneuriser une application. Trouver la meilleure façon pour obtenir une image facilement utilisable et maintenable ou encore la meilleure façon d’orchestrer une application conteneurisée sous Windows est un challenge qui demande du temps et de l’analyse.
Enfin, le refus de la direction de changer d’hébergeur alors que cela nous faisait réaliser des économies aurait dû me faire comprendre que l’avenir de cette plateforme était compromis.
\par
......
......@@ -4,7 +4,7 @@ Le but de ce projet est d’utiliser la simplicité et la souplesse d’utilisat
\subsection{Les bénéfices de l’orchestration de conteneurs}
La conteneurisation de notre application et son orchestration permettrait de réduire le temps passé et les erreurs liés au déploiement de l’application.
La conteneurisation de notre suite logicielle et son orchestration permettrait de réduire le temps passé et les erreurs liés au déploiement de l’application.
\par
L’installation d’une nouvelle instance de l’application serait simplifiée et réduite à une heure maximum, au lieu de quatre heures minimum actuellement. Cela consisterait à quelques étapes : création d’un utilisateur SQL serveur, restauration de la base de données, création des fichiers yml (basés sur des modèles) pour le déploiement de l’application, création des fichiers de configuration des applications (basés sur des modèles également), déploiement de l’application par une commande sur l’orchestrateur de conteneurs et configuration du DNS et du proxy inverse pour atteindre le serveur d’application depuis l’extérieur.
\par
......@@ -16,11 +16,11 @@ Il serait possible de lancer plusieurs instances de notre application sur le mê
Comme dans toute solution il n’y a pas que des avantages. L’inconvénient principal ici concerne la formation des équipes. Les principes liés aux conteneurs, à l’orchestration et aux systèmes répartis sont totalement inconnus des membres de l’équipe. Il faut donc prévoir une formation complète, la documentation de l’architecture et les procédures correspondantes.
\par
Un autre inconvénient se rapporte à l’indisponibilité des nœuds du cluster pour maintenance. Que ce soit la mise à jour du moteur de conteneur, une mise à jour de sécurité ou une mise à niveau du système d’exploitation, tous les conteneurs s’exécutant sur le nœud devront être déplacés. Selon les orchestrateurs, cela peut être réalisé avec plus ou moins de facilité. Cette spécificité rejoint la formation des équipes et le besoin de compréhension du fonctionnement de l’orchestrateur pour éviter les erreurs. Ainsi que la création de procédures claires et détaillées.
Un autre inconvénient se rapporte à l’indisponibilité des nœuds du cluster pour maintenance. Que ce soit la mise à jour du moteur de conteneur, une mise à jour de sécurité ou une mise à niveau du système d’exploitation, tous les conteneurs s’exécutant sur le nœud devront être déplacés. Selon les orchestrateurs, cela peut être réalisé avec plus ou moins de facilité. Cette spécificité rejoint la formation des équipes et le besoin de compréhension du fonctionnement de l’orchestrateur pour éviter les erreurs, ainsi que la création de procédures claires et détaillées.
\subsection{Les coûts}
Cette plateforme d’hébergement induit des coûts de fonctionnement (dépenses liées au prestataire Saas) et de maintenance (main d’œuvre) défini dans le graphique \ref{fig:repartitioncoutbenefice}. Ils occupent 45 \% du chiffre d’affaires de cette plateforme. Le but est de les réduire au maximum tout en améliorant la qualité de service.
Cette plateforme d’hébergement induit des coûts de fonctionnement (dépenses liées au prestataire Saas) et de maintenance (main d’œuvre) définis dans le graphique \ref{fig:repartitioncoutbenefice}. Ils occupent 45 \% du chiffre d’affaires de cette plateforme. Le but est de les réduire au maximum tout en améliorant la qualité de service.
\par
\begin{figure}[h!]
\centering
......
......@@ -4,7 +4,7 @@ Lors de l’analyse du projet, j’ai décidé de restreindre le choix des orche
\subsection{Architecture réseau}
Au niveau de l’orchestrateur, une instance Kronos Efficient déployée est identifiée par un port accessible depuis n’importe quel nœud du cluster. Il suffit de rediriger le port HTTPS (443) vers le port correspondant à l’instance Kronos Efficient concernée sur un nœud master du cluster. La faiblesse dans ce cas sera liée à la disponibilité du nœud sur lequel la redirection sera faite. C’est pourquoi j’ai choisi d’utiliser un proxy inverse conçu pour ce cas Traeffic. Il écoute directement l’API de l’orchestrateur pour connaitre les services disponibles. Il suffit de configurer les règles pour indiquer le nom de domaine et l’URL à rediriger vers quel service.
Au niveau de l’orchestrateur, une instance Kronos Efficient déployée est identifiée par un port accessible depuis n’importe quel nœud du cluster. Il suffit de rediriger le port HTTPS (443) vers le port correspondant à l’instance Kronos Efficient concernée sur un nœud master du cluster. La faiblesse dans ce cas sera liée à la disponibilité du nœud sur lequel la redirection sera faite. C’est pourquoi j’ai choisi d’utiliser un proxy inverse conçu pour ce cas Traefik. Il écoute directement l’API de l’orchestrateur pour connaitre les services disponibles. Sa configuration est simple. Elle consiste en l'ajout de règles dans la définition du service en lui-même pour indiquer le nom de domaine et l’URL à rediriger vers le service en question.
\begin{figure}[h!]
\includegraphics[width=\linewidth]{choixorchestrateur/images/orchestratordraftarch}
......@@ -14,14 +14,14 @@ Au niveau de l’orchestrateur, une instance Kronos Efficient déployée est ide
\subsection{Dimensionnement et tolérance aux pannes}
Au début du projet, notre infrastructure contienait onze serveurs applicatifs. Le dimensionnement d’une instance Kronos Efficient dépend du nombre d’utilisateurs, de salariés et des modules inclus dans la licence. En règle générale, au niveau d’une instance Efficient, IIS + Efficient consomme deux Go de RAM et utilise deux CPUs. Les ressources prisent par Autotask et Agent sont bien inférieures, respectivement 50 ko et 20 Mo. Ainsi, une instance Efficient requiert deux CPUs et deux Go et demi de RAM. Le détail est résumé dans le tableau \ref{table:ResumeRessources}.
Au début du projet, notre infrastructure contenait onze serveurs applicatifs. Le dimensionnement d’une instance Kronos Efficient dépend du nombre d’utilisateurs, de salariés et des modules inclus dans la licence. En règle générale, au niveau d’une instance Efficient, IIS + Efficient consomme deux Go de RAM et utilise deux CPUs. Les ressources prisent par Autotask et Agent sont bien inférieures, respectivement 50 ko et 20 Mo. Ainsi, une instance Efficient requiert deux CPUs et deux Go et demi de RAM. Le détail est résumé dans le tableau \ref{table:ResumeRessources}.
\begin{table}[ht]
\begin{center}
\begin{tabular}{ |m{13em}|m{6em}|m{6em}|m{6em}|m{6em}| }
\hline
% header
\thead{Application} & \thead{CPU} & \thead{RAM} & \thead{Espace de stockage} & \thead{Nombre d'instance} \\
\thead{Application} & \thead{CPU} & \thead{RAM} & \thead{Espace de stockage} & \thead{Nombre d'instances} \\
\hline
Kronos Efficient 5 & 2 & 2,5 Go & 100 Mo & 11 \\
\hline
......@@ -47,7 +47,7 @@ Au début du projet, notre infrastructure contienait onze serveurs applicatifs.
Pour déterminer le nombre de nœuds au sein du cluster et offrir une tolérance aux pannes correctes, il faut faire un compromis entre performance, tolérance aux pannes et coût. L’ajout de nœuds master à un cluster le rend plus tolérant aux pannes. Cependant, un nœud master supplémentaire réduit les performances d’écriture, car davantage de nœuds doivent accepter des propositions pour mettre à jour l’état du cluster. Cela signifie également une augmentation des communications réseau. L’ensemble des nœuds master est nommé quorum. Si le cluster perd le quorum, les nœuds worker fonctionnent toujours, mais ils ne peuvent plus accepter de nouvelles tâches. Cela signifie que les conteneurs continuent à exister et à fonctionner correctement, mais il n’est plus possible de les gérer de façon globale.
\par
Pour maintenir le quorum, une majorité de masters doivent être disponibles. Un nombre impair de nœuds master est recommandé, car avoir un nombre impair garantit qu’au cours d’une partition réseau, les chances que le quorum reste disponible pour traiter les demandes sont augmentées si le réseau est partitionné en deux ensembles. Le maintien du quorum n’est pas garanti s’il survient plus de deux partitions réseau.
Pour maintenir le quorum, une majorité de masters doivent être disponibles. Un nombre impair de nœuds master est recommandé. Car avoir un nombre impair garantit qu’au cours d’une partition réseau, les chances que le quorum reste disponible pour traiter les demandes sont augmentées si le réseau est partitionné en deux ensembles. Le maintien du quorum n’est pas garanti s’il survient plus de deux partitions réseau.
\par
En plus de maintenir un nombre impair de nœuds master, il faut tenir compte de la topologie du centre de données et en particulier où placer les nœuds master. Pour une tolérance de panne optimale, le quorum doit être distribué sur un minimum de trois zones de disponibilité pour prendre en charge les défaillances d’un centre de données du prestataire. S’il advient une défaillance dans l’une de ces zones, le quorum restera disponible pour traiter les demandes et rééquilibrer les charges de travail.
\par
......@@ -60,7 +60,7 @@ En plus de maintenir un nombre impair de nœuds master, il faut tenir compte de
\newpage
Dans le cas présent, je considère que la perte d’un nœud master doit permettre au quorum de fonctionner correctement. Suivant la recommandation de Docker (figure \ref{fig:swarmrecommandation}), le cluster sera composé de trois nœuds master. Chacun devrait être dans un centre de données différent de notre prestataire. Après vérification cette architecture est difficilement réalisable chez notre prestataire actuel. Il n’offre pas une communication rapide et sécurisée entre ses centres de données. La seule option qu’il propose est de nous garantir qu’une VM ne sera pas sur le même hyperviseur physique qu’une autre par un système d’exclusion.
Dans le cas présent, je considère que la perte d’un nœud master doit permettre au quorum de fonctionner correctement. Suivant la recommandation de Docker (figure \ref{fig:swarmrecommandation}), le cluster sera composé de trois nœuds master. Chacun devrait être dans un centre de données différent de notre prestataire. Après vérification, cette architecture est difficilement réalisable chez notre prestataire actuel. Il n’offre pas une communication rapide et sécurisée entre ses centres de données. La seule option qu’il propose est de nous garantir qu’une VM ne sera pas sur le même hyperviseur physique qu’une autre par un système d’exclusion.
\par
Par défaut, les nœuds master agissent également en tant que nœuds worker. Le planificateur peut donc assigner des tâches à un nœud master. Pour les clusters de petite taille et non critiques, cela présente un risque relativement faible tant que les services sont planifiés en utilisant des contraintes de ressources pour le processeur et la mémoire. Toutefois, comme les nœuds master utilisent l’algorithme de consensus Raft pour répliquer les données de manière cohérente, ils sont sensibles à la pénurie de ressources. Pour des raisons de coûts, les nœuds master accepteront des tâches.
\par
......@@ -100,7 +100,7 @@ La configuration actuelle demande au total soixante Go de RAM et un Go et neuf c
\begin{tabular}{ |m{6em}|m{6em}|m{6em}|m{6em}| }
\hline
% header
\thead{Nombre de noeuds} & \thead{CPU} & \thead{RAM} & \thead{Espace de stockage} \\
\thead{Nombre de nœuds} & \thead{CPU} & \thead{RAM} & \thead{Espace de stockage} \\
\hline
4 & 8 & 20,5 Go & 69723 Mo \\
\hline
......
......@@ -135,7 +135,7 @@ OVH est un prestataire français. Il dispose de deux centres de données en Fran
\subsection{Étude de déploiement sur Interoute}
Interoute est notre prestataire actuel. Il ne nous convient plus. Nous avons été face à de multiples limitations techniques. Cela nous a fait perdre en crédibilité face à nos clients et perdre énormément de temps. L’infrastructure est déjà hébergée chez eux. Cela évite donc les frais de migration. Malheureusement, leur offre n’inclut que l’orchestrateur de conteneurs Rancher qui ne gère pas les conteneurs Windows. Comme je l’ai expliqué au début de ce chapitre, le déploiement de Docker Swarm est compromis, car il n’est pas possible de déployer des machines virtuelles sous Windows Server 2019.
Interoute est notre prestataire actuel. Il ne nous convient plus. Nous avons été face à de multiples limitations techniques. Cela nous a fait perdre en crédibilité face à nos clients et perdre énormément de temps. Toutefois, l’infrastructure est déjà existante. Cela évite donc les frais de migration. Malheureusement, leur offre n’inclut que l’orchestrateur de conteneurs Rancher qui ne gère pas les conteneurs Windows. Comme je l’ai expliqué au début de ce chapitre, le déploiement de Docker Swarm est compromis, car il n’est pas possible de déployer des machines virtuelles sous Windows Server 2019.
\subsection{Choix final}
......
......@@ -2,4 +2,4 @@
Mon équipe est très réduite. La gestion de la plateforme d’hébergement doit nous prendre le moins de temps possible pour nous concentrer sur la qualité du support pour nos clients. C’est pourquoi les deux critères les plus importants sont le temps et le coût. La solution choisie doit permettre à l’équipe d’économiser du temps de maintenance sans une courbe d’apprentissage élevée. J’ai donc décidé de déployer Kubernetes chez Microsoft Azure.
\par
J’ai présenté le projet à la direction de l’unité de business Kronos Efficient. Elle a été très enthousiaste, notamment par rapport aux gains. Elle a ensuite porté le projet auprès de la direction du groupe. Le projet a été entravé, le groupe a refusé de migrer vers un autre prestataire malgré nos arguments financier et technique et un plan de migration détaillé et chiffré. Nous avons tout de même décidé de migrer l’infrastructure actuelle vers Docker Swarm. Six mois après cette décision, Mirantis a racheté Docker Enterprise \cite{MirantisAcqDockerEEI} et a annoncé la fin du développement de Docker Swarm deux ans plus tard \cite{MirantisAcqDockerEEII}. Finalement, en février 2020, Mirantis revient sur sa décision comprenant que Docker Swarm n’est pas un concurrent à Kubernetes, mais une alternative viable \cite{MirantisAcqDockerEEIII}.
\ No newline at end of file
J’ai présenté le projet à la direction de l’unité de business Kronos Efficient. Elle a été très enthousiaste, notamment par rapport aux gains. Elle a ensuite porté le projet auprès de la direction du groupe. Le projet a été entravé, le groupe a refusé de migrer vers un autre prestataire malgré nos arguments financiers et techniques et un plan de migration détaillé et chiffré. Nous avons tout de même décidé de migrer l’infrastructure actuelle vers Docker Swarm. Six mois après cette décision, Mirantis a racheté Docker Enterprise \cite{MirantisAcqDockerEEI} et a annoncé la fin du développement de Docker Swarm deux ans plus tard \cite{MirantisAcqDockerEEII}. Finalement, en février 2020, Mirantis revient sur sa décision comprenant que Docker Swarm n’est pas un concurrent à Kubernetes, mais une alternative viable \cite{MirantisAcqDockerEEIII}.
\ No newline at end of file
......@@ -35,11 +35,11 @@ Enfin, j’ai une contrainte assez forte concernant le code de l’application.
La conteneurisation de Kronos Efficient s’est faite en trois étapes : création d’une image fonctionnelle, standardisation et optimisation.
\par
Ma première idée de se baser sur l’image officielle ASP.Net a été un échec, car elle repose sur celle d’IIS. Notre application est incompatible avec le fonctionnement de cette image. L’équipe IIS a créé un exécutable ServiceMonitor.exe qui lance un service en tant que point d’entrée du conteneur. Il vérifie que le service w3svc, dans le cas d’IIS, est bien démarré. Si le service est redémarré alors le conteneur se ferme. À la fin du processus de configuration d’Efficient, nous avons besoin de redémarrer IIS pour que la partie ASP prenne en compte les nouveaux paramètres, entre autres la chaine de connexion à la base de données. Pour pallier ce problème, je me suis basé directement sur l’image officielle Windows Server Core et configuré l’image pour installer et configurer IIS et Efficient. L’image est de fait plus lourde.
Ma première idée de se baser sur l’image officielle ASP.Net a été un échec, car elle repose sur celle d’IIS. Notre application est incompatible avec le fonctionnement de cette image. L’équipe IIS a créé un exécutable ServiceMonitor.exe qui lance un service en tant que point d’entrée du conteneur. Il vérifie que le service w3svc, dans le cas d’IIS, est bien démarré. Mais en cas de redémarrage du service, le conteneur se ferme. À la fin du processus de configuration d’Efficient, nous avons besoin de redémarrer IIS pour que la partie ASP prenne en compte les nouveaux paramètres, entre autres la chaine de connexion à la base de données. Pour pallier ce problème, je me suis basé directement sur l’image officielle Windows Server Core et configuré l’image pour installer et configurer IIS et Efficient. L’image est de fait plus lourde.
\par
Cette configuration a été assez longue à mettre en place et s’est soldée par un succès. Je n’étais pas sûr de la compatibilité d’Efficient avec Windows Server Core. La plus grosse difficulté a été d’y faire fonctionner la partie ASP. J’y ai passé beaucoup de temps en passant par des phases d’espoir et de désespoir. Finalement, il manquait simplement la bibliothèque oledlg.dll pour que cela fonctionne \cite{Technet2015} \cite{MSCore2009}. Ce fonctionnement est lié au fonctionnement des anciennes applications ASP. Le code est compilé dans des bibliothèques dynamiques (DLL) et les pages ASP leur font appels par VbScript. Le lien entre les DLLs et VbScript est assuré par la technologie OLE Automation (Object Linking and Embedding), reposant sur l’architecture COM (Composant Model Object). Elle permet à des logiciels de communiquer entre eux. L’automation quant à elle, est la technique qui permet de scripter des composants écrits dans un langage interprété en dehors d’un programme compilé. COM est remplacée depuis 2009 par le Framework .NET créant une rupture avec les anciennes applications.
\par
Une fois l’application fonctionnelle dans un conteneur. J’ai standardisé le conteneur en normalisant la configuration d’IIS et de Kronos Efficient. Les conteneurs déployés à partir de cette image seront plus robustes, car les bonnes pratiques oubliées par les techniciens seront appliquées par défaut. J’ai extrait les éléments de configuration ayant besoin d’être adaptés pour chaque instance. L’application génère des URL à la volée pour intégrer la partie ASP dans la partie ASP.Net. Il faut donc spécifier une URL de base. L’adresse IP publique est nécessaire si le serveur est derrière un proxy inverse. Et enfin, la chaine de connexion à la base de données. La configuration de Kronos Efficient et l’application des droits sur les différents répertoires doit se faire par un script Powershell lancé au démarrage. En effet, comme nous l’avons vu dans l’état de l’art, seule la couche courante d’un conteneur est inscriptible, toutes les autres sont en lecture seule.
Une fois l’application fonctionnelle dans un conteneur. J’ai standardisé le conteneur en normalisant la configuration d’IIS et de Kronos Efficient. Les conteneurs déployés à partir de cette image seront plus robustes, car les bonnes pratiques oubliées par les techniciens seront appliquées par défaut. J’ai extrait les éléments de configuration ayant besoin d’être adaptés pour chaque instance. L’application génère des URL à la volée pour intégrer la partie ASP dans la partie ASP.Net. Il faut donc spécifier une URL de base. L’adresse IP publique est nécessaire si le serveur est derrière un proxy inverse. Et enfin, la chaine de connexion à la base de données. La configuration de Kronos Efficient et l’application des droits sur les différents répertoires doivent se faire par un script Powershell lancé au démarrage. En effet, comme nous l’avons vu dans l’état de l’art, seule la couche courante d’un conteneur est inscriptible, toutes les autres sont en lecture seule.
\par
Nous l’avons vu à plusieurs reprises dans ce document, les concepts fondamentaux des conteneurs précisent qu’un conteneur est immuable et éphémère. Par exemple, il peut être recréé à tout moment par un orchestrateur si un nœud du cluster n’est plus disponible. Toutes les données générées dans la couche inscriptible du conteneur seront alors perdues. Pour éviter ça, il faut utiliser des volumes. Les volumes sont le mécanisme pour gérer la persistance des données générées par les conteneurs. Il est possible de les lier à un répertoire de l’hôte ou de laisser Docker les gérer entièrement. Ils permettent de facilement persister les données d’un emplacement dans un conteneur, ainsi que de les sauvegarder ou migrer. Les volumes ont été créés pour persister les données dans la couche accessible en écriture d’un conteneur. Ils n’augmentent pas la taille des conteneurs qui l’utilisent et le contenu du volume existe en dehors du cycle de vie d’un conteneur donné.
\par
......@@ -134,7 +134,7 @@ Microsoft MessageQueuing (MSMQ) est une implémentation de file d’attente de m
\par
Le premier obstacle a été l’impossibilité d’utiliser MessageQueuing. En effet, il est impossible d’installer ou d’utiliser MSMQ sur l’image officielle Windows Server Core. Malgré la demande massive des utilisateurs, Microsoft a annoncé que MSMQ ne serait jamais disponible dans un conteneur Windows. MSMQ repose sur de très anciennes technologies qui seraient trop compliquées à adapter. Malheureusement, Microsoft n’a pas donné d’alternative ou annoncé qu’ils travaillaient sur une alternative. Il m’était donc impossible d’utiliser Agent dans un conteneur sans modifier son code pour utiliser un autre système de messagerie.
\par
J’ai donc décidé de développer un outil qui lancerait uniquement un contrôleur. Ainsi j’ai toujours trois images à créer, mais en production il n’y aura pas trois conteneurs pour une installation complète, mais treize : Efficient, Autotask et un conteneur par contrôleur. J’ai analysé le code d’Agent et créé une application console C# légère (une centaine de lignes de code). Elle prend en paramètre l’espace de nom et la classe du contrôleur à charger et la fréquence de lancement. Elle charge le contrôleur via l’injection de dépendance, l’initialise et l’exécute à la fréquence voulue. Mise à part les difficultés liées à l’injection de dépendance, j’ai rencontré une grosse difficulté par rapport à un bug lié au conteneur Windows. L’exécution d’une ligne de code pour récupérer une saisie utilisateur au clavier à laquelle on attache une vérification engendre une exception NullReferenceException dans un conteneur, mais pas en dehors. Cela a été difficile à déboguer, mais une fois le problème identifié, j’ai été en mesure de détecter si l’application s’exécute dans un conteneur ou non et ainsi adapter son comportement, voir figure \ref{fig:agentcode}. Ce problème corrigé, j’ai été en mesure de tester chaque contrôleur séparément et valider leur fonctionnement.
J’ai donc décidé de développer un outil qui lancerait uniquement un contrôleur. Ainsi j’ai toujours trois images à créer, mais en production il n’y aura pas trois conteneurs pour une installation complète, mais treize : Efficient, Autotask et un conteneur par contrôleur. J’ai analysé le code d’Agent et conçu une application console C# légère (une centaine de lignes de code). Elle prend en paramètre l’espace de nom et la classe du contrôleur à charger et la fréquence de lancement. Elle charge le contrôleur via l’injection de dépendance, l’initialise et l’exécute à la fréquence voulue. Mis à part les difficultés liées à l’injection de dépendance, j’ai rencontré une grosse difficulté par rapport à un bug lié au conteneur Windows. L’exécution d’une ligne de code pour récupérer une saisie utilisateur au clavier suivie de sa vérification engendre une exception NullReferenceException dans un conteneur, mais pas en dehors. Cela a été difficile à déboguer, mais une fois le problème identifié, j’ai été en mesure de détecter si l’application s’exécute dans un conteneur ou non et ainsi adapter son comportement, voir figure \ref{fig:agentcode}. Ce problème corrigé, j’ai été en mesure de tester chaque contrôleur séparément et valider leur fonctionnement.
\begin{figure}[h!]
\includegraphics[width=\linewidth]{conteneurisation/images/agentcode}
......
......@@ -2,7 +2,7 @@
\subsection{Création d’une forge logicielle}
La conteneurisation et le déploiement des images sont des opérations longues. Elles peuvent être automatisées. Le code source de Kronos Efficient est hébergé sur un dépôt SVN en Inde. Les applications associées à Kronos Efficient le sont sur un dépôt Git en Europe. GitLab est utilisé pour faciliter les différents dépôts et l’organisation des développeurs. J’ai mis en place un service de livraison continue (Continous delivery) grâce à gitlab-ci intégré à GitLab. Une évolution du projet de déploiement sera de mettre en place de l’intégration continue (Continous intégration). Ainsi, la mise à jour des conteneurs sera totalement automatisée. Je vais décrire succinctement son fonctionnement.
La conteneurisation et le déploiement des images sont des opérations longues. Elles peuvent être automatisées. Un dépôt SVN en Inde héberge le code source de Kronos Efficient est hébergé sur un dépôt SVN en Inde. Les applications associées à Kronos Efficient le sont sur un dépôt Git en Europe. GitLab est utilisé pour faciliter les différents dépôts et l’organisation des développeurs. J’ai mis en place un service de livraison continue (Continous delivery) grâce à gitlab-ci intégré à GitLab. Une évolution du projet de déploiement sera de mettre en place de l’intégration continue (Continous intégration). Ainsi, la mise à jour des conteneurs sera totalement automatisée. Je vais décrire succinctement son fonctionnement.
\par
\begin{figure}[h!]
......@@ -187,7 +187,7 @@ Affiche les logs sur la sortie standard \\
\subsection{Création de l’image Kronos Efficient Import Tool}
Kronos Efficient Import Tool permet d’importer des données dans Kronos Efficient à partir de différentes sources de données. Il est composé d’une application Winform pour créer les fichiers de configuration et effectuer des tests, d’une application console pour exécuter les imports et d’un service Windows pour exécuter les imports en automatique.
Kronos Efficient Import Tool permet d’importer des données dans Kronos Efficient à partir de différentes sources de données. Il est composé d’une application WinForm pour créer les fichiers de configuration et effectuer des tests, d’une application console pour exécuter les imports et d’un service Windows pour exécuter les imports en automatique.
\par
Comme tous les autres produits de la suite Kronos Efficient, elle est écrite en C#. Elle dialogue avec Kronos Efficient à l’aide de son web service. Le service utilise une base de données pour vérifier les imports à exécuter. Il scrute le contenu de la SuNotification qui lui indique des informations pour lancer l’import tels l’heure de lancement et l’emplacement du fichier de configuration à utiliser. Les fichiers de configuration sont stockés sur le disque. J’ai profité de la conteneurisation pour ajouter une nouvelle fonctionnalité : permettre le lancement d’un import à partir d’une chaine de caractère XML directement lisible dans la table SuNotification. Cette modification a deux objectifs : améliorer les performances et centraliser les configurations.
\par
......
......@@ -15,7 +15,7 @@ Les espaces de noms offrent une autre forme d’isolation pour l’interaction d
\par
L’utilisation de système de fichier UnionFS est également un avantage clé de l’utilisation des conteneurs Docker. Les conteneurs fonctionnent à partir d’une image. Tout comme une image dans le monde de la virtualisation matérielle (VM), elle représente un état à un moment particulier. Une image de conteneur est un instantané du système de fichiers, mais elle a tendance à être beaucoup plus petite qu’un instantané d’une VM. Un conteneur partage le noyau hôte et exécute généralement un ensemble de processus réduit, de sorte que le système de fichiers est léger et que le démarrage est très court (de l’ordre de la seconde). Bien que ces contraintes ne soient pas strictement appliquées.
\par
Le système de fichiers UnionFS permet également un stockage, un téléchargement et une exécution efficaces de ces images. Pour schématiser, on peut se représenter ce système de fichier comme un gâteau composé de différentes couches, chaque couche étant cuite indépendamment et assemblée par la suite. Le noyau Linux est la couche de base. Il est possible d’ajouter par-dessus un système d’exploitation tel que Red Hat Linux ou Ubuntu. Pour ajouter ensuite une application telle que Nginx ou Apache. Chaque modification crée une nouvelle couche. Enfin, lorsque toutes les modifications sont effectuées et donc que de nouvelles couches sont ajoutées, il y a toujours la couche finale, le glaçage, qui correspond à la couche de l’exécution (runtime). C’est la couche seule inscriptible. Docker rend cela vraiment efficace en mettant en cache les couches à leur construction. Par exemple, lors de la construction d’image si deux images sont toutes deux basées sur Alpine (une version allégée de Linux très utilisée avec les conteneurs). La construction de la deuxième image sera très rapide, car la couche Alpine sera déjà en cache.
Le système de fichiers UnionFS permet également un stockage, un téléchargement et une exécution efficaces de ces images. Pour schématiser, on peut se représenter ce système de fichier comme un gâteau composé de différentes couches, chaque couche étant cuite indépendamment et assemblée par la suite. Le noyau Linux est la couche de base. Il est possible d’ajouter par-dessus un système d’exploitation tel que Red Hat Linux ou Ubuntu, pour ajouter ensuite une application telle que Nginx ou Apache. Chaque modification crée une nouvelle couche. Enfin, lorsque toutes les modifications sont effectuées et donc que de nouvelles couches sont ajoutées, il y a toujours la couche finale, le glaçage, qui correspond à la couche de l’exécution (runtime). C’est la couche seule inscriptible. Docker rend cela vraiment efficace en mettant en cache les couches à leur construction. Par exemple, lors de la construction d’image, si deux images sont toutes deux basées sur Alpine (une version allégée de Linux très utilisée avec les conteneurs), la construction de la deuxième image sera très rapide, car la couche Alpine sera déjà en cache.
\begin{figure}[h!]
\includegraphics[width=\linewidth]{etatart/images/layercake}
......@@ -25,17 +25,17 @@ Le système de fichiers UnionFS permet également un stockage, un téléchargeme
\section{Quels usages pour un conteneur ?}
Les conteneurs sont donc utilisés depuis de nombreuses années, pourquoi un tel engouement de nos jours ?
Les conteneurs sont utilisés depuis de nombreuses années. Pourquoi un tel engouement de nos jours ?
\par
Premièrement Docker à apporter un outillage et une facilité d’utilisation qui n’existaient pas avant. Deuxièmement, le principe de conteneur est idéal pour l’intégration continue et le déploiement continu. En ayant un processus continu de construction et de déploiement de code, les organisations sont en mesure d’instiller le contrôle de la qualité et les tests dans le cadre du cycle de travail quotidien. Le résultat est que les mises à jour et corrections de bogues se produisent beaucoup plus rapidement et la qualité globale s’améliore.
Premièrement Docker a apporté un outillage et une facilité d’utilisation qui n’existaient pas avant. Deuxièmement, le principe de conteneur est idéal pour l’intégration continue et le déploiement continu. En ayant un processus continu de construction et de déploiement de code, les organisations sont en mesure d’instiller le contrôle de la qualité et les tests dans le cadre du cycle de travail quotidien. Le résultat est que les mises à jour et corrections de bogues se produisent beaucoup plus rapidement et la qualité globale s’améliore.
\par
Cependant, il a toujours été difficile de créer des environnements de développement qui correspondent à ceux des tests et de la production. Souvent, des incohérences dans ces environnements rendent difficile l’obtention de tous les avantages d’une livraison continue. Grâce à Docker, les développeurs sont désormais en mesure d’avoir des déploiements vraiment portables. Les conteneurs déployés sur l’ordinateur portable d’un développeur sont facilement déployés sur un serveur de stockage interne. Ils sont ensuite facilement transférés vers le serveur de production fonctionnant dans le cloud. C’est possible notamment grâce au système de fichier UnionFS et à son système de couches (layer). Il devient très facile de s’assurer que l’application est déployée avec tout ce qui est nécessaire à son bon fonctionnement (système d’exploitation, librairies, application, fichier de configuration…). L’application et son environnement sont les mêmes du développement à la production.
\par
Autre avantage, toutes les dépendances étant empaquetées dans les différentes couches, le même serveur hôte peut avoir plusieurs conteneurs exécutant une variété de versions de système d’exploitation ou de package. Chaque conteneur est indépendant et isolé des autres et de l’hôte. Il est alors possible d’avoir plusieurs langages et Frameworks sur le même serveur hôte sans les conflits de dépendance typiques que nous aurions dans une machine virtuelle (VM) avec un seul système d’exploitation.
Autre avantage, toutes les dépendances sont empaquetées dans les différentes couches. Le même serveur hôte peut donc avoir plusieurs conteneurs exécutant une variété de versions de système d’exploitation ou de package. Chaque conteneur est indépendant et isolé des autres et de l’hôte. Il est alors possible d’avoir plusieurs langages et Frameworks sur le même serveur hôte sans les conflits de dépendance typiques que nous aurions dans une machine virtuelle (VM) avec un seul système d’exploitation.
\par
De même, l’environnement de l’application étant empaqueté, il est toujours le même, peu importe où elle est déployée. Le comportement de l’application est alors plus prévisible et les tests avant chaque version plus efficace.
\par
Enfin, il faut penser un conteneur comme une instance jetable d’une application. Jetable, car toutes ses couches (excepté la dernière) sont immuables. Mais aussi, car sa vitesse de démarrage est tellement rapide qu’il est possible de déployer une application quasi instantanément. L’unité de déploiement est de l’ordre de la seconde.
Enfin, il faut penser un conteneur comme une instance jetable d’une application, car toutes ses couches sont immuables. Mais aussi, car sa vitesse de démarrage est tellement rapide qu’il est possible de déployer une application quasi instantanément. L’unité de déploiement est de l’ordre de la seconde.
\section{De l’interopérabilité des conteneurs}
......@@ -59,7 +59,7 @@ Les conteneurs ont démocratisé l’architecture basée sur les microservices,
\subsection{Mise à échelle}
En pensant et architecturant une application s’exécuter en parallèle sur plusieurs conteneurs, l’ajout de conteneurs permet d’absorber des pics d’utilisation. De même, les conteneurs peuvent être retirés lorsque la demande baisse. L’utilisation d’orchestrateurs, tels que Kubernetes, Docker Swarm ou Apache Mesos, simplifie grandement cette mise à l’échelle élastique.
L’ajout de conteneurs permet d’absorber des pics d’utilisation, car l'application a été conçue et architecturée pour s’exécuter en parallèle sur plusieurs conteneurs . De même, les conteneurs peuvent être retirés lorsque la demande baisse. L’utilisation d’orchestrateurs, tels que Kubernetes, Docker Swarm ou Apache Mesos, simplifie grandement cette mise à l’échelle élastique.
\subsection{Haute disponibilité}
......
......@@ -3,15 +3,15 @@ Références globales \cite{DockerSwarmDocs} \cite{FicherDockerII}
Docker Swarm Mode, également appelé SwarmKit, correspond aux fonctionnalités de gestion de cluster et d’orchestration de Docker Engine. La couche d’orchestration de Docker est un projet distinct utilisé directement dans Docker, intégrée dans Docker Engine, le moteur de Docker.
\par
Un cluster « Swarm » se compose de plusieurs hôtes Docker qui fonctionnent en mode Swarm. Ils agissent en tant que managers (gestionnaires) pour gérer l’adhésion et la délégation ou en tant que worker (travailleurs) pour exécuter des services ou tâches. Un hôte peut être les deux en même temps. La définition d’un service permet de spécifier son état optimal (nombre de répliques, ressources réseau et de stockage disponible, service vers le monde extérieur, etc.). Docker travaille pour maintenir cet état désiré. Par exemple, si un nœud de travail devient indisponible, Docker planifie les tâches de ce nœud sur d’autres nœuds. Une tâche est un conteneur en cours d’exécution faisant partie d’un service et gérée par un manager, par opposition à un conteneur autonome.
Un cluster « Swarm » se compose de plusieurs hôtes Docker qui fonctionnent en mode Swarm. Ils agissent en tant que managers (gestionnaires) pour gérer l’adhésion et la délégation ou en tant que worker (travailleurs) pour exécuter des services ou tâches. Un hôte peut être les deux en même temps. La définition d’un service permet de spécifier son état optimal (nombre de répliques, ressources réseau et de stockage disponibles, service vers le monde extérieur, etc.). Docker travaille pour maintenir cet état désiré. Par exemple, si un nœud de travail devient indisponible, Docker planifie les tâches de ce nœud sur d’autres nœuds. Une tâche est un conteneur en cours d’exécution faisant partie d’un service et gérée par un manager, par opposition à un conteneur autonome.
\par
Avant Docker v1.12.0-rc1, Docker Swarm, nommé maintenant Docker Swarm Standalone, permettait simplement de grouper plusieurs hôtes Docker en un unique gros hôte. Son défaut majeur était l’absence de service de découverte intégré. Il était alors nécessaire de mettre en place un système de découverte de service pour permettre à un conteneur ayant besoin d’un service de trouver le conteneur correspondant, et ce même s’il a changé d’adresse ou d’hôte. Ce système de découverte prenait souvent la forme d’une base de données clé/valeur (Consul, etcd ou encore Zookeeper). N’étant pas intégré, il fallait l’installer et le configurer séparément. L’installation et la configuration du cluster en étaient alourdies, mais cela permettait une plus grande flexibilité.
\par
Docker Swarm Mode est né le 15 juin 2016 avec Docker v1.12.0-rc1. Il contient les fonctionnalités majeures d’un orchestrateur de conteneurs :
\begin{itemize}
\item \textbf{Modèle de service déclaratif} : Docker Engine utilise une approche déclarative pour définir l’état souhaité des différents services. Par exemple, il est possible de décrire une application composée d’un service frontal web avec des services de mise en file d’attente de messages et un backend de base de données.
\item \textbf{Mise à l’échelle} : pour chaque service, il est possible de déclarer le nombre de tâches à exécuter. Le nœud manager s’adapte automatiquement en ajoutant ou en supprimant des tâches pour maintenir l’état souhaité à chaque modification.
\item \textbf{Réconciliation d’état souhaitée} : le nœud manager surveille en permanence l’état du cluster et réconcilie les différences entre l’état actuel et l’état souhaité. Par exemple, si un service est configuré pour exécuter 10 répliquas d’un conteneur et qu’un nœud hébergeant deux de ces répliqua tombe en panne, le manager crée deux nouveaux conteneurs sur un ou plusieurs nœuds worker disponibles pour remplacer les répliques perdues.
\item \textbf{Mise à l’échelle} : pour chaque service, il est possible de déclarer le nombre de tâches à exécuter. Le nœud manager ajoute ou supprime des tâches pour maintenir l’état souhaité à chaque modification.
\item \textbf{Réconciliation d’état souhaitée} : le nœud manager surveille en permanence l’état du cluster et réconcilie les différences entre l’état actuel et l’état souhaité. Par exemple, si un service est configuré pour exécuter 10 répliques d’un conteneur et qu’un nœud hébergeant deux de ces répliques tombe en panne, le manager crée deux nouveaux conteneurs sur un ou plusieurs nœuds worker disponibles pour remplacer les répliques perdues.
\item \textbf{Réseau multihôte} : il est possible de spécifier un réseau overlay pour les services. Le master attribue automatiquement des adresses aux conteneurs sur le réseau overlay lorsqu’il initialise ou met à jour l’application.
\item \textbf{Découverte du service} : les nœuds manager affectent à chaque service un nom DNS unique et répartissent la charge entre les conteneurs en cours d’exécution. Chaque conteneur qui s’exécute peut-être interrogé via un serveur DNS intégré.
\item \textbf{Équilibrage de charge} : les ports pour les services peuvent être exposés à un équilibreur de charge externe. En interne, Swarm permet de spécifier comment distribuer les conteneurs de chaque service entre les nœuds.
......@@ -57,7 +57,7 @@ Un service est défini par des informations telles que
\item le port où le cluster rend service disponible pour le monde extérieur
\item un réseau overlay pour la communication avec d’autres services du cluster
\item des limites et réservations pour les CPU et la mémoire
\item le nombre de répliqua désirés
\item le nombre de répliques désirés
\end{itemize}
Lors du déploiement d’un service, le manager accepte la définition du service envoyé par l’utilisateur et la considère comme l’état désiré du service. Il planifie ensuite la création du service sur les nœuds disponibles du cluster.
......@@ -119,7 +119,7 @@ Tous les nœuds peuvent être hébergés sous Windows. Toutefois, il existe des
\begin{itemize}
\item Il est nécessaire de déployer la mise à jour KB4015217 pour Windows Server 2016. Elle contient une amélioration du service de réseau hôte (HNS) pour la prise en charge d’un pilote réseau de superposition à utiliser sur Windows Server 2016 afin de connecter les conteneurs entre hôtes à l’aide du moteur Docker Swarm. Sans cette mise à jour, le routage du port hôte au port du conteneur ne fonctionne pas.
\item L’encryption du trafic entre conteneurs n’est pas supportée
\item Le maillage de routage pour les hôtes dockers Windows est pris en charge à partir de Windows Server 2019 \cite{Friis2017} \cite{Lloyd2017}. Sous windows Server 2016, l’équilibreur de charge utilisant le réseau maillé ne fonctionne pas. Il est possible de configurer un équilibreur de charge externe et utiliser le mode « publish-port » de Swarm pour exposer les ports hôtes des conteneurs sur lesquels l’équilibrage de charge doit être effectué. Mais dans ce cas, le service sera lié à un hôte.
\item Le maillage de routage pour les hôtes dockers Windows est pris en charge à partir de Windows Server 2019 \cite{Friis2017} \cite{Lloyd2017}. Sous Windows Server 2016, l’équilibreur de charge utilisant le réseau maillé ne fonctionne pas. Il est possible de configurer un équilibreur de charge externe et utiliser le mode « publish-port » de Swarm pour exposer les ports hôtes des conteneurs sur lesquels l’équilibrage de charge doit être effectué. Mais dans ce cas, le service sera lié à un hôte.
\end{itemize}
......
This diff is collapsed.
......@@ -4,7 +4,7 @@ Références globales \cite{K8sVSSwarmI} \cite{K8sVSSwarmII}
La force de Docker Swarm Mode réside dans sa simplicité d’installation et d’utilisation. Il est directement intégré à Docker. Il reprend la philosophie et les concepts de Docker, comme la compatibilité avec les fichiers docker-compose.yml. Cela rend son apprentissage très simple et dans la continuité de celui de Docker. Cette simplicité a un prix : l’extensibilité. Il n’est que très peu modulaire et se cantonne à rester dans le monde Docker. Il est impossible d’utiliser un autre moteur de conteneur que Docker. Il n’est pas possible non plus d’utiliser un autre planificateur que celui intégré. Docker est un projet jeune qui évolue rapidement. Bien que le projet soit libre et le poids important de Docker sur le marché des conteneurs, la communauté n’est pas aussi forte que celle de Kubernetes. La majeure partie des contributions provient de Docker Inc directement. Docker Swarm est idéal pour de petits ou moyens clusters. Il permet à moindre effort de déployer des applications avec la qualité de service des systèmes distribués.
\par
Kubernetes possède de multiples forces : son extensibilité, sa communauté, sa large adoption (d’où l’offre abondante de fournisseurs cloud), son expérience, sa rapide évolution, ses concepts et fonctionnalités avancées (pods, utilisations de multiples moteurs de conteneurs, configuration avancée des volumes, secrets…). Le seul véritable inconvénient est le coût d’apprentissage et de maîtrise de K8S. C’est pourquoi, dans le cadre d’une utilisation in-premise ou si Docker est connu, il est plutôt adapté à une utilisation demandant de grands besoins ou des fonctionnalités spécifiques qui ne sont pas fournies par Docker Swarm.
Kubernetes possède de multiples forces : son extensibilité, sa communauté, sa large adoption (d’où l’offre abondante de fournisseurs cloud), son expérience, sa rapide évolution, ses concepts et fonctionnalités avancées (pods, utilisations de multiples moteurs de conteneurs, configuration avancée des volumes, secrets…). Le seul véritable inconvénient est son coût d’apprentissage et de maîtrise. C’est pourquoi, il est recommandé dans le cadre d’une utilisation cloud ou si Docker n'est pas connu. Il est plutôt adapté à une utilisation demandant de grands besoins ou des fonctionnalités spécifiques qui ne sont pas fournies par Docker Swarm.
\begin{table}[ht]
\begin{center}
......
\section{Présentation de Kronos}
Kronos est un éditeur de logiciels américain spécialisé dans la gestion de capital humain ou HCM pour l’acronyme anglais. Nos produits couvrent l’ensemble des pratiques liées à la gestion des ressources humaines, à la gestion du personnel d’une organisation pour qu’ils contribuent de manière significative à la productivité globale de celle-ci.
Kronos est un éditeur de logiciels américain spécialisé dans la gestion de capital humain ou HCM pour l’acronyme anglais. Nos produits couvrent l’ensemble des pratiques liées à la gestion des ressources humaines.
\subsection{Historique}
Kronos est une multinationale américaine détenue par le fonds d’investissement Hellman \& Friedman LLC. Elle emploie 6000 collaborateurs à travers le monde, dont 13 en France.
Kronos est une entreprise multinationale américaine détenue par le fonds d’investissement Hellman \& Friedman LLC. Elle emploie 6000 collaborateurs à travers le monde, dont 13 en France.
\par
Pour développer sa présence en Europe continentale, elle acquiert Captor en 2008. Captor est un éditeur de logiciel spécialisé dans le même domaine, mais de taille moindre. Elle est présente en Belgique (siège social), en France, aux Pays-Bas et au Royaume-Uni. La majorité de notre clientèle est située en France et aux Pays-Bas. Elle ne propose qu’un seul produit Efficient People Solutions destiné aux petites et moyennes entreprises. Ce produit sera renommé Kronos Efficient après l’acquisition.
\par
En mars 2020, Kronos et Ultimate Software fusionnent pour devenir une force de 12 000 collaborateurs présents dans plus de 100 pays. Nous servons maintenant 22 000 clients directs et 24 000 clients indirects à travers le monde pour un chiffre d’affaires annuel de 3 milliards de dollars. Nos principaux concurrents mondiaux sont Workday et SAP HCM. Sur notre territoire, ce sont Workday, Horoquartz et Bodet.
En France, Kronos déploie principalement deux solutions : Kronos Efficient et Workforce Ready. Ce dernier a été lancé en 2019 et est en pleine expansion contrairement à Kronos Efficient qui compose la base solide de nos clients.
En France, Kronos déploie principalement deux solutions : Kronos Efficient et Workforce Ready. Nous avons lancé ce dernier en 2019 sur le marché français. Il est en pleine expansion contrairement à Kronos Efficient qui compose la base solide de nos clients.
\par
Notre structure interne scinde les équipes par application nommée unité de business (BU). Chaque BU contient des équipes commerciales, services, support ainsi que recherche et développement.
\subsection{Nos produits}
Actuellement, nous maintenons quatre produits qui ont les mêmes fonctionnalités, deux d’entre-elles sont destinées aux grandes entreprises (plus de 10 000 employés) et deux d’entre elles sont entièrement SAAS (Software as a Service).
Actuellement, nous maintenons quatre produits qui ont les mêmes fonctionnalités, deux d’entre eux sont destinés aux grandes entreprises (plus de 10 000 employés) et deux d’entre elles sont entièrement SAAS (Software as a Service).
Workforce Central Suite est une suite logicielle installée localement destinée aux grandes entreprises.
Workforce Dimension Suite est une suite logicielle SAAS destinée aux grandes entreprises.
Kronos Efficient est une suite logicielle installée localement destinée aux petites et moyennes entreprises (PME).
......
......@@ -2,7 +2,7 @@
\subsection{Embauche}
En 2005, j’ai intégré Captor France (rachetée par Kronos en 2007) en tant qu’intervenant support (hotline). Pendant deux ans, j’ai préparé un diplôme de technicien supérieur en support et maintenance informatique au CESI dans le cadre d’un contrat en alternance. En 2007, à la suite de l’obtention de mon diplôme, j’ai été embauché au même poste. Mes tâches sont restées les mêmes, c’est-à-dire l’installation, la configuration, le conseil utilisateur et le dépannage à distance de nos logiciels et matériels de l’époque, tout en assurant la gestion des incidents (renseignement et suivi des incidents, planification d’intervention sur site).
En 2005, j’ai intégré Captor France (rachetée par Kronos en 2007) en qualité de technicien support (hotline). Pendant deux ans, j’ai préparé un diplôme de technicien supérieur en support et maintenance informatique au CESI dans le cadre d’un contrat en alternance. En 2007, à la suite de l’obtention de mon diplôme, j’ai été embauché au même poste. Mes tâches sont restées les mêmes. C’est-à-dire assurer l’installation, la configuration, le conseil utilisateur et le dépannage à distance de nos logiciels et matériels de l’époque, ainsi que la gestion des incidents (renseignement et suivi des incidents, planification d’intervention sur site).
\subsection{Évolution}
......@@ -10,9 +10,9 @@ En 2008, j’ai évolué vers un poste de concepteur spécialisé dans les inté
\par
Premièrement, j’ai réalisé les analyses et développements des imports-exports de données entre Kronos Efficient et des produits tiers, principalement des ERP ou des logiciels de paie (Oracle, SAP, Sage, Cegid…). Ces intégrations consistaient à définir les besoins du client, les données à envoyer et le format dans lequel les envoyer et les recevoir. Elles étaient réalisées en configurant une application nommée Kronos Efftools liée à Kronos Efficient et en gérant les spécificités client en T-SQL (Microsoft SQL Server). J’étais seul chargé de cette tâche pour tous nos clients français.
\par
Deuxièmement, j’ai été responsable du développement des spécifiques client. Une analyse des besoins du client était nécessaire suivi du développement, de la rédaction de la documentation de développement et utilisateur, de la livraison et du support utilisateur. J’étais, et suis encore, seul chargé de cette tâche pour tous nos clients français.
Deuxièmement, j’ai été responsable du développement des spécifiques client. Une analyse des besoins du client était nécessaire, suivie du développement, de la rédaction de la documentation de développement et utilisateur, de la livraison et du support utilisateur. J’étais, et suis encore, seul chargé de cette tâche pour tous nos clients français.
\par
Enfin, j’ai été, et suis encore, seul développeur des applications liées à Kronos Efficient, que ce soit aussi bien des outils internes que des produits annexes vendus tels qu’un générateur avancé de rapport (Kronos Efficient Analytics), un moteur d’acquisition de soldes de congés (Kronos Efficient Acquisition), une interface web adaptative (Kronos Efficient Mobile) et des outils d’import/export et migration de données et autres analyseurs de paramétrage.
Enfin, j’ai été, et suis encore, seul développeur des applications liées à Kronos Efficient. Elles sont composées d'outils internes et des produits annexes présents au catalogue, tels qu’un générateur avancé de rapport (Kronos Efficient Analytics), un moteur d’acquisition de soldes de congés (Kronos Efficient Acquisition), une interface web adaptative (Kronos Efficient Mobile) et des outils d’import/export et migration de données et autres analyseurs de paramétrage.
\subsection{Responsabilités}
......
......@@ -2,7 +2,7 @@
\subsection{Historique}
Kronos Efficient, aujourd’hui en version 5.x, est un produit initialement développé par Captor. Kronos l’a hérité lors du rachat. Initialement, il est né de la volonté de s’adapter au plus près des besoins des entreprises. Il est l’héritier d’Efficient 4.x en y ajoutant une personnalisation avancée et un moteur de processus métier (workflow). Efficient 4.x de son côté permettait la gestion des temps de travail et des absences, la planification, la gestion d’activité et de projets, l’accès physique aux bâtiments. Efficient 4.x est sorti en 2001 et Efficient 5.x en 2009. Actuellement, le développement et la maintenance d’Efficient 4.x sont arrêtés. Efficient 5.x constitue la majeure partie de notre parc client en Europe continentale, et, par conséquent, de nos revenus et des demandes de support de nos clients. Efficient est toutefois voué à disparaître. Depuis 2019, son développement est limité à la correction de bogues uniquement et il ne figure plus à notre catalogue pour les potentiels clients. Workforce Ready, lancé en 2019 en France, est son successeur et se développe correctement sur notre clientèle et sur de nouveaux clients.
Kronos Efficient, aujourd’hui en version 5.x, est un produit initialement développé par Captor. Kronos a acquis cette suite logicielle lors du rachat. Initialement, il est né de la volonté de s’adapter au plus près des besoins des entreprises. Il est l’héritier d’Efficient 4.x en y ajoutant une personnalisation avancée et un moteur de processus métier (workflow). Efficient 4.x de son côté permettait la gestion des temps de travail et des absences, la planification, la gestion d’activité et de projets, l’accès physique aux bâtiments. Efficient 4.x est sorti en 2001 et Efficient 5.x en 2009. Actuellement, le développement et la maintenance d’Efficient 4.x sont arrêtés. Efficient 5.x constitue la majeure partie de notre parc client en Europe continentale, et, par conséquent, de nos revenus et des demandes de support de nos clients. Efficient est toutefois voué à disparaître. Depuis 2019, son développement est limité à la correction de bogues uniquement et il ne figure plus à notre catalogue pour les potentiels clients. Workforce Ready, lancé en 2019 en France, est son successeur et se développe correctement sur notre clientèle et sur de nouveaux clients.
\subsection{Architecture}
......@@ -51,7 +51,7 @@ Au fur et à mesure des années, des besoins clients ont émergé et ont nécess
\subsection{Kronos Efficient Mobile}
Kronos Efficient Mobile est une application web adaptative permettant une utilisation confortable de Kronos Efficient aux périphériques mobiles. Elle offre des fonctionnalités essentielles pour les salariés et les gestionnaires.
Kronos Efficient Mobile est une application web adaptative, permettant une utilisation confortable de Kronos Efficient aux périphériques mobiles. Elle offre des fonctionnalités essentielles pour les salariés et les gestionnaires.
\par
D’un point de vue technique, elle est conçue en C\#/Asp.NET. Elle se connecte à Kronos Efficient par son service web SOAP.
\newpage
......
\section{Présentation de la plateforme d’hébergement}
Pour douze de nos clients, nous hébergeons Kronos Efficient. Ils y ont accès par une URL publique dédiée. Ainsi nous fournissons l’application en mode SAAS, mais, comme indiqué précédemment, cette application a été conçue pour être installée dans l’infrastructure de nos clients. Toutefois, son aspect « web » facilite grandement son hébergement. Seul Autotask doit communiquer en local (UDP) avec le matériel et doit donc être installé dans le même réseau local que celui-ci. Tous les clients hébergés ont au minimum Kronos Efficient, KEIT et Kronos Efftools installés. En fin de compte, toutes les applications de son écosystème y sont installées.
Pour douze de nos clients, nous hébergeons Kronos Efficient. Ils y ont accès par une adresse URL publique dédiée. Ainsi nous fournissons l’application en mode SAAS, mais, comme indiqué précédemment, cette application a été conçue pour être installée dans l’infrastructure de nos clients. Toutefois, son aspect « web » facilite grandement son hébergement. Seul Autotask doit communiquer en local (UDP) avec le matériel et doit donc être installé dans le même réseau local que celui-ci. Tous les clients hébergés ont au minimum Kronos Efficient, KEIT et Kronos Efftools installés. En fin de compte, toutes les applications de son écosystème y sont installées.
\subsection{Architecture}
......@@ -32,4 +32,4 @@ La première architecture est schématisée par la figure \ref{fig:KE5HostingAcc
La seconde architecture, représentée par la figure \ref{fig:KE5HostingWebFront}, ne nécessite qu’une seule adresse IP publique, mais toujours un sous-domaine par client. Le proxy inverse redirige le trafic vers le serveur d’application en fonction du sous-domaine.
\par
L’architecture à accès direct a été le choix initial lors de la mise en place de la plateforme d’hébergement. À chaque demande de nouvelle adresse IP publique, un bogue paralyse entièrement le réseau qu’Interoute nous fournit. Aucun de nos clients n’a alors accès à l’application pendant plusieurs heures, suivant la réactivité du support Interoute. Nous avons donc été contraints de mettre en place le proxy inverse afin de n’utiliser qu’une seule adresse IP publique. Cela pose deux problèmes majeurs. Un problème de fiabilité : si le proxy inverse rencontre un incident, plusieurs clients perdent l’accès à leur instance. Nous aurions pu redonder le proxy inverse et utiliser un mécanisme de basculement (fail-over), mais le manque de temps nous a obligés à renoncer à cette solution, la durée de tests étant trop longue. Nous avons minimisé les risques en prenant un instantané (« snapshot ») du proxy inverse après chaque modification. Ainsi il nous est possible de le restaurer en cas de problème et à condition que le système de snapshot fourni par Interoute soit fiable. Le second problème concerne la maintenance. Notre architecture est hétérogène sans aucune logique. Lors de chaque opération de maintenance, le technicien doit consulter la documentation pour s’assurer de l’architecture utilisée pour le serveur sur lequel il intervient. Il doit également mettre la documentation à jour s’il fait des modifications. Cest chronophage et source d’erreurs.
L’architecture à accès direct a été le choix initial lors de la mise en place de la plateforme d’hébergement. À chaque demande de nouvelle adresse IP publique, un bogue paralyse entièrement le réseau qu’Interoute nous fournit. Aucun de nos clients n’a alors accès à l’application pendant plusieurs heures, suivant la réactivité du support Interoute. Nous avons donc été contraints de mettre en place le proxy inverse afin de n’utiliser qu’une seule adresse IP publique. Cela pose deux problèmes majeurs. Un problème de fiabilité : si le proxy inverse rencontre un incident, plusieurs clients perdent l’accès à leur instance. Nous aurions pu redonder le proxy inverse et utiliser un mécanisme de basculement (fail-over), mais le manque de temps nous a obligés à renoncer à cette solution, la durée de tests étant trop longue. Nous avons minimisé les risques en prenant un instantané (« snapshot ») du proxy inverse après chaque modification. Ainsi il nous est possible de le restaurer en cas de problème et à condition que le système de snapshot fourni par Interoute soit fiable. Le second problème concerne la maintenance. Notre architecture est hétérogène sans aucune logique. Lors de chaque opération de maintenance, le technicien doit consulter la documentation pour s’assurer de l’architecture utilisée pour le serveur sur lequel il intervient. Il doit également mettre la documentation à jour s’il fait des modifications. Cette situation est chronophage et source d’erreurs.
Afin de pallier efficacement aux premiers incidents et ainsi assurer une bonne qualité de service, je dois préparer la maintenance avant la mise en production.
Afin de remédier efficacement aux premiers incidents et ainsi assurer une bonne qualité de service, je dois préparer la maintenance avant la mise en production.
\section{Mise à jour}
......@@ -6,7 +6,7 @@ Afin de pallier efficacement aux premiers incidents et ainsi assurer une bonne q
Pour assurer une qualité de service satisfaisante, il est important que les applications soient à jour et que les mises à jour puissent se faire sans coupure de service.
\par
En qualité de product owner, je diffuse les nouvelles versions et les patchs de Kronos Efficient. Je rajoute à ma procédure de diffusion la modification et le déploiement des images Docker. J’ai donc simplement rajouté ces deux étapes dans les pipelines de livraison continue de ma forge logicielle. Ainsi, à chaque \verb|push| du code sur la branche \verb|master| du dépôt, les images sont créées. Elles sont envoyées sur le dépôt Docker à chaque création de tag. J’ai appliqué ce fonctionnement à toutes les applications liées à Kronos Efficient. Les utilisateurs peuvent déployer l’application par un installeur et configurer leur environnement manuellement ou utiliser l’image Docker.
En qualité de product owner, je diffuse les nouvelles versions et les patchs de Kronos Efficient. Je rajoute à ma procédure de diffusion la modification et le déploiement des images Docker. J’ai donc simplement rajouté ces deux étapes dans les pipelines de livraison continue de ma forge logicielle. Ainsi, à chaque envoi \verb|push| du code sur la branche \verb|master| du dépôt, les images sont créées. Elles sont envoyées sur le dépôt Docker à chaque création de tags. J’ai appliqué ce fonctionnement à toutes les applications liées à Kronos Efficient. Les utilisateurs peuvent déployer l’application par un installeur et configurer leur environnement manuellement ou utiliser l’image Docker.
\par
Pour mettre à jour une instance client, il suffit de relancer la commande de déploiement \cite{WinContUpdate}
\begin{tcolorbox}[colback=consolebg,boxsep=1pt,left=2pt,right=2pt,top=0pt,bottom=0pt]
......@@ -18,7 +18,7 @@ Docker va alors mettre à jour tous les services appartenant à cette stack. Si
\subsection{Mise à jour des systèmes d’exploitation}
Actuellement, les mises à jour des serveurs Windows sont gérées par un profil de sécurité et un serveur Windows Server Update Service (WSUS). Les mises à jour de sécurité et critiques sont approuvées et deployées automatiquement le dimanche à 03h00. Si un redémarrage est nécessaire, il est fait automatiquement entre 04h00 et 06h00. Les interventions manuelles se limitent à approuver des mises à jour particulières pour SQL Server.
Actuellement, un profil de sécurité et un serveur Windows Server Update Service (WSUS) gèrent les mises à jour des serveurs Windows. Les mises à jour de sécurité et critiques sont approuvées et déployées automatiquement le dimanche à 03h00. Si besoin, les serveurs sont redémarrés automatiquement entre 04h00 et 06h00. Les interventions manuelles se limitent à approuver des mises à jour particulières pour SQL Server.
% \begin{figure}[h!]
% \includegraphics[width=\linewidth]{etatart/images/layercake}
......
\section{Formation de l’équipe}
La plateforme d’hébergement est administrée et supportée par uniquement quatre personnes, trois personnes de mon équipe et moi-même. La formation se fait en deux sessions: \emph{Découverte de Docker sous Windows} sur deux journées et \emph{Fonctionnement de la nouvelle architecture} sur une journée. L’important est d’axer la formation sur les informations utiles à l’administration et au support et surtout sur la pratique. J’appuie donc chaque fonctionnement théorique en l’appliquant à un cas concret. Je suis enseignant vacataire pour un public BAC+4 sur la sécurité informatique, l'administration de bases de données et l’automatisation et le déploiement. J’ai adapté mon cours sur les conteneurs pour ne garder uniquement que le nécessaire, c'est-à-dire les parties sur Windows et le déploiement.
Uniquement quatre personnes, trois personnes de mon équipe et moi-même administrons et supportons la plateforme d’hébergement. La formation se fait en deux sessions: \emph{Découverte de Docker sous Windows} sur deux journées et \emph{Fonctionnement de la nouvelle architecture} sur une journée. L’important est d’axer la formation sur les informations utiles à l’administration et au support et surtout sur la pratique. J’appuie donc chaque fonctionnement théorique en l’appliquant à un cas concret. Je suis enseignant vacataire pour un public BAC+4 sur la sécurité informatique, l'administration de bases de données et l’automatisation et le déploiement. J’ai adapté mon cours sur les conteneurs pour ne garder que le nécessaire, c'est-à-dire les parties sur Windows et le déploiement.
Plan de formation du cours \emph{Découverte de Docker sous Windows} :
\begin{itemize}
......@@ -12,7 +12,7 @@ Plan de formation du cours \emph{Découverte de Docker sous Windows} :
\end{itemize}
\item Deuxième demi-journée
\begin{itemize}
\item Communications extra-conteneurs (théorie/exercices)
\item Communications extra conteneurs (théorie/exercices)
\item Persistance des données (théorie/exercices)
\end{itemize}
\item Troisième demi-journée
......
......@@ -12,7 +12,7 @@ Le système de supervision en place surveille les éléments essentiels des serv
\item si le service Kronos Efficient Import Tool est démarré
\item si le service Kronos Efficient Acquisition est démarré
\end{itemize}
Avec la conteneurisation de la suite Kronos Efficient, tous ces tests sont toujours possibles exception faite de la surveillance de services. Les conteneurs ont la faculté de vérifier eux-même leur santé (\verb|HEALTHCHECK| dans la description de l’image) et d’afficher leur statut. Ainsi, l’orchestrateur recrée automatiquement un conteneur en mauvaise santé. Cette fonctionnalité ajoute une petite sécurité, mais elle ne permet pas d’alerter en cas de conteneur défectueux. Pour être informé d’une anomalie et être en mesure d’agir rapidement, il faut que le système de supervision reçoive les informations sur l’état de tous les services déployés au sein de Docker Swarm.
Avec la conteneurisation de la suite Kronos Efficient, tous ces tests sont toujours possibles exception faite de la surveillance de services. Les conteneurs ont la faculté de vérifier eux-mêmes leur santé (\verb|HEALTHCHECK| dans la description de l’image) et d’afficher leur statut. Ainsi, l’orchestrateur recrée automatiquement un conteneur en mauvaise santé. Cette fonctionnalité ajoute une petite sécurité, mais elle ne permet pas d’alerter en cas de conteneur défectueux. Pour être informé d’une anomalie et être en mesure d’agir rapidement, il faut que le système de supervision reçoive les informations sur l’état de tous les services déployés au sein de Docker Swarm.
\par
La supervision du cluster est, quant à elle, classique. Elle consiste à surveiller la disponibilité d’une machine (up/down) et de ses ressources (utilisation CPU, RAM et espace disque) et l’état du service Docker. À cela j’ajoute la santé du cluster via deux informations à vérifier : la disponibilité de chaque nœud master (\verb|ManagerStatus.Reachability| devrait être égal à \verb|Leader| ou \verb|Reachable|) et le statut de chaque nœud (\verb|Status.State| devrait être égal à \verb|Ready|).
\par
......
\section{Maintenance de l’orchestrateur}
Un des objectifs de ce projet est le gain de temps de maintenance. Il faut automatiser au maximum les tâches d’installation et de maintenance. Concrètement, j’ai écrit un script pour créer un nouveau nœud worker dans le cluster et un autre pour mettre à jour Docker dans le cluster, le tout accompagné d’une procédure.
Un des objectifs de ce projet est le gain de temps de maintenance. Il est nécessaire d'automatiser au maximum les tâches d’installation et de maintenance. Concrètement, j’ai écrit un script pour créer un nouveau nœud worker dans le cluster et un autre pour mettre à jour Docker dans le cluster, le tout accompagné d’une procédure.
\par
La création d’un nouveau nœud worker comprend l’ajout et la configuration d’une VM via l’API d’Interoute, l’activation de la licence Windows, l’intégration de la machine dans l’Active Directory, la configuration des mises à jour Windows, l’installation de l’antivirus et du client pour la supervision, l’installation de Docker et l’intégration au cluster.
\par
La mise à jour d’un cluster doit se faire nœud par nœud. Les nœuds master doivent être mis à jour en premier. La meilleure méthode, suggérée ici \cite{FisherSwarmUpgrade} par Bret Fisher, est de recréer de nouvelles machines. Le script de création d’un nœud worker simplifie le travail. Il reste à définir en tant que master les nouveaux nœuds supposés l’être et supprimer les anciens nœuds. Attention à bien ajouter les nouveaux nœuds au load balancer avant de supprimer un ancien nœud.
La mise à jour d’un cluster doit se faire nœud par nœud. Les nœuds master doivent être mis à jour en premier. La meilleure méthode, suggérée ici \cite{FisherSwarmUpgrade} par Bret Fisher, est de recréer de nouvelles machines. Le script de création d’un nœud worker simplifie le travail. Il reste à définir en tant que master les nouveaux nœuds supposés l’être et supprimer les anciens nœuds. Et bien évidemment penser à ajouter les nouveaux nœuds au load balancer avant de supprimer un ancien nœud.
\par
Enfin pour être en mesure de restaurer le cluster après un désastre, il faut planifier sa sauvegarde. Pour effectuer la sauvegarde, il faut se connecter sur un nœud master, arrêter Docker pour éviter toute modification et sauvegarder le répertoire \verb|C:\ProgramData\docker\swarm| entièrement.
......
......@@ -50,7 +50,7 @@
\vspace{0.3cm}
\makebox[\textwidth][c]{\centering{\large{\textit{présentée par} : }} {\Large{\textbf{Yoann Calamai}}}}\\
\vspace{.4cm}
\makebox[\textwidth][c]{\centering{\large{\textit{soutenue le} : }} {\Large{\textbf{XX Janvier 2021}}}}\\
\makebox[\textwidth][c]{\centering{\large{\textit{soutenue le} : }} {\Large{\textbf{XX janvier 2021}}}}\\
\vspace{.3cm}
\makebox[\textwidth][c]{\centering{\large{\textit{pour obtenir le grade de} : }}}\\
......
......@@ -14,7 +14,7 @@ Prenons le cheminement d’une requête pour expliquer le fonctionnement de cett
\item Un utilisateur accède à l’URL \url{https://test.kronosefficient.com/efficient5} via son navigateur pour ouvrir son instance Kronos Efficient.
\item Le load balancer reçoit la requête et la redirige vers un des serveurs du cluster Docker.
\item Grâce au réseau maillé (mesh), la requête est redirigée vers Traefik, car il écoute sur le port 443 (HTTPS) du cluster.
\item Le fichier de déploiement pour test.kronosefficient.com contient la règle de routage pour Traefik. Plus pécisément, elle est déclarée dans la section \verb|label| du service Kronos Efficient (voir extrait ci-dessous). Cette règle (ligne 6) indique à Traefik que les requêtes vers test.kronosefficient.com et test.kronosefficient.com/efficient5 doivent être redirigées vers ce conteneur.
\item Le fichier de déploiement pour test.kronosefficient.com contient la règle de routage pour Traefik. Plus précisément, elle est déclarée dans la section \verb|label| du service Kronos Efficient (voir extrait ci-dessous). Cette règle (ligne 6) indique à Traefik que les requêtes vers test.kronosefficient.com et test.kronosefficient.com/efficient5 doivent être redirigées vers ce conteneur.
\end{itemize}
\begin{tcolorbox}[colback=consolebg,boxsep=1pt,left=2pt,right=2pt,top=0pt,bottom=0pt]
......@@ -34,7 +34,7 @@ services:
% \label{fig:traefikLabelExample}
% \end{figure}
Ce fichier de déploiement contient la définition des conteneurs Kronos Efficient, Autotask, Kronos Efficient Mobile et des contrôleurs Agent. Il permet de déployer tous les services nécessaires à un client au sein d’une stack. Une stack est une notion Docker Swarm regroupant des services ayant besoin de communiquer entre eux. Pour faire le parallèle avec Kubernetes, il est possible de se la représenter comme un pod léger. Les communications internes des services sont isolées sur un réseau dédié à la stack. Seuls Kronos Efficient et Kronos Efficient Mobile sont accessibles de l’extérieur. Ce fichier de déploiement est déployé par Portainer. Ce dernier simplifie la gestion du cluster et des conteneurs en affichant un tableau de bord de la santé des conteneurs et en permettant un déploiement facilité de stacks et de conteneurs individuels. En plus d’avoir une vision sur l’ensemble des ressources Docker, il permet de lancer une console pour se connecter sur un conteneur depuis son navigateur. Il fournit également des templates de conteneurs pour pouvoir déployer des applications rapidement. La prise en main est plus simple pour des néophytes et la courbe d’apprentissage plus douce. C’est parfait pour mon équipe qui, à mon grand désespoir, a des difficultés à utiliser des programmes en ligne de commandes.
Ce fichier de déploiement contient la définition des conteneurs Kronos Efficient, Autotask, Kronos Efficient Mobile et des contrôleurs Agent. Il permet de déployer tous les services nécessaires à un client au sein d’une stack. Une stack est une notion Docker Swarm regroupant des services ayant besoin de communiquer entre eux. Pour faire le parallèle avec Kubernetes, il est possible de se la représenter comme un pod léger. Les communications internes des services sont isolées sur un réseau dédié à la stack. Seuls Kronos Efficient et Kronos Efficient Mobile sont accessibles de l’extérieur. Ce fichier de déploiement est déployé par Portainer. Ce dernier simplifie la gestion du cluster et des conteneurs en affichant un tableau de bord de la santé des conteneurs et en permettant un déploiement facilité de stacks et de conteneurs individuels. En plus d’avoir une vision sur l’ensemble des ressources Docker, il permet de lancer une console pour se connecter sur un conteneur depuis son navigateur. Il fournit également des modèles de conteneurs pour pouvoir déployer des applications rapidement. La prise en main est plus simple pour des néophytes et la courbe d’apprentissage plus douce. C’est parfait pour mon équipe qui, à mon grand désespoir, a des difficultés à utiliser des programmes en ligne de commandes.
Malheureusement, cette maquette n’est possible qu’avec Windows Server 2019 et n’est donc pas encore envisageable avec Interoute, notre prestataire actuel.
......
......@@ -2,7 +2,7 @@
\subsection{Création du cluster Swarm}
La création du cluster est très simple. Il suffit d’installer Docker et de créer le cluster en une commande. La création de la machine virtuelle se fait via l’interface web d’Interoute. J'ai automatisé le dépoiement par un script Powershell (voir figure \ref{fig:InstallDockerps1}).
La création du cluster est très simple. Il suffit d’installer Docker et de créer le cluster en une commande. La création de la machine virtuelle se fait via l’interface web d’Interoute. J'ai automatisé le déploiement par un script Powershell (voir figure \ref{fig:InstallDockerps1}).
\begin{figure}[h!]
......
......@@ -62,7 +62,7 @@ networks:
\end{tcolorbox}
L'extrait ci-dessus est épuré pour ne montrer que la définition du conteneur Kronos Efficient. Le fichier complet est disponible en annexe. Il comporte quatre sections principales : la version du format Compose utilisée dans le fichier (ligne 1), la définition des services à déployer (ligne 3), les volumes utilisés (ligne 34), les réseaux utilisés (ligne 37).
La service \verb|Efficient5| est défini à partir de la ligne 4. L’image à utiliser pour créer le conteneur est précisée (ligne 5). Viennent ensuite les paramètres de déploiement (ligne 6) précisant le nombre de répliques de conteneur (ligne 7) et une politique de redémarrage (lignes 8-12) suivies de la politique de mise à jour (lignes 13-16). Les variables d’environnement utilisées pour configurer le conteneur sont spécifiées (lignes 17-24). Le volume utilisé pour persister les données est défini (lignes 25-26). Kronos Efficient utilise un volume pour stocker les documents liés à un salarié, ceux-ci sont stockés sur le disque. Ensuite, le label utilisé pour configurer traefik est mis en commentaire (lignes 27-28) car, comme nous l'avons vu précédemment, la maquette avec Traefik ne fonctionne pas sous Windows Server 2016. C'est pourquoi, le mappage de port est spécifié. Ici, le port 80 du cluster est mappé sur le port 80 du conteneur (lignes 29-30). Pour finir, le réseau utilisé par le conteneur est précisé.
Le service \verb|Efficient5| est défini à partir de la ligne 4. L’image à utiliser pour créer le conteneur est précisée (ligne 5). Viennent ensuite les paramètres de déploiement (ligne 6) précisant le nombre de répliques de conteneur (ligne 7) et une politique de redémarrage (lignes 8-12) suivit de la politique de mise à jour (lignes 13-16). Les variables d’environnement utilisées pour configurer le conteneur sont spécifiées (lignes 17-24). Le volume utilisé pour persister les données est défini (lignes 25-26). Kronos Efficient utilise un volume pour stocker les documents liés à un salarié, ceux-ci sont stockés sur le disque. Ensuite, le label utilisé pour configurer Traefik est mis en commentaire (lignes 27-28), car, comme nous l'avons vu précédemment, la maquette avec Traefik ne fonctionne pas sous Windows Server 2016. C'est pourquoi le mappage de port est spécifié. Ici, le port 80 du cluster est mappé sur le port 80 du conteneur (lignes 29-30). Pour finir, le réseau utilisé par le conteneur est précisé.
\par
En juin 2017, Docker a ajouté la possibilité de joindre des fichiers de configuration lors de la création d’un conteneur. Par exemple, la commande suivante créer une nouvelle configuration nommée \verb|KE5WebConfig| contenant le fichier \verb|.\efficient5\web.config|.
......@@ -78,7 +78,7 @@ Cependant, sous Windows, l’implémentation de la commande \verb|docker config|
\item Les fichiers de configuration avec des cibles personnalisées ne sont pas directement montés par liaison (bind-mount) dans les conteneurs Windows, puisque Windows ne prend pas en charge ce type de montage pour les fichiers. Au lieu de cela, les configurations d’un conteneur sont toutes montées dans le répertoire \verb|C:\ProgramData\Docker\interne| dans le conteneur. Des liens symboliques sont utilisés pour pointer à partir de là vers la cible souhaitée.
\item Lors de la création d’un service qui utilise des conteneurs Windows, les options permettant de spécifier l’UID, le GID et le mode ne sont pas prises en charge pour les configs. Les configs ne sont actuellement accessibles que par les administrateurs et les utilisateurs ayant un accès au système dans le conteneur.
\end{itemize}
Par rapport à ce dernier point, les premiers tests sont un échec total, car il n’est pas possible de spécifier des droits sur ces fichiers pour un conteneur Windows, comme il est possible de le faire avec conteneur Linux. IIS n’a pas les droits sur les fichiers de configuration et génère une erreur. En 2018, lors de ces tests, peu de personnes ont tenté cette configuration, car je n’ai trouvé qu’une pull request sur le dépôt Moby \cite{PullRequestChown} concernant l’ajout du paramètre \verb|--chown| pour les commandes \verb|ADD| et \verb|COPY| permettant de spécifier le propriétaire d’un fichier lors de la création du conteneur. Cela n’aide pas mais c’est un pas vers la solution. Un incident similaire \cite{IssueWindowsSecret} à mon expérience, mais relatif aux secrets, fait référence à cette pull request. Encore un autre incident sur le dépôt Docker-IIS \cite{IssueWebConfig} expose le problème que je rencontre sans donner de solution ou de moyen de contourner le problème. À ce jour, il n’y a pas de solution.
Par rapport à ce dernier point, les premiers tests sont un échec total. Il n’est pas possible de spécifier des droits sur ces fichiers pour un conteneur Windows, comme il est possible de le faire avec conteneur Linux. IIS n’a pas les droits sur les fichiers de configuration et génère une erreur. En 2018, lors de ces tests, peu de personnes ont tenté cette configuration. Je n’ai trouvé qu’une pull request sur le dépôt Moby \cite{PullRequestChown} concernant l’ajout du paramètre \verb|--chown| pour les commandes \verb|ADD| et \verb|COPY| permettant de spécifier le propriétaire d’un fichier lors de la création du conteneur. Cela n’aide en rien, mais c’est un pas vers la solution. Un incident analogue \cite{IssueWindowsSecret} à mon expérience, mais relatif aux secrets, fait référence à cette pull request. Encore un autre incident sur le dépôt Docker-IIS \cite{IssueWebConfig} expose le problème que je rencontre sans donner de solution ou de moyen de contourner le problème. À ce jour, il n’y a pas de solution.
\par
De la même façon que les fichiers de configuration, les informations sensibles pourraient être gérées par Docker par la commande \verb|docker secret|. Le fonctionnement est très similaire aux configurations vues précédemment. Toutefois, les informations sensibles font partie des fichiers de configuration (chaine de connexion à la base de données, identifiants …) et il y a de fortes limitations sous Windows \cite{DockerSecret}. Ce système d’exploitation n’a pas de pilote intégré pour la gestion des disques RAM, donc dans les conteneurs Windows en cours d’exécution, les secrets sont conservés en texte clair sur le disque racine du conteneur. Les mêmes limitations que pour les configurations s’appliquent également. Si les données sensibles ne sont pas cryptées en mémoire, mais présentent sur le disque, il n’y a aucun intérêt à utiliser les secrets.
......
......@@ -14,9 +14,9 @@ J’ai étudié la mise en place de deux serveurs proxy interne : Haproxy et Ngi
\subsubsection{HAProxy}
\textbf{HAProxy} est un équilibreur de charge à haute disponibilité et un serveur proxy pour les applications basées sur TCP et HTTP. Il est libre et gratuit. Il a la réputation d'être rapide et efficace. Il est notamment utilisé par un certain nombre de sites web à forte charge tel que GitHub, Bitbucket, Stack Overflow, Reddit, Speedtest.net, Tumblr, Twitter, … Il est écrit en C et est supporté sur Linux, FreeBSD, OpenBSD, Solarix et AIX. Une image Docker officielle existe permettant de l’utiliser dans un conteneur Linux sans effort. Par contre, aucune image pour Windows n’existe. Il est possible de le compiler pour Windows en utilisant Cygwin. La création d’une image pour Windows est donc possible, mais n'est pas viable pour ce projet. Cela prendrait trop de temps à mettre en place. Il faudrait créer une nouvelle image à chaque mise à jour ou release officielle de HAProxy pour que l’image soit à jour et éviter les failles de sécurité. Ce serait un trop gros travail de maintenance à assumer.
\textbf{HAProxy} est un équilibreur de charge à haute disponibilité et un serveur proxy pour les applications basées sur TCP et HTTP. Il est libre et gratuit. Il a la réputation d'être rapide et efficace. Des sites web à forte charge tels que GitHub, Bitbucket, Stack Overflow, Reddit, Speedtest.net, Tumblr ou encore Twitter l'utilisent. Il est écrit en C et est supporté sur Linux, FreeBSD, OpenBSD, Solarix et AIX. Une image Docker officielle existe permettant de l’utiliser dans un conteneur Linux sans effort. Par contre, aucune image pour Windows n’existe. Cygwin permet de le compiler et de l'utiliser sous Windows. La création d’une image pour Windows est donc possible, mais n'est pas viable pour ce projet. Cela prendrait trop de temps à mettre en place. Il faudrait créer une nouvelle image à chaque mise à jour ou release officielle de HAProxy pour que l’image soit à jour et éviter les failles de sécurité. Ce serait un trop gros travail de maintenance à assumer.
\par
Mise à part ce point bloquant, HAProxy est adapté à notre besoin. Sa configuration est simple. Elle consiste en un fichier découpé en cinq sections. La section \verb|global| regroupe tous les paramètres de configuration du serveur HAProxy. La section \verb|defaults| concerne les paramètres par défaut. La section \verb|resolvers| est utilisée pour gérer l’utilisation du serveur DNS Docker. La section \verb|frontend| configure le ou les ports à écouter et les règles de redirection. Enfin, la section \verb|backend| définit quels sont les serveurs (dans notre cas les conteneurs) vers lesquels renvoyer les requêtes.
Mis à part ce point bloquant, HAProxy est adapté à notre besoin. Sa configuration est simple. Elle consiste en un fichier découpé en cinq sections. La section \verb|global| regroupe tous les paramètres de configuration du serveur HAProxy. La section \verb|defaults| concerne les paramètres par défaut. La section \verb|resolvers| est utilisée pour gérer l’utilisation du serveur DNS Docker. La section \verb|frontend| configure le ou les ports à écouter et les règles de redirection. Enfin, la section \verb|backend| définit quels sont les serveurs (dans notre cas les conteneurs) vers lesquels renvoyer les requêtes.
\par
La section \verb|frontend| ci-dessous est nommée \verb|fe_web| (ligne 1). Elle écoute sur le port 80 (ligne 2). Elle redirige les requêtes http://test.kronosefficient.com et http://test.kronosefficient.com/efficient5 vers le backend \verb|test_ke| (lignes 3 et 4). Ce dernier définit le serveur nommé \verb|test_efficient5| (ligne 8) qui correspond au service \verb|efficient5| déployé dans la stack \verb|test.kronosefficient.com|. Le DNS Docker résout le nom du service par l’IP du conteneur au sein du cluster Swarm. Le conteneur HAProxy doit être sur le même réseau privé virtuel que le conteneur Kronos Efficient.
......@@ -63,7 +63,7 @@ Pour utiliser HAProxy, il faut ajouter des nœuds worker Linux au cluster Swarm,
\newpage
\subsubsection{Nginx}
\textbf{Nginx} est un serveur web pouvant être utilisé en tant qu’équilibreur de charge et serveur proxy pour les applications basées sur HTTP. Il est libre et gratuit. À la base, il a été écrit pour surpasser le serveur web Apache en terme de performance. Il peut traiter environ quatre fois plus de requêtes à la seconde et utilise moins de mémoire. Il est écrit en C et est supporté sur Linux, FreeBSD, OpenBSD, Solarix, AIX, macOS et Windows. Une image Docker officielle existe permettant de l’utiliser dans un conteneur Linux sans effort. Par contre, aucune image pour Windows n’existe. Toutefois, une image est facile à créer, car le binaire existe.
\textbf{Nginx} est un serveur web pouvant être utilisé en tant qu’équilibreur de charge et serveur proxy pour les applications basées sur HTTP. Il est libre et gratuit. À la base, il a été écrit pour surpasser le serveur web Apache en matière de performance. Il peut traiter environ quatre fois plus de requêtes à la seconde et utilise moins de mémoire. Il est écrit en C et est supporté sur Linux, FreeBSD, OpenBSD, Solarix, AIX, macOS et Windows. Une image Docker officielle existe permettant de l’utiliser dans un conteneur Linux sans effort. Par contre, aucune image pour Windows n’existe. Toutefois, une image est facile à créer, car le binaire existe.
\par
La configuration ressemble beaucoup à celle d’Apache en simplifiée. Nous utilisons actuellement Apache en tant que proxy inverse. L’apprentissage du format de fichier de configuration sera plus rapide. Toutefois, il faudrait créer une nouvelle image à chaque mise à jour ou release officielle de Nging pour que l’image soit à jour et éviter les failles de sécurité. Ce serait un trop gros travail de maintenance à assumer.
\\
......
\section{Recettes}
Avant de mettre en production, il est nécessaire de s’assurer que la conteneurisation n’ait pas endommagé une fonctionnalité. Ainsi, je mets en place une recette technique et une recette fonctionnelle.
Avant de mettre ce projet en production, je dois m’assurer que la conteneurisation n’ait pas endommagé une fonctionnalité. Ainsi, je mets en place une recette technique et une recette fonctionnelle.
\subsection{Recette technique}
......
......@@ -6,13 +6,13 @@ Concernant la gestion de projet, j’ai utilisé l’application OpenProject, ca
\subsection{Architecture de migration}
Dans cette optique, le serveur web frontal actuel est dupliqué. Une adresse IP publique différente de celle utilisée actuellement lui est assignée. La configuration des hôtes virtuels du serveur web est modifiée pour rediriger vers le cluster Docker Swarm. Ainsi les phases de tests et de déploiement sont séparées. Il suffit de modifier le fichier hosts de la machine qui réalise les tests pour pointer vers le nouveau serveur sans modifier la production. De la même façon, le déploiement se fera par changement de DNS public. Cette méthode permet de basculer client par client sans aucune coupure de service et en réalisant les tests en amont. L’ancien serveur sera stoppé lorsque le DNS de tous les clients aura été mis à jour, 24h en général.
Dans cette optique, le serveur web frontal actuel est dupliqué. Une adresse IP publique différente de celle utilisée actuellement lui est assignée. La configuration des hôtes virtuels du serveur web est modifiée pour rediriger vers le cluster Docker Swarm. Ainsi les phases de tests et de déploiement sont séparées. Il suffit de modifier le fichier hosts de la machine qui réalise les tests pour pointer vers le nouveau serveur sans modifier la production. De la même façon, le déploiement se fera par changement de DNS public. Cette méthode permet de basculer client par client sans aucune coupure de service et en réalisant les tests en amont. L’ancien serveur sera stoppé lorsque le DNS de tous les clients aura été mis à jour, moins de 24 h en général.
\subsection{Audit complet des serveurs d’applications}
Afin de s’assurer de la continuité de service, de la cohérence des tests et de prioriser les mises en production, il est nécessaire d’auditer chaque serveur applicatif afin de personnaliser le processus de mise en production pour chacun d’entre eux.
Afin de s’assurer de la continuité de service, de la cohérence des tests et de hiérarchiser l'ordre des instances à mettre en production, il est nécessaire d’auditer chaque serveur applicatif. De plus, cette tâche permet de personnaliser le processus de mise en production pour chacun d’entre eux.
Les conteneurs à déployer découlent directement de la liste des applications installées. Le logiciel d’inventaire permet d’obtenir cette liste sans effort.
À l’inverse, analyser les imports/exports est laborieux faute de standardisation. Le même process est réalisé de façon différente d’un client à l’autre. Ce manque de rigueur impose une analyse poussée afin de ne pas oublier un paramètre « codé en dur ».
À l’inverse, analyser les imports/exports est laborieux faute de standardisation. Le même procédé est réalisé de façon différente d’un client à l’autre. Ce manque de rigueur impose une analyse poussée afin de ne pas oublier un paramètre « codé en dur ».
\subsection{Les étapes d’une mise en production}
......
......@@ -27,9 +27,9 @@ La recette technique est fortement liée à l’étape précédente. En règle g
\par
La recette technique est beaucoup plus longue. Les tests sont manuels. Si le nombre d’instances à migrer était plus important, il aurait été intéressant de les automatiser. Dans le cas présent, la mise en place de l’automatisation des tests par Selenium ou un outil similaire prendrait plus de temps que les tests manuels. De plus, tous les spécifiques doivent être testés manuellement.
\par
La mise en production est simplement le changement du DNS publique pour pointer vers l’adresse IP publique dédiée à la nouvelle infrastructure.
La mise en production est simplement le changement du DNS public pour pointer vers l’adresse IP publique dédiée à la nouvelle infrastructure.
\par
J’ai ajouté une période d’attente de quatre nuits entre la mise en production du serveur et l’arrêt de l’ancien serveur applicatif pour laisser le temps au changement de DNS publique de se répliquer. Il convient de vérifier les logs de l’ancien serveur web afin de s’assurer que plus aucun client ne se connecte dessus. Dans le cas inverse, il faudra investiguer pourquoi le changement DNS ne s’est pas fait et mettre en place une solution.
J’ai ajouté une période d’attente de quatre nuits entre la mise en production du serveur et l’arrêt de l’ancien serveur applicatif pour laisser le temps au changement de DNS public de se répliquer. Il convient de vérifier les logs de l’ancien serveur web afin de s’assurer que plus aucun client ne se connecte dessus. Dans le cas inverse, il faudra investiguer pourquoi le changement DNS ne s’est pas fait et mettre en place une solution.
\par
Il est important de noter que les tâches les plus longues concernent l’écriture et réalisation des tests. Elles sont essentielles pour assurer une qualité de service.
......
\section{Mise en œuvre}
En termes de respect de planning, la mise en production a été chaotique. Un quart de l’équipe support dont je suis le chef d’équipe n’a pas été remplacé. Le support client quotidien est alors devenu une priorité. Je n’ai pas été en mesure de me dégager une seule journée complète pour réaliser la mise en production. Heureusement, les mesures prises pour assurer la continuité de service m’ont permis d’avancer dès que j’en avais le temps sans aucune coupure de service.
En ce qui concerne le respect du planning, la mise en production a été chaotique. Un quart de l’équipe support dont je suis le chef d’équipe n’a pas été remplacé à la suite de départ ou fin de contrat. Le support client quotidien est alors devenu une priorité. Je n’ai pas été en mesure de me dégager une seule journée complète pour réaliser la mise en production. Heureusement, les mesures prises pour assurer la continuité de service m’ont permis d’avancer dès que j’en avais le temps sans aucune coupure de service.
\par
La phase d’analyse de l’existant m’a permis de découvrir que deux clients avaient des spécifiques d’interface paie impossible à intégrer dans la nouvelle infrastructure sans les réécrire. En effet, il s’agit de pages web ASP développées spécifiquement. Le fait de lier un fichier de l’hôte à un conteneur par un volume (« bind mount ») n’est pas supporté sous Windows. En même temps, j’ai constaté que ces pages étaient vulnérables à plusieurs attaques, notamment aux injections SQL et divulgations d’informations. Même en gardant ces deux instances hors de la nouvelle infrastructure, il nous est impossible de garder ces failles qui mettent en péril la sécurité des données de nos clients.
\par
Pendant cette phase, notre direction mondiale a décidé d’arrêter cette plateforme pour prioriser notre produit SaaS Workforce Ready (WFR) dédié aux petites et moyennes entreprises. En 2017, WFR a été lancé en Europe, mais son manque de fonctionnalités par rapport à la gestion RH européenne a été un frein à son développement. Cette annonce a été une surprise pour nous et nos clients. Les récents investissements dans des projets tels qu’un audit de sécurité ou la mise en conformité ISO 27001 ne laissaient pas présager une telle décision. De plus, les revenus du produit Efficient constituent 90 \% des revenus PME de l’Europe. À l’époque de leur installation, un tiers des clients hébergés étaient intéressés par un produit SaaS et utilisaient WFR. Le produit ne correspondait pas du tout à leurs besoins, c’est pourquoi nous leur avions proposé Efficient en mode hébergé. La date d’arrêt a été fixée au 31 décembre 2020. Aucune négociation n’a été possible. Laissant une année à notre équipe commerciale pour convaincre nos clients Efficient hébergés de basculer vers WFR. De mon côté, malgré le temps passé et les difficultés surmontées, j’ai stoppé ce projet, car le retour sur investissement est inexistant sur la période de vie restante de cette infrastructure.
Pendant cette phase, notre direction mondiale a décidé d’arrêter cette plateforme pour éviter de concurrencer notre produit SaaS Workforce Ready (WFR) dédié aux petites et moyennes entreprises. En 2017, WFR a été lancé en Europe, mais son manque de fonctionnalités par rapport à la gestion RH européenne a été un frein à son développement. Cette annonce a été une surprise pour nous et nos clients. Les récents investissements dans des projets tels qu’un audit de sécurité ou la mise en conformité ISO 27001 ne laissaient pas présager une telle décision. De plus, les revenus du produit Efficient constituent 90 \% des revenus PME de l’Europe. À l’époque de leur installation, un tiers des clients hébergés étaient intéressés par un produit SaaS et utilisaient WFR. Le produit ne correspondait pas du tout à leurs besoins, c’est pourquoi nous leur avions proposé Efficient en mode hébergé. La date d’arrêt a été fixée au 31 décembre 2020. Aucune négociation n’a été possible. Laissant une année à notre équipe commerciale pour convaincre nos clients Efficient hébergés de basculer vers WFR. De mon côté, malgré le temps passé et les difficultés surmontées, j’ai stoppé ce projet, car le retour sur investissement est inexistant sur la période de vie restante de cette infrastructure.
% \begin{figure}[h!]
......
......@@ -23,11 +23,11 @@ Le déploiement des instances Kronos Efficient par un orchestrateur de conteneur
\begin{itemize}
\item la réduction des coûts en permettant l’exécution de plusieurs instances de l’application sur un même serveur, réduisant le nombre de licences Windows et de ressources dédiées au système d’exploitation.
\item l’amélioration de la disponibilité en intégrant un système automatique de redéploiement d’un conteneur en cas d’échec de celui-ci
\item la facilité de la maintenance en basant le déploiement et la mise à jour d’une instance de l’application via un unique fichier YML et une unique commande
\item la facilité de la maintenance en basant le déploiement et la mise à jour d’une instance de l’application via un unique fichier YAML et une unique commande
\end{itemize}
Les aspects intégrité et confidentialité des données ont été gérés par l’équipe sécurité via une certification ISO 27001 et un audit de sécurité réalisé par une société externe.
L’équipe sécurité a géré les aspects intégrité et confidentialité des données via une certification ISO 27001 et un audit de sécurité réalisé par une société externe.
J’ai été acteur sur l’ensemble des sous-projets que ce soit en tant que maître d’ouvrage, architecte ou développeur. Quelques mois avant le lancement du projet, j’ai recruté un étudiant en alternance au CESI. Il prépare un master « Responsable en ingénierie système et réseau ». Il fait donc partie de mon équipe et gère le support utilisateur au quotidien. Pour son projet de fin d’études, il a réalisé le projet de supervision et de clustering SQL Server sous ma direction.
De mon côté, j’ai réalisé seul le projet dont il est question ici : le déploiement des instances Kronos Efficient par un orchestrateur de conteneurs.
De mon côté, j’ai réalisé seul le projet de conteneurisation et déploiement des instances Kronos Efficient par un orchestrateur de conteneurs.
\begin{table}[ht]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment