Exécutez votre premier conteneur

Beginner

This tutorial is from open-source community. Access the source code

Introduction

Dans ce laboratoire, vous exécuterez votre premier conteneur Docker.

Les conteneurs ne sont qu'un processus (ou un groupe de processus) s'exécutant en isolation. L'isolation est obtenue grâce aux espaces de noms Linux, aux groupes de contrôle (cgroups), à seccomp et à SELinux. Notez que les espaces de noms Linux et les groupes de contrôle sont intégrés au noyau Linux! En dehors du noyau Linux lui-même, il n'y a rien de spécial dans les conteneurs.

Ce qui rend les conteneurs utiles, c'est l'outil qui les entoure. Pour ces laboratoires, nous utiliserons Docker, qui est un outil largement adopté pour utiliser des conteneurs pour construire des applications. Docker fournit aux développeurs et aux opérateurs une interface conviviale pour construire, expédier et exécuter des conteneurs dans n'importe quel environnement doté d'un moteur Docker. Comme le client Docker nécessite un moteur Docker, une alternative est d'utiliser Podman, qui est un moteur de conteneurs sans démon pour développer, gérer et exécuter des conteneurs OCI et est capable d'exécuter des conteneurs en tant que root ou en mode sans root. Pour ces raisons, nous recommandons Podman, mais en raison de son adoption, ce laboratoire utilise toujours Docker.

Dans la première partie de ce laboratoire, nous exécuterons notre premier conteneur et apprendrons à l'inspecter. Nous pourrons constater l'isolation d'espace de noms que nous obtenons à partir du noyau Linux.

Après avoir exécuté notre premier conteneur, nous plongerons dans d'autres utilisations des conteneurs. Vous pouvez trouver de nombreux exemples de cela sur le Docker Store, et nous exécuterons plusieurs types différents de conteneurs sur le même hôte. Cela nous permettra de voir l'avantage de l'isolation - où nous pouvons exécuter plusieurs conteneurs sur le même hôte sans conflits.

Nous utiliserons quelques commandes Docker dans ce laboratoire. Pour la documentation complète des commandes disponibles, consultez la documentation officielle.

Ceci est un Guided Lab, qui fournit des instructions étape par étape pour vous aider à apprendre et à pratiquer. Suivez attentivement les instructions pour compléter chaque étape et acquérir une expérience pratique. Les données historiques montrent que c'est un laboratoire de niveau débutant avec un taux de réussite de 90%. Il a reçu un taux d'avis positifs de 92% de la part des apprenants.

Commencez

Ouvrez un terminal sur la machine virtuelle LabEx et exécutez docker -h, qui vous montrera la page d'aide de l'interface de ligne de commande (CLI) Docker.

VOLUME Gérer les volumes

La ligne de commande Docker peut être utilisée pour gérer plusieurs fonctionnalités du moteur Docker. Dans ce laboratoire, nous nous concentrerons principalement sur la commande container.

Installez podman sur votre machine virtuelle LabEx.

sudo apt-get update
sudo apt-get install podman -y

Si podman est installé, vous pouvez exécuter la commande alternative pour comparer.

sudo podman -h

Vous pouvez également vérifier la version de votre installation Docker avec docker version

docker version

Client:
Version: 20.10.21
...

Server:
Engine:
Version: 20.10.21
...

Vous constatez que Docker installe à la fois un Client et un Server : Docker Engine. Par exemple, si vous exécutez la même commande pour podman, vous ne verrez que la version de la CLI, car podman s'exécute sans démon et dépend d'un runtime de conteneur conforme à OCI (runc, crun, runv, etc.) pour interfacer avec le système d'exploitation et créer les conteneurs en cours d'exécution.

sudo podman version --events-backend=none
Version: 3.4.4
API Version: 3.4.4
Go Version: go1.17.3
Built: Thu Jan 1 08:00:00 1970
OS/Arch: linux/amd64

Exécutez votre premier conteneur

Nous allons utiliser l'interface de ligne de commande (CLI) Docker pour exécuter notre premier conteneur.

Ouvrez un terminal sur la machine virtuelle LabEx.

Exécutez la commande.

docker container run -t ubuntu top

Utilisez la commande docker container run pour exécuter un conteneur avec l'image ubuntu en utilisant la commande top. Le drapeau -t attribue un pseudo-terminal TTY dont nous avons besoin pour que top fonctionne correctement.

