Docker 04 -- Conteneurs.docx

Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...

Full Transcript

Conteneurs Maintenant que nous en savons un peu plus sur les images, il est temps d\'entrer dans les conteneurs. Comme il s\'agit d\'un livre sur Docker, nous parlerons spécifiquement des conteneurs Docker. Cependant, Docker implémente les spécifications d\'image et de conteneur publiées par l\'Ope...

Conteneurs Maintenant que nous en savons un peu plus sur les images, il est temps d\'entrer dans les conteneurs. Comme il s\'agit d\'un livre sur Docker, nous parlerons spécifiquement des conteneurs Docker. Cependant, Docker implémente les spécifications d\'image et de conteneur publiées par l\'Open Container Initiative (OCI) sur https://www.opencontainers.org. Cela signifie qu\'une grande partie de ce que vous apprenez ici s\'appliquera à d\'autres environnements d\'exécution de conteneurs conformes à l\'OCI. De plus, les choses que vous apprendrez vous aideront si vous avez besoin d\'apprendre et d\'utiliser Kubernetes. Nous diviserons ce chapitre en trois parties habituelles : Le TLDR La plongée profonde Les commandes Conteneurs Docker - Le TLDR Un conteneur est l\'instance d\'exécution d\'une image. De la même manière que vous pouvez démarrer une machine virtuelle (VM) à partir d\'un modèle de machine virtuelle, vous démarrez un ou plusieurs conteneurs à partir d\'une seule image. La grande différence entre une machine virtuelle et un conteneur est que les conteneurs sont plus rapides et plus légers. Au lieu d\'exécuter un système d\'exploitation complet comme une machine virtuelle, les conteneurs partagent le système d\'exploitation/noyau avec l\'hôte sur lequel ils s\'exécutent. Il est également courant que les conteneurs soient basés sur des images minimalistes qui n\'incluent que les logiciels et les dépendances requis par l\'application. La figure 7.1 montre une seule image Docker utilisée pour démarrer plusieurs conteneurs Docker. Figure 7.1 La façon la plus simple de démarrer un conteneur est avec la docker container runcommande. La commande peut prendre beaucoup d\'arguments, mais dans sa forme la plus basique, vous lui indiquez une image à utiliser et une application à exécuter : docker container run \ \. La commande suivante démarrera un conteneur Ubuntu Linux exécutant le shell Bash en tant qu\'application. \>\> docker container run -it ubuntu /bin/bash Vous pouvez utiliser la commande suivante pour démarrer un conteneur Windows exécutant l\'application PowerShell. \> docker container run -it mcr.microsoft.com/powershell:nanoserver pwsh.exe Dans chacun des exemples, les -itdrapeaux connecteront votre fenêtre de terminal actuelle au shell du conteneur. Les conteneurs s\'exécutent jusqu\'à ce que l\'application qu\'ils exécutent se ferme. Dans les exemples précédents, le conteneur Linux se fermera à la fermeture du shell Bash et le conteneur Windows se fermera à la fin du processus PowerShell. Un moyen simple de le démontrer consiste à démarrer un nouveau conteneur et à lui dire d\'exécuter la commande sleep pendant 10 secondes. Le conteneur va démarrer, s\'emparer de votre terminal pendant 10 secondes, puis sortir. Voici un moyen simple de le démontrer sur un hôte Linux Docker. \>\> docker container run -it alpine:latest sleep 10 Vous pouvez faire la même chose avec un conteneur Windows avec la commande suivante. \> conteneur docker exécuter microsoft/powershell:nanoserver pwsh -c \"Start-Sleep -s 10\" Vous pouvez arrêter manuellement un conteneur en cours d\'exécution avec la docker container stopcommande. Vous pouvez ensuite le redémarrer avec docker container start. Pour vous débarrasser définitivement d\'un conteneur, vous devez le supprimer explicitement avec docker container rm. C\'est le pitch d\'ascenseur ! Entrons maintenant dans le détail... Conteneurs Docker - La plongée profonde Les premières choses que nous aborderons ici sont les différences fondamentales entre un conteneur et une machine virtuelle. C\'est principalement de la théorie à ce stade, mais c\'est quelque chose d\'important. Attention : en tant qu\'auteur, je vais dire ceci avant d\'aller plus loin. Beaucoup d\'entre nous sont passionnés par les choses que nous faisons et les compétences que nous avons. Vous vous souvenez des grands noms d\'Unix qui ont résisté à la montée de Linux. Vous vous souvenez peut-être aussi des personnes qui ont résisté à VMware au début. Dans les deux cas, la résistance était vaine. Dans cette section, je vais mettre en évidence ce que je considère comme certains des avantages du modèle de conteneur par rapport au modèle de machine virtuelle. Mais je suppose que beaucoup d\'entre vous seront des experts en VM avec beaucoup investi dans l\'écosystème VM. Je suppose aussi qu\'un ou deux d\'entre vous voudront peut-être me battre pour certaines des choses que je dis. Alors laissez-moi être clair... Je suis un grand gars et je vous battrais au corps à corps :-D Je plaisante. Cependant, je n\'essaie pas de détruire votre empire ou de traiter votre bébé de laid. Les conteneurs et les machines virtuelles fonctionneront côte à côte pendant de nombreuses années. Nous y voilà. Conteneurs vs VM Les conteneurs et les machines virtuelles ont tous deux besoin d\'un hôte pour s\'exécuter. Cela peut aller de votre ordinateur portable, d\'un serveur bare metal dans votre centre de données, jusqu\'à une instance dans le cloud public. En fait, de nombreux services cloud offrent désormais la possibilité d\'exécuter des conteneurs sur des back-ends sans serveur éphémères. Ne vous inquiétez pas si cela ressemble à de la techno-babillage, cela signifie simplement que le back-end est tellement virtualisé que le concept d\'hôte ou de nœud n\'a plus de sens --- votre conteneur s\'exécute simplement, et vous n\'avez pas besoin de se soucier du comment ou du où. Quoi qu\'il en soit... supposons une exigence où votre entreprise dispose d\'un seul serveur physique qui doit exécuter 4 applications métier. Dans le modèle VM, le serveur physique est sous tension et l\'hyperviseur démarre (nous sautons le BIOS et le code du chargeur de démarrage, etc.). Une fois démarré, l\'hyperviseur revendique toutes les ressources physiques du système telles que le processeur, la RAM, le stockage et les cartes réseau. Il sculpte ensuite ces ressources matérielles dans des versions virtuelles qui ressemblent exactement à la réalité. Il les regroupe ensuite dans une construction logicielle appelée machine virtuelle (VM). Nous prenons ces machines virtuelles et installons un système d\'exploitation et une application sur chacune d\'elles. En supposant le scénario d\'un seul serveur physique devant exécuter 4 applications métier, nous créerions 4 machines virtuelles, installerions 4 systèmes d\'exploitation, puis installerions les 4 applications. Quand tout est fait, cela ressemble un peu à la figure 7.2. ![Une image contenant texte Description générée automatiquement](media/image2.png) Figure 7.2 Les choses sont un peu différentes dans le modèle de conteneur. Le serveur est sous tension et le système d\'exploitation démarre. Dans le monde Docker, cela peut être Linux ou une version moderne de Windows qui prend en charge les primitives de conteneur dans son noyau. Semblable au modèle VM, le système d\'exploitation réclame toutes les ressources matérielles. En plus du système d\'exploitation, nous installons un moteur de conteneur tel que Docker. Le moteur de conteneur prend ensuite les ressources du système d\'exploitation, telles que l\' arborescence des processus , le système de fichiers et la pile réseau , et les découpe dans des constructions isolées appelées conteneurs. Chaque conteneur ressemble à un véritable système d\'exploitation. À l\'intérieur de chaque conteneur, nous exécutons une application. Si nous supposons le même scénario d\'un seul serveur physique devant exécuter 4 applications métier, nous diviserions le système d\'exploitation en 4 conteneurs et exécuterions une seule application à l\'intérieur de chacun. Ceci est illustré à la figure 7.3. Illustration 7.3 À un niveau élevé, les hyperviseurs effectuent la virtualisation matérielle : ils divisent les ressources matérielles physiques en versions virtuelles appelées VM. D\'autre part, les conteneurs effectuent la virtualisation du système d\'exploitation - ils découpent les ressources du système d\'exploitation dans des versions virtuelles appelées conteneurs. La taxe VM Construisons sur ce que nous venons de couvrir et approfondissons l\'un des problèmes avec le modèle d\'hyperviseur. Nous avons commencé avec un seul serveur physique et la nécessité d\'exécuter 4 applications métier. Dans les deux modèles, nous avons installé soit un système d\'exploitation, soit un hyperviseur (un système d\'exploitation spécialisé hautement adapté aux machines virtuelles). Jusqu\'à présent, les modèles sont presque identiques. Mais c\'est là que s\'arrêtent les similitudes. Le modèle de machine virtuelle découpe les ressources matérielles de bas niveau dans les machines virtuelles. Chaque machine virtuelle est une construction logicielle contenant des processeurs virtuels, de la RAM virtuelle, des disques virtuels, etc. En tant que tel, chaque machine virtuelle a besoin de son propre système d\'exploitation pour réclamer, initialiser et gérer toutes ces ressources virtuelles. Et malheureusement, chaque système d\'exploitation est livré avec son propre ensemble de bagages et de frais généraux. Par exemple, chaque système d\'exploitation consomme une tranche de CPU, une tranche de RAM, une tranche de stockage, etc. Certains ont besoin de leurs propres licences, ainsi que de personnes et d\'infrastructures pour les corriger et les mettre à niveau. Chaque système d\'exploitation présente également une surface d\'attaque importante. Nous appelons souvent tout cela la taxe sur le système d\'exploitation ou la taxe sur les VM --- chaque système d\'exploitation que vous installez consomme des ressources ! Le modèle de conteneur a un seul système d\'exploitation/noyau exécuté sur l\'hôte. Il est possible d\'exécuter des dizaines ou des centaines de conteneurs sur un seul hôte, chaque conteneur partageant ce seul système d\'exploitation/noyau. Cela signifie un seul système d\'exploitation consommant du CPU, de la RAM et du stockage. Un seul système d\'exploitation nécessitant une licence. Un seul système d\'exploitation qui doit être mis à jour et corrigé. Et un seul noyau d\'OS présentant une surface d\'attaque. Au total, une seule facture de taxes OS ! Cela peut sembler peu dans notre exemple d\'un seul serveur exécutant 4 applications métier. Mais lorsque vous commencez à parler de centaines ou de milliers d\'applications, cela change la donne. Une autre chose à considérer est les heures de début des applications. Comme un conteneur n\'est pas un système d\'exploitation à part entière, il démarre beaucoup plus rapidement qu\'une machine virtuelle. N\'oubliez pas qu\'il n\'y a pas de noyau à l\'intérieur d\'un conteneur qui doit être localisé, décompressé et initialisé - sans parler de tout le matériel énumérant et initialisant associé à un démarrage normal du noyau. Rien de tout cela n\'est nécessaire lors du démarrage d\'un conteneur. Le noyau partagé unique, exécuté sur la machine hôte, est déjà démarré. Résultat net, les conteneurs peuvent démarrer en moins d\'une seconde. La seule chose qui a un impact sur l\'heure de démarrage du conteneur est le temps qu\'il faut pour démarrer l\'application qu\'il exécute. Tout cela revient à dire que le modèle de conteneur est plus léger et plus efficace que le modèle VM. Vous pouvez regrouper plus d\'applications sur moins de ressources, les démarrer plus rapidement et payer moins en frais de licence et d\'administration, tout en présentant moins de surface d\'attaque pour le côté obscur. Qu\'est-ce qu\'il ne faut pas aimer !? Eh bien, une chose qui n\'est pas si géniale avec le modèle de conteneur est la sécurité. Par défaut, les conteneurs sont moins sécurisés et isolent moins la charge de travail que les machines virtuelles. Des technologies existent pour sécuriser les conteneurs et les verrouiller, mais au moment de la rédaction, certaines d\'entre elles sont d\'une complexité prohibitive. Avec la théorie à l\'écart, jouons avec quelques conteneurs. Conteneurs en cours d\'exécution Pour suivre ces exemples, vous aurez besoin d\'un hôte Docker fonctionnel. Si vous ne l\'avez pas déjà, je vous recommande d\'installer Docker Desktop sur votre Mac ou votre PC (il suffit de rechercher sur Google \"Docker Desktop\" et de suivre la procédure d\'installation suivante, suivante, suivante). Nous allons montrer des exemples pour les conteneurs Linux et Windows. Toutefois, si vous exécutez Docker Desktop sur Windows 10, vous pouvez suivre les exemples Linux en exécutant Docker Desktop en Linux containersmode. Vérifier que Docker est en cours d\'exécution La première chose que je fais toujours lorsque je me connecte à un hôte Docker est de vérifier que Docker est en cours d\'exécution. \>\> docker version Client : Docker Engine - Communauté Version : 19.03.8 Version API : 1.40 Système d\'exploitation/Arch : darwin/amd64 Expérimental : vrai Serveur : Docker Engine - Communauté Moteur: Version : 19.03.8 Version API : 1.40 (version minimale 1.12) Système d\'exploitation/Arch : linux/amd64 Expérimental : vrai \ Tant que vous obtenez une réponse dans le Clientet Servervous devriez être prêt à partir. Si vous obtenez un code d\'erreur dans la Serversection, il y a de fortes chances que le démon Docker (serveur) ne soit pas en cours d\'exécution ou que votre compte d\'utilisateur n\'ait pas l\'autorisation d\'y accéder. Si vous êtes sur une machine Linux et que votre compte utilisateur n\'est pas autorisé à accéder au démon, vous devez vous assurer qu\'il est membre du dockergroupe Unix local. Si ce n\'est pas le cas, vous pouvez l\'ajouter avec usermod -aG docker \, puis vous devrez vous déconnecter et vous reconnecter à votre shell pour que les modifications prennent effet. Si votre compte d\'utilisateur est déjà membre du dockergroupe local, le problème peut être que le démon Docker n\'est pas en cours d\'exécution. Pour vérifier l\'état du démon Docker, exécutez l\'une des commandes suivantes en fonction du système d\'exploitation de votre hôte Docker. Les systèmes Linux n\'utilisant pas Systemd. \>\> service docker status docker start/running, processus 29393 Systèmes Linux utilisant Systemd. \>\> systemctl is-active docker actif Systèmes Windows (exécutés à partir d\'un terminal PowerShell). \> Docker Get-Service Nom d\'état DisplayName \-\-\-\-\-- \-\-\-- \-\-\-\-\-\-\-\-\-\-- Exécution du moteur Docker Docker Si le démon Docker est en cours d\'exécution, vous pouvez continuer. Démarrage d\'un conteneur simple Si vous utilisez Docker Desktop, vous pouvez suivre les exemples Linux ou Windows. Assurez-vous simplement que Docker Desktop est défini sur le bon mode. La façon la plus simple de démarrer un conteneur est avec la docker container runcommande. La commande suivante démarre un conteneur simple qui exécutera une version conteneurisée d\'Ubuntu Linux. \>\> docker container run -it ubuntu:latest /bin/bash Impossible de trouver l\'image \'ubuntu:latest\' localement dernier : Extraire de la bibliothèque/ubuntu d51af753c3d3 : Tirer complet fc878cd0a91c : Tirage complet 6154df8ff988 : Tirez complet fee5db0ff82f : Extraction terminée Résumé : sha256:747d2dbbaaee995098c9792d99bd333c6783ce56150d1b11e333bbceed5c54d7 Statut : image plus récente téléchargée pour ubuntu:latest root\@50949b614477:/\# Voici un exemple Windows qui démarre un conteneur exécutant PowerShell (pwsh.exe). \> conteneur docker run -it mcr.microsoft.com/powershell:nanoserver pwsh.exe conteneur docker run -it mcr.microsoft.com/powershell:nanoserver pwsh.exe Impossible de trouver l\'image \'mcr.microsoft.com/powershell:nanoserver\' localement nanoserver : Extraire de PowerShell 0fe89239909b : Tirez complet 2c9371eb1f40 : Tirer complet \ 806da439b031 : Tirer complet Résumé : sha256:cefdb984d9\...ad3ab2079a Statut : image plus récente téléchargée pour mcr.microsoft.com/powershell:nanoserver PowerShell 7.0.0 Copyright (c) Microsoft Corporation. Tous les droits sont réservés. PS C :\\\> Regardons de plus près la commande. docker container runindique à Docker d\'exécuter un nouveau conteneur. Les -itdrapeaux rendent le conteneur interactif et l\'attachent à votre terminal. ubuntu:latestou mcr.microsoft.com/powershell:nanoserverindiquez à Docker à partir de quelle image démarrer le conteneur. Enfin, /bin/bashet pwsh.exesont les applications respectives que chaque conteneur exécutera. Lorsque vous appuyez sur Return, le client Docker a empaqueté la commande et l\'a postée sur le serveur d\'API exécuté sur le démon Docker. Le démon Docker a accepté la commande et a recherché le référentiel d\'images local de l\'hôte Docker pour voir s\'il avait déjà une copie de l\'image demandée. Dans les exemples cités, ce n\'est pas le cas, il est donc allé à Docker Hub pour voir s\'il pouvait le trouver là-bas. Il l\'a trouvé, extrait localement et stocké dans son cache local. Remarque : dans une installation Linux standard prête à l\'emploi, le démon Docker implémente l\'API Docker Remote sur un socket IPC/Unix local sur /var/run/docker.sock. Sous Windows, il écoute sur un canal nommé à npipe:////./pipe/docker\_engine. Il est possible de configurer le démon Docker pour écouter sur le réseau. Le port réseau non-TLS par défaut pour Docker est 2375, le port TLS par défaut est 2376. Une fois l\'image extraite, le démon a demandé à containerdand runcde créer et de démarrer le conteneur. Si vous suivez, votre terminal est maintenant attaché au conteneur - regardez attentivement et vous verrez que votre invite de shell a changé. Dans l\'exemple Linux cité, l\'invite du shell est devenue root\@50949b614477:/\#. Le nombre long après \@correspond aux 12 premiers caractères de l\'ID unique du conteneur. Dans l\'exemple Windows, il a été remplacé par PS C:\\\>. Essayez d\'exécuter certaines commandes de base à l\'intérieur du conteneur. Vous remarquerez peut-être que certains d\'entre eux ne fonctionnent pas. En effet, les images sont optimisées pour être légères. Par conséquent, toutes les commandes et tous les packages normaux ne sont pas installés. L\'exemple suivant montre quelques commandes - l\'une réussit et l\'autre échoue. root\@50949b614477:/\# ls -l total 64 lrwxrwxrwx 1 racine racine 7 23 avril 11:06 bin -\> usr/bin drwxr-xr-x 2 racine racine 4096 15 avril 11:09 démarrage drwxr-xr-x 5 racine racine 360 ​​27 avril 17:24 dev drwxr-xr-x 1 racine racine 4096 27 avril 17:24 etc. drwxr-xr-x 2 racine racine 4096 15 avril 11:09 domicile lrwxrwxrwx 1 racine racine 7 23 avril 11:06 lib -\> usr/lib \ root\@50949b614477:/\# ping nigelpoulton.com bash : ping : commande introuvable Comme vous pouvez le voir, l\' pingutilitaire n\'est pas inclus dans l\'image officielle d\'Ubuntu. Processus de conteneur Lorsque nous avons démarré le conteneur Ubuntu dans la section précédente, nous lui avons dit d\'exécuter le shell Bash ( /bin/bash). Cela fait du shell Bash le seul et unique processus exécuté à l\'intérieur du conteneur. Vous pouvez le voir en courant ps -elfdepuis l\'intérieur du conteneur. root\@50949b614477:/\# ps -elf FS UID PID PPID NI ADDR SZ WCHAN STIME TTY TIME CMD 4 S racine 1 0 0 - 4558 attendre 00:47 ? 00:00:00 /bin/bash 0 R racine 11 1 0 - 8604 - 00:52 ? 00:00:00 ps -elfe Le premier processus de la liste, avec le PID 1, est le shell Bash que nous avons demandé au conteneur de s\'exécuter. Le deuxième processus est la ps -elfcommande que nous avons exécutée pour produire la liste. Il s\'agit d\'un processus de courte durée qui se termine dès que la sortie est affichée. Pour faire court, ce conteneur exécute un seul processus --- /bin/bash. Remarque : les conteneurs Windows sont légèrement différents et ont tendance à exécuter un certain nombre de processus en arrière-plan. Si vous êtes connecté au conteneur et tapez exit, vous mettrez fin au processus Bash et le conteneur se fermera (se terminera). En effet, un conteneur ne peut exister sans son processus principal désigné. Cela est vrai pour les conteneurs Linux et Windows --- tuer le processus principal dans le conteneur tuera le conteneur. Appuyez sur Ctrl-PQpour quitter le conteneur sans terminer son processus principal. Cela vous replacera dans le shell de votre hôte Docker et laissera le conteneur s\'exécuter en arrière-plan. Vous pouvez utiliser la docker container lscommande pour afficher la liste des conteneurs en cours d\'exécution sur votre système. \>\> docker container ls CNTNR ID IMAGE COMMANDE NOMS D\'ÉTAT CRÉÉS 509\...74 ubuntu:latest /bin/bash 6 min Jusqu\'à 6 min malade\_montalcini Il est important de comprendre que ce conteneur est toujours en cours d\'exécution et que vous pouvez y rattacher votre terminal avec la docker container execcommande. \>\> docker container exec -it 50949b614477 bash root\@50949b614477:/\# La commande pour se rattacher au conteneur Windows Nano Server PowerShell serait docker container exec -it \ pwsh.exe. Comme vous pouvez le voir, l\'invite du shell est revenue au conteneur. Si vous exécutez ps -elfà nouveau la commande, vous verrez maintenant deux processus Bash ou PowerShell. En effet, la docker container execcommande a créé un nouveau processus Bash ou PowerShell et s\'y est attaché. Cela signifie que taper exitdans ce shell ne mettra pas fin au conteneur, car le processus Bash ou PowerShell d\'origine continuera à s\'exécuter. Tapez exit pour quitter le conteneur et vérifiez qu\'il est toujours en cours d\'exécution avec un fichier docker container ls. Il fonctionnera toujours. Si vous suivez les exemples, vous devez arrêter et supprimer le conteneur avec les deux commandes suivantes (vous devrez remplacer l\'ID de votre conteneur). \>\> docker container stop 50949b614477 50949b614477 \>\> docker container rm 50949b614477 50949b614477 Les conteneurs démarrés dans les exemples précédents ne seront plus présents sur votre système. Cycle de vie des conteneurs Dans cette section, nous examinerons le cycle de vie d\'un conteneur - de la naissance, au travail et aux vacances, jusqu\'à la mort éventuelle. Nous avons déjà vu comment démarrer des conteneurs avec la docker container runcommande. Commençons-en un autre afin de pouvoir le parcourir tout au long de son cycle de vie. Les exemples suivants proviendront d\'un hôte Linux Docker exécutant un conteneur Ubuntu. Cependant, tous les exemples fonctionneront avec le conteneur Windows PowerShell des exemples précédents - vous devrez évidemment remplacer les commandes Linux par leurs commandes Windows équivalentes. Comme mentionné précédemment, si vous exécutez Docker Desktop sur un ordinateur portable Windows 10 Pro, vous pouvez exécuter en mode conteneurs Linux et suivre tous les exemples Linux. \>\> docker container run \--name percy -it ubuntu:latest /bin/bash root\@9cb2d2fd1d65 :/\# C\'est le conteneur créé, et nous l\'avons nommé \"percy\" pour persistant. Maintenant, mettons-le au travail en y écrivant des données. La procédure suivante écrit du texte dans un nouveau fichier du /tmprépertoire et vérifie que l\'opération a réussi. Assurez-vous d\'exécuter ces commandes à partir du conteneur que vous venez de démarrer. root\@9cb2d2fd1d65:/\# cd tmp root\@9cb2d2fd1d65:/tmp\# ls -l totale 0 root\@9cb2d2fd1d65:/tmp\# echo \"Sunderland est la plus grande équipe de football du monde\" \> newfile root\@9cb2d2fd1d65:/tmp\# ls -l total 4 -rw-r\--r\-- 1 racine racine 14 avril 27 11:22 nouveaufichier root\@9cb2d2fd1d65:/tmp\# cat nouveaufichier Sunderland est la plus grande équipe de football du monde Appuyez sur Ctrl-PQpour sortir du conteneur sans le tuer. Utilisez maintenant la docker container stopcommande pour arrêter le conteneur et le mettre en vacances. \>\> docker container stop percy percy Vous pouvez utiliser le nom ou l\'ID du conteneur avec la docker container stopcommande. Le format est docker container stop \. Exécutez maintenant une docker container lscommande pour répertorier tous les conteneurs en cours d\'exécution. \>\> docker container ls CONTAINER ID IMAGE COMMANDE ÉTAT CRÉÉ NOMS DES PORTS Le conteneur n\'est pas répertorié dans la sortie ci-dessus, car il est à l\'état arrêté. Exécutez à nouveau la même commande, mais cette fois ajoutez l\' -aindicateur pour afficher tous les conteneurs, y compris ceux qui sont arrêtés. \>\> docker container ls -a CNTNR ID IMAGE COMMANDE NOMS D\'ÉTAT CRÉÉS 9cb\...65 ubuntu:latest /bin/bash 4 mins Sortie (0) percy Nous pouvons maintenant voir le conteneur s\'afficher sous la forme Exited (0). Arrêter un conteneur revient à arrêter une machine virtuelle. Bien qu\'il ne soit pas en cours d\'exécution, l\'intégralité de sa configuration et de son contenu existe toujours sur le système de fichiers local de l\'hôte Docker. Cela signifie qu\'il peut être redémarré à tout moment. Utilisons la docker container startcommande pour le ramener de vacances. \>\> docker container start percy percy \>\> docker conteneur ls ID DE CONTENEUR IMAGE COMMANDE NOMS DE STATUT CRÉÉS 9cb2d2fd1d65 ubuntu:latest \"/bin/bash\" 4 min Jusqu\'à 3 sec percy Le conteneur arrêté est maintenant redémarré. Il est temps de vérifier que le fichier que nous avons créé précédemment existe toujours. Connectez-vous au conteneur redémarré avec la docker container execcommande. \>\> docker container exec -it percy bash root\@9cb2d2fd1d65 :/\# Votre invite de shell changera pour indiquer que vous travaillez maintenant dans l\'espace de noms du conteneur. Vérifiez que le fichier que vous avez créé précédemment est toujours là et contient les données que vous y avez écrites. root\@9cb2d2fd1d65:/\# cd tmp root\@9cb2d2fd1d65:/\# ls -l -rw-r\--r\-- 1 root root 14 Sep 13 04:22 nouveaufichier root\@9cb2d2fd1d65:/\# cat nouveaufichier Sunderland est la plus grande équipe de football du monde Comme par magie, le fichier que vous avez créé est toujours là et les données qu\'il contient sont exactement comme vous l\'avez laissé. Cela prouve que l\'arrêt d\'un conteneur ne détruit pas le conteneur ou les données qu\'il contient. Bien que cet exemple illustre la nature persistante des conteneurs, il est important que vous compreniez deux choses : Les données créées dans cet exemple sont stockées sur le système de fichiers local des hôtes Docker. Si l\'hôte Docker tombe en panne, les données seront perdues. Les conteneurs sont conçus pour être des objets immuables et il n\'est pas recommandé d\'y écrire des données. Pour ces raisons, Docker fournit des volumes qui existent séparément du conteneur, mais qui peuvent être montés dans le conteneur lors de l\'exécution. À ce stade de votre parcours, il s\'agissait d\'un exemple efficace de cycle de vie d\'un conteneur, et vous auriez du mal à établir une différence majeure entre le cycle de vie d\'un conteneur et celui d\'une machine virtuelle. Tuons maintenant le conteneur et supprimons-le du système. Vous pouvez supprimer un conteneur en cours d\' exécution avec une seule commande, en passant l\' -findicateur à docker container rm. Cependant, il est considéré comme une bonne pratique d\'adopter l\'approche en deux étapes consistant à arrêter d\'abord le conteneur, puis à le supprimer. Cela donne à l\'application/au processus exécuté dans le conteneur une chance de s\'arrêter proprement. Plus d\'informations à ce sujet dans une seconde. L\'exemple suivant arrêtera le percyconteneur, le supprimera et vérifiera l\'opération. Si votre terminal est toujours attaché au conteneur percy, vous devrez revenir au terminal de votre hôte Docker en tapant Ctrl-PQ. \>\> docker container stop percy percy \>\> docker container rm percy percy \>\> docker container ls -a CONTAINER ID IMAGE COMMANDE ÉTAT CRÉÉ NOMS DES PORTS Le conteneur est maintenant supprimé - littéralement effacé de la surface de la planète. S\'il s\'agissait d\'un bon conteneur, il devient une fonction sans serveur dans l\'au-delà. Si c\'était un vilain conteneur, ça devient un terminal stupide :-D Pour résumer le cycle de vie d\'un conteneur... Vous pouvez arrêter, démarrer, mettre en pause et redémarrer un conteneur autant de fois que vous le souhaitez. Ce n\'est que lorsque vous supprimez explicitement un conteneur que vous courez le risque de perdre ses données. Même dans ce cas, si vous stockez des données en dehors du conteneur dans un volume , ces données persisteront même après la disparition du conteneur. Mentionnons rapidement pourquoi nous avons recommandé une approche en deux étapes consistant à arrêter le conteneur avant de le supprimer. Arrêter les conteneurs avec grâce La plupart des conteneurs du monde Linux exécuteront un seul processus. Les choses sont un peu différentes avec les conteneurs Windows, mais ils exécutent toujours un seul processus d\'application principal et les règles suivantes s\'appliquent. Dans l\'exemple précédent, le conteneur exécutait l\' /bin/bashapplication. Lorsque vous arrêtez un conteneur en cours d\'exécution avec docker container rm \ -f, le conteneur est arrêté sans avertissement. La procédure est assez violente - un peu comme se faufiler derrière le conteneur et lui tirer une balle dans la nuque. Vous ne donnez littéralement au conteneur et à l\'application qu\'il exécute aucune chance de terminer une opération et de quitter gracieusement. Cependant, la docker container stopcommande est beaucoup plus polie - comme pointer un pistolet vers la tête des conteneurs et dire \"vous avez 10 secondes pour dire vos derniers mots\". Cela indique au processus à l\'intérieur du conteneur qu\'il est sur le point d\'être arrêté, ce qui lui donne une chance de mettre les choses en ordre avant la fin. Une fois terminé, vous pouvez ensuite supprimer le conteneur avec docker container rm. La magie dans les coulisses ici peut être expliquée avec des signaux Linux/POSIX. docker container stopenvoie un signal SIGTERM au processus d\'application principal à l\'intérieur du conteneur (PID 1). Comme nous l\'avons dit, cela donne au processus une chance de nettoyer les choses et de se fermer gracieusement. S\'il ne sort pas dans les 10 secondes, il recevra un SIGKILL. C\'est effectivement la balle dans la tête. Mais bon, il a eu 10 secondes pour se débrouiller en premier. docker container rm \ -fne prend pas la peine de demander gentiment avec un SIGTERM , il va directement au SIGKILL. Conteneurs à réparation automatique avec règles de redémarrage Il est souvent judicieux d\'exécuter des conteneurs avec une stratégie de redémarrage. Il s\'agit d\'une forme d\'auto-réparation qui permet à Docker de les redémarrer automatiquement après certains événements ou échecs. Les stratégies de redémarrage sont appliquées par conteneur et peuvent être configurées de manière impérative sur la ligne de commande dans le cadre de docker-container runcommandes, ou de manière déclarative dans des fichiers YAML pour une utilisation avec des outils de niveau supérieur tels que Docker Swarm, Docker Compose et Kubernetes. Au moment de la rédaction, les politiques de redémarrage suivantes existent : always unless-stopped on-failed La politique toujours est la plus simple. Il redémarre toujours un conteneur arrêté à moins qu\'il n\'ait été explicitement arrêté, par exemple via une docker container stopcommande. Un moyen simple de le démontrer consiste à démarrer un nouveau conteneur interactif, avec la \--restart alwaysstratégie, et à lui dire d\'exécuter un processus shell. Lorsque le conteneur démarre, vous serez attaché à sa coque. Taper exitdepuis le shell tuera le processus PID 1 du conteneur et tuera le conteneur. Cependant, Docker le redémarrera automatiquement car il a la \--restart alwayspolitique. Si vous émettez une docker container lscommande, vous verrez que le temps de disponibilité du conteneur est inférieur au temps écoulé depuis sa création. Mettons-le à l\'épreuve. Si vous suivez un long parcours avec les conteneurs Windows, remplacez la docker container runcommande de l\'exemple par celle-ci : docker container run \--name neversaydie -it \--restart always mcr.microsoft.com/powershell:nanoserver. \>\> docker container run \--name neversaydie -it \--restart always alpine sh/\# Attendez quelques secondes avant de taper la exitcommande. Une fois que vous avez quitté le conteneur et que vous êtes revenu à votre invite de shell normale, vérifiez l\'état du conteneur. \>\> docker container ls CONTENEUR ID IMAGE COMMANDE CRÉÉ ÉTAT NOM 0901afb84439 alpin \"sh\" il y a 35 secondes Up 9 secondes neversaydie Découvrez comment le conteneur a été créé il y a 35 secondes, mais n\'est opérationnel que depuis 9 secondes. C\'est parce que la exitcommande l\'a tué et Docker l\'a redémarré. Sachez que Docker a redémarré le même conteneur et n\'en a pas créé de nouveau. En fait, si vous l\'inspectez avec docker container inspectvous pouvez voir qu\'il restartCounta été incrémenté. Une caractéristique intéressante de la \--restart alwayspolitique est que si vous arrêtez un conteneur avec docker container stopet redémarrez le démon Docker, le conteneur sera redémarré. Pour être clair... vous démarrez un nouveau conteneur avec la \--restart alwaysstratégie, puis vous l\'arrêtez avec la docker container stopcommande. À ce stade, le conteneur est dans l\' Stopped (Exited)état. Cependant, si vous redémarrez le démon Docker, le conteneur sera automatiquement redémarré lorsque le démon reviendra. Vous devez en être conscient. La principale différence entre les stratégies toujours et sauf si arrêté est que les conteneurs avec la \--restart unless-stoppedstratégie ne seront pas redémarrés lorsque le démon redémarre s\'ils étaient dans l\' Stopped (Exited)état. Cela pourrait être une phrase déroutante, alors passons en revue un exemple. Nous allons créer deux nouveaux conteneurs. L\'un appelé « toujours » avec la \--restart alwayspolitique, et l\'autre appelé « à moins d\'être arrêté » avec la \--restart unless-stoppedpolitique. Nous les arrêterons tous les deux avec la docker container stopcommande puis redémarrerons Docker. Le conteneur \"toujours\" redémarrera, mais pas le conteneur \"sauf si arrêté\". Créer les deux nouveaux conteneurs \>\> docker container run -d \--name always \\ \--restart always \\ alpine sleep 1d \>\> docker container run -d \--name unless-stopped \\ \--restart unless-stopped \\ alpine sleep 1d \>\> docker container ls ID DE CONTENEUR IMAGE COMMANDE NOMS D\'ÉTAT 3142bd91ecc4 alpin \"sleep 1d\" Jusqu\'à 2 secondes à moins d\'être arrêté 4f1b431ac729 alpin \"sleep 1d\" Jusqu\'à 17 secondes toujours Nous avons maintenant deux conteneurs en cours d\'exécution. L\'un appelé \"toujours\" et l\'autre appelé \"à moins d\'être arrêté\". Arrêtez les deux conteneurs \>\> docker container stop always unless-stopped \>\> docker container ls -a ID DE CONTENEUR NOMS D\'ÉTAT D\'IMAGE 3142bd91ecc4 alpine Sorti (137) il y a 3 secondes à moins d\'être arrêté 4f1b431ac729 alpine Sortie (137) il y a 3 secondes toujours Redémarrez Docker. Le processus de redémarrage de Docker est différent sur différents systèmes d\'exploitation. Cet exemple montre comment arrêter Docker sur les hôtes Linux exécutant systemd. Pour redémarrer Docker sur Windows Server 2016, utilisez restart-service Docker. \>\> systemlctl redémarrage docker Une fois Docker redémarré, vous pouvez vérifier l\'état des conteneurs. \>\> systemlctl restart docker NOMS DE STATUT CRÉÉS PAR LE CONTENEUR \>\> docker container ls -a 314..cc4 il y a 2 minutes Sorti (137) il y a 2 minutes sauf si arrêté 4f1..729 il y a 2 minutes Jusqu\'à 9 secondes toujours Notez que le conteneur « toujours » (démarré avec la \--restart alwaysstratégie) a été redémarré, mais pas le conteneur « sauf si arrêté » (démarré avec la \--restart unless-stoppedstratégie). La stratégie en cas d\' échec redémarrera un conteneur s\'il se termine avec un code de sortie différent de zéro. Il redémarrera également les conteneurs au redémarrage du démon Docker, même les conteneurs qui étaient à l\'état arrêté. Si vous travaillez avec Docker Compose ou Docker Stacks, vous pouvez appliquer la stratégie de redémarrage à un serviceobjet comme suit. Nous parlerons plus en détail de ces technologies plus tard dans le livre. version: \"3\" services: myservice: \ restart\_policy: condition: always \| unless-stopped \| on-failureExemple de serveur Web Jusqu\'à présent, nous avons vu comment démarrer un conteneur simple et interagir avec lui. Nous avons également vu comment arrêter, redémarrer et supprimer des conteneurs. Examinons maintenant un exemple de serveur Web basé sur Linux. Dans cet exemple, nous allons démarrer un nouveau conteneur à partir d\'une image que j\'utilise dans quelques-uns de mes cours vidéo Pluralsight. L\'image exécute un serveur Web simple sur le port 8080. Vous pouvez utiliser les commandes docker container stopet docker container rmpour nettoyer tous les conteneurs existants sur votre système. Exécutez ensuite la commande suivante pour démarrer un nouveau conteneur de serveur Web. \>\> docker container run -d \--name webserver -p 80:8080 \\\ nigelpoulton/pluralsight-docker-ci Impossible de trouver l\'image \'nigelpoulton/pluralsight-docker-ci:latest\' localement dernier : extrait de nigelpoulton/pluralsight-docker-ci a3ed95caeb02 : Extraction terminée 3b231ed5aa2f : Tirer terminé 7e4f9cd54d46 : Tirer terminé 929432235e51 : Tirer complet 6899ef41c594 : Tirer complet 0b38fccd0dab : Extraction terminée Résumé : sha256:7a6b0125fe7893e70dc63b2\...9b12a28e2c38bd8d3d Statut : image plus récente téléchargée pour nigelpoulton/plur\...docker-ci:latest 6efa1838cd51b92a4817e0e7483d103bf72a7ba7ffb5855080128d85043fef21 Notez que votre invite de shell n\'a pas changé. C\'est parce que ce conteneur a été démarré en arrière-plan avec le -ddrapeau. Démarrer un conteneur comme celui-ci ne l\'attache pas à votre terminal. Examinons quelques-uns des autres arguments de la commande. Nous savons que docker container runcommence un nouveau conteneur. Cependant, cette fois, nous lui donnons le -ddrapeau au lieu de -it. -dreprésente le mode démon et indique au conteneur de s\'exécuter en arrière-plan. Vous ne pouvez pas utiliser les drapeaux -det dans la même commande.-it Après cela, la commande nomme le conteneur \"webserver\". L\' -pindicateur mappe le port 80 sur l\'hôte Docker au port 8080 à l\'intérieur du conteneur. Cela signifie que le trafic atteignant l\'hôte Docker sur le port 80 sera dirigé vers le port 8080 à l\'intérieur du conteneur. Il se trouve que l\'image que nous utilisons pour ce conteneur définit un service Web qui écoute sur le port 8080. Cela signifie que le conteneur lancera un serveur Web qui écoute sur le port 8080. Enfin, la commande indique au conteneur de se baser sur l\' nigelpoulton/pluralsight-docker-ciimage. Cette image contient un serveur Web node.js et toutes les dépendances. Il est maintenu environ une fois par an, il contiendra donc des vulnérabilités ! Une fois le conteneur en cours d\'exécution, une docker container lscommande affichera le conteneur en cours d\'exécution et les ports mappés. Il est important de savoir que les mappages de ports sont exprimés sous la forme host-port:container-port. \>\> docker container lsCONTAINER ID COMMANDE ÉTAT NOMS DES PORTS 6efa1838cd51 /bin/sh -c\... Jusqu\'à 2 minutes 0.0.0.0:80-\>8080/tcp serveur web Certaines colonnes ont été supprimées de la sortie pour améliorer la lisibilité. Maintenant que le conteneur est en cours d\'exécution et que les ports sont mappés, vous pouvez vous y connecter en pointant un navigateur Web vers l\'adresse IP ou le nom DNS de l\' hôte Docker sur le port 80. La figure 7.4 montre la page Web qui est servie par le récipient. Illustration 7.4 Illustration 7.4 Les mêmes commandes docker container stop, docker container pause, docker container startet docker container rmpeuvent être utilisées sur le conteneur. Inspection des conteneurs Dans l\'exemple de serveur Web précédent, vous avez peut-être remarqué que nous n\'avons pas spécifié d\'application pour le conteneur lorsque nous avons émis la docker container runcommande. Pourtant, le conteneur exécutait un service Web. Comment est-ce arrivé? Lors de la création d\'une image Docker, vous pouvez intégrer une instruction qui répertorie l\'application par défaut pour tous les conteneurs qui utilisent l\'image. Vous pouvez voir cela pour n\'importe quelle image en exécutant un fichier docker image inspect. \>\> docker image inspect nigelpoulton/pluralsight-docker-ci \[ { \"Identifiant\": \"sha256:07e574331ce3768f30305519\...49214bf3020ee69bba1\", \"RepoTags\": \[ \"nigelpoulton/pluralsight-docker-ci:latest\" \ \], \"Commande\": \[ \"/bin/sh\", \"-c\", \"\#(nop) CMD \[\\\"/bin/sh\\\" \\\"-c\\\" \\\"cd /src \\u0026\\u0026 nœud./app.js\\\"\]\" \], \ La sortie est coupée pour faciliter la recherche des informations qui nous intéressent. Les entrées après Cmdmontrent la commande/application que le conteneur exécutera à moins que vous ne la remplaciez par une autre lorsque vous lancez le conteneur avec docker container run. Si vous supprimez tous les échappements du shell dans l\'exemple, vous obtenez la commande suivante /bin/sh -c \"cd /src && node./app.js\". C\'est l\'application par défaut qu\'un conteneur basé sur cette image exécutera. N\'hésitez pas à inspecter d\'autres images, parfois l\'application par défaut est répertoriée comme Entrypointau lieu de Cmd. Il est courant de créer des images avec des commandes par défaut comme celle-ci, car cela facilite le démarrage des conteneurs. Il force également un comportement par défaut et constitue une forme d\'auto-documentation - c\'est-à-dire que vous pouvez inspecter l\'image et savoir quelle application elle est conçue pour exécuter. C\'est ce que nous avons fait pour les exemples de ce chapitre. Voyons un moyen rapide de ranger notre système. Ranger Examinons le moyen le plus simple et le plus rapide de se débarrasser de chaque conteneur en cours d\'exécution sur votre hôte Docker. Soyez averti cependant, la procédure détruira de force tous les conteneurs sans leur donner la possibilité de se nettoyer. Cela ne doit jamais être effectué sur des systèmes de production ou des systèmes exécutant des conteneurs importants. Exécutez la commande suivante à partir du shell de votre hôte Docker pour supprimer tous les conteneurs. \>\> docker container rm \$(docker container ls -aq) -f 6efa1838cd51 Dans cet exemple, il n\'y avait qu\'un seul conteneur en cours d\'exécution, donc un seul a été supprimé (6efa1838cd51). Cependant, la commande fonctionne de la même manière que la docker image rm \$(docker image ls -q)commande que nous avons utilisée dans le chapitre précédent pour supprimer toutes les images sur un seul hôte Docker. Nous savons déjà que la docker container rmcommande supprime les conteneurs. Le passer \$(docker container ls -aq)comme argument, lui passe effectivement l\'ID de chaque conteneur sur le système. L\' -findicateur force l\'opération afin que même les conteneurs en cours d\'exécution soient détruits. Résultat net... tous les conteneurs, en cours d\'exécution ou arrêtés, seront détruits et supprimés du système. La commande ci-dessus fonctionnera dans un terminal PowerShell sur un hôte Windows Docker. Conteneurs - Les commandes docker container runest la commande utilisée pour démarrer de nouveaux conteneurs. Dans sa forme la plus simple, il accepte une image et une commande comme arguments. L\'image est utilisée pour créer le conteneur et la commande est l\'application que le conteneur exécutera au démarrage. Cet exemple démarrera un conteneur Ubuntu au premier plan et lui demandera d\'exécuter le shell Bash : docker container run -it ubuntu /bin/bash. Ctrl-PQdétachera votre shell du terminal d\'un conteneur et laissera le conteneur fonctionner (UP)en arrière-plan. docker container lsrépertorie tous les conteneurs en cours d\'exécution (UP). Si vous ajoutez le -adrapeau, vous verrez également les conteneurs à l\' (Exited)état arrêté. docker container execexécute un nouveau processus à l\'intérieur d\'un conteneur en cours d\'exécution. C\'est utile pour attacher le shell de votre hôte Docker à un terminal à l\'intérieur d\'un conteneur en cours d\'exécution. Cette commande démarrera un nouveau shell Bash à l\'intérieur d\'un conteneur en cours d\'exécution et s\'y connectera : docker container exec -it \ bash. Pour que cela fonctionne, l\'image utilisée pour créer le conteneur doit inclure le shell Bash. docker container stoparrêtera un conteneur en cours d\'exécution et le mettra dans l\' Exited (0)état. Il le fait en envoyant un SIGTERMau processus avec le PID 1 à l\'intérieur du conteneur. Si le processus n\'a pas été nettoyé et arrêté dans les 10 secondes, un SIGKILL sera émis pour arrêter de force le conteneur. docker container stopaccepte les ID de conteneur et les noms de conteneur comme arguments. docker container startredémarrera un conteneur arrêté (Exited). Vous pouvez donner docker container startle nom ou l\'ID d\'un conteneur. docker container rmsupprimera un conteneur arrêté. Vous pouvez spécifier des conteneurs par nom ou ID. Il est recommandé d\'arrêter un conteneur avec la docker container stopcommande avant de le supprimer avec docker container rm. docker container inspectvous montrera des informations détaillées sur la configuration et l\'exécution d\'un conteneur. Il accepte les noms de conteneurs et les ID de conteneurs comme argument principal. Résumé du chapitre Dans ce chapitre, nous avons comparé et contrasté les modèles de conteneur et de VM. Nous avons examiné le problème de taxation du système d\'exploitation inhérent au modèle de machine virtuelle et avons vu comment le modèle de conteneur peut apporter d\'énormes avantages de la même manière que le modèle de machine virtuelle a apporté d\'énormes avantages par rapport au modèle de serveur physique. Nous avons vu comment utiliser la docker container runcommande pour démarrer quelques conteneurs simples, et nous avons vu la différence entre les conteneurs interactifs au premier plan et les conteneurs exécutés en arrière-plan. Nous savons que tuer le processus PID 1 à l\'intérieur d\'un conteneur tuera le conteneur. Et nous avons vu comment démarrer, arrêter et supprimer des conteneurs. Nous avons terminé le chapitre en utilisant la docker container inspectcommande pour afficher les métadonnées détaillées du conteneur. Jusqu\'ici tout va bien!

Use Quizgecko on...
Browser
Browser