0% ont trouvé ce document utile (0 vote)
66 vues190 pages

Cours - DOCKER

Le document présente une introduction complète à la conteneurisation avec Docker, en expliquant ses avantages, inconvénients, et son fonctionnement. Il aborde également les bénéfices pour les développeurs et les administrateurs, ainsi que les stratégies cloud et DevOps associées. Enfin, il détaille les différentes offres commerciales et les technologies sous-jacentes à Docker.

Transféré par

ka.stanislasconstantin
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
66 vues190 pages

Cours - DOCKER

Le document présente une introduction complète à la conteneurisation avec Docker, en expliquant ses avantages, inconvénients, et son fonctionnement. Il aborde également les bénéfices pour les développeurs et les administrateurs, ainsi que les stratégies cloud et DevOps associées. Enfin, il détaille les différentes offres commerciales et les technologies sous-jacentes à Docker.

Transféré par

ka.stanislasconstantin
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

CONTAINÉRISATION DOCKER

VINCENT LAINE
SOMMAIRE

◼ Conteneurisation Docker
◼ Run – port mapping
◼ Bénéfices des containers
◼ Run – volume mapping
◼ Apports pour les Dev-Ops
◼ Docker Commands
◼ Docker hub
◼ Inspect container
◼ NOTIONS DE BASE DOCKER
◼ Container logs
◼ OFFRES COMMERCIALES
◼ DOCKER FILE
◼ DOCKER COMPOSE
◼ Build Multistage
◼ DOCKER MACHINE
◼ TAG / PUSH / PULL
◼ DOCKER SWARM
◼ DOCKER ENGINE
◼ DOCKER HUB / REGISTRY
◼ FONCTIONNEMENT DES VOLUMES DE STOCKAGE EN CLUSTER
◼ Le réseau dans Docker (Que les 3 principaux)
◼ Variables d’environnement
CONTENEURISATION DOCKER

◼ Qu’est ce que Docker ?

◼ Docker permet d'embarquer une application dans un ou plusieurs containers logiciels qui pourra s'exécuter sur
n'importe quel serveur machine.

Docker est une plate-forme de virtualisation par conteneur qui, à la différence de la virtualisation par hyperviseur
qui nécessite de créer une machine virtuelle embarquant un système d'exploitation invité pour s'assurer de son
indépendance avec la machine principale.
Il va permettre d'isoler une ou plusieurs applications dans des conteneurs en utilisant les ressources de la machine
hôte.
Docker doit pouvoir être exécutée sur n'importe quel environnement, quel que soit son contenu, évitant ainsi divers
problèmes de compatibilité entre les applications et l'hôte qui les exécute.
DOCKER

Avantages
◼ Un conteneur n'a besoin que de quelques centaines de Mo d'espace disque pour être déployé,
contrairement à une VM. Un conteneur va directement utiliser les ressources dont il a besoin sur le
serveur physique.
◼ La possibilité d'exploiter directement une application sans être contraint de modifier les librairies
installées sur la machine hôte ou de se soucier des versions des logiciels installés sur cette dernière.
◼ C'est un gain de temps non négligeable, l'administrateur système n'a plus autant à s'accorder avec
l'équipe de développement pour être certain que son serveur possédera toutes les dépendances
nécessaires au déploiement d'une application.
◼ La possibilité de partager la configuration complète d'une application sur n'importe quel poste grâce
aux Dockerfiles.
◼ Une simple exécution du fichier permet de déployer des conteneurs prêts à l'emploi, avec la possibilité
d'en modifier certains aspects sans affecter leur configuration.
DOCKER

Inconvénients
◼ Comme les conteneurs utilisent directement les ressources de la machine hôte, il est par exemple
impossible de déployer un conteneur basé sur un système d'exploitation Windows sur un serveur
physique Linux.
◼ Certaines applications ne se prêtent pas à un déploiement morcelé par couche car certaines d'entre
elles ne peuvent fonctionner que de façon monolithique, il est donc préférable d'effectuer des tests de
conteneurisation avant de se lancer dans un déploiement d'application déjà existante.
◼ Il peut être parfois difficile de définir une sécurité poussée entre les différents environnements Docker
d'une même machine physique, les conteneurs utilisant les ressources du noyau et des composants
systèmes de cette dernière, certaines situations ont plus de chance de se répercuter sur le système
d'exploitation sous-jacent ou sur d'autres conteneurs.
BÉNÉFICES DES CONTAINERS

◼ Agilité
◼ Les containers sont rapides et simples à mettre en œuvre
◼ Portabilité
◼ Les containers sont portables sur tout type d’environnement
◼ Du poste développeur, aux serveurs de l’entreprise, au plateformes cloud privées ou publiques
◼ Consistance
◼ Les containers ne subissent aucune modification du poste du développeur à l’environnement de production
◼ Ils sont conçus pour être réutilisés
◼ Optimisation des coûts
◼ Que ce soit en en termes de ressources nécessaires (RAM, stockage..) ou de management (agilité, portabilité…)
◼ Profite des coûts d’investissement plus bas du Cloud provider CAPEX/OPEX
◼ Elasticité
◼ Orchestrateur !
◼ Autoscaling
APPORTS POUR LES DEV-OPS

◼ Développeurs
◼ « build once… run everywhere »
◼ Le container est un environnement sécurisé, stable, portable sur tous environnements
◼ Il résout les problèmes de dépendances ou de packages manquant lors du déploiement
◼ Plusieurs versions de librairies peuvent être utilisées dans différentes containers du fait de leur isolation
◼ Forte automatisation de toutes les phases (test, intégration, packaging..)
◼ Réduit voire élimine les problèmes d’environnement clients différents de ceux de l’éditeur
◼ Rapidité de déploiement, de retour arrière comparativement aux VMs
◼ En définitif, tout semble simple et rapide !
APPORTS POUR LES DEVOPS

◼ Administrateurs
◼ « configure once… run everywhere »
◼ Rend le cycle de vie des applications plus efficace, consistant, et reproductible
◼ Améliore le rendu de la qualité du code développé
◼ Élimine définitivement les inconsistances entre les différents environnements de développement, test, et
production
◼ Apporte une répartition des responsabilités claire avec les développeurs
◼ Améliore sensiblement la vitesse et l’agilité des procédés d’intégration et de déploiement continu
◼ Améliore beaucoup d’aspects comparativement aux VMs du fait de leur taille réduite : performance, coûts,
déploiement, portabilité..
APPORTS POUR L’ENTREPRISE

◼ Stratégie cloud
◼ Facilite l’évolution vers le(s) cloud(s) public(s)
◼ Facilite l’évolution vers l’hybridation et le multi-clouds

◼ Stratégie de modernisation applicative


◼ Containerisation des applications « legacy »
◼ Transformation des applications « legacy » en microservices
◼ Accélère le développement de nouvelles applications sur le modèle microservices

◼ Stratégie DevOps
◼ Résout les problèmes de gestion des différents environnements par la consistance des containers
◼ Facilite les démarches d’intégration et de déploiement continu
◼ Facilite l’autoscaling des applications
LIMITES - MOBILITÉ DES CONTAINERS
◼ Registre
◼ Registre Docker public
◼ Registre privé
◼ Registre en mode SaaS
◼ Quay.io
◼ …

◼ Problématique des données


◼ Stockage objet
◼ Bases de données !

◼ Kubernetes
◼ 2017 meilleure gestion du stockage stateless/statefull sur les pods
LIMITES - INTEROPÉRABILITÉ ET VERROUILLAGE

◼ Docker
◼ A ce niveau, la portabilité est assurée par la nature même de Docker
◼ Simplement particularité containers Linux vs Windows
◼ containers Rocket / LXC…

◼ Interopérabilité des Orchestrateurs


◼ Google Cloud : Kubernetes
◼ Microsoft Azure : Marathon et Mesos >> Juin 2017 : Draft et Kubernetes suite au rachat de DEIS
◼ Amazon : ECS > EC2 Container Service
LIMITES - SÉCURITÉ DES CONTAINERS

◼ Isolation
◼ Isolation native entre les containers
◼ Partage de librairies pour l’optimisation mais en lecture seule

◼ Sécurité
◼ Kernel « hardened » > Grsecurity / PaX
◼ Linux Security Module
◼ SE Linux / AppArmor
◼ Os Minimaux / réduction de la surface d’attaque > CoreOS / Fedora Atomic / VMWare Photon…
DOCKER

Docker est une technologie de conteneurisation reposant sur le noyau Linux et ses fonctionnalités de
virtualisation par conteneurs (LXC pour Linux Containers), notamment :
◼ le composant cgroups pour contrôler et limiter l'utilisation des ressources pour un processus ou un groupe
de processus (utilisation de la RAM, CPU entre autres) associé au système d'initialisation systemd qui permet
de définir l'espace utilisateur et de gérer les processus associés ;
◼ les espaces de noms ou namespaces qui permettent de créer des environnements sécurisés de manière à
isoler les conteneurs et empêcher par exemple qu’un groupe puisse « voir » les ressources des autres
groupes.

Docker utilise des fonctionnalités natives au noyau Linux, comme les cgroups ou les namespaces, mais offre les
outils pour le faire de manière simplifiée pour permettre, entre autres :
◼ la duplication et la suppression des conteneurs ;
◼ l’accessibilité des conteneurs à travers la gestion des API et CLI ;
◼ la migration (à froid ou à chaud) de conteneurs.
DOCKER

◼ Les conteneurs Docker sont construits à partir des images


Docker. Une image Docker est un package léger,
autonome et exécutable d'un logiciel qui inclut tout ce
qui est nécessaire pour l'exécuter :
◼ code de l’application,
◼ environnement d’exécution (runtime),
◼ outils système et librairies, etc.

◼ Disponible pour les applications basées sur Linux et


Windows, le logiciel conteneurisé fonctionnera toujours
de la même manière, quel que soit l'environnement.
DOCKER

◼ Différence entre Docker et Machine Virtuelle


DOCKER

Machine Virtuelle
◼ Basée sur un Hyperviseur
◼ Permet d’émuler des machines complètes : un Os avec une ou plusieurs applications
◼ Machine virtuelles lourdes (plusieurs giga)

Docker
◼ Plus léger, baser sur un moteur de conteneur (Docker)
◼ Sur la couche supérieure, on retrouve les applications installées dans chacun des conteneurs
◼ Un seul système d’exploitation, celui de la machine hôte qui fait bénéficier de ses ressources aux différents conteneurs
◼ Conteneur plus léger (rarement au-dessus de 500 Mo)
◼ Permet de segmenter une application en micro-service (un docker par service : apache, base de données …)
POURQUOI TANT D’ENGOUEMENT ? QUELLES SONT LES UTILISATIONS
POSSIBLES, EFFICACES ET PERTINENTES DE DOCKER ?

◼ Déployer rapidement un service lorsque l’on a besoin de le déployer plusieurs fois : cette
reproductibilité est la base de docker, c’est typiquement l’utilisation que peut en faire un fournisseur
de cloud.
◼ Distribuer une application : Docker en tant que "système de distribution d'une application" : n’ont plus
à packager une application sous différents systèmes (deb, rpm, etc)
◼ Développer et tester une application, Docker permet :
◼ de concevoir une architecture de test plus agile, chaque conteneur de test pouvant par exemple intégrer une
brique de l'application (base de données, langages, composants, …), le développeur pourra tester sur la même
machine plusieurs versions d'un même logiciel en inter changeant le conteneur correspondant.
◼ de développer une application selon le concept d’architecture de micro-services avec pour chaque couche des
conteneurs isolant les composants de l’application ;
◼ faciliter le process de mise à jour de l’application : les images Docker sont versionnées et permettent une mise à
jour simplifiée et maîtrisée. Le process de rollback est aussi simplifié : on redéploie la version précédente de
l’image.
◼ d’avoir un environnement de développement identique à l’environnement de production
DOCKER HUB

◼ C’est quoi ?

◼ https://hub.docker.com/

◼ Regroupe toutes les images docker disponibles

◼ Permet de retrouver toutes les images officielles

◼ Et celle de la communauté

◼ Tout le monde peut déposer son propre conteneur (inscription obligatoire)


TECHNOLOGIES SOUS-JACENTES

