ajout + de != types réseaux et namespaces
This commit is contained in:
parent
6a25a78d8e
commit
98f3525e1c
324
HowtoDocker.md
324
HowtoDocker.md
|
@ -75,7 +75,7 @@ son propre *registry*.
|
||||||
|
|
||||||
Il est conseillé d'utiliser le paquet docker-ce des dépôts du projet Docker :
|
Il est conseillé d'utiliser le paquet docker-ce des dépôts du projet Docker :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# apt install apt-transport-https
|
# apt install apt-transport-https
|
||||||
# echo "deb http://download.docker.com/linux/debian buster stable" > /etc/apt/sources.list.d/docker.list
|
# echo "deb http://download.docker.com/linux/debian buster stable" > /etc/apt/sources.list.d/docker.list
|
||||||
# wget -O /etc/apt/trusted.gpg.d/docker.asc https://download.docker.com/linux/debian/gpg
|
# wget -O /etc/apt/trusted.gpg.d/docker.asc https://download.docker.com/linux/debian/gpg
|
||||||
|
@ -83,25 +83,25 @@ Il est conseillé d'utiliser le paquet docker-ce des dépôts du projet Docker :
|
||||||
# chmod 644 /etc/apt/trusted.gpg.d/docker.asc
|
# chmod 644 /etc/apt/trusted.gpg.d/docker.asc
|
||||||
# apt update
|
# apt update
|
||||||
# apt install docker-ce
|
# apt install docker-ce
|
||||||
~~~
|
```
|
||||||
|
|
||||||
> *Note* : Pour Debian 9 :
|
> *Note* : Pour Debian 9 :
|
||||||
>
|
>
|
||||||
> ~~~
|
> ```
|
||||||
> # apt install apt-transport-https
|
> # apt install apt-transport-https
|
||||||
> # echo "deb http://download.docker.com/linux/debian stretch stable" > /etc/apt/sources.list.d/docker.list
|
> # echo "deb http://download.docker.com/linux/debian stretch stable" > /etc/apt/sources.list.d/docker.list
|
||||||
> # wget https://download.docker.com/linux/debian/gpg -O /etc/apt/trusted.gpg.d/docker.asc
|
> # wget https://download.docker.com/linux/debian/gpg -O /etc/apt/trusted.gpg.d/docker.asc
|
||||||
> # apt update
|
> # apt update
|
||||||
> # apt install docker-ce
|
> # apt install docker-ce
|
||||||
> ~~~
|
> ```
|
||||||
|
|
||||||
Sur sa machine de travail, il est utile d'ajouter son utilisateur dans le
|
Sur sa machine de travail, il est utile d'ajouter son utilisateur dans le
|
||||||
groupe _docker_ pour pouvoir interagir avec le démon _dockerd_ sans passer root
|
groupe _docker_ pour pouvoir interagir avec le démon _dockerd_ sans passer root
|
||||||
à chaque fois :
|
à chaque fois :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# adduser $USER docker
|
# adduser $USER docker
|
||||||
~~~
|
```
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
|
@ -109,12 +109,12 @@ groupe _docker_ pour pouvoir interagir avec le démon _dockerd_ sans passer root
|
||||||
|
|
||||||
Créer le fichier `/etc/docker/daemon.json` et y mettre :
|
Créer le fichier `/etc/docker/daemon.json` et y mettre :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
{
|
{
|
||||||
"data-root": "<VOTRE_CHEMIN>",
|
"data-root": "<VOTRE_CHEMIN>",
|
||||||
"storage-driver": "overlay"
|
"storage-driver": "overlay"
|
||||||
}
|
}
|
||||||
~~~
|
```
|
||||||
|
|
||||||
NB : Anciennement il fallait "graph" à la place de "data-root".
|
NB : Anciennement il fallait "graph" à la place de "data-root".
|
||||||
|
|
||||||
|
@ -137,9 +137,9 @@ Pour autoriser des hôtes à se connecter à l'engine, il faut leur créer une c
|
||||||
et un certificat.
|
et un certificat.
|
||||||
Pour ce faire, il suffit de lancer le script:
|
Pour ce faire, il suffit de lancer le script:
|
||||||
|
|
||||||
~~~
|
```
|
||||||
/home/docker/tls$ ./shellpki create
|
/home/docker/tls$ ./shellpki create
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Les fichiers seront créés, par défaut, dans le répertoire
|
Les fichiers seront créés, par défaut, dans le répertoire
|
||||||
`/home/docker/tls/files/$CN`
|
`/home/docker/tls/files/$CN`
|
||||||
|
@ -154,47 +154,48 @@ en cours d'exécution.
|
||||||
|
|
||||||
#### Lister les conteneurs
|
#### Lister les conteneurs
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ docker ps
|
$ docker ps
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Options utiles :
|
Options utiles :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
-a : lister tous les conteneurs
|
-a : lister tous les conteneurs
|
||||||
-l : lister les conteneurs récemment lancés
|
-l : lister les conteneurs récemment lancés
|
||||||
-q : lister uniquement les ID des conteneurs
|
-q : lister uniquement les ID des conteneurs
|
||||||
~~~
|
```
|
||||||
|
|
||||||
#### Instancier un nouveau conteneur
|
#### Instancier un nouveau conteneur
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ docker run <image> [commande]
|
$ docker run <image> [commande]
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Options utiles :
|
Options utiles :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
--name="nom" : donner un nom au conteneur
|
--name NOM : donner un nom au conteneur
|
||||||
-p port_hôte:port_conteneur : rendre un port accessible depuis l'hôte
|
-p port_hôte:port_conteneur : rendre un port accessible depuis l'hôte
|
||||||
-d : lancer le conteneur en mode 'détaché'
|
-d : lancer le conteneur en mode 'détaché'
|
||||||
-it : lancer le conteneur en mode intéractif avec tty
|
-it : lancer le conteneur en mode intéractif avec tty
|
||||||
~~~
|
--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
|
Un conteneur existant est un conteneur précédemment instancié avec `docker
|
||||||
run`.
|
run`.
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ docker start <ID ou nom du conteneur>
|
$ 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>
|
$ docker stop|kill <ID ou nom du conteneur>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Lorsque le conteneur n'est plus en fonction, il existe toujours et peut être
|
Lorsque le conteneur n'est plus en fonction, il existe toujours et peut être
|
||||||
listé à l'aide de la commande `docker ps -a`
|
listé à l'aide de la commande `docker ps -a`
|
||||||
|
@ -203,71 +204,71 @@ listé à l'aide de la commande `docker ps -a`
|
||||||
|
|
||||||
Pour s'assurer qu'un conteneur démarre ou non au démarrage du démon Docker, il existe un paramètre RestartPolicy :
|
Pour s'assurer qu'un conteneur démarre ou non au démarrage du démon Docker, il existe un paramètre RestartPolicy :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ docker inspect -f "{{ .HostConfig.RestartPolicy.Name }}" monconteneur
|
$ docker inspect -f "{{ .HostConfig.RestartPolicy.Name }}" monconteneur
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Les valeurs possibles sont :
|
Les valeurs possibles sont :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
no Ne redémarre pas automatiquement le conteneur. (défaut)
|
no Ne redémarre pas automatiquement le conteneur. (défaut)
|
||||||
on-failure Redémarre le conteneur s'il crash suite à une erreur (code de sortie non nul)
|
on-failure Redémarre le conteneur s'il crash suite à une erreur (code de sortie non nul)
|
||||||
always Toujours redémarrer le conteneur s’il s’arrête. S'il est arrêté manuellement, il est redémarré uniquement lorsque le démon Docker redémarre ou que le conteneur lui-même est redémarré manuellement.
|
always Toujours redémarrer le conteneur s’il s’arrête. S'il est arrêté manuellement, il est redémarré uniquement lorsque le démon Docker redémarre ou que le conteneur lui-même est redémarré manuellement.
|
||||||
unless-stopped Semblable à always, sauf que lorsque le conteneur est arrêté (manuellement ou autrement), il n'est pas redémarré même après le redémarrage du démon Docker.
|
unless-stopped Semblable à always, sauf que lorsque le conteneur est arrêté (manuellement ou autrement), il n'est pas redémarré même après le redémarrage du démon Docker.
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Pour mettre à jour la politique :
|
Pour mettre à jour la politique :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ docker update --restart=always monconteneur
|
$ docker update --restart=always monconteneur
|
||||||
~~~
|
```
|
||||||
|
|
||||||
#### Supprimer un conteneur
|
#### Supprimer un conteneur
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ docker rm <ID ou nom du 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>
|
$ docker exec <ID ou nom du conteneur> <commande>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Options utiles :
|
Options utiles :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
-t : alloue un TTY
|
-t : alloue un TTY
|
||||||
-i : attache stdin (mode interactif)
|
-i : attache stdin (mode interactif)
|
||||||
~~~
|
```
|
||||||
|
|
||||||
On utilise habituellement la commande suivante pour obtenir un shell dans un conteneur en fonctionnement :
|
On utilise habituellement la commande suivante pour obtenir un shell dans un conteneur en fonctionnement :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ docker exec -ti <ID ou nom du conteneur> bash
|
$ 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
|
Il s'agit en fait de la sortie standard et la sortie d'erreur du processus
|
||||||
lancé à l'intérieur du conteneur :
|
lancé à l'intérieur du conteneur :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ docker logs <ID ou nom du conteneur>
|
$ docker logs <ID ou nom du conteneur>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Options utiles :
|
Options utiles :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
-f : suivre les logs en direct
|
-f : suivre les logs en direct
|
||||||
-t : afficher un timestamp devant chaque ligne
|
-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>
|
$ docker inspect <ID ou nom du conteneur>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Cette commande s'applique généralement à n'importe quel objet Docker
|
Cette commande s'applique généralement à n'importe quel objet Docker
|
||||||
(conteneur, image, service, réseau…) et donne une liste exhaustive des
|
(conteneur, image, service, réseau…) et donne une liste exhaustive des
|
||||||
|
@ -275,100 +276,99 @@ attributs de l'objet, formaté en JSON.
|
||||||
|
|
||||||
Il est aussi possible de récupérer une sous partie en utilisant l'argument --format
|
Il est aussi possible de récupérer une sous partie en utilisant l'argument --format
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# Récupérer les IP du container d05daab5c59e
|
# Récupérer les IP du container d05daab5c59e
|
||||||
$ docker inspect d05daab5c59e --format "{{range .NetworkSettings.Networks }}{{ .IPAddress }}{{ end }}"
|
$ docker inspect d05daab5c59e --format "{{range .NetworkSettings.Networks }}{{ .IPAddress }}{{ end }}"
|
||||||
# Récupérer l'IP du container f4bae02ef1407adc92f1aa2cc32c8e9fae75dac87126e2bf4964db265e9ad55d sur l'interface docker_gwbridge
|
# Récupérer l'IP du container f4bae02ef1407adc92f1aa2cc32c8e9fae75dac87126e2bf4964db265e9ad55d sur l'interface docker_gwbridge
|
||||||
$ docker inspect docker_gwbridge --format "{{ .Containers.f4bae02ef1407adc92f1aa2cc32c8e9fae75dac87126e2bf4964db265e9ad55d.IPv4Address }}"
|
$ docker inspect docker_gwbridge --format "{{ .Containers.f4bae02ef1407adc92f1aa2cc32c8e9fae75dac87126e2bf4964db265e9ad55d.IPv4Address }}"
|
||||||
~~~
|
```
|
||||||
|
|
||||||
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 )
|
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
|
$ docker image ls
|
||||||
~~~
|
```
|
||||||
|
|
||||||
#### Construire une image
|
#### Construire une image
|
||||||
|
|
||||||
Pour construire ou mettre à jour une image :
|
Pour construire ou mettre à jour une image :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ docker build <repertoire>
|
$ docker build <repertoire>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Le répertoire doit contenir un fichier _Dockerfile_ décrivant l'image à
|
Le répertoire doit contenir un fichier _Dockerfile_ décrivant l'image à
|
||||||
construire.
|
construire.
|
||||||
|
|
||||||
Option utiles :
|
Option utiles :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
-t : ajoute un tag à l'image
|
-t : ajoute un tag à l'image
|
||||||
~~~
|
```
|
||||||
|
|
||||||
#### Ajouter un tag à une image existante
|
#### Ajouter un tag à une image existante
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ docker tag <tag actuel> <nouveau tag>
|
$ 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>
|
$ docker push <image>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Avant de pousser une image, il est nécessaire de lui attribuer le bon _tag_ qui
|
Avant de pousser une image, il est nécessaire de lui attribuer le bon _tag_ qui
|
||||||
doit contenir l'adresse du dépôt distant.
|
doit contenir l'adresse du dépôt distant.
|
||||||
|
|
||||||
Par exemple pour pousser l'image _foo-image_ sur le dépôt Docker _registry.example.net:5000_ :
|
Par exemple pour pousser l'image _foo-image_ sur le dépôt Docker _registry.example.net:5000_ :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ docker tag foo-image registry.example.net:5000/foo-image
|
$ docker tag foo-image registry.example.net:5000/foo-image
|
||||||
$ docker push 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>
|
$ docker pull <image>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
#### Copier des fichiers dans/depuis un conteneur
|
#### Copier des fichiers dans/depuis un conteneur
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ docker cp <fichier> <conteneur>:<chemin>
|
$ docker cp <fichier> <conteneur>:<chemin>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
On peut aussi le faire de conteneur à conteneur :
|
On peut aussi le faire de conteneur à conteneur :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ docker cp <conteneurA>:<fichier> <conteneurB>:<chemin>
|
$ docker cp <conteneurA>:<fichier> <conteneurB>:<chemin>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
### Astuces
|
### Astuces
|
||||||
|
|
||||||
Éteindre/Tuer/Supprimer tous les conteneurs :
|
Éteindre/Tuer/Supprimer tous les conteneurs :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ docker ps -aq |xargs -r docker stop|kill|rm
|
$ docker ps -aq |xargs -r docker stop|kill|rm
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Supprimer toutes les images :
|
Supprimer toutes les images :
|
||||||
|
|
||||||
~~~
|
```bash
|
||||||
$ docker images -q |xargs -r docker image rm
|
$ docker images -q |xargs -r docker image rm
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Démarrer un conteneur existant avec un shell bash (pour des fins de debug par exemple) :
|
Démarrer un conteneur existant avec un shell bash (pour des fins de debug par exemple) :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ docker run -it IMAGE bash
|
$ docker run -it IMAGE bash
|
||||||
~~~
|
```
|
||||||
|
|
||||||
## Dockerfile
|
## Dockerfile
|
||||||
|
|
||||||
|
@ -384,9 +384,9 @@ Référence pour la syntaxe des fichiers _Dockerfile_ : [https://docs.docker.com
|
||||||
|
|
||||||
Exemple avec une image exécutant rsyslog :
|
Exemple avec une image exécutant rsyslog :
|
||||||
|
|
||||||
- depuis un répertoire vierge, création d'un fichier _Dockerfile_ :
|
- depuis un répertoire vierge, création d'un fichier _Dockerfile_ :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
~/docker-images/rsyslog $ $EDITOR Dockerfile
|
~/docker-images/rsyslog $ $EDITOR Dockerfile
|
||||||
|
|
||||||
# Image sur laquelle notre image se base
|
# Image sur laquelle notre image se base
|
||||||
|
@ -415,20 +415,20 @@ EXPOSE 514/udp
|
||||||
|
|
||||||
# La commande suivante est exécutée lorsque le conteneur est exécuté
|
# La commande suivante est exécutée lorsque le conteneur est exécuté
|
||||||
CMD /usr/sbin/rsyslogd -n
|
CMD /usr/sbin/rsyslogd -n
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Dans la mesure du possible, voici quelques bonnes pratiques à respecter :
|
Dans la mesure du possible, voici quelques bonnes pratiques à respecter :
|
||||||
|
|
||||||
- la commande spécifiée par _CMD_ doit s'exécuter en avant plan et ne pas
|
- la commande spécifiée par _CMD_ doit s'exécuter en avant plan et ne pas
|
||||||
forker. Si la commande rend la main, le conteneur sera alors arrêté ;
|
forker. Si la commande rend la main, le conteneur sera alors arrêté ;
|
||||||
- la commande doit envoyer ses logs sur stdout et/ou stderr. Cela permet de
|
- la commande doit envoyer ses logs sur stdout et/ou stderr. Cela permet de
|
||||||
les consulter directement à l'aide de `docker logs`.
|
les consulter directement à l'aide de `docker logs`.
|
||||||
|
|
||||||
Un exemple à ne **pas** écrire :
|
Un exemple à ne **pas** écrire :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
CMD /usr/bin/foo -d; tail -f /var/log/foo.log
|
CMD /usr/bin/foo -d; tail -f /var/log/foo.log
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Dans le cas où `/usr/bin/foo -d` lance le démon foo en arrière plan, le
|
Dans le cas où `/usr/bin/foo -d` lance le démon foo en arrière plan, le
|
||||||
conteneur s'exécutera correctement mais Docker va monitorer le processus tail
|
conteneur s'exécutera correctement mais Docker va monitorer le processus tail
|
||||||
|
@ -438,15 +438,15 @@ pourra pas être redémarré automatiquement.
|
||||||
À supposer que foo ne puisse pas envoyer ses logs sur stdout, le bon example
|
À supposer que foo ne puisse pas envoyer ses logs sur stdout, le bon example
|
||||||
serait :
|
serait :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
CMD touch /var/log/foo.log && tail -f /var/log/foo.log & /usr/bin/foo
|
CMD touch /var/log/foo.log && tail -f /var/log/foo.log & /usr/bin/foo
|
||||||
~~~
|
```
|
||||||
|
|
||||||
À noter que seulement une seule directive `CMD` est acceptée dans un _Dockerfile_.
|
À noter que seulement une seule directive `CMD` est acceptée dans un _Dockerfile_.
|
||||||
|
|
||||||
On peut ensuite construire notre image, en lui donnant ici le _tag_ _rsyslog_ :
|
On peut ensuite construire notre image, en lui donnant ici le _tag_ _rsyslog_ :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
~/docker-images/rsyslog $ ls
|
~/docker-images/rsyslog $ ls
|
||||||
Dockerfile custom.conf
|
Dockerfile custom.conf
|
||||||
~/docker-images/rsyslog $ docker build -t rsyslog .
|
~/docker-images/rsyslog $ docker build -t rsyslog .
|
||||||
|
@ -454,7 +454,7 @@ Dockerfile custom.conf
|
||||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||||
rsyslog latest 4bea99cda08c 8 minutes ago 470MB
|
rsyslog latest 4bea99cda08c 8 minutes ago 470MB
|
||||||
debian stretch 5b712ae16dd7 3 days ago 100MB
|
debian stretch 5b712ae16dd7 3 days ago 100MB
|
||||||
~~~
|
```
|
||||||
|
|
||||||
## Utilisation avancée
|
## Utilisation avancée
|
||||||
|
|
||||||
|
@ -464,7 +464,7 @@ Un _docker registry_ permet d'héberger des images Docker.
|
||||||
|
|
||||||
On peut le déployer avec la _stack_ suivante :
|
On peut le déployer avec la _stack_ suivante :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
version: "3.6"
|
version: "3.6"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
@ -492,24 +492,24 @@ volumes:
|
||||||
secrets:
|
secrets:
|
||||||
certificate:
|
certificate:
|
||||||
file: certificate.pem
|
file: certificate.pem
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Attention, le certificat doit absolument être valide et le Common Name doit correspondre avec le nom utilisé pour y accéder.
|
Attention, le certificat doit absolument être valide et le Common Name doit correspondre avec le nom utilisé pour y accéder.
|
||||||
|
|
||||||
Lors d'un déploiement d'une stack existante, en cas d'erreur :
|
Lors d'un déploiement d'une stack existante, en cas d'erreur :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
image registrydocker.example.com:5000/XXX could not be accessed on a registry to record
|
image registrydocker.example.com:5000/XXX could not be accessed on a registry to record
|
||||||
its digest. Each node will access registrydocker.example.com:5000/XXX independently,
|
its digest. Each node will access registrydocker.example.com:5000/XXX independently,
|
||||||
possibly leading to different nodes running different
|
possibly leading to different nodes running different
|
||||||
versions of the image.
|
versions of the image.
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Il peut s'agir de différents problèmes (réseau, SSL, etc…), Docker n'est pas très bavard sur la cause de l'échec. Un bon moyen de déboguer la situation est avec :
|
Il peut s'agir de différents problèmes (réseau, SSL, etc…), Docker n'est pas très bavard sur la cause de l'échec. Un bon moyen de déboguer la situation est avec :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ curl https://registrydocker.example.com:5000/v2/_catalog
|
$ curl https://registrydocker.example.com:5000/v2/_catalog
|
||||||
~~~
|
```
|
||||||
|
|
||||||
La requête devrait retourner la liste des images hébergées au format json.
|
La requête devrait retourner la liste des images hébergées au format json.
|
||||||
|
|
||||||
|
@ -521,15 +521,15 @@ plusieurs machines.
|
||||||
|
|
||||||
#### Initialiser le cluster
|
#### Initialiser le cluster
|
||||||
|
|
||||||
~~~
|
```
|
||||||
docker0# docker swarm init
|
docker0# docker swarm init
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Joindre les autres machines au cluster créé (il vous suffit généralement de copier-coller la commande retournée par `docker swarm init` :
|
Joindre les autres machines au cluster créé (il vous suffit généralement de copier-coller la commande retournée par `docker swarm init` :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
docker1# docker swarm join --token <token> <IP du premier node>
|
docker1# docker swarm join --token <token> <IP du premier node>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Par défaut la machine sur laquelle le cluster a été initialisée a le rôle de
|
Par défaut la machine sur laquelle le cluster a été initialisée a le rôle de
|
||||||
_manager_, et les suivantes ont le rôle de _worker_. On ne peut déployer de
|
_manager_, et les suivantes ont le rôle de _worker_. On ne peut déployer de
|
||||||
|
@ -538,21 +538,21 @@ recevoir les services à rouler.
|
||||||
|
|
||||||
Pour ajouter des machines plus tard, il suffit de générer un nouveau token :
|
Pour ajouter des machines plus tard, il suffit de générer un nouveau token :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
docker0# docker swarm join-token <manager|worker>
|
docker0# docker swarm join-token <manager|worker>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
#### Lister les machines du cluster
|
#### Lister les machines du cluster
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# docker node ls
|
# docker node ls
|
||||||
~~~
|
```
|
||||||
|
|
||||||
#### Ajouter des labels à une machine
|
#### Ajouter des labels à une machine
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# docker node update --label-add <clé>=<valeur> <machine>
|
# docker node update --label-add <clé>=<valeur> <machine>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Les _labels_ servent notamment à définir des contraintes de placement des
|
Les _labels_ servent notamment à définir des contraintes de placement des
|
||||||
services lors de l'utilisation de _docker stack_.
|
services lors de l'utilisation de _docker stack_.
|
||||||
|
@ -565,35 +565,35 @@ L'infra est à décrire dans un fichier YAML.
|
||||||
|
|
||||||
Déployer (ou mettre à jour à chaud) une nouvelle _stack_ :
|
Déployer (ou mettre à jour à chaud) une nouvelle _stack_ :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# docker stack deploy -c <stack_name.yml> <stack name>
|
# docker stack deploy -c <stack_name.yml> <stack name>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Lister les _stacks_ :
|
Lister les _stacks_ :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# docker stack ls
|
# docker stack ls
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Lister les _services_, toutes _stacks_ confondues ou pour une _stack_ donnée :
|
Lister les _services_, toutes _stacks_ confondues ou pour une _stack_ donnée :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# docker service ls
|
# docker service ls
|
||||||
# docker stack services <stack name>
|
# docker stack services <stack name>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Lister les _tasks_ (replicas) d'une _stack_ ou d'un _service_ donné :
|
Lister les _tasks_ (replicas) d'une _stack_ ou d'un _service_ donné :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# docker stack ps <stack name>
|
# docker stack ps <stack name>
|
||||||
# docker service ps <service name>
|
# docker service ps <service name>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Supprimer une _stack_ :
|
Supprimer une _stack_ :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# docker stack rm <stack name>
|
# docker stack rm <stack name>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
### Réseaux (docker network)
|
### Réseaux (docker network)
|
||||||
|
|
||||||
|
@ -601,30 +601,40 @@ Docker permet de gérer différentes topologies de réseaux pour connecter les c
|
||||||
|
|
||||||
_drivers_ réseau supportés :
|
_drivers_ réseau supportés :
|
||||||
|
|
||||||
- _bridge_ : utilise les bridges Linux ;
|
- _bridge_ : utilise les bridges Linux, chaque bridge est isolée des autre reseaux et docker et permet de resoudre les noms des conteneurs au sein du bridge.
|
||||||
- _overlay_ : utilisé dans le cas d'un cluster Swarm, permet d'avoir un
|
|
||||||
réseau unique partagé entre tous les hôtes Docker et permet de faire du
|
- _host_ : Aucune isolation réseaux, le conteneur tourne comme un processus normal dans le namespace par défaut : il partage le réseaux avec son hôte.
|
||||||
load-balancing entre les conteneurs (replicas) d'un service ;
|
|
||||||
- _macvlan_ : permet d'assigner directement des adresses IP publiques aux
|
- _overlay_ : utilisé dans le cas d'un cluster Swarm, permet d'avoir un
|
||||||
conteneurs, donc aucun NAT n'est fait contrairement aux précédents.
|
réseau unique partagé entre tous les hôtes Docker et permet de faire du
|
||||||
|
load-balancing entre les conteneurs (replicas) d'un service ;
|
||||||
|
|
||||||
|
- _macvlan_ : permet d'assigner directement des adresses IP publiques aux
|
||||||
|
conteneurs (chaque conteneur à une mac unique), donc aucun NAT n'est fait contrairement aux précédents.
|
||||||
|
|
||||||
|
> Attention l'interface de l'hôte doit être configurée pour fonctionner en mode "promiscuité" pour que cela fonctionne.
|
||||||
|
|
||||||
|
- _ipvlan_ : Comme _macvlan_ sauf que la mac utilisée est celle de l'hôte donc pas besoin d'activer la promiscuité.
|
||||||
|
|
||||||
|
- _none_ : Isolation complete du conteneur
|
||||||
|
|
||||||
Créer un réseau :
|
Créer un réseau :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# docker create -d <driver> […] <network name>
|
# docker create -d <driver> […] <network name>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Lister les réseaux créés :
|
Lister les réseaux créés :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# docker network ls
|
# docker network ls
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Informations détaillées sur un réseau :
|
Informations détaillées sur un réseau :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# docker network inspect <network name>
|
# docker network inspect <network name>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
### Volumes (docker volume)
|
### Volumes (docker volume)
|
||||||
|
|
||||||
|
@ -643,7 +653,7 @@ _/var/lib/docker/volumes/"nom du volume"/\_data/_.
|
||||||
|
|
||||||
On peut gérer les volumes avec la commande `docker volume` :
|
On peut gérer les volumes avec la commande `docker volume` :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# docker volume create vol1
|
# docker volume create vol1
|
||||||
vol1
|
vol1
|
||||||
# docker volume ls
|
# docker volume ls
|
||||||
|
@ -651,7 +661,7 @@ DRIVER VOLUME NAME
|
||||||
local vol1
|
local vol1
|
||||||
# docker volume rm vol1
|
# docker volume rm vol1
|
||||||
vol1
|
vol1
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Dans le cas d'un cluster Docker Swarm, les volumes ne sont pas répliqués entre
|
Dans le cas d'un cluster Docker Swarm, les volumes ne sont pas répliqués entre
|
||||||
les membres du cluster. Si un conteneur monte un volume, il faut bien penser à
|
les membres du cluster. Si un conteneur monte un volume, il faut bien penser à
|
||||||
|
@ -676,9 +686,9 @@ volume.
|
||||||
Les _config_ ne peuvent pas non plus être mis à jour lors d'un redéploiement de
|
Les _config_ ne peuvent pas non plus être mis à jour lors d'un redéploiement de
|
||||||
stack :
|
stack :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
failed to update config foo: Error response from daemon: rpc error: code = InvalidArgument desc = only updates to Labels are allowed
|
failed to update config foo: Error response from daemon: rpc error: code = InvalidArgument desc = only updates to Labels are allowed
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Il faut obligatoirement soit supprimer l'objet _config_ et donc les objets qui
|
Il faut obligatoirement soit supprimer l'objet _config_ et donc les objets qui
|
||||||
en dépendent (conteneurs), soit créer un nouveau _config_ (avec un nouveau nom
|
en dépendent (conteneurs), soit créer un nouveau _config_ (avec un nouveau nom
|
||||||
|
@ -689,7 +699,7 @@ Les _config_ se gèrent avec la commande `docker config`. Le serveur doit avoir
|
||||||
le rôle _manager_ dans le cluster Swarm pour pouvoir créer un objet _config_,
|
le rôle _manager_ dans le cluster Swarm pour pouvoir créer un objet _config_,
|
||||||
puisque cela impacte l'ensemble du cluster :
|
puisque cela impacte l'ensemble du cluster :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# docker config create vim-config .vimrc
|
# docker config create vim-config .vimrc
|
||||||
07kaw58mhvtkqem46ipkd97i1
|
07kaw58mhvtkqem46ipkd97i1
|
||||||
# docker config ls
|
# docker config ls
|
||||||
|
@ -697,7 +707,7 @@ ID NAME DRIVER
|
||||||
07kaw58mhvtkqem46ipkd97i1 vim-config Less than a second ago Less than a second ago
|
07kaw58mhvtkqem46ipkd97i1 vim-config Less than a second ago Less than a second ago
|
||||||
# docker config rm vim-config
|
# docker config rm vim-config
|
||||||
vim-config
|
vim-config
|
||||||
~~~
|
```
|
||||||
|
|
||||||
### Fichiers sensibles (docker secrets)
|
### Fichiers sensibles (docker secrets)
|
||||||
|
|
||||||
|
@ -735,7 +745,7 @@ Référence sur le format du fichier :
|
||||||
|
|
||||||
Voici un aperçu :
|
Voici un aperçu :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ cat ma-stack.yml
|
$ cat ma-stack.yml
|
||||||
version: "3.6"
|
version: "3.6"
|
||||||
|
|
||||||
|
@ -782,7 +792,7 @@ configs:
|
||||||
secrets:
|
secrets:
|
||||||
ssl_cert:
|
ssl_cert:
|
||||||
file: example.com.pem
|
file: example.com.pem
|
||||||
~~~
|
```
|
||||||
|
|
||||||
On lance ici 2 _services_, _web_ et _mysql_. On spécifie que _web_ doit avoir 2
|
On lance ici 2 _services_, _web_ et _mysql_. On spécifie que _web_ doit avoir 2
|
||||||
réplicas, il y aura donc 2 _tasks_ (et donc 2 conteneurs) qui seront démarrés,
|
réplicas, il y aura donc 2 _tasks_ (et donc 2 conteneurs) qui seront démarrés,
|
||||||
|
@ -808,11 +818,11 @@ contrainte de placement pour _web_.
|
||||||
|
|
||||||
Ensuite on peut déployer notre _stack_ :
|
Ensuite on peut déployer notre _stack_ :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ ls
|
$ ls
|
||||||
ma-stack.yml nginx.conf example.com.pem
|
ma-stack.yml nginx.conf example.com.pem
|
||||||
$ docker stack deploy -c ma-stack.yml ma-stack
|
$ docker stack deploy -c ma-stack.yml ma-stack
|
||||||
~~~
|
```
|
||||||
|
|
||||||
#### Surcharge de paramètre
|
#### Surcharge de paramètre
|
||||||
|
|
||||||
|
@ -823,7 +833,7 @@ fusionnés. Cela permet de réutiliser un fichier de _stack_ pour différents
|
||||||
environnement (preprod, prod…) en changeant uniquement des variables
|
environnement (preprod, prod…) en changeant uniquement des variables
|
||||||
d'environement, mots de passe, etc…
|
d'environement, mots de passe, etc…
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ cat ma-stack.dev.yml
|
$ cat ma-stack.dev.yml
|
||||||
version: "3.6"
|
version: "3.6"
|
||||||
services:
|
services:
|
||||||
|
@ -833,13 +843,13 @@ services:
|
||||||
- MYSQL_DB=foo_dev
|
- MYSQL_DB=foo_dev
|
||||||
- MYSQL_USER=foo_dev
|
- MYSQL_USER=foo_dev
|
||||||
- MYSQL_PASS=deb2Ozpifut?
|
- MYSQL_PASS=deb2Ozpifut?
|
||||||
~~~
|
```
|
||||||
|
|
||||||
On peut ensuite déployer ainsi :
|
On peut ensuite déployer ainsi :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ docker stack deploy -c ma-stack.yml -c ma-stack.dev.yml ma-stack
|
$ docker stack deploy -c ma-stack.yml -c ma-stack.dev.yml ma-stack
|
||||||
~~~
|
```
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
|
@ -851,9 +861,9 @@ effacé les règles spécifiques à Docker, notamment dans la table _nat_.
|
||||||
Pour restaurer les règles netfilter de Docker, il n'y a pas d'autre moyen que
|
Pour restaurer les règles netfilter de Docker, il n'y a pas d'autre moyen que
|
||||||
de redémarrer le démon :
|
de redémarrer le démon :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# /etc/init.d/docker restart
|
# /etc/init.d/docker restart
|
||||||
~~~
|
```
|
||||||
|
|
||||||
### Espace insuffisant lors du build d'une image
|
### Espace insuffisant lors du build d'une image
|
||||||
|
|
||||||
|
@ -870,9 +880,9 @@ Solutions:
|
||||||
|
|
||||||
Vérifier que le tag _latest_ est bien précisé dans le nom de l'image dans le _docker-stack.yml_ :
|
Vérifier que le tag _latest_ est bien précisé dans le nom de l'image dans le _docker-stack.yml_ :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
image: registrydocker.example.com:5000/foo:latest
|
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é) ?
|
||||||
|
|
||||||
|
@ -881,9 +891,9 @@ Il faut bloquer le port en question dans le pare-feu, dans la chaîne iptables D
|
||||||
|
|
||||||
Pour bloquer l'accès au _registry_ Docker depuis l'extérieur par exemple :
|
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
|
# 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é.
|
||||||
|
|
||||||
|
@ -893,34 +903,46 @@ Stopper le conteneur du service avec un `docker stop <conteneur du service>`. Do
|
||||||
|
|
||||||
L'adresse IP virtuelle qui redirige aléatoirement sur chacune des _tasks_ (si le réseau utilise le driver _overlay_, cas par défaut) :
|
L'adresse IP virtuelle qui redirige aléatoirement sur chacune des _tasks_ (si le réseau utilise le driver _overlay_, cas par défaut) :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ getent hosts <nom du service>
|
$ getent hosts <nom du service>
|
||||||
~~~
|
```
|
||||||
|
|
||||||
L'adresse IP des différentes _tasks_ d'un service :
|
L'adresse IP des différentes _tasks_ d'un service :
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ getent hosts tasks.<nom du 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
|
Docker et autres technologies de conteneurs, utilisent des namespace
|
||||||
linux pour isoler les processus. L’utilité pgrep(1) est capable
|
linux pour isoler les processus. L’utilité pgrep(1) est capable
|
||||||
de filtrer les processus par namespace sur la base d’un autre
|
de filtrer les processus par namespace sur la base d’un autre
|
||||||
processus.
|
processus.
|
||||||
|
|
||||||
~~~
|
```
|
||||||
$ pgrep --ns $dockerPID $query
|
$ pgrep --ns $dockerPID $query
|
||||||
~~~
|
```
|
||||||
|
|
||||||
Ce concept provient du système Plan9
|
Ce concept provient du système Plan9
|
||||||
|
|
||||||
|
### 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/`.
|
||||||
|
|
||||||
|
On peut monter `/proc/${pid_conteneur}/ns/` dans `var/run/netns/` pour utiliser ip OU plus simplement utiliser nsenter à la place :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# nsenter -t $pid_conteneur -n
|
||||||
|
```
|
||||||
|
|
||||||
|
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 l'interface docker0
|
Vous devez autoriser l'interface docker0
|
||||||
|
|
||||||
~~~
|
```
|
||||||
# Autorisation Docker
|
# Autorisation Docker
|
||||||
/sbin/iptables -A INPUT -i docker0 -j ACCEPT
|
/sbin/iptables -A INPUT -i docker0 -j ACCEPT
|
||||||
~~~
|
```
|
||||||
|
|
Loading…
Reference in a new issue