tuto 2022 5, 6
This commit is contained in:
parent
3d7c03fbbd
commit
2af52619c7
43 changed files with 1073 additions and 431 deletions
|
@ -25,7 +25,7 @@ steps:
|
|||
- make -C tutorial/4
|
||||
- mv tutorial/4/tutorial.pdf dist/tutorial-4.pdf
|
||||
- make -C tutorial/5
|
||||
- mv tutorial/5/tutorial.pdf dist/tutorial-5.pdf
|
||||
- mv tutorial/5/tutorial-5-srs.pdf tutorial/5/tutorial-5-gistre.pdf dist/
|
||||
- make -C tutorial/k8s
|
||||
- mv tutorial/k8s/tutorial.pdf dist/tutorial-6.pdf
|
||||
- make -C subject/1
|
||||
|
|
|
@ -256,6 +256,7 @@ Et de ces quelques articles :
|
|||
* [File-based capabilities](https://lwn.net/Articles/211883/)
|
||||
* [A bid to resurrect Linux capabilities](https://lwn.net/Articles/199004/)
|
||||
* [False Boundaries and Arbitrary Code Execution](https://forums.grsecurity.net/viewtopic.php?f=7&t=2522#p10271)
|
||||
* [Linux Capabilities on HackTricks](https://book.hacktricks.xyz/linux-unix/privilege-escalation/linux-capabilities)
|
||||
|
||||
Pour revenir à Docker, un certain nombre de *capabilities* sont désactivées par
|
||||
défaut ; vous pouvez en ajouter et en retirer via les arguments `--cap-add` et
|
||||
|
|
|
@ -1,20 +1,47 @@
|
|||
include ../pandoc-opts.mk
|
||||
|
||||
SOURCES = tutorial.md \
|
||||
SOURCES_SRS = tutorial-srs.md \
|
||||
../devops/devops.md \
|
||||
../devops/what.md \
|
||||
../devops/tools.md \
|
||||
../devops/tools-gitea.md \
|
||||
../devops/tools-gitea-ansible.md \
|
||||
../devops/tools-gitea-end.md \
|
||||
../devops/tools-drone.md \
|
||||
../devops/tools-drone-ansible.md \
|
||||
../devops/tools-drone-oauth.md \
|
||||
../devops/tools-drone-runner.md \
|
||||
../devops/tools-drone-runner-ansible.md \
|
||||
../devops/tools-end.md \
|
||||
../devops/ci.md \
|
||||
../devops/publish-docker.md \
|
||||
../docker-internals/oci.md \
|
||||
../docker-internals/registry.md \
|
||||
rendu.md
|
||||
rendu-srs.md
|
||||
|
||||
SOURCES_GISTRE = tutorial-gistre.md \
|
||||
../devops/what-gistre.md \
|
||||
../devops/what-gistre-see-srs.md \
|
||||
../devops/tools.md \
|
||||
../devops/tools-gitea.md \
|
||||
../devops/tools-gitea-cmd.md \
|
||||
../devops/tools-gitea-end.md \
|
||||
../devops/tools-drone.md \
|
||||
../devops/tools-drone-cmd.md \
|
||||
../devops/tools-drone-oauth.md \
|
||||
../devops/tools-drone-runner.md \
|
||||
../devops/tools-drone-runner-cmd.md \
|
||||
../devops/tools-end.md \
|
||||
../devops/ci-gistre.md \
|
||||
../devops/run-gistre.md \
|
||||
rendu-gistre.md
|
||||
|
||||
|
||||
all: tutorial.pdf
|
||||
all: tutorial-5-srs.pdf tutorial-5-gistre.pdf
|
||||
|
||||
tutorial.pdf: ${SOURCES}
|
||||
tutorial-5-srs.pdf: ${SOURCES_SRS}
|
||||
pandoc ${PANDOCOPTS} -o $@ $+
|
||||
|
||||
tutorial-5-gistre.pdf: ${SOURCES_GISTRE}
|
||||
pandoc ${PANDOCOPTS} -o $@ $+
|
||||
|
||||
clean::
|
||||
rm tutorial.pdf
|
||||
rm tutorial-5-srs.pdf tutorial-5-gistre.pdf
|
||||
|
|
|
@ -10,11 +10,15 @@ abstract: |
|
|||
|
||||
\vspace{1em}
|
||||
|
||||
À la demande de Nabih, ce TP a été raccourci
|
||||
|
||||
\vspace{1em}
|
||||
|
||||
Tous les éléments de ce TP (exercices et projet) sont à rendre à
|
||||
<virli@nemunai.re> au plus tard le **mercredi 4 novembre 2020 à 12 h
|
||||
<virli@nemunai.re> au plus tard le **jeudi 18 novembre 2021 à 23 h
|
||||
42**. Consultez la dernière section de chaque partie pour plus d'informations
|
||||
sur les éléments à rendre. Et n'oubliez pas de répondre aux [questions de
|
||||
cours](https://virli.nemunai.re/quiz/5).
|
||||
cours](https://virli.nemunai.re/quiz/13).
|
||||
|
||||
En tant que personnes sensibilisées à la sécurité des échanges électroniques,
|
||||
vous devrez m'envoyer vos rendus signés avec votre clef PGP. Pensez à
|
||||
|
|
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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
include ../pandoc-opts.mk
|
||||
|
||||
SOURCES = tutorial.md oci.md runc.md linuxkit.md linuxkit-adlin.md linuxkit-content.md rendu.md
|
||||
SOURCES = tutorial.md oci.md registry.md runc.md linuxkit.md linuxkit-content.md rendu.md
|
||||
|
||||
|
||||
all: tutorial.pdf
|
||||
|
|
|
@ -41,19 +41,19 @@ L'image la plus simple que l'on puisse réaliser pourrait être :
|
|||
<div lang="en-US">
|
||||
```yaml
|
||||
kernel:
|
||||
image: linuxkit/kernel:4.14.80
|
||||
image: linuxkit/kernel:5.10.76
|
||||
cmdline: "console=tty0 console=ttyS0"
|
||||
init:
|
||||
- linuxkit/init:c563953a2277eb73a89d89f70e4b6dcdcfebc2d1
|
||||
- linuxkit/runc:83d0edb4552b1a5df1f0976f05f442829eac38fe
|
||||
- linuxkit/containerd:326b096cd5fbab0f864e52721d036cade67599d6
|
||||
- linuxkit/init:eb597ef74d808b5320ad1060b1620a6ac31e7ced
|
||||
- linuxkit/runc:21dbbda709ae138de0af6b0c7e4ae49525db5e88
|
||||
- linuxkit/containerd:2f0907913dd54ab5186006034eb224a0da12443e
|
||||
onboot:
|
||||
- name: dhcpcd
|
||||
image: linuxkit/dhcpcd:v0.6
|
||||
image: linuxkit/dhcpcd:v0.8
|
||||
command: ["/sbin/dhcpcd", "--nobackground", "-f", "/dhcpcd.conf", "-1"]
|
||||
services:
|
||||
- name: getty
|
||||
image: linuxkit/getty:2eb742cd7a68e14cf50577c02f30147bc406e478
|
||||
image: linuxkit/getty:3c6e89681a988c3d4e2610fcd7aaaa0247ded3ec
|
||||
env:
|
||||
- INSECURE=true
|
||||
trust:
|
||||
|
@ -91,7 +91,7 @@ Il reste possible de se dissocier également de ces namespaces, en précisant :
|
|||
<div lang="en-US">
|
||||
```yaml
|
||||
- name: getty
|
||||
image: linuxkit/getty:2eb742cd7a68e14cf50577c02f30147bc406e478
|
||||
image: linuxkit/getty:3c6e89681a988c3d4e2610fcd7aaaa0247ded3ec
|
||||
net: new
|
||||
```
|
||||
</div>
|
||||
|
@ -101,7 +101,7 @@ Ou inversement, pour persister dans le namespace initial :
|
|||
<div lang="en-US">
|
||||
```yaml
|
||||
- name: getty
|
||||
image: linuxkit/getty:2eb742cd7a68e14cf50577c02f30147bc406e478
|
||||
image: linuxkit/getty:3c6e89681a988c3d4e2610fcd7aaaa0247ded3ec
|
||||
pid: host
|
||||
```
|
||||
</div>
|
||||
|
@ -118,7 +118,7 @@ On commence donc d'abord par créer le nouveau *namespace*, en prenant soin de
|
|||
<div lang="en-US">
|
||||
```yaml
|
||||
- name: getty
|
||||
image: linuxkit/getty:2eb742cd7a68e14cf50577c02f30147bc406e478
|
||||
image: linuxkit/getty:3c6e89681a988c3d4e2610fcd7aaaa0247ded3ec
|
||||
net: new
|
||||
runtime:
|
||||
bindNS: /run/netns/mynewnetns
|
||||
|
@ -132,7 +132,7 @@ réutiliser plus tard ce chemin, en remplacement du mot clef `new` :
|
|||
<div lang="en-US">
|
||||
```yaml
|
||||
- name: xxxx
|
||||
image: linuxkit/xxxx:v0.6
|
||||
image: linuxkit/xxxx:v0.8
|
||||
net: /run/netns/mynewnetns
|
||||
```
|
||||
</div>
|
||||
|
|
|
@ -177,3 +177,9 @@ Hello from Docker!
|
|||
|
||||
Pensez également à tester avec d'autres images, comme par exemple
|
||||
`nemunaire/youp0m`. Il vous faudra alors extraire plusieurs couches.
|
||||
|
||||
Pour gérer les différentes couches, vous pouvez utiliser une stratégie
|
||||
similaire au driver `vfs` : en extrayant chaque tarball l'une au dessus de
|
||||
l'autre, en essayant de gérer les *whiteout files*. Ou bien en suivant le
|
||||
driver `overlayfs`, en montant un système de fichier à chaque couche (dans ce
|
||||
cas, votre script devra être lancé en `root`).
|
||||
|
|
|
@ -6,18 +6,23 @@ Rendu
|
|||
Modalités de rendu
|
||||
------------------
|
||||
|
||||
En tant que personnes sensibilisées à la sécurité des échanges électroniques,
|
||||
vous devrez m'envoyer vos rendus signés avec votre clef PGP.
|
||||
|
||||
Un service automatique s'occupe de réceptionner vos rendus, de faire des
|
||||
vérifications élémentaires et de vous envoyer un accusé de réception (ou de
|
||||
rejet).
|
||||
|
||||
Ce service écoute sur l'adresse <virli@nemunai.re>, c'est donc à cette adresse
|
||||
Ce service écoute sur l'adresse <virli@nemunai.re>. C'est donc à cette adresse
|
||||
et exclusivement à celle-ci que vous devez envoyer vos rendus. Tout rendu
|
||||
envoyé à une autre adresse et/ou non signé et/ou reçu après la correction ne
|
||||
sera pas pris en compte.
|
||||
|
||||
Afin d'orienter correctement votre rendu, ajoutez une balise `[TP6]` au sujet
|
||||
de votre courriel. N'hésitez pas à indiquer dans le corps du courriel votre
|
||||
ressenti et vos difficultés ou bien alors écrivez votre meilleure histoire
|
||||
drôle si vous n'avez rien à dire.
|
||||
|
||||
Mais n'oubliez pas de répondre au [sondage](https://virli.nemunai.re/quiz/16)
|
||||
pour me permettre d'améliorer ce cours.
|
||||
|
||||
|
||||
Tarball
|
||||
-------
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
---
|
||||
title: Virtualisation légère -- TP n^o^ 3
|
||||
title: Virtualisation légère -- TP n^o^ 6
|
||||
subtitle: Les projets de l'Open Container Initiative
|
||||
author: Pierre-Olivier *nemunaire* [Mercier]{.smallcaps}
|
||||
institute: EPITA
|
||||
date: Mercredi 28 octobre 2020
|
||||
date: Vendredi 19 novembre 2021
|
||||
abstract: |
|
||||
Après avoir beaucoup parlé de Docker, nous allons voir dans ce TP la
|
||||
manière dont les différents projets qu'il utilise dans sa plomberie
|
||||
|
@ -11,10 +11,10 @@ abstract: |
|
|||
|
||||
\vspace{1em}
|
||||
|
||||
Les éléments de ce TP constituent du contenu bonus que vous pouvez rendre à
|
||||
<virli@nemunai.re> au plus tard le dimanche 22 novembre 2020 à 23
|
||||
h 42. Consultez la dernière section de chaque partie pour plus d'information
|
||||
sur les éléments à rendre.
|
||||
**Ce TP est un sujet alternative au TP Kubernetes** que les GISTRE
|
||||
peuvent rendre à la place, à <virli@nemunai.re> au plus tard le
|
||||
vendredi 3 décembre 2021 à 23 h 42. Consultez la dernière section de
|
||||
chaque partie pour plus d'information sur les éléments à rendre.
|
||||
|
||||
En tant que personnes sensibilisées à la sécurité des échanges électroniques,
|
||||
vous devrez m'envoyer vos rendus signés avec votre clef PGP. Pensez à
|
||||
|
|
|
@ -15,27 +15,41 @@ dessus de `curl`.
|
|||
Obtenir de l'aide
|
||||
-----------------
|
||||
|
||||
Commençons par apprivoiser `kubectl` en prenant quelques
|
||||
renseignements et surtout en apprennant comment obtenir de l'aide :
|
||||
|
||||
<div lang="en-US">
|
||||
```bash
|
||||
kubectl describe type/name
|
||||
kubectl describe type name
|
||||
kubectl explain type
|
||||
```
|
||||
</div>
|
||||
|
||||
Les `type`s que vous pouvez découvrir sont ceux que l'on a vu à la
|
||||
sections précédentes : `node`, `pod`, ...
|
||||
|
||||
La commande `describe` permet d'afficher l'état tel qu'il est attendu
|
||||
et tel qu'il est actuellement (cela permet de se rendre lorsque les
|
||||
deux divergent).
|
||||
|
||||
|
||||
`get`
|
||||
-----
|
||||
|
||||
Une autre manière, moins verbeuse, de récupérer des informations est
|
||||
d'utiliser `get` :
|
||||
|
||||
```bash
|
||||
kubectl get node
|
||||
```
|
||||
|
||||
Plus d'infos :
|
||||
On peut ajouter des options pour avoir plus d'infos :
|
||||
|
||||
```bash
|
||||
kubectl get nodes -o wide
|
||||
```
|
||||
|
||||
Lisible par une machine :
|
||||
... ou rendre la sortie lisible par une machine :
|
||||
|
||||
```bash
|
||||
kubectl get no -o yaml
|
||||
|
@ -91,7 +105,7 @@ conteneurs, gérés par lui-même... notamment :
|
|||
- `kube-controller-manager` et `kube-scheduler`, deux autres composants
|
||||
indispensables,
|
||||
- `coredns` : un composant additionnel pour gérer la résolution de noms internes
|
||||
(pour pas avoir à s'embêter avec les IP),
|
||||
(pour ne pas avoir à s'embêter avec les IP),
|
||||
- `kube-proxy` : 1 par nœud, pour gérer l'ouverture des ports notamment,
|
||||
- `kindnet`, `weave` : 1 par nœud, le plugin réseau.
|
||||
|
||||
|
@ -110,9 +124,9 @@ Nous devons lancer un *pod* (qui ne contiendra qu'un seul conteneur).
|
|||
kubectl run pingpong --image alpine ping 1.1.1.1
|
||||
```
|
||||
|
||||
`kubectl` doit nous indiquer nous qu'un *pod* a été créée.
|
||||
`kubectl` doit nous indiquer nous qu'un *pod* a été créé.
|
||||
|
||||
Si l'on affiche la liste des pods, vous devriez avoir quelque chose qui
|
||||
Si l'on affiche la liste des *pod*s, vous devriez avoir quelque chose qui
|
||||
ressemble à cela :
|
||||
|
||||
```
|
||||
|
@ -144,7 +158,7 @@ Notez ici l'option -f qui permet de suivre les logs en direct.
|
|||
Notre premier test ayant réussi, nous pouvons arrêter de DDos Cloudflare :
|
||||
|
||||
```bash
|
||||
kubectl delete deploy/pingpong
|
||||
kubectl delete pods pingpong
|
||||
```
|
||||
|
||||
|
||||
|
@ -152,13 +166,13 @@ kubectl delete deploy/pingpong
|
|||
|
||||
Bien ... maintenant que nous savons nous débrouiller avec `kubectl`, attaquons
|
||||
les choses sérieuses : en temps normal avec Kubernetes, nous ne déploierons pas
|
||||
de *pod* directement, car cela reviendrait à utiliser Docker, mais des tâches
|
||||
de déploiement.
|
||||
de *pod* directement, car cela reviendrait à utiliser Docker. Nous allons
|
||||
plutôt créer des tâches de déploiement.
|
||||
|
||||
Essayons sans plus attendre de lancer nos `ping` à travers une tâche de déploiement :
|
||||
|
||||
```bash
|
||||
kubectl create deployment pingpong --image=alpine -- ping 1.1.1.1
|
||||
kubectl create deployment pingpong --image=alpine -- ping 8.8.8.8
|
||||
```
|
||||
|
||||
Si l'on regarde maintenant la sortie de `kubectl get all`, on obtient :
|
||||
|
@ -177,19 +191,21 @@ NAME DESIRED CURRENT READY AGE
|
|||
replicaset.apps/pingpong-98f6d5899 1 1 0 123s
|
||||
```
|
||||
|
||||
Oula, on a vraiment lancé tout ça ?!
|
||||
|
||||
Pas de panique, on peut très facilement le décortiquer :
|
||||
|
||||
Les tâches de déploiements (*deployment.apps*) sont des ressources de
|
||||
haut-niveau et sont là pour s'assurer que les migrations se font en douceur :
|
||||
elles vont permettre de basculer progressivement les pods d'une version X à une
|
||||
version Y (par exemple si l'on change notre ping d'alpine vers debian), mais
|
||||
éventuellement de revenir sur la version X si besoin, en cours de migration.
|
||||
Elles délèguent aux *replicatsets* la gestion des pods.
|
||||
|
||||
Le *replicatset* est là pour indiquer le nombre de pods que l'on désire, et
|
||||
s'assurer que le nombre de pods actuellement lancé est bien en adéquation avec
|
||||
le nombre de pods attendu.
|
||||
Les tâches de déploiement (*deployment.apps*) sont des ressources de
|
||||
haut niveau et sont là pour s'assurer que les migrations se font en douceur :
|
||||
elles vont permettre de basculer progressivement les *pod*s d'une version X à une
|
||||
version Y (par exemple si l'on change notre ping d'alpine 3.14 vers alpine
|
||||
edge), mais éventuellement de revenir sur la version X si besoin, en cours de
|
||||
migration. Elles délèguent ensuite aux *replicatsets* la gestion des *pod*s.
|
||||
|
||||
Le *replicatset* est là pour indiquer le nombre de *pod*s que l'on désire et
|
||||
s'assurer que le nombre de *pod*s actuellement lancé est bien en adéquation avec
|
||||
le nombre de *pod*s attendu.
|
||||
\
|
||||
|
||||
Pour résumer : `kubectl` a créé une tâche de déploiement
|
||||
`deploy/pingpong`. Cette tâche de déploiement a créé elle-même un *replicatset*
|
||||
|
@ -198,7 +214,7 @@ Pour résumer : `kubectl` a créé une tâche de déploiement
|
|||
|
||||
### Passage à l'échelle : facile ?
|
||||
|
||||
Pour lancer 3 ping en parallèle, modifions la tâche de déploiement comme suit :
|
||||
Pour lancer 3 `ping`s en parallèle, modifions la tâche de déploiement comme suit :
|
||||
|
||||
```bash
|
||||
kubectl scale deploy/pingpong --replicas 3
|
||||
|
@ -206,9 +222,10 @@ kubectl scale deploy/pingpong --replicas 3
|
|||
|
||||
À ce stade, comme nous ne modifions que le nombre de replicats, Kubernetes va
|
||||
tout simplement propager ce nombre au *replicatset* existant. Puis, le
|
||||
*replicatset* voyant un décalage entre le nombre de pods attendus et le nombre
|
||||
de pods en cours d'exécution, il va en lancer de nouveaux, afin de répondre à
|
||||
*replicatset* voyant un décalage entre le nombre de *pod*s attendus et le nombre
|
||||
de *pod*s en cours d'exécution, il va en lancer de nouveaux, afin de répondre à
|
||||
la demande.
|
||||
\
|
||||
|
||||
Et que se passe-t-il alors, si l'on tue un *pod* ?
|
||||
|
||||
|
@ -216,31 +233,32 @@ Et que se passe-t-il alors, si l'on tue un *pod* ?
|
|||
kubectl delete pod pingpong-yyyy
|
||||
```
|
||||
|
||||
Cela supprime bien un *pod*, mais un autre est relancé instantannément car le
|
||||
Cela supprime bien un *pod*, mais un autre est relancé instantanément car le
|
||||
*replicatset* constate une différence dans le nombre attendu.
|
||||
|
||||
Si nous voulons arrêter de DDoS Cloudflare, il ne s'agit pas de tuer chacun des
|
||||
pods un par un, car de nouveaux seraient créés par le *replicatset*. Si l'on
|
||||
supprime le *replicatset*, la tâche de déploiement en rećréera un similaire.
|
||||
Si nous voulons arrêter de DDoS Google/Cloudflare, il ne s'agit pas de tuer
|
||||
chacun des *pod*s un par un, car de nouveaux seraient créés par le
|
||||
*replicatset*. Si l'on supprime le *replicatset*, la tâche de déploiement en
|
||||
recréera un similaire (avec de nouveaux *pod*s).
|
||||
|
||||
Pour arrêter nos conteneurs, il convient donc de supprimer la tâche de
|
||||
déploiement :
|
||||
|
||||
```bash
|
||||
kubectl delete deploy/pingpong
|
||||
kubectl delete deploy pingpong
|
||||
```
|
||||
|
||||
|
||||
### Exposer son conteneur
|
||||
|
||||
Exposer un conteneur revient à créer un nouveau service (une *resource*
|
||||
service). Un service est une adresse IP que l'on peut considérer comme stable
|
||||
pour un *pod* ou un groupe de *pods*.
|
||||
Exposer un conteneur revient à créer un nouveau service (une ressource
|
||||
*service*). Un service est une adresse IP que l'on peut considérer comme stable
|
||||
pour un *pod* ou un groupe de *pod*s.
|
||||
|
||||
Il est nécessaire de créer un service si l'on veut pouvoir se connecter à un
|
||||
Il est nécessaire de créer un *service* si l'on veut pouvoir se connecter à un
|
||||
*pod*.
|
||||
|
||||
Une fois le service créé, le serveur DNS interne va permettre de résoudre le
|
||||
Une fois le *service* créé, le serveur DNS interne va permettre de résoudre le
|
||||
nom du *pod* depuis les autres conteneurs.
|
||||
|
||||
|
||||
|
@ -249,12 +267,12 @@ nom du *pod* depuis les autres conteneurs.
|
|||
Il y a différents types de services :
|
||||
|
||||
- `ClusterIP` (par défaut) : une adresse IP virtuelle est allouée pour le
|
||||
service, elle n'est accessible que depuis le réseau interne (par les pods et
|
||||
service, elle n'est accessible que depuis le réseau interne (par les *pod*s et
|
||||
les nœuds). Il n'y a pas de translation de port à effectuer.
|
||||
- `NodePort` : un port est alloué pour le service, sur tous les nœuds le
|
||||
cluster, et n'importe qui peut alors s'y connecter. Le port est choisi
|
||||
cluster et n'importe qui peut alors s'y connecter. Le port est choisi
|
||||
aléatoirement.
|
||||
- `LoadBalancer` : lorsque l'infrastructure sous-jacente fourni un
|
||||
- `LoadBalancer` : lorsque l'infrastructure sous-jacente fournit un
|
||||
load-balancer (typiquement AWS, GCE, Azure, ...), un service `NodePort` est
|
||||
créé pour utiliser ce load-balancer externe.
|
||||
- `ExternalName` : une entrée DNS est créée pour avoir un alias.
|
||||
|
@ -262,6 +280,8 @@ Il y a différents types de services :
|
|||
|
||||
#### Le retour de `youp0m`
|
||||
|
||||
Déployons maintenant l'image `youp0m` pour voir comment utiliser les *service*s :
|
||||
|
||||
```bash
|
||||
kubectl create deployment youp0m --image=nemunaire/youp0m
|
||||
```
|
||||
|
@ -287,7 +307,7 @@ différents nœuds.
|
|||
Si vous passez par `kind`, vous pouvez constater le bon fonctionnement grâce à :
|
||||
|
||||
```bash
|
||||
docker exec -it kind-control-plane curl 10.96.179.154:8080
|
||||
docker exec -it kind-control-plane curl 10.102.129.233:8080
|
||||
```
|
||||
|
||||
|
||||
|
@ -306,11 +326,15 @@ la configuration nécessaire :
|
|||
kubectl create -f https://virli.nemunai.re/insecure-dashboard.yaml
|
||||
```
|
||||
|
||||
::::: {.warning}
|
||||
|
||||
Notez que le dashboard, avec cette configuration, va s'exécuter sans les
|
||||
prérequis minimum de sécurité : pas de certificat TLS, ni
|
||||
d'authentification. Ceci est juste pour jouer avec l'interface, en production,
|
||||
on n'utilisera pas cette recette.
|
||||
|
||||
:::::
|
||||
|
||||
Regardons où nous pouvons contacter notre dashboard :
|
||||
|
||||
```bash
|
||||
|
@ -323,7 +347,7 @@ kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6m51s
|
|||
Regardons si cela répond :
|
||||
|
||||
```bash
|
||||
$ docker exec -it kind-control-plane curl 127.0.0.1:31505
|
||||
$ docker exec -it kind-control-plane curl 10.96.78.69:80
|
||||
<p class="browsehappy">You are using an <strong>outdated</strong> browser.
|
||||
```
|
||||
|
||||
|
@ -332,10 +356,10 @@ Pas très sympa... il faudrait que l'on puisse le voir dans un navigateur plus
|
|||
|
||||
Étant donné que notre cluster ne se trouve pas directement sur notre machine,
|
||||
mais dans différents conteneurs Docker, nous ne pouvons pas accéder à
|
||||
`127.0.0.1`. Heureusement, au moment de la création de notre cluster, nous
|
||||
avons renseigné plusieurs ports redirigés au sein de notre configuration. Il va
|
||||
donc falloir indiquer à Kubernetes que l'on désire utiliser un port spécifique
|
||||
pour exposer le tableau de bord.
|
||||
`127.0.0.1`. Heureusement, au moment de la création de notre cluster avec
|
||||
`kind`, nous avons renseigné plusieurs ports redirigés au sein de notre
|
||||
configuration. Il va donc falloir indiquer à Kubernetes que l'on désire
|
||||
utiliser un port spécifique pour exposer le tableau de bord.
|
||||
|
||||
Pour ce faire, éditons le fichier `insecure-dashboard.yaml`, pour ajouter, dans
|
||||
la partie `Service` un *node port* plus spécifique :
|
||||
|
|
BIN
tutorial/k8s/docker-desktop-k8s.png
Normal file
BIN
tutorial/k8s/docker-desktop-k8s.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
|
@ -3,14 +3,16 @@
|
|||
Introduction
|
||||
============
|
||||
|
||||
Notre application du jour
|
||||
-------------------------
|
||||
|
||||
Aujourd'hui, nous allons travailler avec un mineur de pépites ... de chocolat !
|
||||
Alors, on se fait un bon thé, on prend sa boîte de gâteaux pour tenir le coup,
|
||||
et c'est parti !
|
||||
<!--De véritables cookies sont à gagner pour celles et ceux qui auront amassés le
|
||||
plus de pépites avant la pause !-->
|
||||
|
||||
<!--Alors, on se fait un bon thé, on prend sa boîte de gâteaux pour tenir le coup,
|
||||
et c'est parti !-->
|
||||
Comme c'est notre dernier cours ensemble, de véritables cookies sont à
|
||||
gagner pour celles et ceux qui auront amassé le plus de pépites d'ici
|
||||
la fin du TP[^cookies] ! Vous pouvez suivre votre progression sur
|
||||
[cette page](https://virli.nemunai.re/scores.html).
|
||||
|
||||
[^cookies]: Dans la limite des stocks disponibles.
|
||||
|
||||

|
||||
|
||||
|
@ -34,7 +36,7 @@ Obtenir l'application
|
|||
|
||||
<div lang="en-US">
|
||||
```shell
|
||||
git clone https://gitea.nemunai.re/srs/chocominer.git
|
||||
git clone https://git.nemunai.re/srs/chocominer.git
|
||||
```
|
||||
</div>
|
||||
|
||||
|
@ -47,7 +49,7 @@ des conteneurs : un serveur DNS nous permettait de se connecter aux différents
|
|||
services à partir de leurs noms.
|
||||
|
||||
Dans Kubernetes, le même principe s'applique : dans aucun cas, nous ne devrions
|
||||
coder en dur des adresses IP. Il convient d'utiliser au maximum le système de
|
||||
inscrire en dur des adresses IP. Il convient d'utiliser au maximum le système
|
||||
DNS, car les IP sont susceptibles de changer !
|
||||
|
||||
|
||||
|
@ -71,13 +73,13 @@ Montée en puissance
|
|||
docker-compose up -d --scale worker=2
|
||||
```
|
||||
|
||||
On remarque que le nombre de hash calculés augmente ! Génial !
|
||||
On remarque que le nombre de hashs calculés augmente ! Génial !
|
||||
|
||||
```bash
|
||||
docker-compose up -d --scale worker=10
|
||||
```
|
||||
|
||||
Mais ça atteint un palier au bout d'un moment ...
|
||||
Mais ça atteint un palier au bout d'un moment...
|
||||
|
||||
|
||||
Identification du goulot d'étranglement
|
||||
|
|
|
@ -5,7 +5,7 @@ Vue d'ensemble de Kubernetes
|
|||
|
||||
*Kubernetes* est un système open source d'orchestration et de gestion de
|
||||
conteneurs. C'est-à-dire qu'il se charge de coller constamment aux
|
||||
spécifications qu'on lui aura demandé.
|
||||
spécifications qu'on lui aura demandées.
|
||||
|
||||
Ce projet est l'aboutissement de plus d'une dizaine d'années d'expérience de
|
||||
gestion de conteneurs applicatifs chez Google (rappelons que c'est eux qui ont
|
||||
|
@ -13,13 +13,13 @@ poussé de nombreuses technologies dans le noyau Linux, notamment les
|
|||
*cgroups*, ...).
|
||||
|
||||
Dans Kubernetes, il n'est pas question d'indiquer comment lancer ses
|
||||
conteneurs, ni même quels cgroups utiliser. On va fournir à l'orchestrateur des
|
||||
informations, des *spécifications* qui vont altérer l'état du cluster. Et c'est
|
||||
en cherchant à être constamment dans l'état qu'on lui a décrit, qu'il va
|
||||
conteneurs, ni même quels *cgroups* utiliser. On va fournir à l'orchestrateur
|
||||
des informations, des *spécifications*, qui vont altérer l'état du cluster. Et
|
||||
c'est en cherchant à être constamment dans l'état qu'on lui a décrit, qu'il va
|
||||
s'adapter pour répondre aux besoins.
|
||||
|
||||
Par exemple, on ne va pas lui expliquer comment lancer des conteneurs ou
|
||||
récupérer des images ; mais on va lui demander d'avoir 5 conteneurs youp0m
|
||||
récupérer des images ; mais on va lui demander d'avoir 5 conteneurs `youp0m`
|
||||
lancés, de placer ces conteneurs derrière un load-balancer ; on pourra
|
||||
également lui demander d'adapter la charge pour absorber les pics de trafic
|
||||
(par exemple lors du Black Friday sur une boutique), mais également, il pourra
|
||||
|
@ -34,7 +34,7 @@ Architecture de Kubernetes
|
|||
Un cluster Kubernetes est composé d'un (ou plusieurs) nœuds *master*, et d'une
|
||||
série de *workers*.
|
||||
|
||||
Sur le master, on retrouve les composants suivants :
|
||||
Sur le(s) *master(s)*, on retrouve les composants suivants :
|
||||
|
||||
API HTTP
|
||||
: On distingue plusieurs API, elles sont toutes utilisées pour communiquer avec
|
||||
|
@ -51,16 +51,13 @@ Le contrôleur
|
|||
**`etcd`**
|
||||
: Il s'agit d'une base de données clef/valeur, supportant la
|
||||
haute-disponibilité, que Kubernetes emploie comme système de stockage
|
||||
persistant pour les objets d'API.
|
||||
persistant pour les objets et ses états.
|
||||
\
|
||||
|
||||
|
||||
Chaque nœud[^minion] (généralement, le nœud *master* est également *worker*) est utilisé
|
||||
Chaque nœud (généralement, le nœud *master* est également *worker*) est utilisé
|
||||
via deux composants :
|
||||
|
||||
[^minion]: historiquement, avant de parler de *node*, on parlait de
|
||||
*minion*. Vous êtes susceptibles de rencontrer encore ce terme dans
|
||||
certaines documentations.
|
||||
|
||||
`kubelet`
|
||||
: C'est l'agent qui va se charger de créer les conteneurs et les manager, afin
|
||||
de répondre aux spécifications.
|
||||
|
@ -70,6 +67,7 @@ via deux composants :
|
|||
|
||||
Sans oublier le moteur de conteneurs (généralement Docker), qui va
|
||||
effectivement se charger de lancer les conteneurs demandés par `kubelet`.
|
||||
\
|
||||
|
||||
|
||||
Évidemment, chaque élément de l'architecture est malléable à souhait, c'est la
|
||||
|
@ -85,11 +83,12 @@ Avec Docker, nous avons eu l'habitude de travailler avec des objets (images,
|
|||
containers, networks, volumes, secrets, ...). Au sein de Kubernetes, cela
|
||||
s'appelle des *resources* et elles sont très nombreuses.
|
||||
|
||||
Parmi les plus courantes, citons les types (désignés *Kind* dans l'API)
|
||||
suivants :
|
||||
Parmi les plus courantes, citons les types (désignés *Kind* dans l'API, rien à
|
||||
voir avec le projet `kind` au début du sujet) suivants :
|
||||
|
||||
node
|
||||
: il s'agit d'une machine physique ou virtuelle, de notre cluster.
|
||||
: il s'agit d'une machine de notre cluster (elle peut être physique ou
|
||||
virtuelle).
|
||||
|
||||
pod
|
||||
: un groupe de conteneurs travaillant ensemble. Il s'agit de la ressource que
|
||||
|
@ -128,8 +127,8 @@ compléter ce schéma...
|
|||
|
||||
Chaque plugin implémente la [spécification
|
||||
CNI](https://github.com/containernetworking/cni/blob/master/SPEC.md#network-configuration)
|
||||
(Container Network Interface). On trouve donc autant de plugin qu'il y a de
|
||||
besoins en terme de réseau.
|
||||
(Container Network Interface). On trouve donc autant de plugins qu'il y a de
|
||||
besoins en termes de réseau.
|
||||
|
||||
Ainsi, à la création d'un conteneur, Kubernetes va laisser aux plugins CNI le
|
||||
loisir d'allouer l'adresse IP, d'ajouter les interfaces réseaux adéquates, de
|
||||
|
|
|
@ -20,7 +20,7 @@ de votre courriel. N'hésitez pas à indiquer dans le corps du courriel votre
|
|||
ressenti et vos difficultés ou bien alors écrivez votre meilleure histoire
|
||||
drôle si vous n'avez rien à dire.
|
||||
|
||||
Mais n'oubliez pas de répondre au [sondage](https://virli.nemunai.re/quiz/8)
|
||||
Mais n'oubliez pas de répondre au [sondage](https://virli.nemunai.re/quiz/16)
|
||||
pour me permettre d'améliorer ce cours.
|
||||
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ allons devoir :
|
|||
- exposer avec un NodePort l'interface graphique de contrôle.
|
||||
|
||||
|
||||
Lancement des *pods*
|
||||
Lancement des *pod*s
|
||||
--------------------
|
||||
|
||||
### Via Helm
|
||||
|
@ -32,7 +32,7 @@ permettant de trouver facilement son bonheur. On va y trouver
|
|||
va avoir besoin pour la suite.
|
||||
|
||||
Mais d'abord, il va nous falloir [installer
|
||||
helm](https://helm.sh/docs/intro/install/). Il utilisera la même configuration
|
||||
Helm](https://helm.sh/docs/intro/install/). Il utilisera la même configuration
|
||||
que `kubectl`, il n'y a rien de plus à configurer.
|
||||
|
||||
Une fois `helm` installé, et le dépôt `influxdata` ajouté, comme précisé dans
|
||||
|
@ -40,7 +40,7 @@ la documentation du *chart* d'InfluxDB, nous pouvons le déployer dans notre
|
|||
cluster :
|
||||
|
||||
```bash
|
||||
helm install influxdata/influxdb --generate-name
|
||||
helm install influxdb influxdata/influxdb
|
||||
```
|
||||
|
||||
Les valeurs de configuration indiquées dans le `README` du *chart* se modifient
|
||||
|
@ -50,7 +50,7 @@ ainsi :
|
|||
helm upgrade -f values.yml your-influx-name influxdata/influxdb
|
||||
```
|
||||
|
||||
Il vous sera entre-autre nécessaire d'ajouter un administrateur afin de pouvoir
|
||||
Il vous sera entre autres nécessaire d'ajouter un administrateur afin de pouvoir
|
||||
utiliser la base de données.
|
||||
|
||||
Nous pouvons ensuite faire de même avec
|
||||
|
@ -61,7 +61,7 @@ mixer avec la méthode ci-dessous (en adaptant certaines valeurs).
|
|||
### Via `kubectl`
|
||||
|
||||
Si vous ne souhaitez pas utiliser `helm`, vous pouvez vous rabattre sur les
|
||||
YAML que l'on a utilisé jusqu'à maintenant, et utiliser `kubectl`. Commençons
|
||||
YAML que l'on a utilisés jusqu'à maintenant, et utiliser `kubectl`. Commençons
|
||||
par lancer `influxdb` :
|
||||
|
||||
```bash
|
||||
|
@ -89,7 +89,7 @@ done
|
|||
|
||||
### Exposer les ports
|
||||
|
||||
Pour trois des applications, des ClusterIP font l'affaire, car ils n'ont pas
|
||||
Pour trois des applications, des `ClusterIP` font l'affaire, car ils n'ont pas
|
||||
besoin d'être exposés en dehors du cluster.
|
||||
|
||||
```bash
|
||||
|
@ -98,6 +98,9 @@ kubectl expose deployment rng --port 80
|
|||
kubectl expose deployment hasher --port 80
|
||||
```
|
||||
|
||||
Si vous avez utilisé le *chart* Helm d'InfluxDB, Un `ClusterIP` a été
|
||||
automatiquement créé.
|
||||
|
||||
Par contre, notre Chronograf doit être exposé, on lui alloue donc un NodePort :
|
||||
|
||||
```bash
|
||||
|
@ -115,9 +118,9 @@ la base `chocominer.autogen`, puis la table `hashes` et enfin on sélectionne
|
|||
l'élément `value`. Pour être tout à fait juste, il faut choisir la fonction
|
||||
`sum`, car nous voulons afficher le nombre total de condensat générés. Un
|
||||
second graphique intéressant est celui du nombre de pépites trouvées : il faut
|
||||
compter (`count`), le nombre d'éléments dans la table `chunks`.
|
||||
compter (`count`) le nombre d'éléments dans la table `chunks`.
|
||||
|
||||

|
||||
|
||||
Vous n'avez pas la même courbe de progression ? continuons le TP alors, pour
|
||||
Vous n'avez pas la même courbe de progression ? Continuons le TP alors, pour
|
||||
augmenter la puissance de notre *rig* !
|
||||
|
|
|
@ -25,7 +25,7 @@ effet, il nous faut répartir les services entre plusieurs machines.
|
|||
Une ressource *daemon sets* va s'assurer que tous les nœuds (ou une partie)
|
||||
vont exécuter une instance d'un *pod*. Ainsi, si un nouveau nœud rejoint le
|
||||
cluster, le *pod* sera automatiquement lancé dessus. Inversement, lorsqu'un
|
||||
nœud quitte le cluster, le pod est nettoyé.
|
||||
nœud quitte le cluster, le *pod* est nettoyé.
|
||||
|
||||
On s'en sert principalement pour exécuter une instance de daemon de stockage
|
||||
(tel que Ceph, `glusterd`, ...) ou pour la collecte de logs (`fluentd`,
|
||||
|
@ -90,7 +90,7 @@ documentation](https://kubernetes.io/docs/concepts/workloads/controllers/daemons
|
|||
|
||||
#### *DaemonSet* `rng`
|
||||
|
||||
Pour réaliser le *DaemonSet* de notre pod `rng`, le plus simple est de partir
|
||||
Pour réaliser le *DaemonSet* de notre *pod* `rng`, le plus simple est de partir
|
||||
d'un export de la ressource existante :
|
||||
|
||||
```bash
|
||||
|
@ -123,8 +123,8 @@ kubectl apply -f rng.yml --validate=false
|
|||
|
||||
#### Trop de *pods* `rng` {-}
|
||||
|
||||
Après avoir appliqué la nouvelle spec, on constate qu'il y a beaucoup de *pods*
|
||||
`rng`. En effet, l'ancien *pod* déployé avec la resource *deployment* est
|
||||
Après avoir appliqué la nouvelle spec, on constate qu'il y a beaucoup de *pod*s
|
||||
`rng`. En effet, l'ancien *pod* déployé avec la ressource *deployment* est
|
||||
toujours là.
|
||||
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@ Mise en place
|
|||
=============
|
||||
|
||||
La mise en place d'un cluster Kubernetes ([prononcé
|
||||
Ku-ber-né-tèce](https://github.com/kubernetes/kubernetes/issues/44308) en grec
|
||||
ancien) est une opération qui peut s'avérer très longue et complexe, car elle
|
||||
nécessite l'installation et la configuration de nombreux composants avant de
|
||||
pouvoir être utilisé sereinement.
|
||||
Ku-ber-né-tice](https://github.com/kubernetes/kubernetes/issues/44308) en grec)
|
||||
est une opération qui peut s'avérer très longue et complexe, car elle nécessite
|
||||
l'installation et la configuration de nombreux composants avant de pouvoir être
|
||||
utilisé sereinement.
|
||||
|
||||
Cette opération n'étant pas très palpitante (c'est beaucoup de lecture de
|
||||
documentations et d'heures passées à essayer de faire tomber en marche tous les
|
||||
|
@ -15,9 +15,9 @@ composants d'un seul coup), nous ne la verrons pas aujourd'hui.
|
|||
|
||||
D'ailleurs, dans le milieu professionnel, il est plutôt rare de voir des
|
||||
entreprises investir dans la gestion de leur propre cluster Kubernetes. La
|
||||
plupart des entreprises qui choisissent d'utiliser Kubernetes pour gérer leurs
|
||||
plupart des entreprises qui font le choix d'utiliser Kubernetes pour gérer leurs
|
||||
infrastructures, choisissent de passer par un prestataire. L'entreprise délègue
|
||||
donc la gestion de leur cluster à une autre entreprise, dont c'est la cœur de
|
||||
donc la gestion de son/ses cluster(s) à une autre entreprise, dont c'est le cœur de
|
||||
métier. La plupart du temps, il va s'agir d'Amazon (via [Elastic Kubernetes
|
||||
Service](https://aws.amazon.com/fr/eks/)), d'Azur ([Kubernetes
|
||||
Service](https://azure.microsoft.com/fr-fr/services/kubernetes-service/)) ou
|
||||
|
@ -25,18 +25,54 @@ Google ([Kubernetes Engine](https://cloud.google.com/kubernetes-engine/)), mais
|
|||
d'autres acteurs plus petits existent aussi
|
||||
([OVHcloud](https://www.ovhcloud.com/fr/public-cloud/kubernetes/), ...).
|
||||
|
||||
::::: {.more}
|
||||
|
||||
Pour jouer aujourd'hui, deux solutions s'offrent à nous pour commencer à
|
||||
Pour l'IoT ou l'Edge Computing, sur du matériel léger, il existe le projet
|
||||
k3s[^k3s] : il s'agit d'une distribution Kubernetes beaucoup plus simple à
|
||||
déployer, et parfaitement adaptée à la production sur Raspberry Pi et autres.
|
||||
|
||||
:::::
|
||||
|
||||
[^k3s]: https://k3s.io/
|
||||
|
||||
Pour jouer aujourd'hui, plusieurs solutions s'offrent à nous pour commencer à
|
||||
utiliser Kubernetes facilement :
|
||||
|
||||
- Kubernetes in Docker (kind) : pour tenter l'aventure sur votre machine,
|
||||
- Play With Kubernetes : si vous ne vous en sortez pas avec `kind`.
|
||||
- [Docker Desktop (for Mac ou for Windows) :](#dockerdesktop) si vous êtes sur l'un de ces
|
||||
systèmes c'est la solution la plus simple,
|
||||
- [Kubernetes in Docker (kind) :](#kind) pour tenter l'aventure sur votre machine,
|
||||
- [Play With Kubernetes :](#pwk) si vous ne vous en sortez pas avec `kind`.
|
||||
|
||||
\newpage
|
||||
|
||||
Docker for Mac/Windows {#dockerdesktop}
|
||||
----------------------
|
||||
|
||||
*Docker Desktop* pour Mac ou pour Windows intégre Kubernetes directement. Il
|
||||
n'est pas activé par défaut, pour cela il convient d'activer l'option dans les
|
||||
préférences de l'application :
|
||||
|
||||

|
||||
|
||||
Une fois l'option activée, vous pouvez passer au chapitre suivant, la commande
|
||||
`kubectl` devrait marcher directement pour vous. C'est principalement grâce à
|
||||
cette commande que nous interagirons avec l'API de Kubernetes.
|
||||
|
||||
Une fois que tout sera opérationnel, nous devrions obtenir :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
42sh$ kubectl version
|
||||
Client Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.2", GitCommit:"8b5a19147530eaac9476b0ab82980b4088bbc1b2", GitTreeState:"archive", BuildDate:"2021-11-18T15:50:50Z", GoVersion:"go1.17.2", Compiler:"gc", Platform:"linux/amd64"}
|
||||
Server Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.5+k3s2", GitCommit:"724ef700bab896ff252a75e2be996d5f4ff1b842", GitTreeState:"clean", BuildDate:"2021-10-05T19:59:14Z", GoVersion:"go1.16.8", Compiler:"gc", Platform:"linux/amd64"}
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
Kubernetes in Docker (kind)
|
||||
Kubernetes in Docker (kind) {#kind}
|
||||
---------------------------
|
||||
|
||||
`kind` est un projet permettant de lancer un cluster kubernetes directement via
|
||||
`kind` est un projet permettant de lancer un cluster Kubernetes directement via
|
||||
Docker.
|
||||
|
||||
Pour commencer, il nous faudra télécharger le binaire (go, donc statique)
|
||||
|
@ -44,15 +80,28 @@ suivant (il existe pour Linux, macOS et Windows) :
|
|||
|
||||
<div lang="en-US">
|
||||
```bash
|
||||
curl -Lo kind https://github.com/kubernetes-sigs/kind/releases/download/v0.9.0/kind-$(uname)-amd64
|
||||
curl -Lo kind https://github.com/kubernetes-sigs/kind/releases/download/v0.11.1/kind-$(uname)-amd64
|
||||
chmod +x kind
|
||||
```
|
||||
</div>
|
||||
|
||||
Placez-le dans un endroit où il sera accessible de votre `$PATH`.
|
||||
Placez le binaire dans un endroit où il sera accessible de votre `$PATH`.
|
||||
|
||||
::::: {.question}
|
||||
|
||||
`uname` est à remplacer par votre système d'exploitation : `darwin` (macOS), `linux`, `windows`.
|
||||
|
||||
Il existe également pour d'autres architectures, consultez la [page des
|
||||
versions](https://github.com/kubernetes-sigs/kind/releases/latest) pour voir
|
||||
les différents binaires existants.
|
||||
|
||||
:::::
|
||||
|
||||
|
||||
Notre prochaine étape est de décrire le cluster que l'on souhaite avoir : 1
|
||||
master et 2 workers. Avant de lancer leur création.
|
||||
master et 2 workers, ça fera l'affaire. Attention tout de même de ne pas être
|
||||
trop extravagant, car chaque nœud consomme pas mal de RAM ! Et puis nous
|
||||
pourrons facilement changer cette configuration plus tard.
|
||||
|
||||
<div lang="en-US">
|
||||
```bash
|
||||
|
@ -81,12 +130,12 @@ Profitons-en pour télécharger `kubectl` :
|
|||
|
||||
<div lang="en-US">
|
||||
```bash
|
||||
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.19.4/bin/linux/amd64/kubectl
|
||||
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.22.2/bin/linux/amd64/kubectl
|
||||
chmod +x kubectl
|
||||
```
|
||||
</div>
|
||||
|
||||
C'est via cette commande que nous interagirons principalement avec l'API de
|
||||
C'est principalement grâce à cette commande que nous interagirons avec l'API de
|
||||
Kubernetes.
|
||||
|
||||
Une fois que tout sera opérationnel, nous devrions obtenir :
|
||||
|
@ -94,19 +143,26 @@ Une fois que tout sera opérationnel, nous devrions obtenir :
|
|||
<div lang="en-US">
|
||||
```
|
||||
42sh$ kubectl version
|
||||
Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"archive", BuildDate:"2020-11-18T12:02:06Z", GoVersion:"go1.15.5", Compiler:"gc", Platform:"linux/amd64"}
|
||||
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.1", GitCommit:"206bcadf021e76c27513500ca24182692aabd17e", GitTreeState:"clean", BuildDate:"2020-09-14T07:30:52Z", GoVersion:"go1.15", Compiler:"gc", Platform:"linux/amd64"}
|
||||
Client Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.2", GitCommit:"8b5a19147530eaac9476b0ab82980b4088bbc1b2", GitTreeState:"archive", BuildDate:"2021-11-18T15:50:50Z", GoVersion:"go1.17.2", Compiler:"gc", Platform:"linux/amd64"}
|
||||
Server Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.5+k3s2", GitCommit:"724ef700bab896ff252a75e2be996d5f4ff1b842", GitTreeState:"clean", BuildDate:"2021-10-05T19:59:14Z", GoVersion:"go1.16.8", Compiler:"gc", Platform:"linux/amd64"}
|
||||
```
|
||||
</div>
|
||||
|
||||
Par défaut, `kubectl` va tenter de contacter le port local 2375, `kind` aura
|
||||
pris soin de l'exposer pour vous au moment de la création du cluster.
|
||||
|
||||
Passez ensuite à la section 2 si vous avez réussi à mettre en place `kind`.
|
||||
Passez ensuite au chapitre suivant si vous avez réussi à mettre en place `kind`.
|
||||
|
||||
Play With Kubernetes
|
||||
Play With Kubernetes {#pwk}
|
||||
--------------------
|
||||
|
||||
::::: {.warning}
|
||||
|
||||
Cette section vous concerne uniquement si vous n'avez pas réussi à créer de
|
||||
cluster Kubernetes selon les autres méthodes décrites.
|
||||
|
||||
:::::
|
||||
|
||||
De la même manière que pour les TP utilisant Docker, si vous avez des
|
||||
difficultés pour réaliser les exercices sur vos machines, vous pouvez utiliser
|
||||
le projet [Play With K8s](https://play-with-k8s.com/) qui vous donnera accès à
|
||||
|
@ -126,7 +182,7 @@ kubeadm init --apiserver-advertise-address $(hostname -i)
|
|||
```
|
||||
</div>
|
||||
|
||||
Cette action peut prendre quelques minutes, et devrait se finir, si tout se
|
||||
Cette action peut prendre quelques minutes et devrait se finir, si tout se
|
||||
passe bien, par :
|
||||
|
||||
<div lang="en-US">
|
||||
|
@ -166,15 +222,27 @@ kubectl apply -n kube-system -f \
|
|||
</div>
|
||||
|
||||
|
||||
Minikube, Docker for Mac/Windows, MicroK8s, ...
|
||||
-----------------------------------------------
|
||||
Minikube, k3d, MicroK8s, ...
|
||||
----------------------------
|
||||
|
||||
Si les solutions précédentes ne sont pas adaptées à votre usage, de nombreuses
|
||||
autres applications permettent de mettre en place un cluster plus ou moins
|
||||
complet, facilement.
|
||||
complet facilement.
|
||||
|
||||
Vous pouvez tenter d'utiliser
|
||||
[k3d](https://k3d.io/),
|
||||
[minikube](https://kubernetes.io/docs/setup/learning-environment/minikube/),
|
||||
[microk8s](https://microk8s.io/), ... Notez également que *Docker for Mac* et
|
||||
*Docker for Windows* intègrent aussi Kubernetes depuis quelques versions ;
|
||||
il convient de l'activer dans les préférences de l'application.
|
||||
[microk8s](https://microk8s.io/), ...
|
||||
|
||||
##### `k3d` {-}
|
||||
|
||||
est un script similaire à `kind`, mais utilise `k3s`, une version plus légère
|
||||
et compacte de Kubernetes.
|
||||
|
||||
Après l'avoir installé, vous pouvez lancer
|
||||
|
||||
<div lang="en-US">
|
||||
```bash
|
||||
k3d cluster create mycluster --agents 2 --kubeconfig-switch-context
|
||||
```
|
||||
</div>
|
||||
|
|
|
@ -3,13 +3,13 @@ title: Ελαφριά εικονικοποίηση -- Πρακτική δουλ
|
|||
subtitle: κυβερνήτης
|
||||
author: Πιέρ-Ολιβιέ *νεμυναιρε* [ῥαφοπώλης]{.smallcaps}
|
||||
institute: ΣΠκΠΤ
|
||||
date: Πέμπτη 19 Νοεμβρίου 2021
|
||||
date: Παρασκευή 19 Νοεμβρίου 2021
|
||||
abstract: |
|
||||
Ο στόχος αυτού του τελευταίου εργαστηρίου είναι να κατανοήσει το κυβερνήτης και την ενορχήστρωση εμπορευματοκιβωτίων.
|
||||
|
||||
\vspace{1em}
|
||||
|
||||
Οι ασκήσεις για αυτό το πρακτικό έργο μπορούν να επιστραφούν στη διεύθυνση <ανδροππήςρε@nemunai.re> το αργότερο την Πέμπτη 26 Νοεμβρίου 2021 στις 11:42 μ.μ., οι ερωτήσεις των μαθημάτων πρέπει επίσης να ολοκληρωθούν πριν από αυτήν την ημερομηνία. Δείτε το τελευταίο μέρος αυτού του εργαστηρίου για λεπτομέρειες.
|
||||
Οι ασκήσεις για αυτό το πρακτικό έργο μπορούν να επιστραφούν στη διεύθυνση <ανδροππήςρε@nemunai.re> το αργότερο την Παρασκευή 3 Δεκεμβρίουz 2021 στις 11:42 μ.μ., οι ερωτήσεις των μαθημάτων πρέπει επίσης να ολοκληρωθούν πριν από αυτήν την ημερομηνία. Δείτε το τελευταίο μέρος αυτού του εργαστηρίου για λεπτομέρειες.
|
||||
|
||||
Καθώς οι άνθρωποι γνωρίζουν την ασφάλεια των ηλεκτρονικών ανταλλαγών, πρέπει να μου στείλετε τις υπογεγραμμένες αποδόσεις σας με το κλειδί PGP. Θυμηθείτε να [με](https://keys.openpgp.org/search?q=nemunaire%40nemunai.re) υπογράψετε το κλειδί σας και μην διστάσετε [να υπογράψετε το δικό σας](https://www.meetup.com/fr/Paris-certification-de-cles-PGP-et-CAcert/).
|
||||
...
|
||||
|
|
|
@ -3,7 +3,7 @@ title: Virtualisation légère -- TP n^o^ 6
|
|||
subtitle: Kubernetes
|
||||
author: Pierre-Olivier *nemunaire* [Mercier]{.smallcaps}
|
||||
institute: EPITA
|
||||
date: Jeudi 19 novembre 2021
|
||||
date: Vendredi 19 novembre 2021
|
||||
abstract: |
|
||||
Le but de ce dernier TP est d'appréhender Kubernetes et l'orchestration de
|
||||
conteneurs.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue