The twelve factor app: La méthodologie de création SAAS
La méthodologie d’application à 12 facteurs a été élaborée par les développeurs de Heroku.
Les facteurs représentent un ensemble de directives ou de meilleures pratiques pour des applications portables et résilientes qui prospéreront dans des environnements cloud (en particulier des applications logicielles en tant que services).
Docker a révolutionné le monde du conteneur, mais qu'aurait été cette prouesse technologique si personne ne l'avait utilisée ? Trois ans avant Docker, en 2011, Adam Wiggins de Heroku présente sa méthodologie de création de Software as a service : The Twelve-Factor App.
Cette méthodologie a radicalement changé la façon dont les développeurs conçoivent leur applications.
1 - Le code de base
Premier Facteur : Une version du code de base par service déployé, ce code pouvant être utilisé pour plusieurs déploiements.
Une image Docker est toujours relative à une version du code d'une application. Nous pouvons ainsi créer une image my-app:v1.11.0 contenant une certaine version du code de l'application, puis, lorsque celui-ci est chargé, construire une nouvelle image my-app:v1.11.1, par exemple. Une fois l'image créée, elle peut être lancée une infinité de fois sans subir la moindre altération
2 - Dépendances
Les dépendances sont le deuxième facteur: elles doivent être explicitement déclarées. Une images Docker est créée à partir d'un Dockerfile, soit un simple fichier , dans lequel chaque étape du build est clairement énoncée: du système d'exploitation qui est utilisé, aux paquets ajoutés, tout est inscrit dans le Dickerfile.
Prenons un exemple
FROM ubuntu:16.04 RUN apt update && \ apt install -y cowsay && \ apt clean CMD ["/usr/games/cowsay", "-f", "tux", "hello glmf"]
L'argument FROM nous indique à partir de quelle image notre nouvelle image est construite, ici il s'agit d'une image Ubuntu 16.04.
Les étapes de RUN successives permettent d'ajouter des librairies et des binaires à l'images initiale.
Finalement, CMD est la commande qui sera exécutée lors du run du conteneur.
3 - Configuration
Les configurations doivent être stockées dans l'environnement. Il est possible, lors de l'exécution du conteneur, de psser des variables d'environnement ou un fichier de variables :
-e, --env list Set environment variables --env-file list Read in a file of environment variables
Ce n'est cependant pas toujours très évident, et un orchestrateur permet de faire bien plus élégamment.
4 - Service externes
Pour attacher un service externe au runtime de Docker, l'option link est très utile. Cette option permet de découvrir une ressources par son nom, et de la lier à notre conteneur avec un autre nom, de telle manière que le code de l'application n'a jamais à changer Prenons une exemple: Une application my-app a besoin d'une base de données MariaDB. Dans notre code, cette ressource s'appelle simplement DB.
$ docker run -d --name mariadb mariadb:10.1 $ docker run -d --link db:mariadb my-app
Le conteneur mariadb est découvert par Docker, et ce service externe se présente sous le nom de db dans notre environnement.
Attention, cette option est devenue legacy et ne sera certainement plus présente dans de prochaines versions de Docker.
5 - Build, Release and Run
Ici, nous nous représentons facilement comment ces étapes sont découplées avec Docker: l'image d'un côté, le runtime de l'autre. Entre les deux, il y a la registry, qui permet de faire la release de l'image en y appliquant un tag particulier.
$ docker build --tag my-app:v1.12.1 $ docker run -d my-app:v1.12.1
6 - Processus
The Twelve-Factor Apps est une méthodologie pour produire des applications stateless, dont la persistance est assurée par un service de backend. Docker est principalement stateless, même s'il permet la persistance de données pour un conteneur. C'est d'ailleurs un sujet qui déchaîne les passions actuellement.
Il n'est pas aisé de faire un service stateful directement avec Docker, mais soyez rassurés si vous voulez conteneuriser des services stateful, Kubernetes s'en charge très bien.
7 - Association de port
C'est un point su lequel les conteneurs excellent, puisque le port mapping est déclaré explicitement au niveau du run, sous la forme de : docker run -p host_port:container_port
$ docker run -d -p 80:80 my-app:v1.12.1
8 - Concurency
Ici, il s'agit de faire face à la charge d'une application en ajoutant de nouveaux processus. Dans la mesure où notre conteneur est stateless, il y répond aisément: les conteneurs sont placés derrière un load balancer, et quand la charge augmente, il suffit d'ajouter de nouveaux conteneurs.
9 - Jetable
Démarrer une application rapidement et l'arrêter tout aussi rapidement est quelque chose pour lequel le conteneur est également fait ! C'est d'ailleurs à ce point facile d'avoir des conteneurs jetables, que s'en est un peu déstabilisant au début. On démarre une application, et pour l'arrêter, on la supprime. Et tout ça ne prend que quelques secondes !
10 - Parité Dev/Prod
Le conteneur n'est jamais que e run d'une image. Cette image n'est pas altérée entre le moment où elle est lancée dans un environnement de développement, de qualité ou de production.
11 - Logs
The Twelve-Factor Apps nous recommande de traiter les logs comme un flux d'événements. Lors du run d'un conteneur, tous les logs générés par l'application (qui tourne au premier plan) sont envoyés vers stdout et stderr, ce qui permet par la suite de les capturer de l’extérieur du conteneur et de les traiter comme un flux de données.
12 - Processus d'administration
Les tâches d'administration et de maintenance doivent être lancées comme des one-off-processes. Il est très facile d'intéragir avec un conteneur de la sorte. Imaginons que nous ayons déjà notre conteneur applicatif my-app en cours d'exécution :
$ docker ps
pour entrer dans un shell interactif à l'interieur du conteneur, il nous suffit d'une seule commande :
$ docker exec -it 0e236769e695 bash root@0e236769e695:/#
Ceci nous permettant d'effectuer une tâche one-off d'administration.
Conclusion
Il est normal que les technologies d'infrastructure épousent les méthodologies de développement.
Et dans un monde qui réclame de l'agilité et un time-to-market de plus en plus court, rien de plus naturel pour une technologie que d'accompagner les équipes de développement pour résoudre leurs problèmes.