📘 Déploiement de logiciel

Ce chapitre introduit la notion de déploiement de logiciel.

1. Étapes d’un déploiement

Le déploiement d’un logiciel est l’action de rendre un logiciel opérable dans un environnement de déploiement donné, pour une exploitation donnée. On peut décomposer un déploiement en différentes étapes :

  1. Un accès à l’environnement de déploiement doit être réalisé, permettant à la fois de contrôler l’environnement et d’y déposer des fichiers. Cet accès peut être soit direct en utilisant l’interface matérielle de la machine, ou distant par le réseau informatique.

  2. L’ensemble des fichiers qui composent le logiciel doivent être copiés dans l’environnement de déploiement.

  3. Si besoin, l’ensemble des dépendances du logiciel déployé doivent être installées dans l’environnement.

  4. Si besoin, d’autres logiciels (par exemple une base de donnée) doivent être conjointement déployés avec le logiciel déployé.

  5. Si c’est un logiciel qui s’exécute en service continu, il doit être exécuté.

Ces étapes peuvent être très influencées par les caractéristiques du déploiement.

Exemple 1. Exemple d’étapes de déploiement de Simplestblog

On peut déployer Simplestblog à l’aide des étapes suivantes :

simplestblog deployment tasks.drawio
  1. En supposant que l’environnement de déploiement possède le logiciel sshd (Openssh) en exécution comme service, on se connecte à distance à l’environnement à l’aide d’un client SSH.

  2. Une fois dans l’environnement de déploiement, on réalise toutes les actions d’installation nécessaires : dépendances, déploiement de la base de données MariaDB, copie du logiciel Simplestblog.

  3. On démarre un processus Simplestblog, qui se met à écouter sur le port publié 5000.

  4. À partir de là, le déploiement est terminé, et les utilisateur⋅ice⋅s peuvent depuis leur propre environnement (par exemple un smartphone) exécuter un navigateur web et se connecter à distance sur le port 5000 de l’environnement de déploiement, afin d’utiliser le logiciel.

Ce schéma ne décrit pas les communications réseau requises lors de ce déploiement :

  • une communication réseau est requise pour que le client SSH de l’administrateur⋅ice système se connecte au processus sshd qui donne le contrôle sur l’environnement de déploiement,

  • une communication réseau est requise pour permettre au processus Simplestblog de se connecter au processus du logiciel de base de données,

  • une communication réseau est requise pour permettre au navigateur web de l’utilisateur⋅ice de se connecter au processus Simplestblog

La notion de communication réseau sera expliqué dans un chapitre plus loin dans le cours.

2. Caractéristiques d’un déploiement

Un déploiement se définit principalement par les caractéristiques du logiciel déployé, et les caractéristiques de l’environnement de déploiement.

2.1. Caractéristiques du logiciel déployé

Un déploiement sera dépendant des caractéristiques du logiciel à déployer, notamment :

  • Un logiciel peut être compilé pour architecture matérielle donnée (x86, ARM, etc.), et/ou être construit pour un système d’exploitation donné (Windows, GNU/Linux, Android etc.).

    • Influence sur le déploiement:l’environnement de déploiement doit être compatible avec le logiciel.

  • Un logiciel peut être exécuté en contrôle direct de manière ponctuelle (typiquement lancé au moment d’une tâche), ou bien s’exécuter sous forme de service continu (typiquement pendant des journées et/ou nuits entières) généralement en arrière-plan (aussi appelé en daemon). Par exemple une commande comme ls, un compilateur comme gcc, ou un logiciel de graphisme comme GIMP s’exécutent de manière ponctuelle au moment de faire une tâche. À l’inverse, un logiciel de pare-feu s’exécute en service continu et en arrière-plan, de l’allumage à l’extinction de l’environnement.

    • Influence sur le déploiement: si le logiciel s’exécute en service continu, il faut l’exécuter dès son déploiement.

  • Un logiciel peut fournir ou non une interface utilisateur directe, que ce soit une interface textuelle (par exemple l’éditeur de texte nano) ou une interface graphique (par exemple un logiciel de graphisme ou un navigateur web). La présence d’une interface implique la possibilité qu’un⋅e humain⋅e interagisse directement avec le logiciel durant son exécution, via l’environnement dans lequel il s’exécute (typiquement à l’aide d’un clavier et/ou d’une souris).

    • Influence sur le déploiement: si le logiciel possède une interface graphique, l’environnement de déploiement devra le permettre.

  • Un logiciel peut avoir besoin de communiquer avec d’autres logiciels en exécution, pour échanger des données et/ou des requêtes. Ces autres logiciels peuvent être soit dans le même environnement, soit dans des environnements distants. Par exemple un navigateur web a besoin de communiquer avec un serveur web, et un serveur web peut avoir besoin de communiquer avec une base de données.

    • Influence sur le déploiement: si le logiciel a des besoins de communication, il faudra s’assurer qu’il a accès aux interfaces réseaux nécessaires et qu’il soit sur les réseaux nécessaires.