◼ Développement
◼ Docker est développé en langage GO
◼ Le daemon Docker se base sur le pilote d’exécution RunC
◼ Control Group CGROUPS
◼ Allocation de ressources RAM et CPU aux containers
◼ Namespaces
◼ Isolation des containers
◼ système de fichiers, nom d’hôte, utilisateurs, réseau, processus
◼ UNION FILE SYSTEM UnionFS
◼ Stockage sur plusieurs couches en lecture seule
◼ Support d’autres pilotes de stockage en fonction des distributions (AUFS, devicemapper, BTRFS, Overlay)
◼ Format des containers Docker
◼ Namespaces + Cgroup + UnionFS
◼ Ce format par défaut est appelé LIBCONTAINER
NOTIONS DE BASE DOCKER

◼ Docker image
◼ Équivalent à une application complète composée de différentes couches liées.

◼ Docker container
◼ Correspond à l’exécution d’une image Docker + une couche de lecture/écriture

◼ Docker engine
◼ Crée, lance et exécute les containers Docker sur les plateformes physiques, virtuelles, en local, dans le
datacenter ou chez un fournisseur de cloud
◼ Docker hub / Registry service
◼ Service de stockage et de distribution des images dans le cloud ou sur un stockage d’entreprise
SYSTÈME EN COUCHES

◼ Chaque couche est liée à la couche sous-jacente


◼ Copy-on-WRITE
◼ 127 couches possibles
BUILD, SHIP, RUN
ÉCOSYSTEM
OFFRES COMMERCIALES

◼ Fonctionnalités
◼ Gestion fine des droits d’accès
◼ Interface grahique (installation, administration, statistiques…)
◼ Signature des images
◼ Docker Trust Registry
◼ Version onpremise du Docker Hub privé
◼ QUAY.IO
◼ Registre en mode Cloud ou OnPremise
◼ Support d’images de type Docker et Rocket
◼ Fonctionnalités de géo-réplication
◼ CoreOS Enterprise Registry
◼ Registre OnPremise
◼ Support d’images Docker / Rocket
DOCKER COMPOSE

◼ Liens de containers
◼ Description YAML
DOCKER SWARM

◼ SWARM
◼ Clustering d’hôtes Docker
◼ Fonctionnalités d’orchestration
DOCKER SWARM
◼ Fonctionnalités
◼ Management de clusters Docker (déploiement, démarrage…)
◼ Mise à jour des nœuds
◼ Communication TLS
◼ Architecture déclarative de l’état désiré (composition de Dockers)
◼ Mode Spread (répartition intelligentes des Dockers sur les nœuds)
◼ Load-balancing
◼ Scaling (manuel!)
◼ Gestion du réseau inter-nœuds en overlay
◼ Stratégies
◼ Filtres / Labels (production, test, ..)
◼ État du nœud
◼ Affinité entre containers
◼ Dépendance entre containers (montages fichier..)
KITEMATIC

◼ Console GUI
◼ Visualisation de l’état de containers
◼ Manipulation des containers
◼ Accès en CLI aux containers
◼ Gestion de ports, logs, volumes de stockage..
SERVICES
◼ Docker Service Discovery
◼ Système d’enregistrement pour containers
◼ Équivalent mécanismes DHCP/DNS

◼ Réseau
◼ Docker – réseau Overlay (Swarm)
◼ Mécanismes de plugins :
◼ Openstack Neutron
◼ Weaveworks
◼ …
DIFFÉRENTES ÉDITIONS
◼ Community
◼ Docker / Compose / Swarm
◼ BASIC
◼ Community + infra, containers, plugins certifiés
◼ 750$ / hôte / an ou 75$ / mois
◼ STANDARD
◼ Basic + registre privé + Docker Datacenter + ldap + multi-tenancy
◼ Par hôte : 1500$/an ou 150$/mois
◼ AVANCEE
◼ Standard + sécurité des images
◼ Par hôte : 2000$/an ou 200$/mois
DOCKER ENGINE

◼ Moteur Docker
◼ Docker Daemon
◼ REST API pour piloter le daemon
◼ Command Line Interface
QUEL OS POUR L’HÔTE ?
◼ Distributions minimales
◼ Le choix idéal ! CoreOS, Fedora Atomic, RancherOS…
◼ • + Sécurisé + Cluster/Réseau + Léger
◼ - mature / stable ?
◼ Production ?
◼ Distribution
◼ Ubuntu / CentOS / Debian / Suse ….
◼ Adapté à la production : en Entreprise & Cloud providers
◼ + Support + Maitrisé + GUI
◼ - sécurisé ? - cluster ?
◼ Poste de développement
◼ Poste Linux : Ubuntu ou autre
◼ Poste Mac/Windows : VirtualBox / Distri minimale Boot2Docker
QUEL OS COMME BASE IMAGE?

◼ SCRATCH
◼ Pas d’OS
◼ Destiné à la création d’images minimales
◼ • + Modules (Kernel)

◼ Distributions minimales
◼ Ubuntu 188Mo
◼ CentOs 172Mo

◼ OS Minimaux
◼ Busybox 2Mo, Alpine 5Mo

◼ Lequel choisir ?
◼ L’OS le mieux maitrisé ?
◼ L’OS le plus léger ?
PLATEFORME DOCKER

◼ Composants de base
◼ Docker Engine
◼ Docker Registry / Hub

◼ Composants plateforme Docker


◼ Docker Compose : outil pour construire et lancer des applications composées de plusieurs containers distincts
◼ Docker Machine : outil d’installation et de configuration des hosts en local ou à distance
◼ Docker Swarm : service de clustering des hosts Docker
◼ Kitematic : interface graphique pour Mac et Windows permettant de lancer et gérer des containers
◼ Docker Trust Registry : version onpremise de Docker Hub avec Role-based Access Control (seul composant Docker
non-opensource)
DOCKER HUB / REGISTRY
◼ Analogie
◼ Docker Hub est équivalent à un repository Github mais pour stocker des images de containers.

◼ Docker Hub
◼ Service de stockage d’images Docker en mode SaaS
◼ La version publique est gratuite et accessible par tous
◼ La version privée est payante et sécurisée

◼ API : push/pull/search images


◼ Intègre une GUI avec statistiques et gère des droits d’accès utilisateur (version privée)

◼ Docker registry
◼ Version Opensource de Docker Hub
◼ Installation Onpremise
◼ API : push/pull/Search
◼ Pas de GUI, pas de gestion des droits d’accès
DOCKER

◼ Installer Docker : sudo apt-get install docker.io docker-compose


◼ Installer une image et la lancer :
◼ docker run -nom image
◼ docker run -di –nom image (d : detach, I : interactive => permet de garder la main sur l’image)

◼ Lorsqu’on lance un « docker run », docker cherche d’abord l’image en local, si elle n’est pas disponible, il la
télécharge depuis Docker Hub (par défaut). Une fois l’image présente en local, le conteneur est lancé.

curl -fsSL https://get.docker.com | sh; >/dev/null


curl -L https://github.com/docker/compose/releases/download/v2.32.4/docker-compose-
linux-x86_64 -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
QUELQUES COMMANDES DE BASE
Commande Explication
docker image ls Lister les images existantes
docker container ls -a Lister les conteneurs
docker ps -a Lister les conteneurs
docker run alpine:latest Lancer ou créer le conteneur alpine
docker run -di --name alpinetest alpine:latest Lancer ou créer le conteneur alpine, le nommer alpinetest et le laisser fonctionner (mode
Detach Interactive)
docker run -di --name alpinetest alpine:latest sleep infinity Comme au dessus mais en plus on conserve un process qui tourne sur le conteneur
docker run -tid -p 8080:80 --name monnginx nginx:latest Lancer le conteneur nginx, le nommer monnginx, le laisser fonctionner. Rediriger son port
80 sur le 8080 de notre machine locale
docker run -tid --name conteneur2 --link conteneur1 alpine Lancer un conteneur alpine que l'on nomme conteneur2, le linker avec conteneur1
(conteneur2 pourra pinguer conteneur1)
docker start monconteneur Redémarrer un conteneur arrêté
docker exec -ti monnginx sh Se connecter au conteneur nommé monnginx avec le shell et le bach
docker stop <nom du conteneur> Arrêter un conteneur
docker container kill $(docker ps -q) Tuer tous les conteneurs
docker start <nom du conteneur> Redémarrer un conteneur
docker rm -f <nom du conteneur> Supprimer un conteneur (-f permet de forcer, même si le conteneur tourne)
docker rm $(docker ps -a -q) Supprimer tous les conteneurs
docker inspect <nom du conteneur> Obtenir les infos sur un conteneur
docker inspect -f "{{.NetworkSettings.IPAddress}}" <nom du conteneur> Obtenir l'ip d'un conteneur
CHEAT SHEET
Commande Description
docker ps Visualiser les conteneurs actifs
docker ps -a Visualiser tous les conteneurs
docker rm [container] Supprimer un conteneur inactif
docker rm -f [container] Forcer la suppression d'un conteneur actif
docker images Lister les images existantes
docker rmi [image] Supprimer une image docker
docker exec -t -i [container] /bin/bash Exécuter des commandes dans un conteneur actif
docker inspect [container] Inspecter la configuration d'un conteneur
docker build -t [image] . Construire une image à partir d'un Dockerfile
docker history [image] Visualiser l'ensemble des couches d'une image
docker logs --tail 5 [container] Visualiser les logs d'un conteneur (les 5 dernières lignes)
CHEAT SHEET - REGISTRY

Commande Description

docker login Se connecter au registry

docker search [name] Rechercher une image

docker pull [image] Récupérer une image

docker push [image] Pouser une image du cache local au registry

docker tag [UUID] [image]:[tag] Tagger une image


FONCTIONNEMENT DES VOLUMES DE STOCKAGE EN CLUSTER

Description:
◼ Pour améliorer la performance et la portabilité d’une infrastructure Swarm il est recommandé de ne
pas stocker les données importantes directement sur la couche d’écriture des conteneurs.
◼ Pour cela il faut utiliser les volumes.
◼ Les volumes sont des espaces de stockages qui peuvent être mappés sur
◼ plusieurs conteneurs/services en même temps.
◼ Docker Swarm met à disposition 3 types de volumes :
◼ Volume Data
◼ Volume Bind
◼ Volume tmpfs
VOLUME DATA
◼ Description :
◼ Le volume de type « data » est la solution de stockage de données la plus utilisée avec Docker Swarm.
◼ C’est le type de stockage par défaut de docker.
◼ Elle offre de nombreux avantages :
◼ Elle n’augmente pas la taille de la couche d’écriture du conteneur.
◼ Cycle de vie indépendant du conteneur/service.
◼ Peut être managé directement via la CLI Docker.
◼ Fonctionne aussi bien sous Linux que Windows.
◼ Facile à déplacer/sauvegarder.
◼ Permet l’utilisation de « volumes driver » pour stocker les données sur des espaces de stockages distants de l’hôte (NFS,
SAMBA, cloud, etc…).
◼ Les volumes docker de type data sont visibles dans le répertoire : /var/
VOLUME BIND

◼ Description :
◼ Le volume de type « bind » consiste à monter un chemin du filesystem de l’hôte directement dans le conteneur.
◼ Ce type de volume est historique à docker, mais il est préférable aujourd’hui d’utiliser les volumes de type « data
».
◼ Ce type de volume ne peut pas être managé via la CLI de Docker et est donc plus difficile à administrer.
◼ Si le chemin du volume « bind » n’existe pas à la création du conteneur, il sera automatiquement créé.
◼ Ce type de volume est dépendant de la structure de répertoire du filesystem.
VOLUME TMPFS

◼ Description :
◼ Ce type de volume permet de stocker de la donnée volatile directement sur la RAM de l’hôte.
◼ Ce type de volume dispose d’une performance très élevée.

◼ Contraintes :
◼ Uniquement disponible sur les hôtes docker Linux.
◼ Le cycle de vie du volume tmpfs est identique à celui du conteneur qui l’utilise.
◼ Un volume tmpfs ne peut être partagé entre plusieurs conteneurs/services.
RÉSUMÉ
RÉSUMÉ
LES VOLUMES DANS DOCKER

◼ Lorsque vous supprimer le conteneur, toutes vos modifications sont perdus car les fichiers sont stockés par
défaut dans ce conteneur

◼ Pour éviter ce problème, il est possible d’utiliser un volume qui sera situé sur la machine hôte

◼ Vous pourrez supprimer le conteneur, et le recréer en conservant vos fichiers modifiés