$ docker container run -it ubuntu top
Impossible de trouver l'image 'ubuntu:latest' localement
latest: Téléchargement depuis la bibliothèque/ubuntu
aafe6b5e13de: Téléchargement terminé
0a2b43a72660: Téléchargement terminé
18bdd1e546d2: Téléchargement terminé
8198342c3e05: Téléchargement terminé
f56970a44fd4: Téléchargement terminé
Digest: sha256:f3a61450ae43896c4332bda5e78b453f4a93179045f20c8181043b26b5e79028
Statut: Téléchargé une image plus récente pour ubuntu:latest

La commande docker run entraînera tout d'abord un docker pull pour télécharger l'image ubuntu sur votre hôte. Une fois téléchargée, elle démarrera le conteneur. La sortie du conteneur en cours d'exécution devrait ressembler à ceci :

top - 20:32:46 up 3 days, 17:40,  0 users,  load average: 0.00, 0.01, 0.00
Tasks:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.1 sy,  0.0 ni, 99.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  2046768 total,   173308 free,   117248 used,  1756212 buff/cache
KiB Swap:  1048572 total,  1048572 free,        0 used.  1548356 avail Mem

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
      1 root      20   0   36636   3072   2640 R   0.3  0.2   0:00.04 top

top est une utilité Linux qui affiche les processus sur un système et les classe par consommation de ressources. Remarquez qu'il n'y a qu'un seul processus dans cette sortie : c'est le processus top lui-même. Nous ne voyons pas les autres processus de notre hôte dans cette liste en raison de l'isolation de l'espace de noms PID.

Les conteneurs utilisent les espaces de noms Linux pour isoler les ressources système des autres conteneurs ou de l'hôte. L'espace de noms PID fournit une isolation pour les identifiants de processus. Si vous exécutez top à l'intérieur du conteneur, vous remarquerez qu'il affiche les processus à l'intérieur de l'espace de noms PID du conteneur, ce qui est très différent de ce que vous pouvez voir si vous exécutez top sur l'hôte.

Même si nous utilisons l'image ubuntu, il est important de noter que notre conteneur n'a pas son propre noyau. Il utilise le noyau de l'hôte et l'image ubuntu est utilisée uniquement pour fournir le système de fichiers et les outils disponibles sur un système ubuntu.

Inspectez le conteneur avec docker container exec

La commande docker container exec est un moyen d'"entrer" dans les espaces de noms d'un conteneur en cours d'exécution avec un nouveau processus.

Ouvrez un nouveau terminal. Sélectionnez Terminal > Nouveau terminal.

Dans le nouveau terminal, utilisez la commande docker container ls pour obtenir l'ID du conteneur en cours d'exécution que vous venez de créer.

$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b3ad2a23fab3 ubuntu "top" 29 minutes ago Up 29 minutes goofy_nobel

Ensuite, utilisez cet ID pour exécuter bash à l'intérieur de ce conteneur en utilisant la commande docker container exec. Puisque nous utilisons bash et que nous voulons interagir avec ce conteneur à partir de notre terminal, utilisez les drapeaux -it pour exécuter en mode interactif tout en attribuant un pseudo-terminal.

$ docker container exec -it ID < CONTAINER > bash
root@b3ad2a23fab3:/#

Et voilà! Nous venons d'utiliser la commande docker container exec pour "entrer" dans les espaces de noms de notre conteneur avec notre processus bash. Utiliser docker container exec avec bash est un modèle courant pour inspecter un conteneur Docker.

Remarquez le changement dans le préfixe de votre terminal. Par exemple, root@b3ad2a23fab3:/. Cela indique que nous exécutons bash "à l'intérieur" de notre conteneur.

