tuto 2022 5, 6
This commit is contained in:
parent
3d7c03fbbd
commit
2af52619c7
43 changed files with 1073 additions and 431 deletions
121
tutorial/devops/ci-gistre.md
Normal file
121
tutorial/devops/ci-gistre.md
Normal file
|
@ -0,0 +1,121 @@
|
|||
\newpage
|
||||
|
||||
## Intégration continue
|
||||
|
||||
::::: {.question}
|
||||
|
||||
La mise en place de l'environnement de CI/CD n'est pas le cœur de la version
|
||||
GISTRE du TP (elle l'est pour les SRS). Aussi cette partie est aussi guidée que
|
||||
possible et toutes les commandes vous sont données pour réduire les frictions
|
||||
de mise en œuvre.
|
||||
|
||||
Mais comme indiqué dans l'introduction au DevOps, vous serez susceptibles
|
||||
d'arriver dans une entreprise qui pratique correctement le DevOps. Dans cette
|
||||
situation, l'ensemble des développeurs et des administrateurs système (les
|
||||
*Ops*), doivent faire en sorte que leurs travaux soient intégrés dans les
|
||||
outils d'intégration continue. Les *Ops* vont évidemment plutôt gérer la mise
|
||||
en place des outils, proprement, c'est ce que demande de faire le TP SRS. Pour
|
||||
vous il s'agit plus de savoir interagir avec, en sachant manipuler la
|
||||
configuration des dépôts.
|
||||
|
||||
:::::
|
||||
|
||||
Une fois Gitea et Drone installés et configurés, nous allons pouvoir rentrer
|
||||
dans le vif du sujet : faire de l'intégration continue sur notre premier projet !
|
||||
|
||||
### Créez un dépôt pour `linky2influx`
|
||||
|
||||
Après avoir créé (ou migré pour les plus malins !) le dépôt
|
||||
[`linky2influx`](https://git.nemunai.re/nemunaire/linky2influx) dans Drone,
|
||||
synchronisez les dépôts, puis activez la surveillance de `linky2influx`.
|
||||
|
||||
Nous allons devoir rédiger un fichier `.drone.yml`, que l'on placera à la racine
|
||||
du dépôt. C'est ce fichier qui sera traité par DroneCI pour savoir comment
|
||||
compiler et tester le projet.
|
||||
|
||||
::::: {.warning}
|
||||
Un fichier `.drone.yml` existe déjà à la racine du dépôt. Celui-ci pourra vous
|
||||
servir d'inspiration, mais il ne fonctionnera pas directement sur votre
|
||||
installation.
|
||||
|
||||
**Vous rencontrerez des problèmes inattendus si vous utilisez le fichier
|
||||
`.drone.yml` du dépôt.** Vous **DEVEZ** partir d'un fichier vide et suivre la
|
||||
documentation pour obtenir un `.drone.yml` fonctionnel.
|
||||
:::::
|
||||
|
||||
|
||||
### Définir les étapes d'intégration
|
||||
|
||||
Toutes les informations nécessaires à l'écriture du fichier `.drone.yml` se
|
||||
trouvent dans [l'excellente documentation du
|
||||
projet](https://docs.drone.io/pipeline/docker/examples/languages/golang/).
|
||||
|
||||
Les étapes sont sensiblement les mêmes que dans le `Dockerfile` présent sur le
|
||||
dépôt.
|
||||
|
||||
Committons puis poussons notre travail. Dès qu'il sera reçu par Gitea, nous
|
||||
devrions voir l'interface de Drone lancer les étapes décrites dans le fichier.
|
||||
|
||||
::::: {.warning}
|
||||
**IMPORTANT :** si vous avez l'impression que ça ne marche pas et que vous avez
|
||||
réutilisé le fichier présent sur le dépôt au lieu de partir de l'exemple donné
|
||||
dans la documentation, **commencez en partant de l'exemple de la
|
||||
documentation** ! Le fichier présent sur le dépôt **ne fonctionnera pas** dans
|
||||
votre situation !
|
||||
:::::
|
||||
|
||||
{height=7.5cm}
|
||||
|
||||
Lorsqu'apparaît enfin la ligne `git.nemunai.re/linky2influx`, le projet est compilé !
|
||||
|
||||
|
||||
### Publier le binaire correspondant aux tags/jalons
|
||||
|
||||
Nous savons maintenant que notre projet compile bien dans un environnement
|
||||
différent de celui du développeur ! Néanmoins, le binaire produit est perdu dès
|
||||
lors que la compilation est terminée, car nous n'en faisons rien.
|
||||
|
||||
Ajoutons donc une nouvelle règle à notre `.droneci.yml` pour placer le binaire
|
||||
au sein de la liste des fichiers téléchargeable aux côtés des tags.
|
||||
|
||||
Vous aurez sans doute besoin de :
|
||||
|
||||
- <https://docs.drone.io/pipeline/conditions/>
|
||||
- <http://plugins.drone.io/drone-plugins/drone-gitea-release/>
|
||||
|
||||
Attention à ne pas stocker votre clef d'API dans le fichier YAML !
|
||||
|
||||
{height=8cm}
|
||||
|
||||
::::: {.more}
|
||||
Lorsque l'on est plusieurs à travailler sur le projet ou pour accroître la
|
||||
sécurité, il convient de créer, un compte *bot* qui sera responsable de la
|
||||
création des *releases*. Ce sera donc sa clef d'API que l'on indiquera dans
|
||||
l'interface de Drone.
|
||||
:::::
|
||||
|
||||
|
||||
### Publier pour plusieurs architectures ?
|
||||
|
||||
Le compilateur Go est fourni avec l'ensemble des backends des différentes
|
||||
architectures matérielles qu'il supporte, nous pouvons donc aisément faire de
|
||||
la compilation croisée pour d'autres architectures.
|
||||
|
||||
Essayons maintenant de compiler `linky2influx` pour plusieurs architectures afin de
|
||||
vérifier que cela fonctionne bien !
|
||||
|
||||
Un exemple est donné tout en haut de cette page :
|
||||
<https://docs.drone.io/pipeline/environment/syntax/>.
|
||||
|
||||
En faisant varier `$GOARCH` en `mips`, `powerpc`, ... nous pouvons générer les
|
||||
binaires correspondant à chaque architecture et système.
|
||||
|
||||
Ajoutez à votre fichier `.drone.yml` les deux architectures pour lesquelles les
|
||||
Raspberry Pi d'Électropcool sont compatibles. Nommez les fichiers selon
|
||||
l'architecture que pourrait renvoyer `uname -m`, cela pourrait nous simplifier la tâche ensuite...
|
||||
\
|
||||
|
||||
Une fois taggé et poussé sur notre dépôt, nous aurons une version exécutable
|
||||
utilisable à la fois sur notre machine de développement, mais aussi sur les
|
||||
Raspberry Pi déjà déployées dans les bâtiments. Nous avons atteint l'un des
|
||||
deux objectifs qui nous était demandé. Tâchons maintenant de trouver un
|
|
@ -1,59 +1,66 @@
|
|||
\newpage
|
||||
|
||||
Intégration continue
|
||||
====================
|
||||
## Intégration continue
|
||||
|
||||
Une fois Gitea et Drone installés et configurés, nous allons pouvoir rentré
|
||||
Une fois Gitea et Drone installés et configurés, nous allons pouvoir rentrer
|
||||
dans le vif du sujet : faire de l'intégration continue sur notre premier projet !
|
||||
|
||||
## `youp0m`
|
||||
|
||||
### Créez un dépôt pour `youp0m`
|
||||
|
||||
Reprenez les travaux réalisés au TP précédent. Nous allons notamment avoir
|
||||
besoin du `Dockerfile` dans la section suivante.
|
||||
|
||||
Après avoir créé (ou migré pour les plus malins !) le dépôt
|
||||
[`youp0m`](https://gitea.nemunai.re/nemunaire/youp0m), dans Drone,
|
||||
[`youp0m`](https://git.nemunai.re/nemunaire/youp0m) dans Drone,
|
||||
synchronisez les dépôts, puis activez la surveillance de `youp0m`.
|
||||
|
||||
Vous allez devoir rédiger un fichier `.drone.yml`, que l'on placera à la
|
||||
racine du dépôt (celui qui existe déjà dans le dépôt pourra servir
|
||||
d'inspiration, mais il ne fonctionnera pas directement sur votre
|
||||
installation). C'est ce fichier qui sera traité par DroneCI pour savoir comment
|
||||
Nous allons devoir rédiger un fichier `.drone.yml`, que l'on placera à la racine
|
||||
du dépôt. C'est ce fichier qui sera traité par DroneCI pour savoir comment
|
||||
compiler et tester le projet.
|
||||
|
||||
::::: {.warning}
|
||||
Un fichier `.drone.yml` existe déjà à la racine du dépôt. Celui-ci pourra vous
|
||||
servir d'inspiration, mais il ne fonctionnera pas directement sur votre
|
||||
installation.
|
||||
|
||||
**Vous rencontrerez des problèmes inattendus si vous utilisez le fichier
|
||||
`.drone.yml` du dépôt.** Vous **DEVEZ** partir d'un fichier vide et suivre la
|
||||
documentation pour obtenir un `.drone.yml` fonctionnel.
|
||||
:::::
|
||||
|
||||
|
||||
### Définir les étapes d'intégration
|
||||
|
||||
Toutes les informations nécessaire à l'écriture du fichier `.drone.yml` se
|
||||
Toutes les informations nécessaires à l'écriture du fichier `.drone.yml` se
|
||||
trouvent dans [l'excellente documentation du
|
||||
projet](https://docs.drone.io/pipeline/docker/examples/languages/golang/).
|
||||
|
||||
Les étapes sont sensiblement les mêmes que dans le `Dockerfile` que vous avez
|
||||
Les étapes sont sensiblement les mêmes que dans le `Dockerfile` que nous avons
|
||||
écrit lors du TP précédent.
|
||||
|
||||
Comittez puis pousser votre travail, dès qu'il sera reçu par Gitea, vous
|
||||
devriez voir l'interface de Drone lancer les étapes décrites dans le fichier.
|
||||
Committons puis poussons notre travail. Dès qu'il sera reçu par Gitea, nous
|
||||
devrions voir l'interface de Drone lancer les étapes décrites dans le fichier.
|
||||
|
||||
{height=6cm}
|
||||
|
||||
::::: {.warning}
|
||||
**IMPORTANT :** si vous avez l'impression que ça ne marche pas et que vous avez
|
||||
réutilisé le fichier présent sur le dépôt au lieu de partir de l'exemple donné
|
||||
dans la documentation, **commencez en partant de l'exemple de la
|
||||
documentation** ! Le fichier présent sur le dépôt ne fonctionnera pas dans
|
||||
documentation** ! Le fichier présent sur le dépôt **ne fonctionnera pas** dans
|
||||
votre situation !
|
||||
|
||||
{height=8cm}
|
||||
:::::
|
||||
|
||||
Lorsqu'apparaît enfin la ligne `git.nemunai.re/youp0m`, le projet est compilé !
|
||||
|
||||
|
||||
### Inspection qualité
|
||||
|
||||
Nous n'avons pas encore de test à proprement parlé. Nous allons utiliser
|
||||
Nous n'avons pas encore de test à proprement parler. Nous allons utiliser
|
||||
[Sonarqube](https://www.sonarqube.org/) pour faire une revue qualité du code !
|
||||
|
||||
Tout d'abord, il faut lancer le conteneur Sonarqube (pensez à l'ajouter à votre
|
||||
playbook !) :
|
||||
Tout d'abord, il faut lancer le conteneur Sonarqube (SRS, pensez à l'ajouter à
|
||||
votre playbook !) :
|
||||
|
||||
<div lang="en-US">
|
||||
```bash
|
||||
|
@ -83,7 +90,7 @@ différent de celui du développeur ! Néanmoins, le binaire produit est perdu d
|
|||
lors que la compilation est terminée, car nous n'en faisons rien.
|
||||
|
||||
Ajoutons donc une nouvelle règle à notre `.droneci.yml` pour placer le binaire
|
||||
au sein de la liste des fichiers téléchargeable aux côtés des tags.
|
||||
au sein de la liste des fichiers téléchargeables aux côtés des tags.
|
||||
|
||||
Vous aurez sans doute besoin de :
|
||||
|
||||
|
@ -94,25 +101,9 @@ Attention à ne pas stocker votre clef d'API dans le fichier YAML !
|
|||
|
||||
{height=8cm}
|
||||
|
||||
::::: {.more}
|
||||
Lorsque l'on est plusieurs à travailler sur le projet ou pour accroître la
|
||||
sécurité, il convient de créer, un compte *bot* qui sera responsable de la
|
||||
création des *releases*. Ce sera donc sa clef d'API que l'on indiquera dans
|
||||
l'interface de Drone.
|
||||
|
||||
|
||||
### Publier pour plusieurs architectures ?
|
||||
|
||||
Le compilateur Go est fourni avec l'ensemble des backends des différentes
|
||||
architectures matérielles qu'il supporte, nous pouvons donc aisément faire de
|
||||
la compilation croisée pour d'autres architectures.
|
||||
|
||||
Essayons maintenant de compiler `youp0m` pour plusieurs architecture afin de
|
||||
vérifier que cela fonctionne bien !
|
||||
|
||||
Un exemple est donné tout en haut de cette page :
|
||||
<https://docs.drone.io/pipeline/environment/syntax/>.
|
||||
|
||||
En faisant varier `$GOARCH` en `arm`, `arm64`, `mips`, ... nous pouvons générer
|
||||
les binaires correspondant à chaque architecture et système.
|
||||
|
||||
Ajoutez au moins 2 autres architectures à votre fichier `.drone.yml`.
|
||||
:::::
|
||||
|
|
|
@ -4,7 +4,7 @@ Le mouvement DevOps
|
|||
===================
|
||||
|
||||
Jusqu'à récemment, et encore dans de nombreuses entreprises, les développeurs
|
||||
et les administrateurs systèmes faisaient partis de deux équipes différentes :
|
||||
et les administrateurs système faisaient partie de deux équipes différentes :
|
||||
les uns développant sur leurs machines avec les dernières bibliothèques,
|
||||
utilisant les derniers frameworks à la mode, sans se préoccuper de la sécurité
|
||||
(ils travaillent en `root` ou avec `sudo` ;)), tandis que les autres tentaient
|
||||
|
@ -17,17 +17,17 @@ utilisé sur un système à jour, et qu'il ne tourne pas en `root`), qu'à la
|
|||
mémoire, il ne faut pas que les autres services présents sur la même machine en
|
||||
pâtissent).
|
||||
|
||||
Une guerre faisait donc rage entre les développeurs qui ne comprennaient pas
|
||||
que les administrateurs système ne pouvaient pas maintenir autant de version
|
||||
d'une bibliothèque qu'il y avait de service : par exemple dans le cas de
|
||||
plusieurs services en PHP, on pouvait leur demander de déployer des
|
||||
applications utilisant la version 5.1, et la 5.2 pour d'autres, ... lorsqu'il y
|
||||
avait des incompatibilités mineures et plus personne pour s'occuper de la
|
||||
maintenance d'un vieux service toujours utilisé.
|
||||
Une guerre faisait donc rage entre les développeurs qui ne comprenaient pas que
|
||||
les administrateurs système ne pouvaient pas maintenir autant de versions d'une
|
||||
bibliothèque qu'il y avait de services : par exemple dans le cas de plusieurs
|
||||
services en PHP, on pouvait leur demander de déployer des applications
|
||||
utilisant la version 5.6, et la 7.2 pour d'autres, ... lorsqu'il y avait des
|
||||
incompatibilités mineures et plus personne pour s'occuper de la maintenance
|
||||
d'un vieux service toujours utilisé.
|
||||
|
||||
Le même principe est aussi valable pour Python, Ruby, ... : les développeurs
|
||||
ont toujours eu tendance à vouloir utiliser les dernières améliorations d'un
|
||||
langage, mais les administrateurs systèmes n'ont alors pas de paquets stables
|
||||
langage, mais les administrateurs système n'ont alors pas de paquets stables
|
||||
dans la distribution. En effet, les distributions stables telles que Debian,
|
||||
RedHat ou CentOS ont des cycles de vie assez long et se concentrent plus sur la
|
||||
stabilité.\
|
||||
|
@ -58,10 +58,11 @@ sont chargées de développer la fiabilité des systèmes d'information de
|
|||
production. Ce sont les équipes SRE, pour Site Reliability Engineering. On
|
||||
confie alors complètement la responsabilité de l'environnement de production
|
||||
aux développeurs qui sont chargés de l'automatiser. Au delà de l'automatisation
|
||||
des déploiements des services, il s'agit ici de développer des mécanismes
|
||||
des déploiements de services, il s'agit ici de développer des mécanismes
|
||||
permettant au système de réagir face aux situations telles que les montées en
|
||||
charges, les pannes, ...
|
||||
|
||||
::::: {.warning}
|
||||
Attention par contre aux entreprises qui recrutent un profil DevOps, car cela a
|
||||
autant de sens que recruter un développeur Scrum ou un développeur cycle en V :
|
||||
DevOps est une méthodologie. Les entreprises qui recrutent un DevOps
|
||||
|
@ -71,6 +72,7 @@ généralement assez difficile à vivre. Alors qu'au contraire, la mouvance DevO
|
|||
doit être prise au sérieux par l'ensemble des développeurs. Lors d'un entretien
|
||||
d'embauche pour ce genre de poste, assurez-vous bien de ne pas être le seul à
|
||||
faire du DevOps.
|
||||
:::::
|
||||
|
||||
|
||||
## Intégration continue
|
||||
|
@ -92,7 +94,7 @@ vers un dossier accessible. Cela permet ainsi aux développeurs de voir les
|
|||
problèmes et de pousser les analyses avec leurs propres outils.
|
||||
|
||||
Sans déploiement continu (la section suivante), c'est également ces produits de
|
||||
compilation que les administrateurs systèmes vont déployer sans peine, lorsque
|
||||
compilation que les administrateurs système vont déployer sans peine, lorsque
|
||||
les développeurs considéreront avoir atteint un jalon, une version stable.
|
||||
|
||||
|
||||
|
@ -100,7 +102,7 @@ les développeurs considéreront avoir atteint un jalon, une version stable.
|
|||
|
||||
Une fois tous les tests passés et les objets produits (on parle d'*artifact* ou
|
||||
d'*assets*), il est possible de déclencher un déploiement : il s'agit de rendre
|
||||
accessible aux utilisateurs finaux le services ou les objets.
|
||||
accessible aux utilisateurs finaux le service ou les objets.
|
||||
|
||||
Dans le cas d'un programme à télécharger
|
||||
([Python](https://buildbot.python.org/all/#/), VLC,
|
||||
|
@ -111,17 +113,19 @@ vers la dernière version (pour que les utilisateurs aient la notifications).
|
|||
Ou bien dans le cas d'un service en ligne (GitHub, Netflix, GMail, ...), il
|
||||
s'agira de mettre à jour le service.
|
||||
|
||||
Parfois les deux seront à faire : à la fois publier un paquet ou un conteneur
|
||||
et mettre à jour un service en ligne : [le serveur
|
||||
Synapse](https://buildkite.com/matrix-dot-org/synapse) du protocole de
|
||||
messagerie Matrix ou encore
|
||||
[Gitlab](https://gitlab.com/gitlab-org/gitlab/-/pipelines).\
|
||||
Parfois les deux seront à faire : à la fois publier un paquet ou un
|
||||
conteneur et mettre à jour un service en ligne : par exemple, [le
|
||||
serveur Synapse](https://buildkite.com/matrix-dot-org/synapse) du
|
||||
protocole de messagerie Matrix ou encore
|
||||
[Gitlab](https://gitlab.com/gitlab-org/gitlab/-/pipelines), tous deux
|
||||
publient des paquets à destination de leurs communautés, et mettent à
|
||||
jour leur service en ligne.\
|
||||
|
||||
Il existe pour cela de très nombreuses stratégies : lorsque l'on n'a pas
|
||||
beaucoup de trafic ni beaucoup de machines, on peut simplement éteindre
|
||||
l'ancien service et démarrer le nouveau, si ça prend quelques millisecondes en
|
||||
étant automatisé, cela peut être suffisant compte tenu du faible
|
||||
traffic.
|
||||
trafic.
|
||||
|
||||
Lorsque l'on a un trafic élevé, de nombreux clients et donc que le service est
|
||||
réparti sur plusieurs machines, on ne peut pas se contenter de tout éteindre et
|
||||
|
@ -143,8 +147,8 @@ surveiller afin d'être le plus proactif possible dans la résolution des
|
|||
problèmes. La pire situation est celle dans laquelle c'est un utilisateur qui
|
||||
nous informe d'un problème... (sur Twitter !?)
|
||||
|
||||
Nous avons réalisé durant le précédent TP, une partie collecte de métriques,
|
||||
avec nos conteneurs TICK. Nous n'allons donc pas nous en occuper aujourd'hui.
|
||||
Nous avons réalisé précédemment une partie collecte de métriques, avec nos
|
||||
conteneurs TICK. Nous n'allons donc pas nous en occuper aujourd'hui.
|
||||
\
|
||||
|
||||
Notez tout de même qu'il y a deux grandes catégories de logiciels de
|
||||
|
@ -167,8 +171,8 @@ Kapacitor, qui permet après avoir analysé les données, d'alerter en fonction
|
|||
d'une évolution.
|
||||
|
||||
L'instrumentation d'une application est une bonne manière de faire remonter des
|
||||
métrique (combien de clients actuellement connectés, combien de
|
||||
messages/transactions traités, ...). Ce sont autant d'information que l'on peut
|
||||
métriques (combien de clients actuellement connectés, combien de
|
||||
messages/transactions traités, ...). Ce sont autant d'informations que l'on peut
|
||||
faire remonter dans sa base de données de métriques.
|
||||
\
|
||||
|
||||
|
@ -185,12 +189,11 @@ un service distribuable, qui est proche de la surcharge, acheter de l'espace de
|
|||
stockage supplémentaire auprès du fournisseur, ...
|
||||
\
|
||||
|
||||
Enfin, citons dans cette partie le [Chaos
|
||||
Monkey](https://fr.wikipedia.org/wiki/Chaos_Monkey), conçu par Netflix, qui est
|
||||
un programme qui va casser de manière aléatoire des éléments de l'environnement
|
||||
de production. Le but est de provoquer sciemment des pannes, des latences,
|
||||
... à n'importe quel niveau du produit, afin d'en tester (brulatement certes)
|
||||
sa résilience. Cela oblige les développeurs, les opérationnels et les
|
||||
architectes à concevoir des services hautement tolérant aux pannes, ce qui fait
|
||||
que le jour où une véritable panne survient, elle n'a aucun impact sur la
|
||||
production (enfin on espère !).
|
||||
Enfin, citons le [Chaos Monkey](https://fr.wikipedia.org/wiki/Chaos_Monkey),
|
||||
conçu par Netflix, qui est un programme qui va casser de manière aléatoire des
|
||||
éléments de l'environnement de production. Le but est de provoquer sciemment
|
||||
des pannes, des latences, ... à n'importe quel niveau du produit, afin d'en
|
||||
tester (brulatement certes) sa résilience. Cela oblige les développeurs, les
|
||||
opérationnels et les architectes à concevoir des services hautement tolérant
|
||||
aux pannes, ce qui fait que le jour où une véritable panne survient, elle n'a
|
||||
aucun impact sur la production (enfin on espère !).
|
||||
|
|
BIN
tutorial/devops/drone-run-linky.png
Normal file
BIN
tutorial/devops/drone-run-linky.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 173 KiB |
BIN
tutorial/devops/electropcool.jpg
Normal file
BIN
tutorial/devops/electropcool.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 216 KiB |
BIN
tutorial/devops/electropcool.png
Normal file
BIN
tutorial/devops/electropcool.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 MiB |
|
@ -10,16 +10,18 @@ jour ensuite (par exemple, dans le cas de Firefox ou de LibreOffice, une fois
|
|||
testés, les paquets sont envoyés sur le serveur d'où ils seront distribués ; il
|
||||
n'y a pas de service/docker à relancer).
|
||||
|
||||
À l'inverse, `youp0m` est à la fois un programme que l'on peut télécharger et
|
||||
un service un ligne qu'il faut déployer pour mettre à jour facilement. Pour
|
||||
simplifier le déploiement, nous utilisons des images Docker. Il faut cependant
|
||||
les générer ...
|
||||
À l'inverse, `youp0m` ou `linky2influx` sont à la fois des programmes que l'on
|
||||
peut télécharger et des services qu'il faut déployer pour les mettre à
|
||||
jour. Pour simplifier le déploiement, nous utilisons des images Docker. Il faut
|
||||
cependant les générer ...
|
||||
|
||||
|
||||
## Mise en place du registre
|
||||
|
||||
*Si vous avez choisi Gitlab, vous pouvez utiliser directement le registre
|
||||
Docker intégré. Si vous utilisez Gitea, continuez cette section.*
|
||||
::::: {.more}
|
||||
Si vous avez choisi Gitlab, vous pouvez utiliser directement le registre
|
||||
Docker intégré. Si vous utilisez Gitea, continuez cette section.
|
||||
:::::
|
||||
|
||||
Afin de disposer de notre propre registre Docker sur lequel publier nos images,
|
||||
nous allons utiliser l'image de registre fournie par Docker. Elle se lance
|
||||
|
@ -31,10 +33,11 @@ docker run --rm -d --name registry --network droneci -p 5000:5000 registry:2
|
|||
```
|
||||
</div>
|
||||
|
||||
Vous trouverez davantage d'informations
|
||||
Vous trouverez davantage d'informations pour le déploiement
|
||||
[ici](https://docs.docker.com/registry/deploying/).
|
||||
|
||||
Vous pouvez tester son bon fonctionnement avec la commande suivante :
|
||||
Nous pouvons tester le bon fonctionnement de notre registre avec la commande
|
||||
suivante :
|
||||
|
||||
<div lang="en-US">
|
||||
```bash
|
||||
|
@ -67,12 +70,14 @@ docker run --rm -p 8080:8080 localhost:5000/youp0m
|
|||
```
|
||||
</div>
|
||||
|
||||
::::: {.more}
|
||||
On notera que ceci est possible exclusivement parce que le registre
|
||||
`localhost:5000` est considéré non-sûr par défaut. C'est à dire qu'il n'a pas
|
||||
besoin de certificat TLS sur sa connexion HTTP pour être utilisé.\
|
||||
Si on avait dû utiliser un autre nom de domaine, il aurait fallu
|
||||
[l'ajouter à la liste des
|
||||
`insecure-registries`](https://docs.docker.com/registry/insecure/).
|
||||
:::::
|
||||
|
||||
|
||||
## Suite du déploiement
|
||||
|
@ -80,9 +85,9 @@ Si on avait dû utiliser un autre nom de domaine, il aurait fallu
|
|||
Pour aujourd'hui, nous en resterons là pour le déploiement, car nous n'avons
|
||||
pas d'environnement de production sur lequel déployer notre service.
|
||||
|
||||
Vous pouvez néamnoins tester les plugins
|
||||
Vous pouvez néanmoins tester les plugins
|
||||
[`scp`](http://plugins.drone.io/appleboy/drone-scp/) ou
|
||||
[`ansible`](http://plugins.drone.io/drone-plugins/drone-ansible/), si vous avez
|
||||
[`ansible`](http://plugins.drone.io/drone-plugins/drone-ansible/) si vous avez
|
||||
une machine virtuelle avec une connexion SSH. N'hésitez pas à l'ajouter à votre
|
||||
`.droneci.yml`.
|
||||
|
||||
|
|
194
tutorial/devops/run-gistre.md
Normal file
194
tutorial/devops/run-gistre.md
Normal file
|
@ -0,0 +1,194 @@
|
|||
\newpage
|
||||
|
||||
## Lancement du module sur la machine cible
|
||||
|
||||
Mettons de côté le déploiement continu, pour nous concentrer sur la manière
|
||||
dont nous allons pouvoir exécuter notre module de relevé de compteur Linky.
|
||||
\
|
||||
|
||||
Le binaire de notre module se lance de la manière suivante :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
42sh$ ./linky2influx --influx-host localhost --influx-username myuser \
|
||||
--influx-password mypasswd /dev/ttyEnedis0
|
||||
# or
|
||||
42sh$ INFLUXDB_HOST=localhost INFLUXDB_USERNAME=myuser INFLUXDB_PASSWORD=mypasswd \
|
||||
./linky2influx /dev/ttyEnedis0
|
||||
```
|
||||
</div>
|
||||
|
||||
où `/dev/ttyEnedis0` est le périphérique correspondant à notre liaison série
|
||||
vers le compteur. On considère qu'une règle `udev` a été écrite pour créer
|
||||
l'entrée correspondante dans `/dev`.
|
||||
\
|
||||
|
||||
L'objectif est d'établir la méthode qui sera la plus efficace pour
|
||||
Électropcool, car elle devra sans doute demander à chacune des équipes de
|
||||
réaliser le packaging des modules qu'elles maintiennent. Il faut pour cela en
|
||||
tester plusieurs. Certaines peuvent sans doute déjà être éliminées car
|
||||
inadaptés, c'est à vous de déterminer parmi les technologies d'empacketages
|
||||
proposées, et celles que vous connaissez, lesquelles vous écartez d'emblée,
|
||||
lesquelles vous souhaitez garder pour explorer davantage, et enfin laquelle
|
||||
retient votre attention.
|
||||
|
||||
Vous êtes tenu de retenir au minimum 2 solutions distinctes (on considère que
|
||||
les technologies listées sur la même lignes sont similaires).
|
||||
|
||||
La liste de technologies proposées est à la suivante :
|
||||
|
||||
- conteneur Docker ou podman,
|
||||
- conteneur LXC (avec base alpine ou nu),
|
||||
- conteneur OCI via runc,
|
||||
- service systemd ou systemd-nspawn,
|
||||
- packages `.ipk` via Yocto/Bitbake,
|
||||
- package Nix,
|
||||
- paquet Snap, FlatPack ou AppImage,
|
||||
- [k3s](https://k3s.io/),
|
||||
- ...
|
||||
|
||||
|
||||
Les sections suivantes vous donneront une idée des éléments attendus pour chacun.
|
||||
|
||||
|
||||
### Docker, podman, ...
|
||||
|
||||
Nous avons déjà un `Dockerfile` dans notre dépôt, vous avez juste à écrire un
|
||||
script shell permettant de lancer le module, il doit bien évidemment avoir
|
||||
accès au périphérique correspondant au compteur.
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
login_x-TP5/docker/run.sh
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
### Conteneur LXC
|
||||
|
||||
LXC peut s'utiliser de multiple manière différentes, y compris avec des images
|
||||
OCI. Choisissez la méthode qui vous semble la plus appropriée, il est attendu
|
||||
au moins un script pour lancer notre conteneur, s'il est différent d'un
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
42sh# lxc-create --template linky2influx --name l2i && lxc-start -n l2i`.
|
||||
```
|
||||
</div>
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
login_x-TP5/lxc/run.sh
|
||||
```
|
||||
</div>
|
||||
|
||||
En complément, vous pouvez inclure au dépôt de `linky2influx` le modèle
|
||||
permettant de créer le conteneur LXC, ainsi qu'un exemple de configuration :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
login_x-TP5/linky2influx/lxc-scripts/template.sh
|
||||
login_x-TP5/linky2influx/lxc-scripts/sample.config
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
### Conteneur OCI via `runc`
|
||||
|
||||
`runc` a besoin d'un fichier `config.json` et éventuellement `runtime.json`. La
|
||||
ligne de commande pour lancer `runc` n'est pas demandée, l'image OCI résultant
|
||||
du `Dockerfile` sera utilisée et présente pour l'exécution.
|
||||
|
||||
|
||||
### Service systemd ou systemd-nspawn
|
||||
|
||||
Le service `systemd` est redondant avec un système Yocto contenant `systemd`,
|
||||
vous pourriez écrire le script `systemd` et profiter de l'utiliser dans votre
|
||||
recette `bitbake`.
|
||||
|
||||
Un service basé sur `nspawn` peut par contre être potentiellement intéressant,
|
||||
il pourra être intégré au dépôt :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
login_x-TP5/linky2influx/systemd/linky2influx.nspawn
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
### Yocto
|
||||
|
||||
Vous pourriez vouloir écrire une recette Bitbake pour créer et déployer le
|
||||
module via un paquet `.ipk` ou similaire en fonction de votre configuration.
|
||||
|
||||
Écrivez la recette au sein de `meta-electropcool` :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
login_x-TP5/meta-electropcool/recipes-support/linky2influx/linky2influx_9999.bb
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
### Nix
|
||||
|
||||
L'expression Nix correspondant au paquet pourra être intégré au dépôt
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
login_x-TP5/linky2influx/linky2influx.nix
|
||||
```
|
||||
</div>
|
||||
|
||||
Précisez ensuite dans un `README-nix.md` à côté, la manière dont vous souhaitez
|
||||
utiliser le package Nix ensuite.
|
||||
|
||||
|
||||
### Snap, Flatpack, AppImage
|
||||
|
||||
Intégrez au dépôt le fichier de description, par exemple :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
login_x-TP5/linky2influx/snapcraft.yaml
|
||||
```
|
||||
</div>
|
||||
|
||||
Il faudra également préciser avec un fichier `run.sh` la manière dont lancer
|
||||
votre conteneur :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
login_x-TP5/{snap,flatpack}/run.sh
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
### k3s
|
||||
|
||||
Nous en apprendrons davantage sur Kubernetes au prochain TP, mais si vous
|
||||
connaissez déjà, vous pourriez vouloir écrire un *Chart* Helm :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
login_x-TP5/k3s/linky2influx.yaml
|
||||
```
|
||||
</div>
|
||||
|
||||
Inutile de vous casser la tête avec ça si vous ne connaissez pas !
|
||||
|
||||
|
||||
### Votre solution
|
||||
|
||||
N'hésitez pas à apporter une autre solution originale, que celles qui seraient
|
||||
listées ici.
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
login_x-TP5/k3s/linky2influx.yaml
|
||||
```
|
||||
</div>
|
||||
\
|
||||
|
||||
À vous de jouer !
|
32
tutorial/devops/tools-drone-ansible.md
Normal file
32
tutorial/devops/tools-drone-ansible.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
Voici à quoi pourrait ressembler le playbook Ansible démarrant notre conteneur
|
||||
Drone :
|
||||
|
||||
<div lang="en-US">
|
||||
```yaml
|
||||
- name: Launch drone container
|
||||
docker_container:
|
||||
name: droneci
|
||||
image: drone/drone:1
|
||||
volumes:
|
||||
- /var/lib/drone:/data
|
||||
state: started
|
||||
restart_policy: unless-stopped
|
||||
memory: 1G
|
||||
memory_swap: 1G
|
||||
networks:
|
||||
- name: drone
|
||||
- name: gitea
|
||||
published_ports:
|
||||
- "80:80"
|
||||
env:
|
||||
DRONE_GITEA_CLIENT_ID: "{{ client.id }}"
|
||||
DRONE_GITEA_CLIENT_SECRET: "{{ client.secret }}"
|
||||
DRONE_GITEA_SERVER: "http://gitea:3000"
|
||||
DRONE_RPC_SECRET: "{{ shared_secret }}"
|
||||
DRONE_SERVER_HOST: "droneci"
|
||||
DRONE_SERVER_PROTO: "http"
|
||||
```
|
||||
</div>
|
||||
|
||||
C'est à vous de définir un `shared_secret`, c'est une chaîne aléatoire qui
|
||||
permettra aux *Runner*s (section suivante) de s'authentifier.
|
26
tutorial/devops/tools-drone-cmd.md
Normal file
26
tutorial/devops/tools-drone-cmd.md
Normal file
|
@ -0,0 +1,26 @@
|
|||
Voici à quoi pourrait ressembler la ligne de commande démarrant notre conteneur
|
||||
Drone :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
export DRONE_GITEA_CLIENT_ID=#FIXME
|
||||
export DRONE_GITEA_CLIENT_SECRET=#FIXME
|
||||
export DRONE_RPC_SECRET=$(openssl rand -base64 30)
|
||||
|
||||
docker container run --name droneci -d \
|
||||
-v /var/lib/drone:/data \
|
||||
--network gitea -p 80:80 \
|
||||
-e DRONE_GITEA_CLIENT_ID -e DRONE_GITEA_CLIENT_SECRET -e DRONE_GITEA_SERVER=http://gitea:3000 \
|
||||
-e DRONE_RPC_SECRET -e DRONE_SERVER_HOST=droneci -e DRONE_SERVER_PROTO=http \
|
||||
drone/drone:1
|
||||
|
||||
docker network connect drone droneci
|
||||
```
|
||||
</div>
|
||||
|
||||
La dernière commande permet à notre conteneur Drone d'être à la fois présent
|
||||
dans le réseau `gitea` et `drone`, ce qui permet de garder les deux réseaux
|
||||
distincts.
|
||||
|
||||
Gardez la variable d'environnement `DRONE_RPC_SECRET` dans un coin, nous en
|
||||
aurons encore besoin juste après.
|
15
tutorial/devops/tools-drone-oauth.md
Normal file
15
tutorial/devops/tools-drone-oauth.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
::::: {.question}
|
||||
|
||||
La version 2 de Drone, encore plus pratique et sympathique est disponible en
|
||||
test. Vous pouvez tout à fait l'utiliser pour la suite du TP. Cela ne change
|
||||
pas la version des *runners* à utiliser.
|
||||
|
||||
:::::
|
||||
|
||||
Une fois lancé, rendez-vous sur l'interface de DroneCI : <http://droneci/>
|
||||
|
||||
Vous serez automatiquement redirigé vers la page d'authentification de Gitea,
|
||||
puis vers l'autorisation OAuth d'accès de Drone à Gitea. Il faut bien
|
||||
évidemment valider cette demande, afin que Drone ait accès à nos dépôts.
|
||||
|
||||
{width=9cm}
|
25
tutorial/devops/tools-drone-runner-ansible.md
Normal file
25
tutorial/devops/tools-drone-runner-ansible.md
Normal file
|
@ -0,0 +1,25 @@
|
|||
Voici à quoi pourrait ressembler le playbook Ansible démarrant notre agent Drone :
|
||||
|
||||
<div lang="en-US">
|
||||
```yaml
|
||||
- name: Launch drone runer
|
||||
docker_container:
|
||||
name: droneci-runner
|
||||
image: "drone/drone-runner-docker:1"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
state: started
|
||||
restart_policy: unless-stopped
|
||||
memory: 2G
|
||||
memory_swap: 2G
|
||||
networks:
|
||||
- name: drone
|
||||
env:
|
||||
DRONE_RPC_PROTO: "http"
|
||||
DRONE_RPC_HOST: "droneci"
|
||||
DRONE_RPC_SECRET: "{{ shared_secret }}"
|
||||
DRONE_RUNNER_CAPACITY: "2"
|
||||
DRONE_RUNNER_NAME: "my-runner"
|
||||
DRONE_RUNNER_NETWORKS: "drone,gitea"
|
||||
```
|
||||
</div>
|
11
tutorial/devops/tools-drone-runner-cmd.md
Normal file
11
tutorial/devops/tools-drone-runner-cmd.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
Voici à quoi pourrait ressembler la ligne de commande démarrant notre agent Drone :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
docker container run --name droneci-runner -d \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock --network drone \
|
||||
-e DRONE_RPC_PROTO=http -e DRONE_RPC_HOST=droneci -e DRONE_RPC_SECRET \
|
||||
-e DRONE_RUNNER_CAPACITY=2 -e DRONE_RUNNER_NAME=my-runner -e DRONE_RUNNER_NETWORKS=drone,gitea \
|
||||
drone/drone-runner-docker:1
|
||||
```
|
||||
</div>
|
15
tutorial/devops/tools-drone-runner.md
Normal file
15
tutorial/devops/tools-drone-runner.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
### *Runner*
|
||||
|
||||
Notre conteneur `droneci` est uniquement une interface graphique qui va
|
||||
centraliser d'un côté les nouveaux commits à traiter, et de l'autre les
|
||||
résultats retournés par les agents chargés d'exécuter le code.
|
||||
|
||||
Il serait impensable d'exécuter arbitrairement du code en parallèle d'une
|
||||
application privilégiée (ici, notre conteneur `droneci` a accès aux dépôts
|
||||
potentiellement privés de Gitea). Les agents qui sont amenés à traiter du code
|
||||
arbitraire s'exécutent à part et peuvent être de différents types. Dans le
|
||||
vocabulaire de Drone, on les appelle des ~~blade~~*runners*.
|
||||
|
||||
Nous allons lancer un *runner* Docker : il s'agit d'un type d'agent qui va
|
||||
exécuter nos étapes de compilation dans des conteneurs Docker (oui, quand on
|
||||
disait que Drone était conçu autour de Docker, c'était pas pour rire !)
|
24
tutorial/devops/tools-drone.md
Normal file
24
tutorial/devops/tools-drone.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
## Logiciel d'intégration continue
|
||||
|
||||
De nombreuses solutions sont disponibles sur Internet, la plupart du temps
|
||||
gratuites pour les projets libres ([Travis CI](https://travis-ci.org/),
|
||||
[CircleCI](https://circleci.com/), ...).
|
||||
|
||||
Mais nous allons déployer notre propre solution, en utilisant [Drone
|
||||
CI](https://drone.io/). C'est une solution d'intégration continue libre et
|
||||
moderne, conçue tout autour de Docker. Idéale pour nous !
|
||||
|
||||
|
||||
### Interface de contrôle et de dispatch des tâches
|
||||
|
||||
La documentation du projet est extrêmement bien faite, suivons la marche à
|
||||
suivre pour [relier Gitea à
|
||||
Drone](https://docs.drone.io/server/provider/gitea/).
|
||||
|
||||
Drone va avoir besoin d'authentifier les utilisateurs afin d'accéder aux dépôts
|
||||
privés (avec l'autorisation des utilisateurs). Pour cela, comme l'indique la
|
||||
documentation de Drone, on va utiliser OAuth2 : dans Gitea, il va falloir créer
|
||||
une *application OAuth2*. Le formulaire de création se trouve dans la
|
||||
configuration du compte utilisateur, sous l'onglet *Applications*. Drone aura
|
||||
également besoin d'une URL de redirection. Dans notre cas, ce sera :
|
||||
`http://droneci/login`.
|
1
tutorial/devops/tools-end.md
Normal file
1
tutorial/devops/tools-end.md
Normal file
|
@ -0,0 +1 @@
|
|||
L'environnement étant prêt, il ne reste plus qu'à nous lancer dans nos projets !
|
29
tutorial/devops/tools-gitea-ansible.md
Normal file
29
tutorial/devops/tools-gitea-ansible.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
Votre playbook ressemblera à quelque chose comme ça :
|
||||
|
||||
<div lang="en-US">
|
||||
```yaml
|
||||
- name: Launch gitea container
|
||||
docker_container:
|
||||
name: gitea
|
||||
image: "gitea/gitea:{{ version }}"
|
||||
volumes:
|
||||
- /var/lib/gitea:/data
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
state: started
|
||||
restart_policy: unless-stopped
|
||||
memory: 1G
|
||||
memory_swap: 1G
|
||||
networks:
|
||||
- name: gitea
|
||||
published_ports:
|
||||
- "2222:22"
|
||||
- "3000:3000"
|
||||
env:
|
||||
RUN_MODE: "prod"
|
||||
DOMAIN: "gitea"
|
||||
SSH_DOMAIN: "gitea"
|
||||
INSTALL_LOCK: "true"
|
||||
SECRET_KEY: "{{ secret_key }}"
|
||||
```
|
||||
</div>
|
13
tutorial/devops/tools-gitea-cmd.md
Normal file
13
tutorial/devops/tools-gitea-cmd.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
La ligne de commande pour lancer Gitea ressemblera à quelque chose comme ça :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
export SECRET_KEY=$(openssl rand -base64 30)
|
||||
|
||||
docker container run --name gitea -d \
|
||||
-v /var/lib/gitea:/data -v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro \
|
||||
--network gitea -p 2222:22 -p 3000:3000 \
|
||||
-e RUN_MODE=prod -e DOMAIN=gitea -e SSH_DOMAIN=gitea -e INSTALL_LOCK=true -e SECRET_KEY \
|
||||
gitea/gitea:1
|
||||
```
|
||||
</div>
|
15
tutorial/devops/tools-gitea-end.md
Normal file
15
tutorial/devops/tools-gitea-end.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
Plus d'infos sur cette page : <https://docs.gitea.io/en-us/install-with-docker/>.
|
||||
|
||||
Une fois le conteneur lancé, vous pouvez accéder à l'interface de gitea sur le
|
||||
port 3000 de votre machine (à moins que vous n'ayez opté pour un autre port).
|
||||
|
||||
Vous pouvez ajouter un nouvel administrateur avec la commande suivante :
|
||||
|
||||
<div lang="en-US">
|
||||
```bash
|
||||
docker exec gitea gitea admin user create --username "${USER}" --random-password \
|
||||
--must-change-password=false --admin --email "${USER}@epita.fr"
|
||||
```
|
||||
</div>
|
||||
|
||||
Notez le mot de passe généré pour [vous y connecter](http://localhost:3000/user/login).
|
43
tutorial/devops/tools-gitea.md
Normal file
43
tutorial/devops/tools-gitea.md
Normal file
|
@ -0,0 +1,43 @@
|
|||
## Gestionnaire de versions
|
||||
|
||||
Avant de pouvoir commencer notre aventure, il est nécessaire d'avoir un
|
||||
gestionnaire de versions. Nous allons ici utiliser Git.
|
||||
|
||||
|
||||
### Problématique du stockage des produits de compilation
|
||||
|
||||
Outre les interfaces rudimentaires fournies au dessus de Git
|
||||
([gitweb](https://git.wiki.kernel.org/index.php/Gitweb)), il y a de nombreux
|
||||
projets qui offrent davantage que le simple hébergement de dépôts. Vous pouvez
|
||||
voir sur GitHub notamment qu'il est possible d'attacher à un tag un [certain
|
||||
nombre de fichiers](https://github.com/docker/compose/releases/latest).
|
||||
|
||||
On notera également que depuis le 1er septembre, GitHub propose un [registre
|
||||
Docker](https://github.blog/2020-09-01-introducing-github-container-registry/)
|
||||
que l'on peut lier avec ses dépôts. Une fonctionnalité que GitLab propose
|
||||
[depuis
|
||||
2016](https://about.gitlab.com/blog/2016/05/23/gitlab-container-registry/).
|
||||
|
||||
En effet, la problématique du stockage des produits de compilation est
|
||||
vaste. Si au début on peut se satisfaire d'un simple serveur web/FTP/SSH pour
|
||||
les récupérer manuellement, on a vite envie de pouvoir utiliser les outils
|
||||
standards directement : `docker pull ...`, `npm install ...`, ...
|
||||
|
||||
Des programmes et services se sont spécialisés là-dedans, citons notamment
|
||||
[Artifactory](https://jfrog.com/artifactory/) ou [Nexus
|
||||
Repository](https://www.sonatype.com/nexus/repository-oss) et bien d'autres.
|
||||
|
||||
Dans un premier temps, nous allons nous contenter de publier un binaire associé
|
||||
à un tag de notre projet.
|
||||
|
||||
|
||||
### Installation et configuration
|
||||
|
||||
Allez c'est parti ! première chose à faire : installer et configurer
|
||||
[Gitea](https://gitea.io/) (ceux qui le souhaitent peuvent choisir
|
||||
[gitlab](https://gitlab.org/) ou une autre plate-forme, mais la suite sera
|
||||
moins guidée).
|
||||
|
||||
Nous allons utiliser l'image :
|
||||
[`gitea/gitea`](https://hub.docker.com/r/gitea/gitea) (ou
|
||||
[`gitlab/gitlab-ce`](https://hub.docker.com/r/gitlab/gitlab-ce)).
|
|
@ -1,199 +1 @@
|
|||
\newpage
|
||||
|
||||
Les bons outils
|
||||
===============
|
||||
|
||||
## Gestionnaire de versions
|
||||
|
||||
Avant de pouvoir commencer notre aventure, il est nécessaire d'avoir un
|
||||
gestionnaire de versions. Nous allons ici utiliser Git.
|
||||
|
||||
|
||||
### Problématique du stockage des produits de compilation
|
||||
|
||||
Outre les interfaces rudimentaires fournies au dessus de Git
|
||||
([gitweb](https://git.wiki.kernel.org/index.php/Gitweb)), il y a de nombreux
|
||||
projets qui offrent davantage que le simple hébergement de dépôts. Vous pouvez
|
||||
voir sur GitHub notamment qu'il est possible d'attacher à un tag un [certain
|
||||
nombre de fichiers](https://github.com/docker/compose/releases/latest).
|
||||
|
||||
On notera également que depuis le 1er septembre, GitHub propose un [registre
|
||||
Docker](https://github.blog/2020-09-01-introducing-github-container-registry/)
|
||||
que l'on peut lier avec ses dépôts. Une fonctionnalité que GitLab propose
|
||||
[depuis
|
||||
2016](https://about.gitlab.com/blog/2016/05/23/gitlab-container-registry/).
|
||||
|
||||
En effet, la problématique du stockage des produits de compilation est
|
||||
vaste. Si au début on peut se satisfaire d'un simple serveur web/FTP/SSH pour
|
||||
les récupérer manuellement, on a vite envie de pouvoir utiliser les outils
|
||||
standards directement : `docker pull ...`, `npm install ...`, ...
|
||||
|
||||
Des programmes et services se sont spécialisés là dedans, citons notamment
|
||||
[Artifactory](https://jfrog.com/artifactory/) ou [Nexus
|
||||
Repository](https://www.sonatype.com/nexus/repository-oss) et bien d'autres.
|
||||
|
||||
Dans la première partie du TP, nous allons nous contenter de publier un binaire
|
||||
associé à un tag de notre projet.
|
||||
|
||||
|
||||
### Installation et configuration
|
||||
|
||||
Aller c'est parti ! première chose à faire : installer et configurer
|
||||
[Gitea](https://gitea.io/) (ceux qui le souhaitent peuvent choisir
|
||||
[gitlab](https://gitlab.org/) ou une autre plate-forme, mais la suite du TP
|
||||
sera moins guidée pour eux).
|
||||
|
||||
Nous allons utiliser l'image :
|
||||
[`gitea/gitea`](https://hub.docker.com/r/gitea/gitea) (ou
|
||||
[`gitlab/gitlab-ce`](https://hub.docker.com/r/gitlab/gitlab-ce)).
|
||||
|
||||
Votre playbook resemblera à quelque chose comme ça :
|
||||
|
||||
<div lang="en-US">
|
||||
```yaml
|
||||
- name: Launch gitea container
|
||||
docker_container:
|
||||
name: gitea
|
||||
image: "gitea/gitea:{{ version }}"
|
||||
volumes:
|
||||
- /var/lib/gitea:/data
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
state: started
|
||||
restart_policy: unless-stopped
|
||||
memory: 1G
|
||||
memory_swap: 1G
|
||||
networks:
|
||||
- name: gitea
|
||||
published_ports:
|
||||
- "2222:22"
|
||||
- "3000:3000"
|
||||
env:
|
||||
RUN_MODE: "prod"
|
||||
DOMAIN: "gitea"
|
||||
SSH_DOMAIN: "gitea"
|
||||
INSTALL_LOCK: "true"
|
||||
SECRET_KEY: "{{ secret_key }}"
|
||||
```
|
||||
</div>
|
||||
|
||||
Plus d'infos sur cette page : <https://docs.gitea.io/en-us/install-with-docker/>.
|
||||
|
||||
Une fois le conteneur lancé, vous pouvez accéder à l'interface de gitea sur le
|
||||
port 3000 de votre machine (à moins que vous n'ayez opté pour un autre port).
|
||||
|
||||
Vous pouvez ajouter un nouvel administrateur avec la commande suivante :
|
||||
|
||||
<div lang="en-US">
|
||||
```bash
|
||||
docker exec gitea gitea admin user create --username "${USER}" --random-password \
|
||||
--must-change-password=false --admin --email "${USER}@epita.fr"
|
||||
```
|
||||
</div>
|
||||
|
||||
Notez le mot de passe généré pour [vous y connecter](http://localhost:3000/user/login).
|
||||
|
||||
|
||||
## Logiciel d'intégration continue
|
||||
|
||||
De nombreuses solutions sont disponibles sur Internet, la plupart du temps
|
||||
gratuite pour les projets libres ([Travis CI](https://travis-ci.org/),
|
||||
[CircleCI](https://circleci.com/), ...).
|
||||
|
||||
Mais nous allons déployer notre propre solution, en utilisant [Drone
|
||||
CI](https://drone.io/). C'est une solution d'intégration continue libre et
|
||||
moderne, conçue tout autour de Docker. Idéale pour nous !
|
||||
|
||||
|
||||
### Interface de contrôle et de dispatch des tâches
|
||||
|
||||
La documentation du projet est extrêmement bien faite, suivons la marche à
|
||||
suivre pour [relier Gitea à
|
||||
Drone](https://docs.drone.io/server/provider/gitea/).
|
||||
|
||||
L'URL de redirection sera dans notre cas : `http://droneci/login`.
|
||||
|
||||
|
||||
Voici à quoi pourrait ressemble le playbook Ansible démarrant notre conteneur
|
||||
Drone :
|
||||
|
||||
<div lang="en-US">
|
||||
```yaml
|
||||
- name: Launch drone container
|
||||
docker_container:
|
||||
name: droneci
|
||||
image: drone/drone:1
|
||||
volumes:
|
||||
- /var/lib/drone:/data
|
||||
state: started
|
||||
restart_policy: unless-stopped
|
||||
memory: 1G
|
||||
memory_swap: 1G
|
||||
networks:
|
||||
- name: drone
|
||||
- name: gitea
|
||||
published_ports:
|
||||
- "80:80"
|
||||
env:
|
||||
DRONE_GITEA_CLIENT_ID: "{{ client.id }}"
|
||||
DRONE_GITEA_CLIENT_SECRET: "{{ client.secret }}"
|
||||
DRONE_GITEA_SERVER: "http://gitea:3000"
|
||||
DRONE_RPC_SECRET: "{{ shared_secret }}"
|
||||
DRONE_SERVER_HOST: "droneci"
|
||||
DRONE_SERVER_PROTO: "http"
|
||||
```
|
||||
</div>
|
||||
|
||||
Une fois lancé, rendez-vous sur l'interface de DroneCI : <http://droneci/>
|
||||
|
||||
Vous serez automatiquement redirigé vers la page d'authentification de Gitea,
|
||||
puis vers l'autorisation OAuth d'accès de Drone à Gitea. Il faut bien
|
||||
évidemment valider cette demande, afin que Drone ait accès à nos dépôts.
|
||||
|
||||
{width=9cm}
|
||||
|
||||
|
||||
### *Runner*
|
||||
|
||||
Notre conteneur `droneci` est uniquement une interface graphique qui va
|
||||
centraliser d'un côté les nouveaux commits à traiter, et de l'autre les
|
||||
résultats retournés par les agents chargés d'exécuter le code.
|
||||
|
||||
Il serait impensable d'exécuter arbitrairement du code en parallèle d'une
|
||||
application privilégiée (ici, notre conteneur `droneci` a accès aux dépôts
|
||||
potentiellement privés de Gitea). Les agents qui sont amenés à traiter du code
|
||||
arbitraire s'exécutent à part et peuvent être de différents types. Dans le
|
||||
vocabulaire de Drone, on les appelle des ~~blade~~*runners*.
|
||||
|
||||
Nous allons lancer un *runner* Docker : il s'agit d'un type d'agent qui va
|
||||
exécuter nos étapes de compilation dans des conteneurs Docker (oui, quand on
|
||||
disait que Drone était conçu autour de Docker, c'était pas pour rire !)
|
||||
|
||||
Voici à quoi pourrait ressemble le playbook Ansible démarrant notre agent Drone :
|
||||
|
||||
<div lang="en-US">
|
||||
```yaml
|
||||
- name: Launch drone runer
|
||||
docker_container:
|
||||
name: droneci-runner
|
||||
image: "drone/drone-runner-docker:1"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
state: started
|
||||
restart_policy: unless-stopped
|
||||
memory: 2G
|
||||
memory_swap: 2G
|
||||
networks:
|
||||
- drone
|
||||
env:
|
||||
DRONE_RPC_PROTO: "http"
|
||||
DRONE_RPC_HOST: "droneci"
|
||||
DRONE_RPC_SECRET: "{{ shared_secret }}"
|
||||
DRONE_RUNNER_CAPACITY: 2
|
||||
DRONE_RUNNER_NAME: "my-runner"
|
||||
DRONE_RUNNER_NETWORKS: "drone,gitea"
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
L'environnement étant prêt, il ne reste plus qu'à nous lancer dans nos projets !
|
||||
|
|
10
tutorial/devops/what-gistre-see-srs.md
Normal file
10
tutorial/devops/what-gistre-see-srs.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
### Pour aller plus loin
|
||||
|
||||
Le mouvement DevOps tend à utiliser mettre en avant la CI/CD, ce ne leur est
|
||||
évidemment pas exclusivement réservé. Toute entreprise ayant une méthodologie
|
||||
de développement saine dispose d'outils automatisés de construction et de
|
||||
tests.
|
||||
|
||||
Pour en savoir plus sur le DevOps, vous devriez lire la première partie du [TP
|
||||
des SRS](https://virli.nemunai.re/tutorial-5-srs.pdf), qui traite justement de
|
||||
ce sujet.
|
127
tutorial/devops/what-gistre.md
Normal file
127
tutorial/devops/what-gistre.md
Normal file
|
@ -0,0 +1,127 @@
|
|||
\newpage
|
||||
|
||||
Électropcool
|
||||
============
|
||||
|
||||
Bienvenue dans la société Électropcool !
|
||||
|
||||
Électropcool est une société française spécialisée dans
|
||||
l'[immotique](https://fr.wikipedia.org/wiki/Immotique), elle vend des
|
||||
équipements IoT, principalement à destination des professionels du bâtiment. Le
|
||||
produit phare est une plate-forme de
|
||||
[GTB](https://fr.wikipedia.org/wiki/Gestion_technique_de_b%C3%A2timent)
|
||||
modulaire de suivi de la vie d'un bâtiment où sont regroupés les différents
|
||||
compteurs, capteurs et actionneurs que l'on retrouve dans les installations.
|
||||
Les nouveaux bâtiments conçus autour la plate-forme permettent de faire de
|
||||
sérieuses économies d'entretien (en ne faisant déplacer les techiciens que
|
||||
lorsque c'est nécessaire) tout en permettant d'anticiper les problèmes (grâce à
|
||||
un moteur de *machine-learning* capable d'anticiper les pannes) et les besoins
|
||||
en combustible (liés à la météo)[^HOMEASSISTANT].
|
||||
|
||||
[^HOMEASSISTANT]: Si ça vous met l'eau à la bouche, jettez un œil du côté du
|
||||
projet <https://www.home-assistant.io/> qui fait un peu moins de
|
||||
*bullshit*, mais est bien réel !
|
||||
|
||||
La principale difficulté que rencontre Électropcool est qu'aucun bâtiment ne
|
||||
dispose des mêmes références de pièces et qu'en dehors des nouveaux bâtiments
|
||||
pour lesquels la société peut imposer des équipements électroniques
|
||||
spécifiquement supportés et compatibles avec la plate-forme qu'elle vend, il lui
|
||||
est bien souvent nécessaire de faire des développements spécifiques pour
|
||||
s'interfacer avec de l'électronique existant : c'est notamment le cas pour les
|
||||
chaudières et les
|
||||
[VMC](https://fr.wikipedia.org/wiki/Ventilation_m%C3%A9canique_contr%C3%B4l%C3%A9e),
|
||||
qui, compte tenu de leur coût de remplacement prohibitif, nécessitent souvent
|
||||
de réaliser des interfaces électroniques spécifiques pour s'adapter à
|
||||
l'existant.
|
||||
|
||||
L'entreprise est en train de prendre un tournant historique et
|
||||
souhaite accélérer ses développements pour faire face à la concurrence
|
||||
qui arrive sur le marché.
|
||||
\
|
||||
|
||||
L'entreprise utilise principalement de nombreux équipements de la *Raspberry Pi
|
||||
fundation*, notamment les [Compute Module 3 et
|
||||
4](https://www.raspberrypi.com/products/compute-module-4/) et les [Raspberry Pi
|
||||
Zero W](https://www.raspberrypi.com/products/raspberry-pi-zero-w/), ainsi que
|
||||
de nombreux PCB fait par l'entreprise, à base de micro-contrôleurs AVR,
|
||||
lorsqu'il est nécessaire de pour s'interfacer avec des équipements
|
||||
propriétaires non prévu pour l'immotique.
|
||||
|
||||
Une grosse partie des travaux est donc réalisé avec un noyau Linux, sur du
|
||||
matériel très performant, pour de l'embarqué.
|
||||
\
|
||||
|
||||
Tous les modules logiciels qui interragissent avec les capteurs sont
|
||||
aujourd'hui intégrés dans un système construit à l'aide de
|
||||
[`bitbake`](https://www.yoctoproject.org/). L'entreprise grossissant à vue d'œil,
|
||||
il devient de plus en plus difficile de synchroniser les équipes concilier la
|
||||
stabilité des *releases* avec le besoin de déployer de nouvelles
|
||||
fonctionnalités chaque semaine.
|
||||
|
||||
Vous avez été chargés d'étudier la meilleure façon de déployer les différents
|
||||
modules, sans qu'il soit nécessaire de reconstruire une image Yocto à chaque
|
||||
fois, mais tout en assurant la stabilité de la plate-forme.
|
||||
|
||||
Le directeur technique vous suggère de regarder du côté des conteneurs
|
||||
applicatifs, qui sont légers et assurent un cloisonnement suffisant pour ne pas
|
||||
entraver la stabilité de la plate-forme en cas de déploiement d'un module
|
||||
défaillant.
|
||||
|
||||
Vous êtes également chargés de jeter les bases du système d'intégration continu
|
||||
des modules. (La partie déploiement continu, sera réalisé plus tard par
|
||||
l'équipe développant le nouveau système de base, suivant le meilleur outil que
|
||||
retiendrez.)
|
||||
\
|
||||
|
||||
Le projet qui vous servira de base pour vos tests sera
|
||||
[`linky2influx`](https://git.nemunai.re/nemunaire/linky2influx) : à partir d'un
|
||||
compteur [Linky](https://fr.wikipedia.org/wiki/Linky), branché sur les bornes
|
||||
de [téléinformation client du
|
||||
compteur](https://hallard.me/demystifier-la-teleinfo/) et [lisant le
|
||||
protocole](https://www.enedis.fr/media/2035/download) pour enregistrer les
|
||||
données dans une *Time-series database*, en l'occurrence InfluxDB.
|
||||
|
||||

|
||||
|
||||
Dans un premier temps, on voudra juste compiler notre projet, pour s'assurer
|
||||
que chaque commit poussé ne contient pas d'erreur de compilation, dans
|
||||
l'environnement défini comme étant celui de production. Ensuite, on ajoutera
|
||||
quelques tests automatiques. Puis nous publierons automatiquement le binaire
|
||||
`linky2influx` comme fichier associé à un tag au sein de l'interface web du
|
||||
gestionnaire de versions.
|
||||
|
||||
Nous testerons enfin différentes solution pour déployer notre binaire, afin
|
||||
d'établir quelle est la solution adéquate.
|
||||
|
||||
|
||||
## Préparer le terrain
|
||||
|
||||
Tous les déploiements sont à faire sur votre machine et la plate-forme de CI
|
||||
utilisera massivement les conteneurs Docker, qui seront regroupés au sein de
|
||||
réseaux Docker. Cela vous permettra d'utiliser la résolution de noms entre vos
|
||||
conteneurs.
|
||||
|
||||
Vous devriez dès maintenant créer les deux réseaux suivants sur votre machines :
|
||||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
docker network create gitea
|
||||
docker network create drone
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
Étant donné que votre machine ne dispose pas de domaine sur Internet et que
|
||||
l'on va essayer de simplifier au maximum l'installation, vous devriez ajouter
|
||||
cette ligne à votre fichier `/etc/hosts` (ou
|
||||
`\Windows\System32\drivers\etc\hosts`) :
|
||||
|
||||
<div lang="en-US">
|
||||
```conf
|
||||
127.0.0.1 gitea droneci
|
||||
```
|
||||
</div>
|
||||
|
||||
Cette ligne va vous permettre de résoudre les noms des conteneurs. Cela
|
||||
permettra aux requêtes OAuth de se faire de manière transparente pour vous
|
||||
lorsque vous serez dans votre navigateur.
|
|
@ -4,19 +4,19 @@ But du TP
|
|||
=========
|
||||
|
||||
Nous allons nous mettre aujourd'hui dans la peau d'une équipe DevOps et
|
||||
réaliser une solution complète de intégration/déploiement continu (le fameux
|
||||
réaliser une solution complète d'intégration/déploiement continu (le fameux
|
||||
CI/CD, pour *Continuous Integration* et *Continuous Delivery*).
|
||||
|
||||
Le résultat attendu d'ici la fin du TP sera de mettre en place toutes les
|
||||
briques décrite dans la section précédente.
|
||||
Le résultat attendu d'ici la fin de cette partie sera de mettre en place toutes
|
||||
les briques décrites dans la section précédente.
|
||||
\
|
||||
|
||||
Nous allons commencer par automatiser le projet `youp0m`, plus simple, puis la
|
||||
plate-forme du FIC dans son ensemble, ce qui représente un petit challenge.
|
||||
Nous allons commencer par automatiser le projet `youp0m`, plus simple, ~~puis
|
||||
la plate-forme du FIC dans son ensemble, ce qui représente un petit challenge~~
|
||||
(merci Nabih !).
|
||||
|
||||
Il est également attendu que vous rendiez un playbook Ansible, permettant de
|
||||
retrouver un environnement similaire. Car on se reservira de cette installation
|
||||
dans un prochain TP.
|
||||
retrouver un environnement similaire. Car on pourra s'en resservir par la suite.
|
||||
\
|
||||
|
||||
Dans un premier temps, on voudra juste compiler notre projet, pour s'assurer
|
||||
|
@ -27,7 +27,7 @@ quelques tests automatiques. Puis nous publierons automatiquement le binaire
|
|||
gestionnaire de versions.
|
||||
|
||||
Enfin, nous mettrons en place un registre Docker qui nous permettra de publier
|
||||
automatiquement l'image Docker assocciée. C'est à partir de cette image Docker
|
||||
automatiquement l'image Docker associée. C'est à partir de cette image Docker
|
||||
que l'on va commencer à déployer automatiquement...
|
||||
|
||||
|
||||
|
@ -50,7 +50,8 @@ Dans votre playbook Ansible, vous pourrez procéder ainsi :
|
|||
|
||||
Étant donné que votre machine ne dispose pas de domaine sur Internet et que
|
||||
l'on va essayer de simplifier au maximum l'installation, vous devriez ajouter
|
||||
cette ligne à votre fichier `/etc/hosts` :
|
||||
cette ligne à votre fichier `/etc/hosts` (ou
|
||||
`\Windows\System32\drivers\etc\hosts`) :
|
||||
|
||||
<div lang="en-US">
|
||||
```conf
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue