Descente d'un niveau dans la hiérarchie pour la TOC

This commit is contained in:
whirigoyen 2023-12-08 10:33:14 +01:00
parent 690a5353a1
commit cfd8eddd89

View file

@ -10,7 +10,7 @@ categories: docker
[Docker](https://www.docker.com/) est une solution qui permet de créer, déployer et gérer des conteneurs Linux.
Il intègre une gestion avancée des images permettant de les compiler, les compléter, les héberger, etc.
## Installation
# Installation
Nous utilisons le paquet `docker-ce` des dépôts du projet Docker :
@ -46,15 +46,15 @@ Sur sa machine de travail, il est utile d'ajouter son utilisateur dans le groupe
# adduser $USER docker
~~~
## Utilisation basique
# Utilisation basique
Une image Docker contient un système minimal avec un ou plusieurs services.
Un conteneur quant à lui est une instance (créée à partir d'une image)
en cours d'exécution.
### Gérer les conteneurs
## Gérer les conteneurs
#### Lister les conteneurs
### Lister les conteneurs
~~~
$ docker ps
@ -68,7 +68,7 @@ Options utiles :
-q : lister uniquement les ID des conteneurs
~~~
#### Instancier un nouveau conteneur
### Instancier un nouveau conteneur
~~~
$ docker run <image> [commande]
@ -86,7 +86,7 @@ Options utiles :
--network NOM : lancer le conterneur sur un réseau docker spécifique existant
~~~
#### Démarrer un conteneur existant
### Démarrer un conteneur existant
Un conteneur existant est un conteneur précédemment instancié avec `docker
run`.
@ -95,7 +95,7 @@ run`.
$ docker start <ID ou nom du conteneur>
~~~
#### Éteindre ou tuer un conteneur
### Éteindre ou tuer un conteneur
~~~
$ docker stop|kill <ID ou nom du conteneur>
@ -104,7 +104,7 @@ $ docker stop|kill <ID ou nom du conteneur>
Lorsque le conteneur n'est plus en fonction, il existe toujours et peut être
listé à l'aide de la commande `docker ps -a`
#### Autostart d'un conteneur
### Autostart d'un conteneur
Pour s'assurer qu'un conteneur démarre ou non au démarrage du démon Docker, il existe un paramètre RestartPolicy :
@ -127,13 +127,13 @@ Pour mettre à jour la politique :
$ docker update --restart=always monconteneur
~~~
#### Supprimer un conteneur
### Supprimer un conteneur
~~~
$ docker rm <ID ou nom du conteneur>
~~~
#### Exécuter des commandes dans un conteneur en fonctionnement
### Exécuter des commandes dans un conteneur en fonctionnement
~~~
$ docker exec <ID ou nom du conteneur> <commande>
@ -152,7 +152,7 @@ On utilise habituellement la commande suivante pour obtenir un shell dans un con
$ docker exec -ti <ID ou nom du conteneur> bash
~~~
#### Visionner les journaux d'un conteneur
### Visionner les journaux d'un conteneur
Il s'agit en fait de la sortie standard et la sortie d'erreur du processus
lancé à l'intérieur du conteneur :
@ -168,7 +168,7 @@ Options utiles :
-t : afficher un timestamp devant chaque ligne
~~~
#### Afficher les informations d'un conteneur
### Afficher les informations d'un conteneur
~~~
$ docker inspect <ID ou nom du conteneur>
@ -189,15 +189,15 @@ $ docker inspect docker_gwbridge --format "{{ .Containers.f4bae02ef1407adc92f1aa
Note : De notre expérience, l'option --format peut se montrer capricieuse, notamment s'il y a en jeu des identifiant de containers. Une alternative est de parser du json manuellement avec [jq](https://wiki.evolix.org/TipsShell#json-avec-jq )
### Gérer les images
## Gérer les images
#### Lister les images locales
### Lister les images locales
~~~
$ docker image ls
~~~
#### Construire une image
### Construire une image
Pour construire ou mettre à jour une image :
@ -214,13 +214,13 @@ Option utiles :
-t : ajoute un tag à l'image
~~~
#### Ajouter un tag à une image existante
### Ajouter un tag à une image existante
~~~
$ docker tag <tag actuel> <nouveau tag>
~~~
#### Pousser une image sur un dépôt distant
### Pousser une image sur un dépôt distant
~~~
$ docker push <image>
@ -236,13 +236,13 @@ $ docker tag foo-image registry.example.net:5000/foo-image
$ docker push registry.example.net:5000/foo-image
~~~
#### Récupérer une image d'un dépôt distant
### Récupérer une image d'un dépôt distant
~~~
$ docker pull <image>
~~~
#### Copier des fichiers dans/depuis un conteneur
### Copier des fichiers dans/depuis un conteneur
~~~
$ docker cp <fichier> <conteneur>:<chemin>
@ -254,7 +254,7 @@ On peut aussi le faire de conteneur à conteneur :
$ docker cp <conteneurA>:<fichier> <conteneurB>:<chemin>
~~~
### Astuces
## Astuces
Éteindre/Tuer/Supprimer tous les conteneurs :
@ -274,9 +274,9 @@ Démarrer un conteneur existant avec un shell bash (pour des fins de debug par e
$ docker run -it IMAGE bash
~~~
## Configuration
# Configuration
#### Changer le chemin de stockage
## Changer le chemin de stockage
Créer le fichier `/etc/docker/daemon.json` et y mettre :
@ -289,7 +289,7 @@ Créer le fichier `/etc/docker/daemon.json` et y mettre :
NB : Anciennement il fallait "graph" à la place de "data-root".
#### TLS
## TLS
Lorsque le docker-engine est exposé, il est important de le sécuriser avec TLS.
@ -309,9 +309,9 @@ Les fichiers seront créés, par défaut, dans le répertoire
`/home/docker/tls/files/$CN`
## Plomberie
# Plomberie
### Le démon docker et son client
## Le démon docker et son client
Docker est une application en mode client-serveur. *dockerd* est un démon qui
fournit une API REST afin d'interagir avec les conteneurs. *docker* est un
@ -319,7 +319,7 @@ client qui permet d'interagir avec le démon en ligne de commande. Il peut
interagir avec un démon en local (sur la même machine) ou avec un démon sur une
machine distante.
### Image
## Image
Une image est un template contenant des instructions pour créer un conteneur
docker. Ces instructions sont listées dans un fichier nommé *Dockerfile*. La
@ -330,11 +330,11 @@ sont reconstruites.
Une fois qu'une image est créée on peut la publier dans un *registry* (`docker
push`).
### Conteneur
## Conteneur
Un conteneur est une instance exécutable d'une image.
### Stack, service et task
## Stack, service et task
Lorsque Docker fonctionne en _swarm mode_ (en cluster), les notions de
_stack_, _service_ et _task_ sont introduites, en plus des précédentes.
@ -363,14 +363,14 @@ conteneur.
Voir : [https://docs.docker.com/engine/swarm/how-swarm-mode-works/services/#services-tasks-and-containers](https://docs.docker.com/engine/swarm/how-swarm-mode-works/services/#services-tasks-and-containers)
## docker registry
# docker registry
Un *registry* sert à héberger des images docker. Il existe des registres
publics tels que *docker hub* ou *docker cloud* mais il est possible d'héberger
son propre *registry*.
## Dockerfile
# Dockerfile
Les fichiers _Dockerfile_ décrivent les étapes de construction d'une image. Ils
permettent de reconstruire à l'identique votre image et de connaitre exactement
@ -380,7 +380,7 @@ volumineuse, on distribue uniquement la procédure de construction
Référence pour la syntaxe des fichiers _Dockerfile_ : [https://docs.docker.com/engine/reference/builder/](https://docs.docker.com/engine/reference/builder/)
### Procédure de création d'une nouvelle image
## Procédure de création d'une nouvelle image
Exemple avec une image exécutant rsyslog :
@ -462,9 +462,9 @@ rsyslog latest 4bea99cda08c 8 minutes ago
debian stretch 5b712ae16dd7 3 days ago 100MB
~~~
## Utilisation avancée
# Utilisation avancée
### Docker registry
## Docker registry
Un _docker registry_ permet d'héberger des images Docker.
@ -519,13 +519,13 @@ $ curl https://registrydocker.example.com:5000/v2/_catalog
La requête devrait retourner la liste des images hébergées au format json.
### Swarm
## Swarm
Swarm permet de mettre en communication plusieurs hôtes Docker afin d'en former
un cluster. On pourra ainsi déployer des applications multi-conteneurs sur
plusieurs machines.
#### Initialiser le cluster
### Initialiser le cluster
~~~
docker0# docker swarm init
@ -548,13 +548,13 @@ Pour ajouter des machines plus tard, il suffit de générer un nouveau token :
docker0# docker swarm join-token <manager|worker>
~~~
#### Lister les machines du cluster
### Lister les machines du cluster
~~~
# docker node ls
~~~
#### Ajouter des labels à une machine
### Ajouter des labels à une machine
~~~
# docker node update --label-add <clé>=<valeur> <machine>
@ -564,14 +564,14 @@ Les _labels_ servent notamment à définir des contraintes de placement des
services lors de l'utilisation de _docker stack_.
#### Supprimer une machine du cluster
### Supprimer une machine du cluster
~~~
# docker node rm <hash-machine>
~~~
### Compose/stack (docker stack)
## Compose/stack (docker stack)
Docker permet de déployer des infrastructures multi-conteneurs (_stacks_) simplement à l'aide de `docker stack` (anciennement Docker Compose, logiciel tier). Il est très utile dans le cadre de déploiement sur un cluster Swarm.
@ -609,7 +609,7 @@ Supprimer une _stack_ :
# docker stack rm <stack name>
~~~
### Réseaux (docker network)
## Réseaux (docker network)
Docker permet de gérer différentes topologies de réseaux pour connecter les conteneurs entre eux à l'aide de `docker network`.
@ -650,7 +650,7 @@ Informations détaillées sur un réseau :
# docker network inspect <network name>
~~~
### Volumes (docker volume)
## Volumes (docker volume)
Les volumes Docker sont des répertoires ou fichiers présents sur l'hôte qui
peuvent être montés à l'intérieur des conteneurs. L'intérêt est de pouvoir
@ -682,7 +682,7 @@ les membres du cluster. Si un conteneur monte un volume, il faut bien penser à
restreindre son placement à un Docker node spécifique, ou bien mettre en place
un système de réplication de fichiers tier.
### Fichiers de configuration (docker config)
## Fichiers de configuration (docker config)
Les _config_ sont des objets permettant de stocker un unique fichier,
généralement un fichier de configuration d'un service.
@ -723,7 +723,7 @@ ID NAME DRIVER
vim-config
~~~
### Fichiers sensibles (docker secrets)
## Fichiers sensibles (docker secrets)
Ce sont des objets permettant de stocker des fichiers, au même titre que les
_configs_, mais dédiés aux fichiers sensibles comme les clés privée ou fichiers
@ -738,7 +738,7 @@ ne peuvent ni être modifiés depuis un conteneur ni depuis l'hôte, ils doivent
Les _config_ se gèrent avec la commande `docker secret`.
### Fichier YAML de description de _stack_ (anciennement _docker-compose.yml_)
## Fichier YAML de description de _stack_ (anciennement _docker-compose.yml_)
Les _stacks_ Docker se décrivent à l'aide d'un fichier YAML. Anciennement le
déploiement d'une _stack_ se faisait à l'aide de Docker-compose et le fichier
@ -838,7 +838,7 @@ ma-stack.yml nginx.conf example.com.pem
$ docker stack deploy -c ma-stack.yml ma-stack
~~~
#### Surcharge de paramètre
### Surcharge de paramètre
On peut surcharger certains paramètres définit dans le premier en créant un
second fichier contenant seulement les paramètres à surcharger. Les 2 fichiers
@ -865,9 +865,9 @@ On peut ensuite déployer ainsi :
$ docker stack deploy -c ma-stack.yml -c ma-stack.dev.yml ma-stack
~~~
## FAQ
# FAQ
### Les conteneurs ont des problèmes de connectivités entre eux/vers l'extérieur
## Les conteneurs ont des problèmes de connectivités entre eux/vers l'extérieur
C'est très probablement lié à un outil manipulant les règles netfilter qui a
effacé les règles spécifiques à Docker, notamment dans la table _nat_.
@ -879,7 +879,7 @@ de redémarrer le démon :
# /etc/init.d/docker restart
~~~
### Espace insuffisant lors du build d'une image
## Espace insuffisant lors du build d'une image
Solutions:
@ -891,7 +891,7 @@ Solutions:
*Build context: Tout ce qui se trouve à la racine du Dockerfile.*
### Voir et modifier le _ENTRYPOINT_ et le _CMD_ d'une image pour déboguer
## Voir et modifier le _ENTRYPOINT_ et le _CMD_ d'une image pour déboguer
Voir les commandes
@ -914,7 +914,7 @@ Re-créer l'image en modifiant un conteneur de cette image
$ docker commit -c 'ENTRYPOINT ["/bin/sleep"]' -c 'CMD ["infinity"]' $idConteneur $nomImage:tag
~~~
### Lors d'un redéploiement d'une stack Docker (docker stack deploy), les services ne sont pas redémarrer avec la nouvelle image
## Lors d'un redéploiement d'une stack Docker (docker stack deploy), les services ne sont pas redémarrer avec la nouvelle image
Vérifier que le tag _latest_ est bien précisé dans le nom de l'image dans le _docker-stack.yml_ :
@ -922,7 +922,7 @@ Vérifier que le tag _latest_ est bien précisé dans le nom de l'image dans le
image: registrydocker.example.com:5000/foo:latest
~~~
### Est-il possible de ne faire écouter un service d'une stack que sur une interface précise de la machine hôte (par exemple sur un LAN privé) ?
## Est-il possible de ne faire écouter un service d'une stack que sur une interface précise de la machine hôte (par exemple sur un LAN privé) ?
Non, Docker ne supporte pas ça.
Il faut bloquer le port en question dans le pare-feu, dans la chaîne iptables DOCKER-USER.
@ -933,7 +933,7 @@ Pour bloquer l'accès au _registry_ Docker depuis l'extérieur par exemple :
# iptables -A DOCKER-USER -i eth0 -p tcp -m tcp --dport 5000 -j DROP
~~~
### Au sein des conteneurs, un `getent <service>` ou `getent tasks.<service>` ne retourne pas l'adresse IP du service alors que celui-ci est bien lancé.
## Au sein des conteneurs, un `getent <service>` ou `getent tasks.<service>` ne retourne pas l'adresse IP du service alors que celui-ci est bien lancé.
Stopper le conteneur du service avec un `docker stop <conteneur du service>`. Docker stack devrait le relancer automatiquement.
@ -951,7 +951,7 @@ L'adresse IP des différentes _tasks_ d'un service :
$ getent hosts tasks.<nom du service>
~~~
### Comment trouver le PID d'un processus roulant dans un conteneur ?
## Comment trouver le PID d'un processus roulant dans un conteneur ?
Docker et autres technologies de conteneurs, utilisent des namespace
linux pour isoler les processus. Lutilité pgrep(1) est capable
@ -964,7 +964,7 @@ $ pgrep --ns $dockerPID $query
Ce concept provient du système Plan9
### Accéder au namespace réseau (ou autres) d'un conteneur
## Accéder au namespace réseau (ou autres) d'un conteneur
Docker ne met pas le namespace réseau qu'il utilise pour ses conteneurs dans `var/run/netns/`, on ne voit donc rien si on joue `ip netns` car le namespace est dans `/proc/${pid_conteneur}/ns/`.
@ -976,7 +976,7 @@ On peut monter `/proc/${pid_conteneur}/ns/` dans `var/run/netns/` pour utiliser
Nous permet d'avoir un shell dans le namespace, `-t` indique d'utiliser le pid target et `-n` indique que nous voulons aller dans le namespace netns
### Accéder aux ports locaux (docker-proxy) avec minifirewall
## Accéder aux ports locaux (docker-proxy) avec minifirewall
Vous devez autoriser activer `DOCKER=on` et autoriser ce que vous voulez sur l'interface `docker0`
@ -985,14 +985,14 @@ DOCKER='on'
/sbin/iptables -A INPUT -i docker0 -j ACCEPT
~~~
### Problème de résolution DNS dans Docker
## Problème de résolution DNS dans Docker
En général on utilise une stack réseau distincte dans les conteneurs, et donc la résolution DNS dans les conteneurs
est assurée par « Docker DNS embedded server » qui va transférer aux serveurs DNS définis sur l'hôte.
Si les serveurs DNS de l'hôte fonctionnent bien mais que la résolution DNS ne se fait plus dans les conteneurs,
vous pouvez en désespoir de cause redémarrer le démon Docker.
### Redémarrer le démon Docker sans redémarrer les conteneurs ?
## Redémarrer le démon Docker sans redémarrer les conteneurs ?
En fonction de la configuration, redémarrer le démon Docker peut éteindre les conteneurs en cours d'exécution… ou pas.