Il existe des logiciels qui ne possèdent pas d’interface graphique directe, mais qui fournissent indirectement une interface graphique par le biais d’un second logiciel. Un exemple classique est un serveur web, qui n’expose aucune interface graphique au niveau de l’environnement où il s’exécute, mais qui peut être contacté par un navigateur web (exécuté soit dans le même environnement, soit dans un environnement distant) et lui fournir une interface web à afficher.

2.2. Caractéristiques de l’environnement de déploiement

L’environnement d’exécution d’un logiciel peut prendre des formes très variées, allant du supercalculateur au lave-linge, en passant l’ordinateurs portable ou le smartphone. Certains caractéristiques nous intéressent particulièrement dans le cadre d’un déploiement :

  • Un environnement possède une architecture matérielle particulière (x86, ARM, etc.) et un système d’exploitation particulier (Windows, GNU/Linux, Android, etc.).

    • Influence sur le déploiement: le logiciel doit être compatible avec l’environnement de déploiement.

  • Un environnement peut posséder ou non une interface homme-machine (écran, clavier, souris, etc.). S’il n’y a pas d’interface, on parle alors d’un environnement headless, qui n’est utilisable que par une connexion à distance.

    • Influence sur le déploiement: si l’environnement est distant et/ou headless, il est nécessaire de faire le déploiement par une connexion à distance (voir Section 3.1).

  • Un environnement peut être directement manipulé par l’utilisateur (poste de travail, téléphone, etc.), ou bien être un environnement distant auquel l’utilisateur se connecte par un réseau.

    • Influence sur le déploiement: si l’environnement est directement manipulé par l’utilisateur,

      • L’utilisateur peut faire le déploiement par lui-même, ce qui nécessite de lui mettre à disposition le logiciel et la procédure d’installation. Cela peut par exemple se faire en publiant un logiciel sur un magasin d’application.

      • Le logiciel peut être pré-installé dans l’environnement dès la création de celui-ci (par exemple installer la couche logicielle d’un smartphone en dernière étape d’usine).

      • Le logiciel peut être installé à distance sur l’environnement utilisateur. C’est notamment parfois le cas dans le cadre d’une gestion automatisée de parc machine dans une organisation (par exemple une entreprise ou un établissement public).

2.3. Cas particulier : le modèle Software-as-a-Service

Le Software-as-a-Service est un modèle technique et économique aujourd’hui très répandu pour la commercialisation et la distribution de logiciels. Ce modèle consiste à déployer un logiciel sous la forme d’un serveur web sur un environnement distant (typiquement chez un hébergeur cloud), et de permettre ensuite aux utilisateurs de s’y connecter à distance via le réseau internet à l’aide d’un navigateur web. La monétisation du logiciel peut ensuite se faire à l’aide de publicité ou d’une offre d’abonnement.

Caractéristiques d’un scénario type Software-as-a-Service
Logiciel type
  • Compilé pour une architecture x86 pour une exécution sur un système GNU/Linux,

  • S’exécute en service continu,

  • Pas d’interface utilisateur directe (mais fournit une interface web indirecte accessible à distance au travers du navigateur web de l’utilisateur),

  • Doit pouvoir communiquer à distance avec le navigateur web de l’utilisateur, et en local avec un logiciel de base de données.

Environnement de déploiement type
  • Architecture x86, système GNU/Linux,

  • Pas d’interface homme-machine,

  • Distant, non directement manipulé par l’utilisateur.

