diff --git a/.drone.yml b/.drone.yml index bd21c89..eda301c 100644 --- a/.drone.yml +++ b/.drone.yml @@ -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 diff --git a/tutorial/3/capabilities.md b/tutorial/3/capabilities.md index 1f30227..bad7084 100644 --- a/tutorial/3/capabilities.md +++ b/tutorial/3/capabilities.md @@ -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 diff --git a/tutorial/5/Makefile b/tutorial/5/Makefile index 55a995b..5b54858 100644 --- a/tutorial/5/Makefile +++ b/tutorial/5/Makefile @@ -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 diff --git a/tutorial/5/tutorial.md b/tutorial/5/tutorial.md index d50ed6f..5ed84df 100644 --- a/tutorial/5/tutorial.md +++ b/tutorial/5/tutorial.md @@ -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 à - au plus tard le **mercredi 4 novembre 2020 à 12 h + 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 à diff --git a/tutorial/devops/ci-gistre.md b/tutorial/devops/ci-gistre.md new file mode 100644 index 0000000..c762d68 --- /dev/null +++ b/tutorial/devops/ci-gistre.md @@ -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 ! +::::: + +![Drone en action](../devops/drone-run-linky.png){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 : + + - + - + +Attention à ne pas stocker votre clef d'API dans le fichier YAML ! + +![Binaire publié automatiquement sur Gitea](../devops/tag-released.png){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 : +. + +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 diff --git a/tutorial/devops/ci.md b/tutorial/devops/ci.md index c912706..60ecf42 100644 --- a/tutorial/devops/ci.md +++ b/tutorial/devops/ci.md @@ -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. +![Drone en action](../devops/drone-run.png){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 ! - -![Drone en action](../devops/drone-run.png){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 !) :
```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 ! ![Binaire publié automatiquement sur Gitea](../devops/tag-released.png){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 : -. - -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`. +::::: diff --git a/tutorial/devops/devops.md b/tutorial/devops/devops.md index a5cccd8..e61e27b 100644 --- a/tutorial/devops/devops.md +++ b/tutorial/devops/devops.md @@ -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 !). diff --git a/tutorial/devops/drone-run-linky.png b/tutorial/devops/drone-run-linky.png new file mode 100644 index 0000000..8a5b745 Binary files /dev/null and b/tutorial/devops/drone-run-linky.png differ diff --git a/tutorial/devops/electropcool.jpg b/tutorial/devops/electropcool.jpg new file mode 100644 index 0000000..f2bbb0d Binary files /dev/null and b/tutorial/devops/electropcool.jpg differ diff --git a/tutorial/devops/electropcool.png b/tutorial/devops/electropcool.png new file mode 100644 index 0000000..be6c3ee Binary files /dev/null and b/tutorial/devops/electropcool.png differ diff --git a/tutorial/devops/publish-docker.md b/tutorial/devops/publish-docker.md index 2c4acfe..c825ae4 100644 --- a/tutorial/devops/publish-docker.md +++ b/tutorial/devops/publish-docker.md @@ -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 ```
-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 :
```bash @@ -67,12 +70,14 @@ docker run --rm -p 8080:8080 localhost:5000/youp0m ```
+::::: {.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`. diff --git a/tutorial/devops/run-gistre.md b/tutorial/devops/run-gistre.md new file mode 100644 index 0000000..016612c --- /dev/null +++ b/tutorial/devops/run-gistre.md @@ -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 : + +
+```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 +``` +
+ +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. + +
+``` +login_x-TP5/docker/run.sh +``` +
+ + +### 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 + +
+```shell +42sh# lxc-create --template linky2influx --name l2i && lxc-start -n l2i`. +``` +
+ +
+``` +login_x-TP5/lxc/run.sh +``` +
+ +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 : + +
+``` +login_x-TP5/linky2influx/lxc-scripts/template.sh +login_x-TP5/linky2influx/lxc-scripts/sample.config +``` +
+ + +### 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 : + +
+``` +login_x-TP5/linky2influx/systemd/linky2influx.nspawn +``` +
+ + +### 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` : + +
+``` +login_x-TP5/meta-electropcool/recipes-support/linky2influx/linky2influx_9999.bb +``` +
+ + +### Nix + +L'expression Nix correspondant au paquet pourra être intégré au dépôt + +
+``` +login_x-TP5/linky2influx/linky2influx.nix +``` +
+ +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 : + +
+``` +login_x-TP5/linky2influx/snapcraft.yaml +``` +
+ +Il faudra également préciser avec un fichier `run.sh` la manière dont lancer +votre conteneur : + +
+``` +login_x-TP5/{snap,flatpack}/run.sh +``` +
+ + + +### k3s + +Nous en apprendrons davantage sur Kubernetes au prochain TP, mais si vous +connaissez déjà, vous pourriez vouloir écrire un *Chart* Helm : + +
+``` +login_x-TP5/k3s/linky2influx.yaml +``` +
+ +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. + +
+``` +login_x-TP5/k3s/linky2influx.yaml +``` +
+\ + +À vous de jouer ! diff --git a/tutorial/devops/tools-drone-ansible.md b/tutorial/devops/tools-drone-ansible.md new file mode 100644 index 0000000..a34e1d4 --- /dev/null +++ b/tutorial/devops/tools-drone-ansible.md @@ -0,0 +1,32 @@ +Voici à quoi pourrait ressembler le playbook Ansible démarrant notre conteneur +Drone : + +
+```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" +``` +
+ +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. diff --git a/tutorial/devops/tools-drone-cmd.md b/tutorial/devops/tools-drone-cmd.md new file mode 100644 index 0000000..26d6188 --- /dev/null +++ b/tutorial/devops/tools-drone-cmd.md @@ -0,0 +1,26 @@ +Voici à quoi pourrait ressembler la ligne de commande démarrant notre conteneur +Drone : + +
+```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 +``` +
+ +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. diff --git a/tutorial/devops/tools-drone-oauth.md b/tutorial/devops/tools-drone-oauth.md new file mode 100644 index 0000000..ad4f366 --- /dev/null +++ b/tutorial/devops/tools-drone-oauth.md @@ -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 : + +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. + +![OAuth Drone](../devops/oauth-drone.png){width=9cm} diff --git a/tutorial/devops/tools-drone-runner-ansible.md b/tutorial/devops/tools-drone-runner-ansible.md new file mode 100644 index 0000000..647b1c1 --- /dev/null +++ b/tutorial/devops/tools-drone-runner-ansible.md @@ -0,0 +1,25 @@ +Voici à quoi pourrait ressembler le playbook Ansible démarrant notre agent Drone : + +
+```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" +``` +
diff --git a/tutorial/devops/tools-drone-runner-cmd.md b/tutorial/devops/tools-drone-runner-cmd.md new file mode 100644 index 0000000..fff43aa --- /dev/null +++ b/tutorial/devops/tools-drone-runner-cmd.md @@ -0,0 +1,11 @@ +Voici à quoi pourrait ressembler la ligne de commande démarrant notre agent Drone : + +
+```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 +``` +
diff --git a/tutorial/devops/tools-drone-runner.md b/tutorial/devops/tools-drone-runner.md new file mode 100644 index 0000000..b4d8427 --- /dev/null +++ b/tutorial/devops/tools-drone-runner.md @@ -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 !) diff --git a/tutorial/devops/tools-drone.md b/tutorial/devops/tools-drone.md new file mode 100644 index 0000000..b3d8731 --- /dev/null +++ b/tutorial/devops/tools-drone.md @@ -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`. diff --git a/tutorial/devops/tools-end.md b/tutorial/devops/tools-end.md new file mode 100644 index 0000000..6c4e617 --- /dev/null +++ b/tutorial/devops/tools-end.md @@ -0,0 +1 @@ +L'environnement étant prêt, il ne reste plus qu'à nous lancer dans nos projets ! diff --git a/tutorial/devops/tools-gitea-ansible.md b/tutorial/devops/tools-gitea-ansible.md new file mode 100644 index 0000000..a72b6db --- /dev/null +++ b/tutorial/devops/tools-gitea-ansible.md @@ -0,0 +1,29 @@ +Votre playbook ressemblera à quelque chose comme ça : + +
+```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 }}" +``` +
diff --git a/tutorial/devops/tools-gitea-cmd.md b/tutorial/devops/tools-gitea-cmd.md new file mode 100644 index 0000000..d522ecc --- /dev/null +++ b/tutorial/devops/tools-gitea-cmd.md @@ -0,0 +1,13 @@ +La ligne de commande pour lancer Gitea ressemblera à quelque chose comme ça : + +
+```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 +``` +
diff --git a/tutorial/devops/tools-gitea-end.md b/tutorial/devops/tools-gitea-end.md new file mode 100644 index 0000000..145979b --- /dev/null +++ b/tutorial/devops/tools-gitea-end.md @@ -0,0 +1,15 @@ +Plus d'infos sur cette page : . + +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 : + +
+```bash +docker exec gitea gitea admin user create --username "${USER}" --random-password \ + --must-change-password=false --admin --email "${USER}@epita.fr" +``` +
+ +Notez le mot de passe généré pour [vous y connecter](http://localhost:3000/user/login). diff --git a/tutorial/devops/tools-gitea.md b/tutorial/devops/tools-gitea.md new file mode 100644 index 0000000..0875f82 --- /dev/null +++ b/tutorial/devops/tools-gitea.md @@ -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)). diff --git a/tutorial/devops/tools.md b/tutorial/devops/tools.md index 1ce654b..16dd787 100644 --- a/tutorial/devops/tools.md +++ b/tutorial/devops/tools.md @@ -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 : - -
-```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 }}" -``` -
- -Plus d'infos sur cette page : . - -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 : - -
-```bash -docker exec gitea gitea admin user create --username "${USER}" --random-password \ - --must-change-password=false --admin --email "${USER}@epita.fr" -``` -
- -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 : - -
-```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" -``` -
- -Une fois lancé, rendez-vous sur l'interface de 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. - -![OAuth Drone](../devops/oauth-drone.png){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 : - -
-```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" -``` -
- - -L'environnement étant prêt, il ne reste plus qu'à nous lancer dans nos projets ! diff --git a/tutorial/devops/what-gistre-see-srs.md b/tutorial/devops/what-gistre-see-srs.md new file mode 100644 index 0000000..f729d28 --- /dev/null +++ b/tutorial/devops/what-gistre-see-srs.md @@ -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. diff --git a/tutorial/devops/what-gistre.md b/tutorial/devops/what-gistre.md new file mode 100644 index 0000000..2969908 --- /dev/null +++ b/tutorial/devops/what-gistre.md @@ -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 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. + +![La prod chez Électropcool](../devops/electropcool.jpg) + +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 : + +
+```shell +docker network create gitea +docker network create drone +``` +
+ + +É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`) : + +
+```conf +127.0.0.1 gitea droneci +``` +
+ +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. diff --git a/tutorial/devops/what.md b/tutorial/devops/what.md index 03124ce..550bc66 100644 --- a/tutorial/devops/what.md +++ b/tutorial/devops/what.md @@ -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`) :
```conf diff --git a/tutorial/docker-internals/Makefile b/tutorial/docker-internals/Makefile index 7671d56..bfd45d2 100644 --- a/tutorial/docker-internals/Makefile +++ b/tutorial/docker-internals/Makefile @@ -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 diff --git a/tutorial/docker-internals/linuxkit-content.md b/tutorial/docker-internals/linuxkit-content.md index 01451a2..581f124 100644 --- a/tutorial/docker-internals/linuxkit-content.md +++ b/tutorial/docker-internals/linuxkit-content.md @@ -41,19 +41,19 @@ L'image la plus simple que l'on puisse réaliser pourrait être :
```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 :
```yaml - name: getty - image: linuxkit/getty:2eb742cd7a68e14cf50577c02f30147bc406e478 + image: linuxkit/getty:3c6e89681a988c3d4e2610fcd7aaaa0247ded3ec net: new ```
@@ -101,7 +101,7 @@ Ou inversement, pour persister dans le namespace initial :
```yaml - name: getty - image: linuxkit/getty:2eb742cd7a68e14cf50577c02f30147bc406e478 + image: linuxkit/getty:3c6e89681a988c3d4e2610fcd7aaaa0247ded3ec pid: host ```
@@ -118,7 +118,7 @@ On commence donc d'abord par créer le nouveau *namespace*, en prenant soin de
```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` :
```yaml - name: xxxx - image: linuxkit/xxxx:v0.6 + image: linuxkit/xxxx:v0.8 net: /run/netns/mynewnetns ```
diff --git a/tutorial/docker-internals/registry.md b/tutorial/docker-internals/registry.md index 2465864..f2c74e9 100644 --- a/tutorial/docker-internals/registry.md +++ b/tutorial/docker-internals/registry.md @@ -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`). diff --git a/tutorial/docker-internals/rendu.md b/tutorial/docker-internals/rendu.md index 408397a..b598cb2 100644 --- a/tutorial/docker-internals/rendu.md +++ b/tutorial/docker-internals/rendu.md @@ -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 , c'est donc à cette adresse +Ce service écoute sur l'adresse . 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 ------- diff --git a/tutorial/docker-internals/tutorial.md b/tutorial/docker-internals/tutorial.md index af0d112..47e31b3 100644 --- a/tutorial/docker-internals/tutorial.md +++ b/tutorial/docker-internals/tutorial.md @@ -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 à - 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, à 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 à diff --git a/tutorial/k8s/discover.md b/tutorial/k8s/discover.md index c226988..d78aedd 100644 --- a/tutorial/k8s/discover.md +++ b/tutorial/k8s/discover.md @@ -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 : + +
```bash -kubectl describe type/name kubectl describe type name kubectl explain type ``` +
+ +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 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

You are using an outdated 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 : diff --git a/tutorial/k8s/docker-desktop-k8s.png b/tutorial/k8s/docker-desktop-k8s.png new file mode 100644 index 0000000..b3e08b4 Binary files /dev/null and b/tutorial/k8s/docker-desktop-k8s.png differ diff --git a/tutorial/k8s/intro.md b/tutorial/k8s/intro.md index 3c792bd..dc55b24 100644 --- a/tutorial/k8s/intro.md +++ b/tutorial/k8s/intro.md @@ -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 ! - + + +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. ![ChocoMiner](dockercoins-diagram.svg) @@ -34,7 +36,7 @@ Obtenir l'application

```shell -git clone https://gitea.nemunai.re/srs/chocominer.git +git clone https://git.nemunai.re/srs/chocominer.git ```
@@ -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 diff --git a/tutorial/k8s/overview.md b/tutorial/k8s/overview.md index 9aaa23a..51cfc45 100644 --- a/tutorial/k8s/overview.md +++ b/tutorial/k8s/overview.md @@ -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 diff --git a/tutorial/k8s/rendu.md b/tutorial/k8s/rendu.md index e7fe6de..7df82b1 100644 --- a/tutorial/k8s/rendu.md +++ b/tutorial/k8s/rendu.md @@ -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. diff --git a/tutorial/k8s/run.md b/tutorial/k8s/run.md index 875cf07..b66f01d 100644 --- a/tutorial/k8s/run.md +++ b/tutorial/k8s/run.md @@ -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`. ![Montée en charge progressive dans Chronograph](nuggets-graph.png) -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* ! diff --git a/tutorial/k8s/scaling.md b/tutorial/k8s/scaling.md index 82c4d12..a284aeb 100644 --- a/tutorial/k8s/scaling.md +++ b/tutorial/k8s/scaling.md @@ -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à. diff --git a/tutorial/k8s/setup.md b/tutorial/k8s/setup.md index 397e87f..628fc24 100644 --- a/tutorial/k8s/setup.md +++ b/tutorial/k8s/setup.md @@ -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 : + +![Paramètres de Docker Desktop](docker-desktop-k8s.png) + +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 : + +
+``` +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"} +``` +
-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) :
```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 ```
-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.
```bash @@ -81,12 +130,12 @@ Profitons-en pour télécharger `kubectl` :
```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 ```
-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 :
``` 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"} ```
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) ```
-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 :
@@ -166,15 +222,27 @@ kubectl apply -n kube-system -f \
-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 + +
+```bash +k3d cluster create mycluster --agents 2 --kubeconfig-switch-context +``` +
diff --git a/tutorial/k8s/tutorial-el.md b/tutorial/k8s/tutorial-el.md index b2792e3..881188f 100644 --- a/tutorial/k8s/tutorial-el.md +++ b/tutorial/k8s/tutorial-el.md @@ -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/). ... diff --git a/tutorial/k8s/tutorial.md b/tutorial/k8s/tutorial.md index b9d0550..68eda0c 100644 --- a/tutorial/k8s/tutorial.md +++ b/tutorial/k8s/tutorial.md @@ -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.