VOLUMES PERSISTANT DANS DOCKER

◼ Lancer un docker avec un volume persistant :

◼ La commande suivante va permettre à docker d’utiliser le répertoire local


◼ /srv/data/html/ au lieu du répertoire du docker /usr/share/nginx/html/

◼ Docker run -tid -p 8080 :80 -v /srv/data/html/:/usr/share/nginx/html/ --namenginx nginx:latest

◼ Autre manière : créer un volume local directement avec docker :


◼ docker volume create nginxlocal
◼ Pour avoir un résumé de la configuration du volume, taper :
◼ docker volume inspect nginxlocal
◼ Le volume est situé ici : /var/lib/docker/nginxlocal/_data
◼ Installer un conteneur nginx utilisant ce volume :
◼ docker run -tid –name nginx -p 8080:80 –
◼ mountsource=nginxlocal,target=/usr/share/nginx/html nginx:latest
VOLUMES PERSISTANT DANS DOCKER

◼ Tips : Sauvegarder les volumes


◼ Ce n’est pas une pratique très courante mais cela peut être utile.
◼ docker run -tid --name conteneur1 -v volume01:/usr/share/nginx/html/ -p 80:80 nginx
◼ docker volume inspect volume01
◼ Vous aurez le Mountpoint qui vous dira ou est le volume
◼ docker inspect conteneur1
◼ Vous retrouverez l'équivalence entre le conteneur et le volume
◼ On peut faire une sauvegarde tar.gz
◼ Lancer un conteneur de sauvegarde léger type alpine
◼ Monter le volume à sauvegarder volume01:/tmp/src
◼ Monter le volume de destination /tmp/:/tmp/dest
◼ Ajouter la commande de sauvegarde type tar -czvf <dest> <source>
◼ Prévoir la suppression automatique
◼ Se rendre dans le conteneur01 avec docker exec puis aller dans le dossier qui contient index.html et le modifier pour tester
◼ Pour sauvegarder ensuite :
◼ docker run --rm -v volume01:/tmp/src/ -v /tmp/:/tmp/dest -u root alpine tar -czvf /tmp/dest/backup.tar.gz /tmp/src/
LE RÉSEAU DANS DOCKER

◼ Par défaut le réseau utilisé pour tous les conteneurs est le 172.17.0.0/16
◼ Docker assigne une ip automatiquement et dynamiquement dans ce range pour tout conteneur créé.
◼ Attention, si un conteneur redémarre, son ip peut changer.
◼ Par défaut, tous les conteneurs peuvent communiquer entre eux car ils sont créés dans le bridge .
◼ Il est possible de créer ses propres réseaux afin d’isoler les conteneurs entre eux.
◼ Les commandes utiles :
◼ docker network ls => liste les réseaux disponibles
◼ docker inspect monréseau => montre le détail du réseau nommé « monréseau »
◼ docker network create -d bridge –subnet 172.18.0.0/24 monréseau => créé le réseau 172.18.0.0/24 nommé
monréseau
LE RÉSEAU DANS DOCKER

◼ Il existe 8 types de réseau utilisable dans docker


◼ bridge
◼ host
◼ The NONE Network
◼ overlay
◼ user defined bridge
◼ macvlan (bridge)
◼ macvlan (802.1q mode)
◼ IPvlan (Layer 2)
◼ IPvlan (Layer 3)
HOST

◼ Ce type de réseau permet aux


conteneurs d’utiliser la même interface
que l’hôte.
◼ Il supprime l’isolation réseau entre les
conteneurs et seront par défaut
accessibles de l’extérieur. Il prendra
donc la IP que votre machine hôte.
DEFAULT BRIDGE
Sous réseau naté (NAT) sur le réseau normal (hote) - 172.17.0.0
USER DEFINED BRIDGE
Autre réseau bridge, isolé les un des autres
MACVLAN (BRIDGE)

◼ macvlan (bridge mode) - Connecté directement a notre réseau physique, un peu comme une VM - tu
peux lui attribuer une adresse de ton réseau local
◼ Donner son subnet local et gateway (box, routeur) et son parent (l'interface réseau de l'hôte) pour
mapper le reseau macvlan dessus
◼ Issue: Cela distribue une mac address au container et une interface réseau ne peux pas avoir plusieurs
mac sur une interface
◼ Il faut donc accepter le mode promiscuité
◼ ip link set eth0 promisc on
◼ et dans l'hyperviseur (workstation, esxi…)
◼ pas de dhcp - SPECIFIER UNE IP ADDRESS POUR LE CONTAINER POUR EVITER UN CONFLIT AVEC L'IP
DE L'HÔTE (VOIR DOC POUR LES OPTIONS AU DEPLOY)
MACVLAN (BRIDGE)
MACVLAN (802.1Q (TRUNKED))

◼ macvlan (802.1q mode) - Connecté directement a notre réseau physique, un peu comme une VM - tu peux lui
attribuer une adresse de ton réseau local, similaire à macvlan mais avec une notion de VLAN et de sous
interfaces.
◼ Réseau sous forme de vlan : - eth0.20 eth0.30 etc..
◼ Donner son subnet local et gateway (box) et son parent (l'interface réseau de l'hote avec .20 (num du vlan)
eg: eth0.20) pour la mapper dessus
◼ Ce réseau crée au hôte des sous interfaces
◼ docker network create -d macvlan \
◼ --subnet 192.168.20.0/24
◼ --gateway 192.168.20.1 \
◼ -o parent=eth0.20 \
◼ macvlan20
MACVLAN (802.1Q (TRUNKED))
IP VLAN (L2)

◼ Les container vont pouvoir avoir leur propre ip sur notre réseau local mais cette fois en partageant la mac
address de l'hôte
◼ docker network create -d ipvlan \
◼ --subnet 192.168.1.0/24
◼ --gateway 192.168.1.1 \
◼ -o parent=eth0 \
◼ new_ipvlan_network

◼ Puis run un container :


◼ docker run -tid --rm --network new_ipvlan_network \
◼ --ip 192.168.1.4/24
◼ -name container01 busybox
IP VLAN (L2)
IP VLAN (L3)
◼ Le container (le network docker) considère l'host (son ip) comme étant le routeur, donc l'ip du host est la gateway
◼ Nous aurons donc besoin de créer des routes statiques sur l'hôte et/ou routeur pour faire communiquer nos réseaux.
◼ docker network create -d ipvlan \
◼ --subnet 192.168.94.0/24 #le réseau que nous créons
◼ -o parent=eth0 -o ipvlan_mode=l3 \ #pas de gateway car le parent est la gateway
◼ --subnet 192.168.95.0/24 #on fait ça si on veux créer plusieurs réseau sur la même interface
◼ new_ipvlan_network
docker run -tid --rm --network new_ipvlan_network \
--ip 192.168.94.8/24
-name container01 busybox

docker run -tid --rm --network new_ipvlan_network \


--ip 192.168.95.9/24
-name container02 busybox

docker inspect new_ipvlan_network


◼ les container ont pas internet, pas de routes
◼ peut pinger les autres container et par le nom aussi
◼ donc ajouter une vrai route sur le réseau si on veux faire communiquer à l'extérieur
◼ no broadcast traffic
IP VLAN (L3)
NONE (NULL) NETWORK

◼ Il n'y a pas d'IP, juste l'adresse du localhost.


NETWORK COMMAND
## Créer un réseau docker
-f ou --force : forcer la suppression
docker network create --driver <DRIVER TYPE> <NETWORK
NAME>
## Connecter un conteneur à un réseau docker
docker network connect <NETWORK NAME> <CONTAINER NAME>
# Lister les réseaux docker
docker network ls
## Déconnecter un conteneur à réseau docker
docker network disconnect <NETWORK NAME> <CONTAINER
## Supprimer un ou plusieurs réseau(x) docker
NAME>
docker network rm <NETWORK NAME>
-f ou --force : forcer la déconnexion

## Récolter des informations sur un réseau docker


## Démarrer un conteneur et le connecter à un réseau
docker network inspect <NETWORK NAME>
docker
-v ou --verbose : mode verbose pour un meilleur
docker run --network <NETWORK NAME> <IMAGE NAME>
diagnostique

## Supprimer tous les réseaux docker non inutilisés