Grâce à l’évolution continue des technologies web, le Software-as-a-Service est aujourd’hui hégémonique et a pris une place très importante : il est de plus en plus courant d’utiliser un logiciel directement depuis un navigateur, plutôt que de télécharger et d’installer un logiciel dans son environnement. C’est le cas de logiciels comme les applications Google (Gmail, Youtube, Google Docs,…), Discord, Netflix, ou Deezer.

Un certain nombre d’exemples et d’exercices de ce cours s’inspirent du modèle Software-as-a-Service.

3. Actions types d’un déploiement

3.1. Accès à distance

De nombreux contextes requièrent de pouvoir déployer à distance un logiciel dans un environnement de déploiement, c’est à dire au travers d’une connexion réseau plutôt que par un accès physique à l’environnement. Pour cela il est nécessaire que l’environnement de déploiement possède un logiciel serveur permettant un accès à distance. Ce logiciel doit rester en exécution en continu, et doit écouter sur un port exposé afin de rendre possible une connexion distante.

On peut distinguer deux aspects de l’accès à distance :

  • Le contrôle à distance consiste principalement à pouvoir modifier les fichiers et exécuter ou stopper des processus de l’environnement de déploiement. C’est par ce biais que l’on peut notamment démarrer à distance le logiciel déployé (si nécessaire). Exemples d’outils et de protocoles : VNC, X2go, RDP, SSH (notamment via la commande ssh), PowerShell Remoting (Windows seulement).

  • Le transfert de données consiste à pouvoir transférer des fichiers vers l’environnement de déploiement, par exemple le logiciel à déployer, ou des fichiers de configurations nécessaires à son fonctionnement. Exemples d’outils et de protocoles : FTP (déconseillé car non sécurisé), SFTP (notamment via la commande scp), SMB, robocopy (Windows seulement).

Un accès à distance à un environnement doit impérativement être sécurisé, pour ne pas "donner les clés" de l’environnement à n’importe qui ! Cela signifie à la fois chiffrer la communication réseau avec l’environnement, et faire très attention à limiter les personnes pouvant s’authentifier. Par exemple, le protocole SSH chiffre toujours la communication, et permet une authentification très fiable par clé cryptographique.

3.1.1. Présentation de la suite logicielle OpenSSH

OpenSSH est un projet de logiciel libre qui met à disposition un ensemble complet d’outils pour gérer l’accès à distance à un environnement de manière sécurisée. Bien que principalement utilisés pour accéder à distance à des environnement de type GNU/Linux, ces outils peuvent également fonctionner avec d’autres systèmes d’exploitation (notamment Windows).

openssh

Trois outils de la suite OpenSSH vont nous intéresser :

  • sshd est un logiciel qui s’exécute comme service dans un environnement et qui écoute par défaut sur le port publié 22. Il joue le rôle de serveur SSH (c’est-à-dire qu’il permet à un client SSH de se connecter à lui pour un contrôle à distance), et de serveur SFTP (c’est-à-dire qu’il permet à un client SFTP de se connecter à lui pour un transfert de données).

  • ssh est un client SSH qui permet de se connecter à distance à un serveur SSH pour effectuer un contrôle à distance en ligne de commande, via l’exécution d’un interpréteur de commandes interactif sur l’environnement de déploiement.

  • scp est un client SFTP qui permet de copier des fichiers depuis/vers un serveur SFTP pour effectuer des transferts de données.

Un grand avantage de ces outils est qu’ils reposent sur des protocoles sécurisés (ici, SSH et SFTP) qui, lorsqu’ils sont bien utilisés, limitent grandement le risque qu’une personne malintentionnée puisse intercepter les communications effectuées avec l’environnement distant.

SFTP est un protocole qui est une extension du protocole SSH. Ainsi, dans les coulisses, un transfert de fichier via SFTP s’accomplit toujours à l’aide d’une connexion SSH.

3.1.2. Authentification d’une connexion SSH

Une connexion SSH requiert une authentification pour s’assurer que seuls les individus ou environnements autorisés puissent se connecter à un serveur SSH donné. Cette sécurité repose sur un ensemble défini de comptes utilisateurs sur le serveur SSH, pour lesquels une connexion SSH est autorisée.