Note : Ce n'est pas la même chose que d'accéder à un hôte ou à une machine virtuelle séparée via ssh. Nous n'avons pas besoin d'un serveur ssh pour nous connecter à un processus bash. Rappelez-vous que les conteneurs utilisent des fonctionnalités au niveau du noyau pour réaliser l'isolation et que les conteneurs s'exécutent au-dessus du noyau. Notre conteneur n'est qu'un groupe de processus s'exécutant en isolation sur le même hôte, et nous pouvons utiliser docker container exec pour entrer dans cette isolation avec le processus bash. Après avoir exécuté docker container exec, le groupe de processus s'exécutant en isolation (c'est-à-dire notre conteneur) inclut top et bash.

Depuis le même terminal, exécutez ps -ef pour inspecter les processus en cours d'exécution.

root@b3ad2a23fab3:/## ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 20:34? 00:00:00 top
root 17 0 0 21:06? 00:00:00 bash
root 27 17 0 21:14? 00:00:00 ps -ef

Vous devriez voir seulement le processus top, le processus bash et notre processus ps.

Pour comparer, quittez le conteneur et exécutez ps -ef ou top sur l'hôte. Ces commandes fonctionneront sur Linux ou Mac. Pour Windows, vous pouvez inspecter les processus en cours d'exécution à l'aide de tasklist.

root@b3ad2a23fab3:/## exit
exit
$ ps -ef
## Beaucoup de processus!

Recherche technique approfondie PID n'est qu'un des espaces de noms Linux qui fournissent aux conteneurs une isolation des ressources système. Les autres espaces de noms Linux incluent :

  • MNT - Monter et démonter des répertoires sans affecter les autres espaces de noms
  • NET - Les conteneurs ont leur propre pile de réseau
  • IPC - Mécanismes de communication interprocessus isolés tels que les files d'attente de messages.
  • User - Vue isolée des utilisateurs sur le système
  • UTC - Définir le nom d'hôte et le nom de domaine par conteneur

Ces espaces de noms fournissent ensemble l'isolation pour les conteneurs qui leur permettent de s'exécuter ensemble de manière sécurisée et sans conflit avec d'autres conteneurs s'exécutant sur le même système. Ensuite, nous démontrerons différentes utilisations des conteneurs et l'avantage de l'isolation lorsque nous exécutons plusieurs conteneurs sur le même hôte.

Note : Les espaces de noms sont une fonctionnalité du Linux noyau. Mais Docker vous permet d'exécuter des conteneurs sur Windows et Mac... Comment cela fonctionne-t-il? Le secret est qu'il est intégré dans le produit Docker ou le moteur Docker un sous-système Linux. Docker a open-sourcé ce sous-système Linux dans un nouveau projet : LinuxKit. Être capable d'exécuter des conteneurs sur de nombreux plateformes différentes est un avantage de l'utilisation de l'outil Docker avec des conteneurs.

En plus de l'exécution de conteneurs Linux sur Windows en utilisant un sous-système Linux, les conteneurs natifs Windows sont désormais possibles grâce à la création de primitives de conteneurs sur le système d'exploitation Windows. Les conteneurs natifs Windows peuvent être exécutés sur Windows 10 ou Windows Server 2016 ou versions ultérieures.

Note : si vous exécutez cet exercice dans un terminal conteneurisé et exécutez la commande ps -ef dans le terminal, vous verrez toujours un ensemble limité de processus après avoir quitté la commande exec. Vous pouvez essayer d'exécuter la commande ps -ef dans un terminal sur votre machine locale pour voir tous les processus.

Nettoyez le conteneur exécutant les processus top en appuyant sur : <ctrl>-c, liste tous les conteneurs et supprimez les conteneurs par leur ID.

docker ps -a

docker rm <CONTAINER ID>

Exécutez plusieurs conteneurs

Explorer le Docker Hub

Le Docker Hub est le registre central public pour les images Docker, qui contient des images communautaires et officielles.

Lorsque vous recherchez des images, vous trouverez des filtres pour les images "Certifiées Docker", "Éditeur vérifié" et "Images officielles". Sélectionnez le filtre "Certifiées Docker" pour trouver des images considérées prêtes pour l'entreprise et testées avec le produit Docker Enterprise Edition. Il est important d'éviter d'utiliser du contenu non vérifié du Docker Store lors du développement de vos propres images destinées à être déployées dans un environnement de production. Ces images non vérifiées peuvent contenir des vulnérabilités de sécurité ou même du logiciel malveillant.

Dans l'étape 2 de ce laboratoire, nous allons démarrer quelques conteneurs en utilisant des images vérifiées du Docker Hub : un serveur web Nginx et une base de données MongoDB.

Exécutez un serveur Nginx

Exécutons un conteneur en utilisant l'image officielle Nginx du Docker Hub.

docker container run --detach --publish 8080:80 --name nginx nginx

Nous utilisons quelques drapeaux nouveaux ici. Le drapeau --detach exécutera ce conteneur en arrière-plan. Le drapeau publish publie le port 80 dans le conteneur (le port par défaut pour Nginx), via le port 8080 sur notre hôte. Rappelez-vous que l'espace de noms NET donne aux processus du conteneur leur propre pile de réseau. Le drapeau --publish est une fonctionnalité qui nous permet d'exposer le réseau à travers le conteneur sur l'hôte.

Comment savez-vous que le port 80 est le port par défaut pour Nginx? Parce que cela est indiqué dans la documentation sur le Docker Hub. En général, la documentation des images vérifiées est très bonne, et vous voudrez vous y référer lorsque vous exécutez des conteneurs à l'aide de ces images.

Nous spécifions également le drapeau --name, qui nomme le conteneur. Chaque conteneur a un nom, si vous ne le spécifiez pas, Docker vous en attribuera un aléatoirement. Spécifier votre propre nom facilite l'exécution de commandes ultérieures sur votre conteneur car vous pouvez référencer le nom au lieu de l'ID du conteneur. Par exemple : docker container inspect nginx au lieu de docker container inspect 5e1.

Depuis que c'est la première fois que vous exécutez le conteneur Nginx, il téléchargera l'image Nginx du Docker Store. Les conteneurs suivants créés à partir de l'image Nginx utiliseront l'image existante située sur votre hôte.

Nginx est un serveur web léger. Vous pouvez accéder au serveur Nginx dans l'onglet Web 8080 de la machine virtuelle LabEx. Basculez dessus et rafraîchissez la page pour voir la sortie de Nginx.

étape 2 nginx

Exécutez un serveur mongo DB

Maintenant, exécutons un serveur MongoDB. Nous utiliserons l'image officielle MongoDB du Docker Hub. Au lieu d'utiliser l'image latest (qui est la valeur par défaut si aucun tag n'est spécifié), nous utiliserons une version spécifique de l'image mongo : 4.4.

docker container run --detach --publish 8081:27017 --name mongo mongo:4.4

Encore une fois, puisque c'est la première fois que nous exécutons un conteneur mongo, nous téléchargerons l'image mongo du Docker Store. Nous utilisons le drapeau --publish pour exposer le port mongo 27017 sur notre hôte. Nous devons utiliser un port autre que 8080 pour la mappage hôte, car ce port est déjà exposé sur notre hôte. Consultez à nouveau la documentation officielle sur le Docker Hub pour obtenir plus de détails sur l'utilisation de l'image mongo.

Voyez la sortie de MongoDB en utilisant 0.0.0.0:8081 dans le navigateur web. Vous devriez voir un message qui retournera un avertissement de la part de MongoDB.

Sortie d'avertissement du serveur MongoDB

Vérifiez vos conteneurs en cours d'exécution avec docker container ls

$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d6777df89fea nginx "nginx -g 'daemon..." Il y a moins d'une seconde Up il y a 2 secondes 0.0.0.0:8080- nginx > 80/tcp
ead80a0db505 mongo "docker-entrypoint..." Il y a 17 secondes Up il y a 19 secondes 0.0.0.0:8081- mongo > 27017/tcp
af549dccd5cf ubuntu "top" Il y a 5 minutes Up il y a 5 minutes priceless_kepler

Vous devriez voir qu'il existe un conteneur serveur web Nginx et un conteneur MongoDB en cours d'exécution sur votre hôte. Notez que nous n'avons pas configuré ces conteneurs pour communiquer entre eux.

Vous pouvez voir les noms "nginx" et "mongo" que nous avons donnés à nos conteneurs, et le nom aléatoire (dans mon cas "priceless_kepler") qui a été généré pour le conteneur ubuntu. Vous pouvez également voir les mappages de ports que nous avons spécifiés avec le drapeau --publish. Pour plus de détails sur ces conteneurs en cours d'exécution, vous pouvez utiliser la commande docker container inspect [container id.

Une chose que vous pourriez remarquer est que le conteneur mongo exécute la commande docker-entrypoint. Il s'agit du nom de l'exécutable qui est exécuté lorsque le conteneur est démarré. L'image mongo nécessite une certaine configuration préalable avant de démarrer le processus de base de données. Vous pouvez voir exactement ce que le script fait en le consultant sur github. En général, vous pouvez trouver le lien vers la source github à partir de la page de description de l'image sur le site web du Docker Store.