docker network prune
DOCKER COMMANDS
RUN – PORT MAPPING
DOCKER COMMANDS
RUN – VOLUME MAPPING
DOCKER COMMANDS
INSPECT CONTAINER
[
{
"Id": "8730b5225d46c6ef72c5867072c091dbba7c51789c982bec7a91c588d330da93",
"Created": "2024-08-14T14:04:49.688862999Z",
"Path": "/myapp",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 1996902,
"ExitCode": 0,
"Error": "",
"StartedAt": "2024-08-14T14:04:50.085142712Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:6964e26f2e46c2fa7df2a168af414645c2e051b2bc6549a14026c22a1d4ce381",
"ResolvConfPath":
"/var/lib/docker/containers/8730b5225d46c6ef72c5867072c091dbba7c51789c982bec7a91c588d330da93/resolv.conf",
DOCKER COMMANDS
CONTAINER LOGS
docker logs webapp-container
DOCKER

◼ docker ps : permet de lister les processus


◼ docker ps -a : permet de lister tous les processus docker, même ceux qui sont terminés
◼ docker exec -ti nomduconteneur sh : Se connecter au conteneur en shell

◼ Exemple avec un serveur web, nginx :


◼ docker run -tid -p 8080:80 --name monnginx nginx:latest
◼ /usr/share/nginx/html/index.html
◼ Modifier le contenu et tester

◼ Explication :
◼ Lancer le conteneur nginx, le nommer monnginx, le laisser fonctionner. Rediriger son port 80 sur le 8080 de
notre machine locale

◼ Accéder au paramétrage du conteneur :


◼ docker inspect nom du conteneur (permet de voir l’adressage ip entre autre)
TP 1 - CRÉATION D’UN CONTAINER

Lancez un premier premier container docker, l’image à utiliser devra être « nginx »
Vérifier si votre container est bien fonctionnel à l’aide de la commande « docker ps »
Stoppez votre container
Supprimez votre container et se rassurer qu’il a bien été supprimé.
Supprimer également les volumes qui auront été créé
TP 2 - LES IMAGES

Combien d’images docker existent-ils dans votre machine à ce stade ?


Relancer à nouveau un container docker à l’aide de l’image nginx
Combien de temps cela prend ? Est-ce le même temps que précédemment?
Supprimer l’image nginx de votre machine
Avez-vous pu supprimer la dite images? Pourquoi?
Supprimer le container nginx
Supprimer à nouveau l’image nginx de votre machine
TP 3 - INTÉRACTION AVEC UN CONTAINER

Lancer le container Ubuntu en mode détaché et interactive avec un tag différent de latest
Que constatez vous?
Créez une nouvelle machine dans l’environnement de labs
Dans cette machine, lancez à nouveau le container ubuntu en mode interactive + nouveau terminal
Que constatez vous?
Supprimez les différents containers présent dans votre machine
Lancez le container Ubuntu en mode détaché avec la commande « sleep 4500 »
Utiliser la commande « docker exec » afin d’exécuter une commande à l’intérieur du container (commande de
création d’un dossier portant votre prénom »
Utiliser docker exec afin d’afficher l’ensemble des fichier et répertoire à l’aide de la commande « ls »
Utiliser docker exec et passez la commande « /bin/bash »
Que constatez vous?
Observez et expliquez le comportement de ces différentes commandes puis supprimez vos environnements
TP 4 - COMMANDES

Lancer le container ubuntu


Vérifier que ce container soit bien lancé et qu’il fonctionne correctement
Pourquoi le container s’est-il arreté
Supprimer le container ubuntu
Lancer à nouveau le container ubuntu en mode attach et en passant en paramètre la commande « sleep 100 » Que
constatez vous?
Lancez à nouveau le container ubuntu en mode attach passant la commande « ls » Que constatez vous?
Lancez le container ubuntu en mode détaché avec la commande « sleep 4500 » Observez et expliquez le
comportement de ces différentes commandes
Supprimez l’ensemble des containers présents (fonctionnels ou arrêtés) sur votre machineSupprimez également
les images exisatantes
TP – 5- PORT MAPPING

◼ Lancer le container nginx en mode détaché et en exposant le port 80 du container sur le port 8080 de l’hote
◼ Vérifier le bon fonctionnement de votre container
◼ Vérifier qu’il est bien joignable à travers le port 8080 de votre hote.
◼ Que constatez vous? Quel est le contenu de la page web afficheé?
◼ A l’aide de docker exec, connectez vous à ce container afin de créer un fichier « index.html » dans lequel vous
feriez
◼ une briève présentation de vous
◼ Déplacer ce fichier index.html précédemment créé vers le répertoire « /usr/share/nginx/html» de votre
container
◼ Arrêtez votre container et redémarrez le à nouveau
◼ Essayez à nouveau d’y accéder à travers le port 8080 de votre hote… Que constatez vous?
TP – 6 : OPÉRATIONS ET INSPECTION D’UN CONTAINER

◼ Créez un fichier « index.html » en local sur votre machine contenant les mêmes informations que celui
du TP 5
◼ Lancez le container nginx en l’exposant sur le port 8080 et en ajoutant l’option (-v
./fichier_index.html:/usr/share/nginx/html//index.html)
◼ Vérifier que le container soit bien lancé
◼ Vérifiez que l’application de notre container nginx est bien consommable à partir du port 8080 de
notre hote
◼ Que constatez vous? Quel est le contenu de la page web afficheé?
◼ Supprimer les containers, images et votre environnement.
VARIABLES D’ENVIRONNEMENT
VARIABLES D’ENVIRONNEMENT EN PYTHON
from flask import Flask
from flask import render_template
import socket
import random
import os
import argparse
app = Flask(__name__)
color_codes = {
"red": "#e74c3c",
"green": "#16a085",
"blue": "#2980b9",
"blue2": "#30336b",
"pink": "#be2edd",
"darkblue": "#130f40"
}
SUPPORTED_COLORS = ",".join(color_codes.keys())
# Get color from Environment variable
COLOR_FROM_ENV = os.environ.get('APP_COLOR')
# Generate a random color
COLOR = random.choice(["red", "green", "blue", "blue2",
"darkblue", "pink"])
VARIABLES D’ENVIRONNEMENT
VARIABLES D’ENVIRONNEMENT DANS DOCKER
VARIABLES D’ENVIRONNEMENT
INSPECTER LES VARIABLES D’ENVIRONNEMENT
[
{
◼ docker inspect sweet_thompson "Id": "feeec06f67afb48834ea0854a9a8e849832eb7c8ebf3197f2759b96584f32680",
"Created": "2024-09-17T15:01:59.736801756Z",
"Path": "python",
"Args": [
"app.py"
],
"State": {
"Status": "running",
"Running": true,
[...]
},
[...]
"Name": "/sweet_thompson",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
[...]
},
[...]
},
"Mounts": [],
"Config": {
[...]
"APP_COLOR=green",
[...]
"Cmd": null,
"Image": "vlaine/webapp-color:amd64",
"Volumes": null,
"WorkingDir": "/opt",
"Entrypoint": [
"python",
"app.py"
],
"OnBuild": null,
"Labels": {}
TP – 7 : MANIPULATION VARIABLES D’ENVIRONNEMENT
◼ Lancez le container nginx en l’exposant sur le port 8080 et en ajoutant l’option (-v
./fichier_index.html:/usr/share/nginx/html//index.html)
◼ Lancez le container Ubuntu en mode détaché avec la commande « sleep 4500 »
◼ Utiliser la commande « docker exec » afin d’exécuter une commande à l’intérieur du container
(commande de création d’un dossier portant votre prénom »
◼ Utiliser docker exec afin d’afficher l’ensemble des fichier et répertoire à l’aide de la commande « ls »
◼ Utiliser docker exec et passez la commande « /bin/bash
◼ Lancez un container à partir de l’image vlaine/webapp-color:amd64 en exposant son port 8080 sur le
port 5000 de votre hôte
◼ Connectez vous sur le port 5000 de votre hôte afin de démarrer l’application
◼ Lancez à nouveau un autre container à base de la même image mais cette fois ci en définissant la
variable d’environnement APP_COLOR=red. (exposez sur le port 8000 )
◼ Run l’application. Que constatez vous?
◼ Supprimer votre environnement
DOCKER-COMPOSE

◼ Compose est un outil pour définir et exécuter des applications multi-conteneurs, aussi appelé "stack".
◼ Les conteneurs étant idéaux pour des applications basées sur des micro services, il devient évident que
rapidement on doit faire fasse à l’interconnexion de plusieurs conteneurs et à la gestion de multi-
conteneurs.
◼ Un fichier docker-compose s'écrit avec le langage YAML.
◼ Il se présentera sous la forme docker-compose.yml
◼ Références officiels : https://docs.docker.com/compose/reference/
◼ Il faut parfois l'installer, soit avec votre gestionnaire de paquet, soit avec curl :
◼ sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-
$(uname -m)" -o /usr/bin/docker-compose && sudo chmod +x /usr/bin/docker-compose
◼ Documentation d'installation : https://docs.docker.com/compose/install/#install-compose
DOCKER-COMPOSE

◼ Arguments de docker-compose !
◼ image qui permet de spécifier l'image source pour le conteneur ;
◼ build qui permet de spécifier le Dockerfile source pour créer l'image du conteneur ;
◼ volume qui permet de spécifier les points de montage entre le système hôte et les conteneurs ;
◼ restart qui permet de définir le comportement du conteneur en cas d'arrêt du processus ;
◼ environment qui permet de définir les variables d’environnement
◼ depends_on qui permet de dire que le conteneur dépend d'un autre conteneur ;
◼ ports qui permet de définir les ports disponibles entre la machine host et le conteneur.
DOCKER-COMPOSE

◼ Pour utiliser docker-compose, vous devez d'abord créer un fichier yml, ici quelques exemples de
docker-compose.yml version: "3"
services: services:
version: "3.9" # optional since v1.27.0 webapp: web:
services: image: examples/web image: "apache:${PHP_VERSION}"
web: restart: 'always'
build: .
ports: depends_on:
- mariadb
ports: - "8000:8000" ports:
- "8000:5000" volumes: - '8080:80'
links:
volumes: - .:/code - logvolume01:/var/log - "/data" - mariadb
depends_on: mariadb:
- redis image: "mariadb:${MARIADB_VERSION}"
restart: 'always'
redis: volumes:
image: redis - "/var/lib/mysql/data:${MARIADB_DATA_DIR}"
volumes: - "/var/lib/mysql/logs:${MARIADB_LOG_DIR}"
- /var/docker/mariadb/conf:/etc/mysql
logvolume01: {} environment:
MYSQL_ROOT_PASSWORD:
"${MYSQL_ROOT_PASSWORD}"
MYSQL_DATABASE: "${MYSQL_DATABASE}"
MYSQL_USER: "${MYSQL_USER}"
MYSQL_PASSWORD: "${MYSQL_PASSWORD}"
DOCKER-COMPOSE
version: '3'
services:
db:
image: mysql:5.7
volumes:
◼ Si par exemple vous voulez installer un wordpress - db_data:/var/lib/mysql
restart: always
avec docker-compose (en partant du principe que environment:
vous n'utilisez pas déjà l'image existante sur le hub MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
;) MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
◼ Vous devrez installer une base de donnée et un
wordpress:
serveur web. depends_on:
- db
◼ docker-compose up -d image: wordpress:latest
ports:
- "8000:80"
◼ Puis http://127.0.0.1:8000 pour accéder à votre restart: always
wordpress environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
DOCKER COMPOSE - CHEAT SHEET

Commande Description
docker-compose up -d Démarre un ensemble de conteneurs en arrière-
plan
docker-compose down Stoppe un ensemble de conteneurs
docker-compose exec [service] [command] Exécute une commande au sein d'un service
docker-compose ps Affiche les stacks
docker-compose logs -f --tail 5 Afficher les logs du stack
docker-compose stop Arrêter un stack
docker-compose config Valider la syntaxe de votre fichier docker-compose
TP DOCKER-COMPOSE

◼ Monter une stack LAMP avec docker compose.


◼ LAMP : LINUX APACHE MYSQL PHP
◼ help :
◼ https://linuxconfig.org/how-to-create-a-docker-based-lamp-stack-using-docker-compose-on-ubuntu-18-04-
bionic-beaver-linux
◼ https://connect.ed-diamond.com/Linux-Pratique/lp-111/creer-son-environnement-de-developpement-lamp-
grace-a-docker-compose
◼ https://github.com/sprintcube/docker-compose-lamp
◼ https://cours.brosseau.ovh/tp/docker/docker_compose.html
DOCKER COMPOSE - AVANCÉ
LE MULTI ENVIRONEMENT

◼ Multi-environnement avec Docker Compose

◼ Docker Compose permet de gérer plusieurs environnements : développement, test, production.

◼ Utilisation de fichiers de surcharge :


◼ docker-compose.yml (configuration commune)
◼ docker-compose.override.yml (développement)
◼ docker-compose.prod.yml (production)

◼ Les fichiers sont fusionnés, le dernier écrasant les valeurs du précédent.


DOCKER COMPOSE - AVANCÉ
LE MULTI ENVIRONEMENT

◼ Fichiers de Surcharge

◼ Docker Compose permet d'utiliser plusieurs fichiers de configuration qui se superposent :


◼ docker-compose.yml : le fichier de base contenant la configuration commune.
◼ docker-compose.override.yml : surcharge automatique pour l'environnement de développement (si présent).
◼ Fichiers spécifiques : comme docker-compose.prod.yml, docker-compose.dev.yml, pour des environnements
spécifiques.
◼ docker-compose -f docker-compose.yml -f docker-compose.prod.yml up
DOCKER COMPOSE - AVANCÉ
LE MULTI ENVIRONEMENT

◼ L'idée générale est que vous aller faire votre compose complet avec toutes vos informations et si il se build
bien vous pourrez créer un compose de prod qui va simplement écraser certaines valeures pour les
remplacer et "alléger" la version prod. Exemple avec un service de base de donnée.
services:
postgres:
services:
image: postgres:13
container_name: postgres postgres:
environment: image: postgres:13-alpine
POSTGRES_USER: ${POSTGRES_USER:-$(cat /run/secrets/postgres_user)}
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-$(cat
/run/secrets/postgres_password)} PGDATA: /var/lib/postgresql/data/pgdata
POSTGRES_DB: ${POSTGRES_DB}
secrets:
- postgres_user
- postgres_password
volumes: # cat .env
- postgres-data:/var/lib/postgresql/data
- ./db/init.sql:/docker-entrypoint-initdb.d/init.sql POSTGRES_USER=admin
networks:
- todo-network
POSTGRES_PASSWORD=secret
healthcheck: # cat .env.prod
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s POSTGRES_USER=admin
timeout: 5s
retries: 5
POSTGRES_PASSWORD=supersecret
[…]
VARIABLES D'ENVIRONNEMENT ET INTERPOLATION

◼ Variables d'Environnement et Interpolation

◼ Permettent de paramétrer les services sans modifier le code. services:


◼ Utilisation : fichier .env pour stocker les variables. app:
environment:
- APP_ENV=${APP_ENV}
◼ Exemple d'interpolation : - DEBUG=${DEBUG:-false}

◼ DB_USER=${DB_USER:-default_user}
◼ Si DB_USER n'est pas défini, default_user sera utilisé.
DÉPENDANCES ET HEALTHCHECK

◼ Dépendances et Healthcheck
services:
web:
build: .
◼ depends_on spécifie l'ordre de démarrage
depends_on:
des services.
- db
◼ Ne vérifie pas l'état de santé du service, le db:
service peut avoir démarré mais ne pas être image: postgres
prêt.
healthcheck:
◼ Utiliser healthcheck pour vérifier si un test: ["CMD", "pg_isready", "-U", "postgres"]
service est prêt. interval: 10s
timeout: 5s
◼ Exemple d'un healthcheck :
retries: 3
◼ test: ['CMD', 'pg_isready -U postgres'] start_period: 30s
◼ interval: 30s, retries: 3
DÉPENDANCES ET HEALTHCHECK

services:
web:
build: .
depends_on:
- db
db:
image: postgres
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"] #la commande à exécuter pour vérifier l'état.
interval: 10s #intervalle entre les vérifications.
timeout: 5s #temps maximal pour que la commande s'exécute.
retries: 3 #nombre de tentatives avant de considérer le service comme défaillant.
start_period: 30s #temps d'attente avant de commencer les vérifications.
GESTION DES SECRETS

◼ Gestion des Secrets

◼ Utilisez les secrets pour sécuriser les informations sensibles.


◼ Les secrets sont montés dans les conteneurs sous forme de fichiers dans /run/secrets/.
◼ Exemple dans Docker Compose :
version: '3.8'
◼ secrets:
services:
◼ db_password: db:
image: postgres
secrets:
◼ file: ./secrets/db_password.txt - db_password
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password

secrets:
db_password:
file: ./secrets/db_password.txt
DOCKER IMAGES

◼ Rappel :
◼ container = plusieurs images/couches en lecture seul + couche Copy-On-Write + RUN

◼ IMAGES
◼ Chaque image est en lecture seule
◼ Partage des images entre containers sur le host
◼ Cache des couches de base en mémoire

c1 c2 c3 c4 c5 c6
app-a app-b app-c app-d app-e
websphere-liberty:8.5.5 websphere-liberty:beta c7 c8
= container
ibm-jre:8.0 mongo:latest
ubuntu:14.04 debian:wheezy = image

bootfs (Kernel)
DOCKER IMAGES - WORKFLOW D'UNE IMAGE
DOCKER IMAGES - WORKFLOW D'UNE IMAGE

• Lecture seule
• Réutilisation
• Couche (Layer)
DOCKER FILE

◼ Rappel :
◼ Docker file permet de créer une image
◼ FROM : Os de base Ubuntu / Alpine…
◼ Chaque commande créé une nouvelle couche
DOCKER FILE - CRÉER SON IMAGE
COMMENT CRÉER SA PROPRE IMAGE DOCKER
DOCKERFILE : ARCHITECTURE EN COUCHES
COMMENT CRÉER SA PROPRE IMAGE DOCKER
DOCKERBUILD : OUTPUT
DOCKERFILE - INSTRUCTIONS

1. FROM
8. ADD
1. Image parente
1. Ajoute un fichier dans l'image
2. LABEL
9. COPY
1. Ajout de métadonnées
1. Ajoute un fichier dans l'image
3. RUN
10. ENTRYPOINT
1. Commande(s) utilisée(s) pour construire l'image
1. Exécuter une commande au démarrage du conteneur
4. ENV
11. WORKDIR
1. Variable d'environnement
1. Permet de changer le chemin courant (cd tier)
5. CMD
12. VOLUME
1. Exécuter une commande au démarrage du conteneur
1. Crée un point de montage
6. EXPOSE
13. USER
1. Port(s) écouté(s) par le conteneur
1. Nom d'utilisateur ou UID à utiliser
7. ARG
14. ONBUILD
1. Variables passées comme paramètres à la construction de
l'image 1. Instructions exécutées lors de la construction d'images
enfants
COPY VS ADD

◼ COPY et ADD sont les deux instructions qui servent à des fins similaires. Ils vous permettent de copier des fichiers d'un
emplacement spécifique dans une image Docker.

◼ COPY prend un src et une destination . Il vous permet uniquement de copier dans un fichier ou un répertoire local de
votre hôte (la machine créant l'image Docker) dans l'image Docker elle-même.

◼ ADD vous permet de le faire aussi, mais il prend également en charge 2 autres sources. Tout d'abord, vous pouvez
utiliser une URL au lieu d'un fichier/répertoire local. Deuxièmement, vous pouvez extraire un fichier tar de la source
directement dans la destination.
◼ Dans la plupart des cas, si vous utilisez une URL, vous téléchargez un fichier zip et utilisez ensuite la RUN commande
pour l'extraire.
◼ Cependant, vous pouvez tout aussi bien utiliser RUN avec curl au lieu d' ADD afin de tout enchaîner en une seule RUN
pour créer une image Docker plus petite.

◼ Un cas d'utilisation valide pour ADD est lorsque vous souhaitez extraire un fichier tar local dans un répertoire
spécifique de votre image Docker. C'est exactement ce que fait l'image Alpine ADD rootfs.tar.gz / .

◼ Si vous copiez des fichiers locaux sur votre image Docker, utilisez toujours COPY car c'est plus explicite.
DOCKERFILE - CRÉER UNE IMAGE

◼ Un dockerfile est un fichier de configuration qui à pour objectif de créer une image.
◼ Nous y retrouverons une séquence d'instruction
◼ FROM : Sur quelle image on se base
◼ ENV : variables d'environnement
◼ EXPOSE : exposer le port du conteneur
◼ VOLUME : Définition des volumes
◼ COPY : cp entre host et conteneur
◼ ENTRYPOINT : processus maitre, car l'idée d'un conteneur est d'avoir un seul process qui tourne
DOCKERFILE - CRÉER UNE IMAGE

◼ L' intérêt d'un dockefile est de relancer une création d'image à tout moment
◼ Meilleure visibilité sur ce qui est fait
◼ Partage facile et possibilité de gitter
◼ Script d'édition de docker file (variables...)
◼ Ne pas se poser de question lors du docker run du conteneur
◼ Création images prod // dev - CI // CD (continuous integration/deployment)
DOCKERFILE - CRÉER UNE IMAGE

◼ FROM ubuntu:latest
◼ MAINTAINER vincent
◼ RUN apt-get update \
◼ && apt-get install -y vim git \
◼ && apt-get clean \
◼ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

◼ docker build -t nomimage:version .


◼ -t nom de l'image
◼ Ne pas oublier le "." qui symbolise le dockerfile
DOCKERFILE - CRÉER UNE IMAGE

◼ docker images
◼ Voir vos images

◼ docker history monimage:v1.0


◼ Voir les séquences joués dans une image

◼ docker run -tid --name test01 monimage:v1.0


◼ docker exec -ti test01 sh
◼ Nous vérifions que git et vim sont installés.

◼ Pour supprimer votre image, d'abord on supprime le conteneur


◼ docker rm -f test01
◼ docker rmi monimage:v1.0
DOCKERFILE – PACKAGING D’UNE APP- MULTI-STAGE BUILD
(TOUTES CES INSTRUCTIONS DANS UN DOCKERFILE)
◼ FROM alpine/git as clone ◼ Depuis l’image avec comme nom clone
◼ WORKDIR /app
◼ On va dans le dossier /app (répertoire de travail)
◼ RUN git clone https://github.com/XXXXXXXXXXXX
◼ On fait une git clone dans le workdir

◼ FROM truc/truc as build ◼ Depuis l’image avec comme nom clone


◼ WORKDIR /app ◼ On va dans le dossier /app (répertoire de travail)
◼ COPY --from=clone /app/helloworld ◼ Depuis l’image clone, monte le /app/helloworld dans le /app de l’image
/app
truc/truc
◼ RUN truc package
◼ Packager l’application

◼ FROM tomcat, cette partie sera l’image final donc pas


◼ FROM tomcat
besoin du « as »
◼ COPY –from=build /app/target/helloworld.sh
◼ Ensuite depuis l’image build tu récupère les
/usr/local/webapps/ROOT
dossiers/fichiers nécessaires dans le dossier de tomcat
◼ COPY –from=build /app/target/helloworld/ /usr/local/webapps/ROOT pour avoir l’appli
◼ EXPOSE 8080 ◼ Puis on expose sur le port 8080
DOCKERFILE : ENTRYPOINT VS CMD

◼ Entrypoint est le processus principal sur lequel va tourner le conteneur qui va permettre de lancer l'image.
◼ CMD est la commande par défaut (arguments/paramètres par défaut)
◼ CMD seule remplace l'entrypoint
FROM alpine
MAINTAINER Vincent
CMD ["ping", "--help"]
◼ Mais ne prend pas les arguments passés en CLI.
◼ Si docker run --rm demo google.fr
◼ Vous aurez un message d'erreur car le CMD ne fera la distinction entre paramètre et process.
FROM alpine
MAINTAINER Vincent
ENTRYPOINT ["ping", "--help"]
◼ docker build -t demo -f Dockerfile .
◼ docker run --rm demo
◼ La commande passe puis en passant docker run --rm demo google.fr, vous ne chargerez pas le container.
DOCKERFILE : ENTRYPOINT VS CMD

FROM alpine
MAINTAINER Vincent
CMD ["--help"]
ENTRYPOINT ["ping"]
◼ docker build -t demo -f Dockerfile .
◼ docker run --rm demo google.fr
◼ La commande passe puis en passant docker run --rm demo google.fr.
◼ On précise le paramètre par défaut dans le CMD et le process dans le entrypoint !
TP : CRÉEZ VOTRE PREMIÈRE IMAGE

◼ Il s’agit ici de créer une image docker afin de conteneuriser une application web statique,
◼ Télécharger les fichiers de l’application à l’aide de git clone « https://github.com/sadofrazer/static-
website-example.git »
◼ conteneuriser cette application à l’aide de l’image de base nginx.
◼ Il s’agit ici de créer une image docker afin de conteneuriser une application web statique,

Faire une V2
◼ conteneuriser cette application sans télécharger les fichiers au préalable en local à l’aide de l’image de
base ubuntu.
◼ Fichiers de l’application se trouvant dans le repo : https://github.com/daviddias/static-webpage-
example.git
MEILLEURES PRATIQUES DANS LA CRÉATION DES IMAGES
◼ Points d’attention :
◼ Les conteneurs créés par l’image doivent être le plus « stateless » possible.
◼ Build context
◼ Use a .dockerignore file
◼ Use multi-stage builds
◼ Gestion des paquets
◼ Chaque conteneur doit avoir une utilité précise.
◼ Minimize the number of layers
◼ Sort multi-line arguments
◼ Build cache
BUILD CONTEXT

◼ Description :
◼ Lorsque l’on utilise la commande « docker build », le daemon docker créé un « context » qui contient tous les
fichiers et dossiers du répertoire contenant le fichier « Dockerfile ».
◼ Lors de la création de l’image, tous les dossiers et fichiers contenus dans le « build context » sont envoyés au
daemon docker, même si ils ne sont pas nécessaires à la création de l’image.
◼ Plus le « Build Context » est volumineux, plus la charge de travail du daemon docker pour créer l’image sera
importante !
◼ Meilleure pratique :
◼ Il est donc nécessaire de s’assurer que seuls les fichiers réellement indispensables à la création de l’image sont
dans le « Build Context ».
LE RÔLE DU DÉMON DOCKER

◼ Le démon Docker utilise le build context pour :


◼ Trouver le Dockerfile.
◼ Accéder aux fichiers nécessaires (COPY, ADD).
◼ Transférer ces fichiers au démon (local ou distant).
TRANSFERT DE FICHIERS ET TAILLE

◼ Docker transfère les fichiers du build context vers le démon Docker dans un dossier temporaire.
◼ Plus le build context est volumineux, plus le transfert sera long.
◼ Utilisez .dockerignore pour exclure les fichiers inutiles et réduire la taille.
SPÉCIFIER LE CONTEXTE DE BUILD

◼ Utilisez docker build <chemin> pour indiquer le contexte de build.


◼ Exemple : docker build . ou docker build /chemin/vers/projet.
◼ Utilisez -f pour spécifier un Dockerfile ailleurs que dans la racine du contexte de build.
BUILD CACHE ET BONNES PRATIQUES

◼ Docker met en cache chaque couche de build pour accélérer les reconstructions.
◼ Combinez des instructions RUN (ex : RUN apt update && apt install ...) pour éviter les problèmes de
cache.
◼ Placez les instructions COPY des fichiers changeants en fin de Dockerfile.
BUILD CACHE ET BONNES PRATIQUES

◼ Docker met en cache chaque couche de build pour accélérer les reconstructions.
◼ Combinez des instructions RUN (ex : RUN apt update && apt install ...) pour éviter les problèmes de
cache.
◼ Placez les instructions COPY des fichiers changeants en fin de Dockerfile.

◼ Cache valide : Si une couche est identique (même instruction, mêmes fichiers copiés), Docker la
réutilise directement, accélérant ainsi la construction.
◼ Cache invalidé : Si une instruction ou un fichier a changé, la couche et toutes celles qui la suivent sont
reconstruites.
BUILD CACHE ET BONNES PRATIQUES

◼ Si vous modifiez uniquement un fichier Python de votre application, seule la dernière couche (COPY . .)
sera reconstruite, les autres étant réutilisées du cache.

FROM python:3.9-slim-buster

WORKDIR /app

COPY requirements.txt requirements.txt


RUN pip3 install -r requirements.txt

COPY . .

CMD ["flask", "run", "--host=0.0.0.0"]


BUILD CACHE ET BONNES PRATIQUES

Attention aux pièges du cache


◼ RUN apt update
◼ RUN apt install ...
◼ Si vous modifiez la liste des paquets à installer, apt update ne sera pas ré-exécuté, ce qui peut causer des problèmes
si de nouveaux paquets sont disponibles.

◼ Solution : le cache busting : Combinez les commandes en une seule instruction : RUN apt update && apt
install ....
◼ Ainsi, toute modification de la liste des paquets invalidera le cache et forcera la ré-exécution de apt update.
BONNES PRATIQUES : ORGANISEZ VOTRE DOCKERFILE

◼ Ordre des instructions :


◼ Placez les instructions les moins susceptibles de changer en haut du Dockerfile.
◼ Les instructions COPY de votre code source, qui changent fréquemment, doivent être placées vers la fin.

◼ Cache busting :
◼ Combinez les instructions liées, comme apt update && apt install, pour éviter les problèmes de cache.
◼ Triez les paquets par ordre alphabétique dans apt install pour faciliter la comparaison lors des reconstructions.

◼ Versions spécifiques :
◼ Fixez les versions des paquets (RUN pip3 install flask==2.0.2) pour éviter les changements inattendus liés aux
mises à jour.
BONNES PRATIQUES : ORGANISEZ VOTRE DOCKERFILE
FROM python:3.9-slim-buster

FROM python:3.9-slim-buster # peu fréquente


RUN apt update && apt install -y \
WORKDIR /app curl \
RUN apt update git \
wget
RUN apt install -y curl git wget -y

COPY . .
VS WORKDIR /app/

# occasionnellement
COPY requirements.txt requirements.txt COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt RUN pip3 install -r requirements.txt --no-cache-dir

CMD ["flask", "run", "--host=0.0.0.0"] # change fréquemment


COPY ./app/app.py ./myapp

CMD ["python ./myapp/app.py"]


.DOCKERIGNORE FILE

◼ Description:
◼ Le fichier caché « .dockerignore » doit être placé dans le même répertoire que le fichier « Dockerfile ».
◼ C’est l'équivalent d’un « .gitignore » pour Git.
◼ Il permet « d’ignorer » les fichiers présent dans le « context » qui ne sont pas nécessaire à la création de l’image.
◼ Ce fichier permet ainsi de créer les images plus rapidement et de diminuer la charge de travail envoyée au
daemon Docker.
GESTION DES PAQUETS

◼ Description :
◼ La gestion des paquets lors de la création des images est capitale pour diminuer la taille de l’image et pour
éviter les problèmes de paquets corrompus.
◼ Il faut installer dans l’image uniquement les paquets strictement nécessaires au bon fonctionnement de
l’application. Cela peut paraître évident, mais il n’est hélas pas rare de voir des images avec des paquets inutiles
!
◼ Une version doit systématiquement être indiquée pour chaque paquet à installer dans l’image pour éviter de
créer des images avec des paquets en version « latest » qui pourrait être corrompues, ou non supportés par
l’application les utilisant.
CHAQUE CONTENEUR DOIT AVOIR UNE UTILITÉ PRÉCISE.

◼ Description:
◼ Chaque conteneur doit avoir une fonctionnalité bien précise.
◼ Segmenter une application en plusieurs « processus » permet d’améliorer la scalabilité horizontale de
l’application et favorise la réutilisation des images de conteneurs.
GESTION DES COUCHES

◼ Description
◼ Docker stocke les images par layer.
◼ Si une même couche est présente sur différentes images, la couche n’est pas dupliquée sur le disque du node.
◼ En suivant ce principe de déduplication des couches en mémoire, il est recommandé de construire les images
dockers en ordonnant les couches, de la moins fréquemment changée à la plus fréquemment changée.
◼ Cela permet ainsi de drastiquement l’espace de disque utilisé par les images.

◼ Eléments à prendre en compte :


◼ Dans le Dockerfile, seules les instructions « ADD », « COPY » et « RUN » ajoutent des couches à l’image.
◼ Toutes les autres instructions ajoutent des couches temporaires qui n’augmentent pas la taille de l’image finale.

◼ Outils intéressant à prendre en compte pour gérer les couche : dive (téléchargeable en amont)
SORT MULTI-LINE ARGUMENTS

◼ Description :
◼ Lorsque c’est possible, arrangez le Dockerfile pour avoir les instructions
◼ les plus petites possible. Cela peut se faire en ayant recours au symbole « \ » avant de faire un retour à la ligne.
◼ Si vous devez installer plusieurs paquets, utilisez le « multi-ligne » pour installer tous les paquets par ordre
alphabétique avec une seule commande RUN.
◼ Cela permet de faciliter les mises à jour et les relectures du Dockerfile par la suite.
◼ Exemple :
BUILD CACHE

◼ Description :
◼ Par défaut, lors de la création d’une image, Docker vas chercher dans son cache local si il y a déjà des couches
utilisables pour la nouvelle image à construire.
◼ L’utilisation du cache d’image Docker permet de construire plus rapidement les images.
◼ Il est possible de désactiver l’utilisation du cache d’images docker en ajoutant l’argument « --no-cache=true » à la
commande « docker build ».
GÉRER LES VARIABLES AU SEIN DES IMAGES

◼ Objectifs:
◼ Il est parfois nécessaire de variabiliser les fichiers nécessaires à la création d’une image. (Par exemple pour
indiquer une base de données postgresql , ou un Bucket Amazon à une application).
◼ Cela permet de personnaliser des images Docker construites en se basant sur les mêmes fichiers source /
Dockerfile.
◼ La technique la plus utilisée est la suivante :
◼ Créer sur l’hôte docker des variables d’environnements.
◼ Appeler ces variables d’environnement dans les fichiers sources / Dockerfile via : ${VARIABLE}

◼ En général, ces variables d’environnement servent à définir les variables déclarées dans les
instructions « ENV » et « ARG » des Dockerfile.
OPTIMISATION DES IMAGES DOCKER
BASE IMAGE VS PARENT IMAGE DANS DOCKER

◼ Les termes Base Image et Parent Image dans Docker désignent les images utilisées dans un Dockerfile,
mais elles ont des rôles différents.
PARENT IMAGE

◼ Une Parent Image est l'image à partir de laquelle un Dockerfile commence. Exemple :
◼ FROM httpd
◼ httpd est une Parent Image, mais elle est elle-même basée sur Debian, qui est une autre Parent Image.
BASE IMAGE

◼ Une Base Image ne dérive d'aucune autre image. Elle est souvent créée from scratch, ce qui signifie
qu'elle part de zéro sans système d'exploitation.
FROM scratch
ADD rootfs.tar.xz /
DIFFÉRENCE ENTRE PARENT IMAGE ET BASE IMAGE

◼ Parent Image : Une image utilisée comme base dans un Dockerfile, mais qui dérive souvent d'une autre
image.
◼ Base Image : Une image construite à partir de scratch sans dépendance à d'autres images.
◼ Exemple : httpd est une Parent Image basée sur Debian, qui est une Base Image.
EXEMPLES CONCRETS

◼ MongoDB : Utilise Ubuntu comme Parent Image, qui est elle-même basée sur scratch.
◼ WordPress : Utilise PHP comme Parent Image, qui utilise Debian, basé sur scratch.
QU'EST-CE QUE L'IMAGE SCRATCH ?

◼ scratch est une image spéciale dans Docker, une image vide de base. Elle est utilisée pour créer des
systèmes minimaux, comme Debian.
◼ On part de zéro et on ajoute seulement les fichiers nécessaires.
CRÉATION D'UNE IMAGE À PARTIR DE SCRATCH

◼ Dockerfile utilisant scratch :


◼ FROM scratch
◼ ADD rootfs.tar.xz /
◼ CMD ["/bin/bash"]
◼ Cela ajoute le système de fichiers minimal Debian à l'image.
OÙ TROUVER DES IMAGES MINIMALES ?

◼ Bien qu'il soit possible de partir de scratch, de nombreuses images minimales, comme Alpine ou
Debian, sont disponibles sur Docker Hub. Ces images sont optimisées pour être petites tout en étant
fonctionnelles.
RÉSUMÉ

◼ Parent Image : Image à partir de laquelle une autre image est construite, ex : httpd basé sur Debian.
◼ Base Image : Image qui ne dépend d'aucune autre image, ex : scratch.
◼ scratch : Image vide minimale utilisée pour créer des systèmes comme Debian.
BUILD MULTISTAGE
PRÉSENTATION
MULTI-STAGE BUILD

◼ Description :
◼ Le « multi-stage builds » est une nouvelle façon de construire les images de conteneurs applicatifs apportés avec
la version 17.05 de Docker.
◼ Cette technique est la plus puissante pour réduire drastiquement la taille d’une image docker.
◼ Le principe est d’utiliser un « Dockerfile » qui aura deux parties.
◼ La première partie déclare une image « intermédiaire » et qui sert à construire l’application.
◼ La deuxième partie déclare une image « minimaliste » (souvent from « scratch », qui est l’image la plus petite possible), et qui
exécute l’application compilée lors de la première partie.
◼ Il y a donc deux fois l’instruction « FROM » dans le Dockerfile.

◼ Au final on obtient une image minimaliste parfaitement fonctionnelle et ne contient que notre application.
BUILD MULTISTAGE
CAS D’UTILISATION
BUILD MULTISTAGE
EXEMPLE D’UTILISATION
DOCKERFILE – PACKAGING D’UNE APP- MULTI-STAGE BUILD
(TOUTES CES INSTRUCTIONS DANS UN DOCKERFILE)
◼ FROM alpine/git as clone ◼ Depuis l’image avec comme nom clone
◼ WORKDIR /app
◼ On va dans le dossier /app (répertoire de travail)
◼ RUN git clone https://github.com/XXXXXXXXXXXX
◼ On fait une git clone dans le workdir

◼ FROM truc/truc as build


◼ Depuis l’image avec comme nom clone
◼ WORKDIR /app
◼ On va dans le dossier /app (répertoire de travail)
◼ COPY --from=clone /app/helloworld
/app ◼ Depuis l’image clone, monte le /app/helloworld dans le /app de l’image
truc/truc
◼ RUN truc package
◼ Packager l’application
◼ FROM tomcat
◼ FROM tomcat, cette partie sera l’image final donc pas
◼ COPY –from=build /app/target/helloworld.sh
besoin du « as »
/usr/local/webapps/ROOT
◼ Ensuite depuis l’image build tu récupère les
◼ COPY –from=build /app/target/helloworld/ dossiers/fichiers nécessaires dans le dossier de tomcat
/usr/local/webapps/ROOT pour avoir l’appli
◼ EXPOSE 8080 ◼ Puis on expose sur le port 8080
BUILD MULTISTAGE
EXEMPLE D’UTILISATION

# Etape 1 : Construction FROM nginx:1.24 AS local_nginx


FROM golang:1.16-alpine AS builder
WORKDIR /app FROM alpine:3.17.3 AS x2
COPY . . RUN echo "hello world" > /var/test.txt
RUN go build -o myapp COPY --from=local_nginx /etc/nginx/nginx.conf /etc

# Etape 2 : Image finale # Ou alors


FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/myapp . FROM alpine:3.17.3 AS x2
EXPOSE 8080 RUN echo "hello world" > /var/test.txt
CMD ["./myapp"] COPY --from=nginx:1.24 /etc/nginx/nginx.conf /etc
BUILD MULTISTAGE
EXEMPLE D’UTILISATION (SCRATCH)

FROM golang:1.16-alpine AS builder


WORKDIR /app WORKDIR /app
COPY go.mod ./ COPY app/ .
RUN go mod download RUN go mod init myapp
COPY . . RUN go env -w CGO_ENABLED=0
RUN CGO_ENABLED=0 GOOS=linux go build -a - GOOS=linux GOARCH=amd64
installsuffix cgo -o app . RUN go build -o myapp .

FROM scratch #alpine:3.17.3 # Etape 2 : Image finale


COPY --from=builder /app/app /app/app FROM scratch
WORKDIR /app WORKDIR /app
EXPOSE 8080 COPY --from=builder /app/myapp
CMD ["./app"] /myapp
USER 1000
EXPOSE 9090
CMD ["/myapp"]
BUILD MULTISTAGE
EXEMPLE D’UTILISATION (SCRATCH) OPTIMISATION ET SÉCURITÉ
# Etape 1 : Download FROM golang:1.16-alpine AS builder
FROM alpine:latest AS git WORKDIR /app
RUN apk add --no-cache git COPY app/ .
RUN git clone https://github.com/vlaine5/mygoapp.git
RUN go mod init myapp
# Etape 1 : Construction RUN go env -w CGO_ENABLED=0
FROM golang:1.16-alpine AS builder GOOS=linux GOARCH=amd64
WORKDIR /app
COPY --from=git /mygoapp ./ RUN go build -o myapp .
RUN go mod init mygoapp
RUN go env -w CGO_ENABLED=0 GOOS=linux GOARCH=arm # Etape 2 : Image finale
RUN go build -a -installsuffix cgo -o myapp .
FROM scratch
# Etape 2 : Image finale WORKDIR /app
FROM scratch COPY --from=builder /app/myapp
COPY --from=builder /app/myapp /myapp
WORKDIR /app /myapp
EXPOSE 8080 EXPOSE 9090
CMD ["/myapp"] CMD ["/myapp"]
BUILD MULTISTAGE
EXEMPLE D’UTILISATION (SCRATCH) BRANCHES
ARG TYPE=development # Production branch
# Etape 1 : Download FROM scratch AS branch-version-production
FROM alpine:latest AS git ENV ENV=production
RUN apk add --no-cache git WORKDIR /app
RUN git clone
https://github.com/vlaine5/mygoapp.git COPY --from=base /app/myapp /myapp

# Etape 2 : Construction # Final


FROM golang:1.16-alpine AS base
WORKDIR /app FROM branch-version-${TYPE} AS final
COPY --from=git /mygoapp ./ WORKDIR /app
RUN go mod init mygoapp EXPOSE 8080
RUN go env -w CGO_ENABLED=0 GOOS=linux
GOARCH=arm CMD ["/myapp"]
RUN go build -a -installsuffix cgo -o myapp .
# Development branch docker build -t my-go-app-prod --build-arg
FROM base AS branch-version-development
COPY --from=base /app/myapp /myapp TYPE=production .
ENV ENV=development docker build -t my-go-app-dev --build-arg
WORKDIR /app TYPE=development .
BUILD MULTISTAGE
EXEMPLE D’UTILISATION
TP – 19 : CRÉATION D’IMAGES DOCKER

◼ Utiliser le build multistage avec 3 stages afin de conteneuriser l’application précédente dans le but de
réduire la taille finale de notre image.
◼ Nous devons avoir 03 stages, le premier nous permettant de récupérer les fichiers source avec comme
base, le second stage nous permettant d’e build notre app à et le troisième de le deployer from scratch
◼ Tagger vos images
◼ Pushez les sur votre registry
TAG / PUSH / PULL

◼ docker tag <imagesource>:<version> <imagedest>:<version>


◼ Sert à donner un tag à son image, pour y ajouter la version latest qui est par defaut par exemple
FROM alpine:latest
LABEL maintener vincent
◼ Puis docker-build –t myalpine:v1.0
◼ Docker images ls
◼ On a maintenant une image myalpine en v1.0
◼ Docker run –ti myalpine
◼ Il ne la trouve pas car il n’y a pas de tag latest
◼ Docker tag myalpine:v1.0 myalpine:latest
◼ On a maintenant une image mais avec 2 tags, v1.0 et latest
◼ Docker run –ti myalpine
TAG / PUSH / PULL
◼ Docker login
◼ Indiquer login/mdp de docker Hub
◼ Docker login <chemin_du_registre>
◼ Pour se connecter à un autre registre
◼ Docker push <regsitre>/<nomimage>:version
◼ Docker pull <regsitre>/<nomimage>:version
◼ Docker push myalpine:latest
◼ Si vous êtes sur un autre repository, vous devrez tag votre image avec le lien complet du regsitre :
◼ Docker tag myalpine:v2.0 registry.gitlab.com/vlne/docker/myalpine:v2.0
◼ Docker push registry.gitlab.com/vlne/docker/myalpine:v2.0
◼ Docker tag myalpine:v2.0 registry.gitlab.com/vlne/docker/myalpine:latest
◼ Docker push registry.gitlab.com/vlne/docker/myalpine:latest
CRÉER UNE IMAGE AVEC UN CONTENEUR

◼ Vous avez chargé un conteneur nginx qui s'appelle test01 par exemple.
◼ Vous avez deux images, ubuntu et nginx.
◼ Vous ajouter ensuite avec docker exec ce que vous souhaitez sur votre conteneur.
◼ exemple : apt install vim git dans votre conteneur
◼ Le but est de personnalisé et commiter le conteneur pour le transformer en image.
◼ L'inconvéniant c'est que si vous voulez recréer votre image vous serez obligé de tout refaire à la main a
contrario du dockerfile.
◼ docker ps, vous récupérez votre id
◼ Puis docker commit -m "Création de mon image" b676fr7qz6t7 vincent:v1.0
◼ Puis vérifier avec docker images, vous devrez la trouver
◼ docker run -tid --name imgvincent vincent:v1.0
◼ Le conteneur est créé, vous pouvez vous y connecter pour vérifier.
◼ docker history b676fr7qz6t7 pour voir les séquences déroulées dans notre création d'image.
CRÉER SA REGISTRY PRIVÉE

◼ Pour créer sa registry vous aurez besoin d'un certificat, de l'image associé, et de stockage.

openssl req -x509 -newkey rsa:4096 -nodes -keyout registryvlne.key -out registryvlne.crt -
days 365 -subj /CN=registry.vlne.fr

sudo certbot certonly --standalone -d registry.vlne.fr --cert-name registryvlne --emai


[email protected] --agree-tos
CRÉER SA REGISTRY PRIVÉE
◼ Il faut ensuite générer un fichier de mot de passe puis lancer un compose permettant de monter sa
resgitry.
docker run --entrypoint htpasswd httpd:2 -Bbn testuser testpassword > auth/htpasswd
version: '3.8'
services:
registry:
restart: always
image: registry:2
container_name: registry
ports:
- 5000:5000
environment:
REGISTRY_HTTP_TLS_CERTIFICATE: /certs/bundle.pem
REGISTRY_HTTP_TLS_KEY: /certs/privkey.pem
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
volumes:
- ./registry/data:/var/lib/registry
- ./registry/certs:/certs
- ./registry/auth:/auth
networks:
- registry

networks:
registry:
driver: bridge
CRÉER SA REGISTRY PRIVÉE

◼ Se connecter à sa registry avec


docker login registry.vlne.fr:5000
Username: vlne
Password:
WARNING! Your password will be stored unencrypted in /home/pi/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credential-stores
Login Succeeded
CRÉER SA REGISTRY PRIVÉE

◼ Puis vous verrez votre mot de passe hashé dans config.json


# cat /home/user/.docker/config.json
{
"auths": {
"https://index.docker.io/v1/":
{
"auth": "MOT DE PASSE"
},
"registry.vlne.fr:5000": {
"auth": "MOT DE PASSE"
}
}
SÉCURITÉ DOCKER
SÉCURISER LE DAEMON

Problèmes si quelqu'un accède au daemon Docker :


◼ Suppression des conteneurs : Toute personne ayant accès au daemon peut supprimer des conteneurs
existants, impactant les utilisateurs.
◼ Perte de données : Si les données d’application sont stockées sous forme de volumes Docker, elles
peuvent être supprimées, causant une perte de données.
◼ Utilisation malveillante : Une personne peut exécuter des conteneurs pour des tâches malveillantes,
comme du minage de bitcoin.
◼ Accès root : Avec un conteneur privilégié, l'attaquant peut obtenir un accès root sur le système hôte et
compromettre l’infrastructure réseau.

Accès au daemon Docker :


◼ Par défaut, Docker expose son daemon uniquement via un socket Unix, accessible uniquement à partir
de l’hôte. Cela empêche tout accès externe au daemon Docker.
SÉCURITÉ DOCKER
SÉCURISER L'HÔTE

◼ Sécurisation de l’hôte Docker :


◼ Première étape : sécuriser l’hôte Docker en suivant les meilleures pratiques de sécurité des serveurs :

◼ Contrôler les utilisateurs ayant accès à l’hôte.


◼ Désactiver l’authentification par mot de passe.
◼ Utiliser des clés SSH.
◼ Désactiver les ports inutilisés.
SÉCURITÉ DOCKER
ACCÈS EXTERNE AU DAEMON

Accès externe au daemon :


◼ Dans certains cas, il peut être nécessaire d’autoriser un accès externe au daemon (pour la gestion à
distance ou l'intégration d'outils). Cela se fait via le fichier /etc/docker/daemon.json en ajoutant l'option hosts.
Cependant, cet accès doit être limité :
◼ Utiliser des interfaces privées, uniquement accessibles depuis l’organisation.
◼ Ne jamais exposer le daemon sur une interface publique.
◼ Exemple de configuration du fichier daemon.json pour autoriser l'accès externe :
{
"hosts": ["unix:///var/run/docker.sock", "tcp://192.168.1.100:2376"]
}
◼ Ici, on permet l’accès via une IP privée (192.168.1.100), tout en maintenant le socket Unix pour les
connexions locales.
SÉCURITÉ DOCKER
ACCÈS VIA TLS

◼ Pour sécuriser l'accès externe, il faut utiliser des


certificats TLS. Voici comment faire :
{
"tls": true,
◼ Créer une autorité de certification (CA). "tlsverify": true,
◼ Générer des certificats pour le serveur (server.pem "tlscacert": "/etc/docker/ca.pem",
et server-key.pem). "tlscert": "/etc/docker/server-cert.pem",
"tlskey": "/etc/docker/server-key.pem",
◼ Configurer le fichier daemon.json pour lire ces
"hosts": ["unix:///var/run/docker.sock",
certificats et activer TLS. "tcp://192.168.1.100:2376"]
}
◼ Avec cette configuration, Docker écoute désormais
sur le port 2376 (port sécurisé avec TLS), et l’accès
non chiffré via le port 2375 est désactivé.
◼ Pour accéder au daemon Docker depuis l’extérieur avec TLS activé, tu dois configurer l'environnement
Docker du côté client.

export DOCKER_HOST=tcp://192.168.1.100:2376
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH=/path/to/certs
◼ Authentification par certificats :

◼ Configurer le fichier daemon.json avec l'option TLS verify pour vérifier les certificats clients.
◼ Générer des certificats pour les clients (client.pem et client-key.pem) et les partager de manière sécurisée
avec les machines clientes.
openssl req -newkey rsa:4096 -nodes -keyout client-key.pem -x509 -days 365 -out client-cert.pem -subj "/CN=client"

◼ Sur le client :

export DOCKER_TLS_VERIFY=1
export DOCKER_HOST=tcp://192.168.1.100:2376
export DOCKER_CERT_PATH=/path/to/certs
◼ Sécurisation de l'hôte Docker :
◼ Restreindre l'accès à l'hôte via SSH.
◼ Désactiver les ports inutiles.
◼ Accès externe au daemon Docker :
◼ Si nécessaire, ajouter l'option hosts dans le fichier daemon.json pour permettre l'accès via une IP privée.
◼ Sécurisation avec TLS :

◼ Utiliser tls et tlsverify dans le fichier daemon.json pour activer la communication chiffrée.
◼ Authentification par certificats :

◼ Générer des certificats pour le client et le serveur.


◼ Activer tlsverify pour forcer l'authentification des clients.
SÉCURITÉ DES NAMESPACES

◼ Isolation avec les namespaces dans Docker


◼ Namespaces : Docker utilise les espaces de noms Linux pour isoler les conteneurs les uns des autres et
de l'hôte.
◼ Types de namespaces :
◼ PID : Isolation des IDs de processus.
◼ NET : Isolation des interfaces réseau.
◼ IPC : Isolation de la communication interprocessus.
◼ MNT : Isolation des points de montage.
◼ UTS : Isolation des noms d'hôtes et des noms de domaine.
Gestion des utilisateurs et sécurité
Par défaut, les conteneurs s'exécutent en tant qu'utilisateur root.
◼ Risques : Si un processus est compromis, il peut potentiellement affecter l'hôte.
◼ Exécuter en tant qu'utilisateur non-root :
◼ Option --user lors de l'exécution :
◼ docker run -u 1000 ubuntu
◼ Le processus s'exécute avec l'ID utilisateur 1000.
◼ Définir l'utilisateur dans le Dockerfile :
◼ FROM ubuntu
◼ USER 1000
◼ CMD ["sleep", "3600"]
◼ Construire l'image :
◼ docker build -t custom-ubuntu .
◼ Exécuter le conteneur :
◼ docker run custom-ubuntu
SÉCURITÉ DES NAMESPACES
Espaces de noms de processus (PID Namespaces)
◼ Sur un système Linux, le processus initial a l'ID 1.
◼ Dans un conteneur Docker, les processus pensent qu'ils commencent à l'ID 1 grâce aux namespaces.
◼ Exemple :
Capabilities

Comprendre l'utilisateur root dans les conteneurs


◼ L'utilisateur root dans un conteneur n'a pas les mêmes privilèges que sur l'hôte.
◼ Limitations : Docker limite les actions que l'utilisateur root peut effectuer dans le conteneur.
Capabilities

Capacités Linux (Linux Capabilities)


◼ Les capacités permettent de diviser les privilèges de l'utilisateur root en morceaux plus petits.
◼ Par défaut, Docker restreint certaines capacités pour renforcer la sécurité.
◼ Ajouter une capacité :
◼ docker run --cap-add=NET_ADMIN ubuntu
◼ Permet des opérations réseau avancées.

◼ Supprimer une capacité :


◼ docker run --cap-drop=MKNOD ubuntu
◼ Empêche la création de périphériques spéciaux.

◼ Exécuter avec tous les privilèges :


◼ docker run --privileged ubuntu
◼ Attention : Risque élevé pour la sécurité.
Capabilities
◼ Gestion des fichiers
◼ Gestion système
◼ CAP_CHOWN : Changer le propriétaire des fichiers.
◼ CAP_SYS_ADMIN : Tâches système critiques (montage de
◼ CAP_DAC_OVERRIDE : Ignorer les permissions d'accès aux disques, etc.).
fichiers.
◼ CAP_SYS_PTRACE : Suivre/déboguer des processus.
◼ CAP_FOWNER : Contourner les permissions des fichiers
possédés par d'autres. ◼ CAP_SYS_MODULE : Charger/décharger des modules du
noyau.
◼ CAP_FSETID : Définir les bits set-user-ID/set-group-ID.
◼ CAP_SYS_BOOT : Redémarrer le système.
◼ CAP_MKNOD : Créer des fichiers de périphériques.
◼ Sécurité
◼ Gestion des processus
◼ CAP_AUDIT_CONTROL : Configurer l'audit du système.
◼ CAP_KILL : Envoyer des signaux à des processus étrangers.
◼ CAP_MAC_ADMIN : Gérer les politiques MAC (contrôle
◼ CAP_SETUID : Changer l'UID (User ID) effectif. d'accès obligatoire).
◼ CAP_SETGID : Changer le GID (Group ID) effectif. ◼ CAP_AUDIT_WRITE : Écrire dans les logs d'audit.
◼ CAP_SYS_NICE : Changer la priorité des processus. ◼ Autres
◼ Gestion du réseau ◼ CAP_SYS_TIME : Modifier l'heure système.
◼ CAP_NET_BIND_SERVICE : Utiliser des ports < 1024. ◼ CAP_IPC_LOCK : Verrouiller des segments de mémoire.
◼ CAP_NET_ADMIN : Gérer les paramètres réseau. ◼ CAP_LINUX_IMMUTABLE : Définir des fichiers comme
immuables.
◼ CAP_NET_RAW : Utiliser des sockets bruts (raw).
BONNES PRATIQUES

◼ Éviter d'exécuter des conteneurs en tant que root.


◼ Limiter les capacités au strict nécessaire.
◼ Ne pas utiliser --privileged sauf en cas de besoin impératif.
◼ Utiliser les user namespaces pour mapper les utilisateurs du conteneur à des utilisateurs non privilégiés
sur l'hôte.
User namespaces

◼ Configurer les user namespaces


◼ Activer les user namespaces dans Docker :
◼ Modifier /etc/docker/daemon.json :
{
"userns-remap": "default"
}
◼ Redémarrer Docker
◼ Avantage : Les utilisateurs dans le conteneur sont mappés à des utilisateurs non privilégiés sur l'hôte.
User namespaces

◼ Remappage vers un utilisateur spécifique


◼ Au lieu d'utiliser "default", vous pouvez spécifier un utilisateur et un groupe particulier sur l'hôte pour
le remappage. Cela permet un contrôle plus précis sur quels utilisateurs sont utilisés pour les
conteneurs.

{
"userns-remap": "username"
}

username : Le nom de l'utilisateur non privilégié sur l'hôte qui sera utilisé pour mapper les utilisateurs à
l'intérieur du conteneur.
User namespaces

◼ Si vous avez un utilisateur dockeruser sur votre système, vous pouvez le spécifier ainsi :

{
"userns-remap": "dockeruser"
}
User namespaces
Remappage vers un UID/GID spécifique
Créer un fichier de mappage :
◼ Vous pouvez créer un mappage d'utilisateur personnalisé dans /etc/subuid et /etc/subgid.
◼ Pour un utilisateur dockeruser, vous pourriez ajouter des lignes similaires à :
◼ /etc/subuid :
◼ dockeruser:100000:65536

◼ /etc/subgid :
◼ dockeruser:100000:65536

◼ dockeruser sur l'hôte est mappé aux UID allant de 100000 à 165536 dans les conteneurs.
Ensuite, dans daemon.json, vous spécifiez cet utilisateur pour le remappage :

{
"userns-remap": "dockeruser"
}
User namespaces

◼ Désactiver le remappage des User Namespaces

◼ docker run --userns=host mycontainer


◼ Cela indique à Docker de ne pas utiliser les User Namespaces pour ce conteneur particulier, permettant
à l'utilisateur à l'intérieur du conteneur de correspondre directement aux utilisateurs sur l'hôte.
User namespaces

◼ Docker utilise les namespaces et les capacités Linux pour isoler les conteneurs et renforcer la sécurité.
◼ Namespaces : Fournissent une isolation en cloisonnant les ressources système.
◼ Capacités : Permettent de contrôler précisément les privilèges accordés aux processus.
◼ Meilleures pratiques :
◼ Exécuter les conteneurs avec des utilisateurs non-root.
◼ Limiter les privilèges en utilisant --cap-add et --cap-drop.
◼ Éviter l'utilisation du flag --privileged.
◼ Configurer les user namespaces pour une isolation supplémentaire.
INTRODUCTION AUX CGROUPS

◼ Les Cgroups (Control Groups) sont une fonctionnalité de Linux permettant d'allouer des ressources
telles que le CPU, la mémoire, et la bande passante réseau entre différents processus. Docker utilise les
Cgroups pour limiter les ressources entre différents conteneurs.
LIMITATION DES RESSOURCES CPU

◼ Par défaut, les conteneurs Docker n'ont aucune restriction sur la quantité de CPU qu'ils peuvent
utiliser.
◼ Les Cgroups permettent de contrôler l'utilisation des ressources CPU pour éviter qu'un conteneur ne
monopolise tout le CPU disponible.
COMMANDE NPROC

◼ Utilisez la commande nproc pour connaître le nombre de processeurs logiques disponibles sur votre
système:
◼ nproc

◼ Cette commande retourne le nombre de processeurs logiques.


◼ Nous pouvons aussi utiliser docker info pour avoir le nombre de processeur disponible.
COMMANDE LSCPU

◼ La commande lscpu donne des informations détaillées sur le CPU, incluant le nombre de cœurs
physiques et logiques.

◼ lscpu

CPU(s): 4
Thread(s) per core: 2
Core(s) per socket: 2
Socket(s): 1
COMPRÉHENSION DU PARTAGE DU CPU

◼ Les processus peuvent partager le CPU en fonction des parts attribuées via les Cgroups.
◼ Un processus avec une part de 1024 recevra deux fois plus de temps CPU qu'un autre avec une part de
512.
LIMITATION DES RESSOURCES CPU AVEC DOCKER

◼ Utilisez l'option --cpu-shares pour définir les parts de CPU d'un conteneur.
◼ Exemple :

docker run -d --name webapp1 --cpu-shares=1024 myapp


docker run -d --name webapp2 --cpu-shares=1024 myapp
docker run -d --name webapp3 --cpu-shares=1024 myapp
docker run -d --name webapp4 --cpu-shares=512 myapp

◼ Cela donne moins de temps CPU au conteneur 4 comparé à d'autres avec des parts plus élevées.
OPTIONS AVANCÉES : LIMITATION CPU

◼ Utilisez --cpuset-cpus pour définir des cœurs CPU spécifiques pour un conteneur.
◼ Exemple :

docker run -d --name webapp1 --cpuset-cpus="0,1" myapp


docker run -d --name webapp2 --cpuset-cpus="0,1" myapp
docker run -d --name webapp3 --cpuset-cpus="2" --cpus="0.5" myapp
docker run -d --name webapp4 --cpuset-cpus="2" myapp

◼ webapp1 et webapp2 utilisent les CPUs 0 et 1.


◼ webapp3 et webapp4 utilisent le CPU 2.
◼ Le CPU 3 est libre.
OPTIONS AVANCÉES : LIMITATION CPU

Limiter le pourcentage de CPU utilisable


Option --cpus (depuis Docker 1.13) :
◼ Définit le nombre de CPUs que le conteneur peut utiliser.

docker run -d --name webapp --cpus="2.5" myapp

◼ Le conteneur ne peut utiliser que 2,5 CPUs (sur un total de 4).


◼ Cela équivaut à environ 62% des ressources CPU totales.
OPTIONS AVANCÉES : LIMITATION CPU

◼ Modifier les ressources CPU d'un conteneur existant


◼ Il est possible de mettre à jour la limite CPU d'un conteneur en cours d'exécution avec la commande
docker container update.

docker container update --cpus="1.5" webapp3


LIMITATION DE LA MÉMOIRE DANS DOCKER

◼ Utilisez l'option --memory pour limiter la quantité de RAM utilisable par un conteneur.
◼ Exemple :

docker run -d --memory=512m nginx

◼ Le conteneur ne pourra pas utiliser plus de 512 Mo de RAM.


GESTION DE L'ESPACE SWAP

◼ Utilisez l'option --memory-swap pour limiter l'utilisation du swap par un conteneur.


◼ Exemple :

docker run -d --memory=512m --memory-swap=768m nginx

◼ Le conteneur pourra utiliser 512 Mo de RAM et 256 Mo de swap.


LIMITS VS RESERVATION
version: '3.8'

services:
webapp:
image: nginx database:
image: mysql
deploy:
environment:
resources: MYSQL_ROOT_PASSWORD: rootpassword
limits: deploy:
cpus: '0.5' # Limite à 50% d'un CPU resources:
memory: 512M # Limite la RAM à 512MB limits:
reservations: cpus: '1.0' # Limite à 1 CPU
cpus: '0.25' # Réserve 25% d'un CPU memory: 1G # Limite la RAM à 1GB
reservations:
pour garantir les performances minimales
cpus: '0.5' # Réserve 50% d'un CPU
memory: 256M # Réserve 256MB de RAM memory: 512M # Réserve 512MB de RAM

limits = maximum que le conteneur peut utiliser.


reservations = minimum garanti pour le conteneur.
Exemple

◼ docker run --rm -it progrium/stress --cpu 2 --io 1 --vm 2 --vm-bytes 128M --timeout
10s
◼ --cpu 2 : Charge le CPU en lançant 2 threads qui effectueront des calculs continus.
◼ --io 1 : Génère une charge I/O (entrées/sorties) en utilisant 1 thread.
◼ --vm 2 : Crée 2 processus de charge mémoire (allocation de mémoire virtuelle).
◼ --vm-bytes 128M : Chaque processus de charge mémoire alloue 128 Mo de mémoire.
◼ --timeout 10s : Le stress test s'exécutera pendant 10 secondes avant de s'arrêter automatiquement.
TP PRATIQUE : LIMITATION DES RESSOURCES

◼ 1. Lancer un conteneur sans limitation de CPU ou mémoire.


◼ 2. Lancer un conteneur avec --cpu-shares pour comparer l'usage CPU.
◼ 3. Limiter la mémoire avec --memory et observer l'impact sur les performances.

Vous aimerez peut-être aussi