Lorsqu’on souhaite établir une connexion SSH (avec les outils scp ou ssh par exemple), il faut donc toujours fournir :

  • le compte utilisateur distant avec lequel on souhaite se connecter,

    Le compte utilisateur distant avec lequel on se connecte va définir ce qu’on sera autorisés où non à faire sur l’environnement distant. Par exemple si ce compte n’a pas les droits administrateur (root), on ne pourra pas modifier les fichiers système ou affecter des services systèmes de l’environnement distant.
  • une preuve que l’on a le droit d’utiliser ce compte utilisateur, qui peut prendre au choix parmi deux formes :

    • le mot de passe de ce compte utilisateur,

    • une clé cryptographique privée (qu’on appelle plus simplement clé SSH) qui prouve que l’on a le droit d’utiliser ce compte utilisateur − à noter que cela nécessite d’enregistrer au préalable sur le compte utilisateur distant la clé cryptographique publique associée à la clé cryptographique privée (principe de la cryptographie asymétrique).

On retiendra que l’utilisation d’une clé cryptographique est plus sécurisée qu’un mot de passe, notamment car une clé cryptographique est impossible à deviner pour un attaquant. Cependant l’utilisation d’un très long (~30 caractères) mot de passe généré aléatoirement peut également fournir des garanties suffisantes de sécurité.

Si on ne fournit pas de compte utilisateur lors d’un appel à scp ou ssh, c’est par défaut le nom du compte utilisateur de la machine cliente qui est utilisé. Par exemple si je suis connecté sous le nom d’utilisateur lucien sur mon ordinateur personnel, et que je me connecte à distance sans spécifier de compte utilisateur, c’est le nom d’utilisateur lucien qui sera utilisé. Pour que cela fonctionne, il faut donc que l’environnement distant où je me connecte possède également un compte utilisateur avec pour nom lucien.

Dans ce chapitre on ne détaillera pas comment spécifiquement gérer une authentification par mot de passe ou par clé SSH, cela sera directement vu en séance de TP.

3.1.3. Usage de l’outil ssh pour le contrôle à distance

L’utilitaire ssh est capable d’utiliser le protocole SSH pour ouvrir une session en ligne de commande sur un environnement de déploiement qui possède un serveur SSH en exécution.

Pour ouvrir une session SSH sur un environnement distant, on peut faire la commande :

$ ssh <utilisateur distant>@<hôte distant>

avec :

  • <utilisateur distant> : le nom d’utilisateur à utiliser pour se connecter au serveur SSH distant,

  • <hôte distant> : le nom d’hôte permettant d’identifier l’environnement distant sur le réseau (cet environnement doit posséder un serveur ssh en exécution),

Une fois connecté, on se retrouve face à un interpréteur de commandes (comme sh ou bash) qui s’exécute sur l’environnement distant, et qui nous permet donc d’interagir manuellement avec cet environnement.

Pour quitter une session SSH, on peut saisir simplement la commande :

$ exit
Exemple 2. Contrôle d’un environnement distant tatooine avec ssh

On souhaite gérer à distance un environnement de déploiement distant à l’aide d’OpenSSH. Cet environnement possède un serveur SSH en exécution (par exemple sshd), et possède un compte utilisateur avec pour nom anakin. Sur le réseau informatique où il se trouve, l’environnement de déploiement possède le nom d’hôte tatooine.

Plus précisément, on souhaite dans l’immédiat déclencher l’installation des dernières dernières mises à jour système sur l’environnement.

On commence par se connecter via ssh avec la commande :

obiwan@alderaan:~$ ssh anakin@tatooine

On arrive alors face à un interpréteur de commandes Linux classique, dont le prompt nous rappelle bien que nous sommes connectés avec le compte anakin et que nous sommes bien sur l’environnement tatooine dans le répertoire utilisateur (dénoté par le symbole ~) :

anakin@tatooine:~$

Le système d’exploitation de l’environnement tatooine étant Fedora Server, on peut installer les dernières mises à jour à l’aide de l’utilitaire dnf. Comme dnf va venir modifier des fichiers système, il est nécessaire d’utiliser la commande sudo pour faire exécuter dnf par le compte utilisateur root :

