Cette page prend en compte la version 1.12 de Docker et supérieure.
→ Documentation officielle:
Installation sur WSL2, sans Docker Desktop:
Installation avec wget
:
# wget -qO- https://get.docker.com | sh
Comme l'installation de Docker le précise, ajouter l'utilisateur au groupe docker
:
$ sudo usermod -aG docker your-user
Permet de ne pas avoir à utiliser sudo
pour les commandes Docker (voir Post-Intallation steps).
Ensuite, se déconnecter de la session et se reconnecter.
Pour essayer voir si l'installation fonctionne :
$ docker run hello-world
Prérequis:
L'installation de Docker pour Windows est une machine virtuelle Hyper-V qui roule MobyLinuxVM qui exécute Docker.
D'abord il faut activer Hyper-V dans Programs and Features de Windows. Il est possible également que la virtualisation matérielle doive être activée dans le BIOS, soit Intel VT/VT-x ou AMD-V.
Télécharger le paquet sur le site de Docker. Installer ce paquet.
$ docker version $ docker info
Pour la gestion plus simple des images et containers, on peut utiliser LazyDocker.
$ docker pull <image-name>
On peut spécifier une version de l'image:
$ docker pull <image-name>:<version>
Exemples:
$ docker pull ubuntu:latest $ docker pull ubuntu:14.04 $ docker pull ubuntu
Quand on ne spécifie pas de version, c'est généralement latest
qui est sélectionné, donc $ docker pull ubuntu
est équivalent à $ docker pull ubuntu:latest
.
Pour obtenir toutes les versions d'une image on utilise -a
:
# docker pull -a fedora
Aucun conteneur ne doit utiliser l'image avant de la supprimer.
$ docker rmi <image-name>
$ docker run -d --name web -p 80:8080 <image-name>
On utilise la commande run
. Le paramètre -d
est pour le mode detached, le –name
est pour donner un nom au conteneur et -p
est pour faire de la redirection de port: le port 80 sur l'hôte ira au port 8080 sur le conteneur.
Avec variables d'environnement:
$ docker run -d --name containerName --restart=always -e DB_URL='url' -p 44302:3000 registry.example.com/imagedir/imagename:latest
$ docker rmi <image-name>
Pour supprimer toutes les images:
$ docker rmi $(docker images -q)
Supprimer les images non utilisées (non tagguées):
$ docker rmi -f $(docker images | grep "<none>" | awk "{print \$3}")
Ultimement, on peut supprimer toutes les images, les containers, volumes et réseaux qui ne sont pas utilisés par un conteneur avec:
$ docker system prune
Pour supprimer tout, peu importe si utilisé ou non:
$ docker system prune -a
Créer l'archive:
$ docker save -o <nom-archive> <nom-image>
Transférer le fichier avec scp.
$ docker load -i <nom-archive>
Commande | Description |
---|---|
docker start <short guid|container name> | Démarre un container |
docker stop <short guid|container name> | Arrête un container |
docker restart <short guid|container name> | Redémarre un container |
docker kill <short guid|container name> | Arrête un container de façon moins gracieuse |
docker rm <short guid|container name> | Supprime un container arrêté. Utiliser -f pour forcer la suppression d'un container en exécution. |
$ docker ps --all $ docker ps --filter "status=exited"
Tel que mentionné probablement dans une autre page de Docker sur ce wiki, on peut tester l'utilisation d'un conteneur par un hello-world
:
$ docker run hello-world
$ docker stop <container-name|container-guid>
Pour arrêter tous les conteneurs:
$ docker stop $(docker ps -aq)
Le -a
signifie all et le -q
signifie quiet.
$ docker container ls --all | grep Exited | cut -d ' ' -f 1 | xargs docker container rm
Supprimer un container sans être certain qu'il existe (utile pour des scripts de CI):
$ docker container rm -f container-name 2>/dev/null || true
Supprimer tous les containers arrêtés:
$ docker rm $(docker ps --filter status=exited -q)
La commande docker attach <shortguid>
permet d'obtenir l'invite de commande du container. Le problème c'est qu'il s'attache au PID 1.
Ceci nous permet d'entrer un namespace. Requiert un PID qu'on peut obtenir avec inspect
.
$ docker inspect <shortguid> | grep Pid "Pid": 1923,
Une fois le PID obtenu, on peut faire:
$ nsenter -m -u -n -p -i -t 1923 /bin/bash
Une fois terminé avec le shell, on peut faire exit
et contrairement à un attach
, un exit
n'arrêtera pas le container.
Si nsenter
n'est pas présent sur le système (hôte), on peut l'obtenir avec ce guide.
À partir de la version 1.3 de Docker, on peut faire la commande exec
:
$ docker exec -it <shortguid> /bin/bash $ docker exec -it c1 sh $ docker exec -u 0 -it c1 sh # force le root
L'alternative à docker exec
est d'utiliser docker debug.
Pour avoir la sortie d'un container, il faut utiliser docker logs
.
$ docker logs containerId
Exemple d'utilisation de volume:
docker run -d --name postgres \ -p 5432:5432 --restart=always \ -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=database_name \ -e PGDATA=/var/lib/postgresql/data/pgdata \ -v pgdata:/var/lib/postgresql/data \ postgres:14.1
Le pgdata
signifie que ce sera stocké sous le /var/lib/docker/volumes
. On peut spécifier un chemin plus spécifique, ici relatif:
-v ./postgres-data:/var/lib/postgresql/data
Les volumes sont localisés (linux) à : /var/lib/docker/volumes/
.
Pour spécifier le réseau d'un conteneur:
docker run -d --name app \ --network <NETWORK_NAME> \ company/app:latest
Liste des réseaux Docker:
$ docker network ls
Inspecter un réseau:
$ docker network inspect <docker-network-name>
Il y a trois réseaux par défaut:
host
bridge
(synonyme de vitual switch, vswitch, ou nat en Windows)none
Drivers:
Scopes:
On peut donc faire:
$ docker network inspect bridge
Utilisation de host.docker.internal
.
--add-host=host.docker.internal:host-gateway
On crée un réseau avec le driver bridge
(c'est la valeur par défaut si non spécifié):
$ docker network create -d bridge --subnet 10.0.0.1/24 new-network
Optionnel: $ sudo apt-get install bridge-utils
$ brctl show
$ ip link show
Ajouter un container à un réseau:
$ docker container run -dt --name c1 --network new-network alpine sleep 1d $ docker container run -dt --name c2 --network new-network alpine sleep 1d
Les deux seront dans le réseau new-network
, en faisant:
$ docker network inspect new-network
"Containers": { "872125d8f607269236387b805786a2106b77ecc65147eb3faf030fcc29263b23": { "Name": "c1", "EndpointID": "936949131a5a94bc3b03ae72031ad165084867ab626f68d6402e41181869d7be", "MacAddress": "02:42:0a:00:00:02", "IPv4Address": "10.0.0.2/24", "IPv6Address": "" }, "9ab0378ebcfb60a347ff388b820820796dea510394b98861365d94d1e753438d": { "Name": "c2", "EndpointID": "9c4eb47cd1efb2518f27f14f4653ff9f6b53bda6bc63d7a63decee6f28091639", "MacAddress": "02:42:0a:00:00:03", "IPv4Address": "10.0.0.3/24", "IPv6Address": "" } },
Tester
Une façon de valider, c'est d'aller dans le container:
$ docker exec -it c1 sh
Dans le container:
# ping 10.0.0.3
ou par le nom du container:
# ping c2
Chaque fois qu'on invoque un container avec l'option --name
, une entrée DNS est créée pour résolver le nom.
En utilisant l'option -p <hostport>:<containerport>
.
Se fait avec le overlay driver. S'applique à plusieurs hosts ou nodes ou machines qui roulent le Docker Engine.
VXLAN tunnel, ports utilisés:
user@node1 $ docker swarm init
Ceci donnera une commande pour joindre le swarm qui sera à exécuter sur d'autres machines.
user@node2 $ docker swarm join --token <token> 172.32.45.12:2377
Une fois que le node2 a joint, on peut faire
user@node1 $ docker node ls
Si on regarde les réseaux (docker network ls
), un nouveau est présent: ingress
de type overlay
.
user@node1 $ docker network create -d overlay new-overlay-network
Le réseau new-overlay-network
sera créé sur node1 mais pas sur les autres nodes. Pour qu'il apparaisse, il faut avoir un container qui l'utilise.
user@node1 $ docker service create --name new-svc --network new-overlay-network --replicas 2 alpine sleep 1d user@node1 $ docker service ps new-srv
Un container sera créé sur le node1 et un autre sur le node2. Sur le node2 on verra désormais le réseau new-overlay-network
.
Linux MACVLAN
Windows l2bridge
MACVLAN requière le mode promiscuous, ce qui n'est pas disponible sur les services cloud tels que AWS/Azure.
Prend en considération deux machines physiques ayant Docker Engine sur un réseau 192.168.1.0/24.
$ docker network create -d ipvlan --subnet=192.168.1.0/24 --gateway=192.168.1.254 --ip-range=192.168.1.0/28 -o ipvlan_mode=l2 -o parent=eth0 ps-ip
Le l2
est pour Layer 2.
Ajouter un container participant au réseau:
$ docker run -dt --name c1 --network ps-ip alpine sleep 1d
Prend en compte quatre nodes, qui participent à un swarm.
user@node1 $ docker network create -d overlay overnet user@node1 $ docker service create --name web -p 5000:8080 --replicas 3 --network overnet image-of/webapp
Le nombre de replicas à 3 est voulu pour démontrer que le 4e node qui n'aura pas de tâche (container du service) pourra quand même résolver le service vers les trois autres nodes.
Application Layer construit sur le L4 routing mesh.
Pour savoir sur quel réseau se trouve un container:
$ docker inspect container-name -f "{{json .NetworkSettings.Networks }}" | jq
$ docker run --name mysqlserver -v /some/path/to/mysqldata:/var/lib/mysql -e MYSQL_ROOT_HOST=% -p 3306:3306 -d mysql/mysql-server:8.0
Un One-time-password sera créé et affiché dans les logs:
$ docker logs mysqlserver 2>&1 | grep GENERATED
FROM node:8.7.0-alpine COPY ["package.json", "./"] RUN npm install --production --silent && mv node_modules ../ COPY . . EXPOSE 3000 CMD npm run start
Le programme nsenter
permet de démarrer un programme dans l'espace de nom (namespace) d'un autre processus.
Ubuntu 14.04 n'a pas nsenter
d'installer. Il est possible d'installer les dépendances et de compiler util-linux
pour l'obtenir, mais vu que c'est parfois utilisé dans le cadre d'une gestion Docker, on peut justement utiliser un conteneur pour se faire.
$ docker run --name nsenter -it ubuntu:14.04
Avec l'option -it
on tombe dans le conteneur.
$ apt-get update $ apt-get install git build-essential libncurses5-dev libslang2-dev gettext zlib1g-dev libselinux1-dev debhelper lsb-release pkg-config po-debconf autoconf automake autopoint libtool
$ git clone git://git.kernel.org/pub/scm/utils/util-linux/util-linux.git util-linux $ cd util-linux/
$ ./autogen.sh $ ./configure --without-python --disable-all-programs --enable-nsenter
make
Une fois sorti du conteneur, ou bien dans un autre shell sur l'hôte, on fait:
# docker cp nsenter:/util-linux/nsenter /usr/local/bin/ # docker cp nsenter:/util-linux/bash-completion/nsenter /etc/bash_completion.d/nsenter
Ensuite on peut utiliser nsenter
sur l'hôte.