Les conteneurs sont autonomes et isolés, ce qui signifie que nous pouvons éviter les conflits potentiels entre les conteneurs avec différentes dépendances système ou de runtime. Par exemple : déployer une application qui utilise Java 7 et une autre application qui utilise Java 8 sur le même hôte. Ou exécuter plusieurs conteneurs Nginx qui ont tous le port 80 comme port d'écoute par défaut (si vous les exposez sur l'hôte en utilisant le drapeau --publish, les ports sélectionnés pour l'hôte doivent être uniques). Les avantages d'isolation sont possibles grâce aux espaces de noms Linux.

Note : Vous n'avez pas dû installer quoi que ce soit sur votre hôte (autre que Docker) pour exécuter ces processus! Chaque conteneur inclut les dépendances dont il a besoin à l'intérieur du conteneur, donc vous n'avez pas besoin d'installer quoi que ce soit directement sur votre hôte.

Exécuter plusieurs conteneurs sur le même hôte nous permet de tirer pleinement parti des ressources (processeur, mémoire, etc.) disponibles sur un seul hôte. Cela peut entraîner d'importantes économies de coûts pour une entreprise.

Alors que l'exécution directe d'images à partir du Docker Hub peut être utile parfois, il est plus utile de créer des images personnalisées et de se référer aux images officielles comme point de départ pour ces images. Nous plongerons dans la construction de nos propres images personnalisées dans le laboratoire 2.

Nettoyage

La fin de ce laboratoire a entraîné la création d'un certain nombre de conteneurs en cours d'exécution sur votre hôte. Nettoyons-les.

Tout d'abord, obtenez la liste des conteneurs en cours d'exécution en utilisant docker container ls.

$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d6777df89fea nginx "nginx -g 'daemon..." Il y a 3 minutes Up il y a 3 minutes 0.0.0.0:8080- nginx > 80/tcp
ead80a0db505 mongo "docker-entrypoint..." Il y a 3 minutes Up il y a 3 minutes 0.0.0.0:8081- mongo > 27017/tcp
af549dccd5cf ubuntu "top" Il y a 8 minutes Up il y a 8 minutes priceless_kepler

Ensuite, exécutez docker container stop [container id] pour chaque conteneur de la liste. Vous pouvez également utiliser les noms des conteneurs que vous avez spécifiés précédemment.

$ docker container stop d67 ead af5
d67
ead
af5

Note : Vous n'avez qu'à référencer suffisamment de chiffres de l'ID pour qu'il soit unique. Trois chiffres sont presque toujours suffisants.

Supprimez les conteneurs arrêtés

docker system prune est une commande très pratique pour nettoyer votre système. Elle supprimera tous les conteneurs arrêtés, tous les volumes inutilisés et les réseaux, ainsi que les images orphelines.

$ docker system prune
AVERTISSEMENT! Cela supprimera :
- tous les conteneurs arrêtés
- tous les volumes non utilisés par au moins un conteneur
- tous les réseaux non utilisés par au moins un conteneur
- toutes les images orphelines
Êtes-vous sûr de vouloir continuer? [y/N] y
Conteneurs supprimés :
7872fd96ea4695795c41150a06067d605f69702dbcb9ce49492c9029f0e1b44b
60abd5ee65b1e2732ddc02b971a86e22de1c1c446dab165462a08b037ef7835c
31617fdd8e5f584c51ce182757e24a1c9620257027665c20be75aa3ab6591740

Espace récupéré au total : 12B

Récapitulatif

Dans ce laboratoire, vous avez créé vos premiers conteneurs Ubuntu, Nginx et MongoDB.

Points clés à retenir

  • Les conteneurs sont composés d'espaces de noms Linux et de groupes de contrôle qui assurent l'isolation des autres conteneurs et de l'hôte.
  • En raison des propriétés d'isolation des conteneurs, vous pouvez planifier de nombreux conteneurs sur un seul hôte sans vous inquiéter des dépendances conflictuelles. Cela facilite l'exécution de plusieurs conteneurs sur un seul hôte : en utilisant pleinement les ressources allouées à cet hôte et en économisant finalement quelques frais de serveur.
  • Évitez d'utiliser du contenu non vérifié du Docker Store lors du développement de vos propres images car ces images peuvent contenir des vulnérabilités de sécurité ou même du logiciel malveillant.
  • Les conteneurs incluent tout ce dont ils ont besoin pour exécuter les processus à l'intérieur d'eux, il n'est donc pas nécessaire d'installer des dépendances supplémentaires directement sur votre hôte.