anakin@tatooine:~$ sudo dnf update
Updating and loading repositories:
 Fedora 42 openh264 (From Cisco) - x86_64       100% |   5.8 KiB/s |   5.8 KiB |  00m01s
 Fedora 42 - x86_64 - Updates                   100% |   5.6 MiB/s |   9.4 MiB |  00m02s
 Fedora 42 - x86_64                             100% |   8.8 MiB/s |  35.4 MiB |  00m04s
Repositories loaded.
…
(la suite des logs est trop verbeuse)

Puis une fois les mises à jour terminées, on choisit de clôre la session SSH :

anakin@tatooine:~$ exit

On reprend alors la main sur l’interpréteur de commandes de notre environnement local :

obiwan@alderaan:~$

3.1.4. Usage de l’outil scp pour le transfert de données

L’utilitaire scp est capable de copier des fichiers d’une machine à une autre à l’aide du protocole SFTP (une extension du protocole SSH).

Pour des raisons de sécurité, il est conseillé de ne pas utiliser une version de scp antérieure à la version 9.0 de OpenSSH. Si ce n’est pas possible, il faut privilégier l’utilitaire rsync en lieu et place.

Pour copier un fichier vers un environnement distant, on peut faire la commande :

$ scp <fichier local> <utilisateur distant>@<hôte distant>:<chemin distant>

avec :

  • <fichier local> : le chemin du fichier local que l’on souhaite copier sur l’environnement distant (cible),

  • <utilisateur distant> : le nom d’utilisateur à utiliser pour se connecter au serveur SSH distant,

  • <hôte distant> : le nom d’hôte permettant d’identifier l’environnement distant sur le réseau (cet environnement doit posséder un serveur ssh en exécution),

  • <chemin distant> : le chemin où copier le fichier sur l’environnement distant.

Nous verrons plus en détail la notion de réseau et de nom d’hôte dans un chapitre futur.

Pour copier un répertoire vers un environnement distant, il suffit d’ajouter l’option -r :

$ scp -r <répertoire local> <utilisateur distant>@<hôte distant>:<chemin distant>

avec <répertoire local> le chemin du répertoire que l’on souhaite copier sur l’environnement distant (cible).

Exemple 3. Envoi de données vers un environnement distant tatooine avec scp

On continue de vouloir administrer l’environnement distant tatooine.

On a préparé un fichier de configuration appelé httpd.conf que l’on souhaite copier à l’emplacement /home/anakin/configuration (à savoir le répertoire utilisateur du compte anakin) de l’environnement tatooine.

Pour effectuer le déploiement, on utilise un compte utilisateur obiwan sur un environnement local appelé alderaan. Depuis alderaan, on réalise la commande suivante :

obiwan@alderaan:~$ scp ./httpd.conf anakin@tatooine:/home/anakin/configuration
Après cette commande (et cela vaut aussi pour les commandes scp qui suivent), il faudra soit s’authentifier par mot de passe, soit par clé SSH.

Pour rappel dans une ligne de commande, le caractère ~, qui correspond automatiquement au chemin du répertoire utilisateur. Comme /home/anakin est le chemin du répertoire utilisateur anakin, sur l’environnement distant, on peut simplifier légèrement la commande de la manière suivante :

obiwan@alderaan:~$ scp ./httpd.conf anakin@tatooine:~/configuration

On souhaite ensuite copier un répertoire mon_site_web directement dans le répertoire /home/anakin. On réalise la commande suivante :

obiwan@alderaan:~$ scp -r ./mon_site_web anakin@tatooine:~/mon_site_web

Pour faire l’opération inverse, à savoir télécharger un fichier situé sur un environnement distant, on peut simplement inverser les arguments positionnels :

$ scp <utilisateur distant>@<hôte distant>:<fichier distant> <chemin local>

avec

  • <hôte distant> : le nom d’hôte permettant d’identifier l’environnement distant sur le réseau (cet environnement doit posséder un serveur ssh en exécution),

  • <fichier distant> : le chemin du fichier de l’environnement distant à copier,

  • <chemin local> : le chemin de l’emplacement où copier le fichier

Et comme pour l’envoi de données, on peut l’option -r si on souhaite télécharger un répertoire :

$ scp -r <utilisateur distant>@<hôte distant>:<répertoire distant> <chemin local>

avec <répertoire distant> le chemin du répertoire distant de l’environnement distant que l’on souhaite télécharger.

Exemple 4. Récupération de données d’un environnement distant tatooine avec scp

On cherche à récupérer des données stockées dans le même environnement que l’exemple précédent, à savoir l’environnement distant tatooine sur lequel on peut se connecter avec le nom d’utilisateur anakin.

D’abord on souhaite récupérer le fichier distant /home/anakin/data/database.sqlite, on réalise donc la commande :

obiwan@alderaan:~$ scp anakin@tatooine:~/data/database.sqlite .
Le point . désigne toujours le répertoire courant où on se situe avec l’interpréteur de commande (c’est à dire le répertoire où on s’est rendu à l’aide de la commande cd).

Puis on souhaite finalement récupérer tout le répertoire distant /home/anakin/data, on fait donc :

obiwan@alderaan:~$ scp -r anakin@tatooine:~/data .

3.2. Installation de dépendances

Il existe différentes manières d’installer les dépendances d’un logiciel dans un environnement :

  • Une dépendance peut être installée "à la main" en allant soit directement chercher le code source de la dépendance (qui doit alors être compilée, le cas échéant), soit aller chercher une version prête à l’emploi de la dépendance. On pourra généralement trouver ces artefacts directement sur le site web du projet logiciel de la dépendance. En procédant ainsi, on a la liberté de sélectionner la version que l’on souhaite, et on doit placer manuellement les fichiers qui composent la dépendance dans l’environnement. En revanche, cela peut mener à un travail laborieux dès lors qu’une dépendance possède elle-même des dépendances, ce qui peut mener à un graphe de dépendances fastidieux à installer.

  • Une dépendance peut être installée à l’aide d’un gestionnaire de paquets, à savoir un outil capable d’aller chercher la dépendance sur un référentiel de logiciels accessible sur Internet. En procédant ainsi, tout le graphe de dépendances est automatiquement installé, avec aucune (ou peu) d’actions manuelles requises. En revanche, une dépendance peut ne pas être disponible sur un référentiel, et si c’est le cas on doit se contenter des versions disponibles sur le référentiel. Enfin, notons que les gestionnaires de paquets peuvent être divisés en deux catégorie :

    • Les gestionnaires de paquets pré-installés au sein des systèmes d’exploitation. Par exemple le système d’exploitation Ubuntu repose sur le gestionnaire apt, le système Alpine sur apk, et Fedora sur dnf.

    • Les gestionnaires de paquets indépendants des systèmes d’exploitation, qui sont généralement spécifiques à un environnement technique particulier. Par exemple le gestionnaire de paquets pip se concentre sur les dépendances Python, tandis que npm se concentre sur les dépendances Javascript.

Il peut être assez vite compliqué de s’assurer d’avoir les bonnes versions requises de toutes les dépendances, et il peut être encore plus compliqué de faire co-habiter plusieurs versions d’une même dépendance dans le même environnement. Certains outils fournissent des mécanismes pour faciliter cela, par exemple la notion de venv fournie par le gestionnaire pip, mais il fait être minutieux.
Exemple 5. Installation des dépendances de Simplestblog dans un environnement Ubuntu

Supposons un environnement Ubuntu. On commence par utiliser le gestionnaire de paquets apt pour installer l’interpréteur Python dans sa version 3 :

# apt update
# apt install python3
apt update permet de télécharger la liste des paquets disponibles sur le référentiel, et apt install permet d’installer l’un des paquets de cette liste.

Les dépendances Python de Simplestblog sont définis dans un fichier qui suit le format standard requirements.txt et qui contient la liste suivante :

flask
mysql-connector-python
waitress

On utilise l’outil pip afin d’installer les dépendances listées dans ce fichier :

# pip install -r requirements.txt

4. Contextes de déploiement étudiés dans ce cours

Dans ce cours nous verrons comment déployer un logiciel pour le rendre utilisable auprès de ses utilisateur⋅ice⋅s. Nous nous intéresserons plus spécifiquement sur les logiciels qui s’exécutent comme des services en continu (typiquement, un serveur web ou une base de données). Plus précisément, on se concentrera sur des environnements de déploiement qui ne fournissent aucune interface graphique (aussi appelés headless), et on étudiera uniquement des logiciels sans interface utilisateur.