Older versions of Docker were called docker
, docker.io
, ou docker-engine
. If these are installed, uninstall them:
apt-get remove docker docker-engine docker.io containerd runc
It’s OK if apt-get
reports that none of these packages are installed.
The contents of /var/lib/docker/, including images, containers, volumes, and networks, are preserved. The Docker Engine package is now called docker-ce
.
apt-get update
apt-get dist-upgrade -y
apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
apt-key fingerprint 0EBFCD88
pub 4096R/0EBFCD88 2017-02-22
Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid Docker Release (CE deb) <docker@docker.com>
sub 4096R/F273FCD8 2017-02-22
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
apt-get update
apt-get install docker-ce docker-ce-cli containerd.io
docker run hello-world
Older versions of Docker were called docker
, docker.io
, ou docker-engine
. If these are installed, uninstall them:
apt-get remove docker docker-engine docker.io containerd runc
It’s OK if apt-get
reports that none of these packages are installed.
The contents of /var/lib/docker/, including images, containers, volumes, and networks, are preserved. The Docker Engine package is now called docker-ce
.
apt-get update
apt-get dist-upgrade -y
apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
apt-key fingerprint 0EBFCD88
pub 4096R/0EBFCD88 2017-02-22
Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid Docker Release (CE deb) <docker@docker.com>
sub 4096R/F273FCD8 2017-02-22
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian \
$(lsb_release -cs) \
stable"
apt-get update
apt-get install docker-ce docker-ce-cli containerd.io
docker run hello-world
Pour configurer le client docker, créer ou editer le fichier ~/.docker/config.json
dans le répertoire home de l'utilisateur.
Configurer un Proxy :
{
"proxies":
{
"default":
{
"httpProxy": "http://LOGIN:PASSWORD@IP:PORT",
"httpsProxy": "http://LOGIN:PASSWORD@IP:PORT"
}
}
}
Avec Powershell:
Ouvrir Powershell en tant qu'administrateur
Executer la commande : & 'C:\Program Files\Docker\Docker\DockerCli.exe' -SwitchDaemon
Avec Cmd:
Ouvrir Powershell en tant qu'administrateur
Executer la commande : "C:\Program Files\Docker\Docker\DockerCli.exe" -SwitchDaemon
Vérifier que docker soit fonctionnel :
docker version
docker run hello-world
Le format des commandes docker peut se faire de deux manière differente, la nouvelle méthode qui sera priviliégier :
docker <command> <sub-command> (options)
par exemple : docker container run -it <docker-name>
L'ancienne méthode qui fonctionne toujours est du type :
docker <command> (options)
par exemple : docker run -it <docker-name>
pour facilité l'utilisation de docker, il est possible d'ajouter un utilisateur au groupe docker avec cette commande :
sudo usermod -aG docker davidlim
les a pour add et g pour groupe. on ajoute alors l'utilisateur davidlim au groupe d'utilisation docker.
docker version
: donne la version de docker
docker info
: donne des informations sur le OS etc.
docker container ps
: donne la liste des docker avec des processus actif
docker ls -a
voir les dockers lancés et l'historique de creation
docker container logs (docker-name)
: donne les indo des log du conteneur s'il en a.
docker container top (docker-name)
: donne les information de consoomation du conteneur en mémoire et cpu
docker cp <file_name> <running_docker_name>:/destination_path
permet de copier un fichier de l'hôte vers dans le docker.
Difference entre une image et un conteneur :
Une image est l'application ou le binaire qui contienne tous les code que nous voulons lancer
Le containeur va contenir l'image, il va 'conteneuriser'. Lorsque qu'une instance de docker est lancer le paramétrage du docker sera persistant jusqu'a sa destruction (remove).
Exemple d'une commande
docker container run --publish 80:80 nginx
si l'image n'existe pas en local docker va le chercher sur le docker hub la dernière version si nous ne specifions pas la version
docker container run --publish 80:80 --detach nginx
detach permet de détacher le process et lancer en arrière plan.
A la création d'un docker un nom est généré de manière aléatoire en associant un nom commun à un adjectif mais il est possible lors de la création d'en spécifier un avec l'option --name
.
docker container run --publish 80:80 --detach --name webhost nginx
pour specifier un nom à un docker.
docker container stop (docker-name)
pour arreter le docker
docker ls -a
voir les docker lancer et l'historique de creation. on peux voir alors lorsqu'un docker est arrêter qu'il est pas "détruit" completement. Pour le détruire il faut utiliser la commande remove. Attention cependant un docker peut etre détruit seulement s'il est arreté pour plus de sécurité, il est toutefois possible de forcé la destruction d'un docker en cour d'utilisation avec l'option -f pour forced.
docker container rm
: destruction d'un docker
docker container rm -f
: forcer la destruction d'un docker deleted a container
Au lancement d'un conteneur celui ci se connecte à un réseau virtuel privée. par default ce réseau, aussi appelé bridge est nommé docker0. Ces réseau est virtuel est de niveau applicatif et concerne tous les dockers ainsi instanciés.
Chaque docker est configuré avec des régle nat firewall sur le réseau physique de l'hôte. Nous allons donc utilise l'option -p
pour publish par exemple :
docker container run --publish 8080:80 --detach nginx
redirection du port 8080 de l'hôte vers le port 80 du docker.
Les dockers peuvent communiquer entre eux a partir du moment qu'il sont sur le même réseau virtuel privé.
Un bonne pratique est alors de crée un réseau virtuel privé pour une application, par exemple :
docker container port <docker_name>
permet de montrer quel redirection de port est mis en place de l'hôte vers le docker.
docker container inspect --format '{{ ,NetworkSettings,IPAddress }}' <docker_name>
donne l'ip adresse du conteneur
docker network ls
montre les réseau virtuel par défaut il y en au moins deux :
docker network inspect <netwoek_id>
montre les information réseau des conteneur
docker network create <network_name>
créer un réseau par exemple docker network create my_app
pour créer un réseau virtuel my_app
Il est possible de créer directement le réseau à la création du docker : docker container run --publish 80:80 --network my_app nginx
docker network connect <network_name> <docker_name>
connecter un conteneur vers un réseau
docker network disconnect <network_name> <docker_name>
deconnecter un conteneur d'un réseau
Cette partie concerne un service DNS fourni dans docker, celui permet de gérer les communications facilement entre les differents conteneurs par leurs noms de domaine.
Il est alors posible par exemple lors d'un ping d'atteindre les dockers par leurs noms : sudo docker container exec -it newnginx1 ping newnginx2
avec newnginx1 et newnginx2 qui appartiennent au même réseau virtuel privé.
l'image nginx ne comporte plus le binaire ping, il faut utilisé l'image nginx:alpine qui possède l'application ping.
L'utilisation des noms de domain dans docker est recommandé, lors de la création/ lancement des dockers, les adresse ip sont généré selon leurs ordre de création par conséquent elles peuvent variées en fonction du l'ordre d'attribution du service DCHP.
C'est alors plus pratique d'utilisé les noms des differents docker.
Si vous devez retenir une leçon aujourd’hui, c’est la règle générale suivante : ENTRYPOINT
+ CMD
= arguments de la commande du conteneur par défaut
Sous réserve de :
ENTRYPOINT
et CMD
, respectivement, dans un contexte de liste (array).Pour démontrer les avantages des ENTRYPOINT
, nous utilisons Chamber , un utilitaire open source qui alimente l’environnement du conteneur avec les valeurs trouvées dans AWS Systems Manager Parameter Store . Un appel typique de la commande est chamber exec production -- program
pour extraire toutes les valeurs du Parameter Store dont la clef présente le préfixe /production
, pour convertir les “/” des clés en undescore “_” et remplir les variables d’environnement avec les clés et les valeurs renvoyées.
Par exemple, si dans le Parameter Store il y a une clé /production/mysql/password
, Chamber définira la variable d’environnement MYSQL_PASSWORD
avec la valeur sécurisée à l’intérieur.
Commençons par un exemple. Voici un extrait de fichier de Dockerfile
qui comporte à la fois un ENTRYPOINT
et un CMD
, tous deux spécifiés en tant que liste (array):
ENTRYPOINT ["/bin/chamber", "exec", "production", "--"]
CMD ["/bin/service", "-d"]
En réunissant les commandes, les arguments par défaut du conteneur seront ["/bin/chamber","exec", "production", "--","/bin/service", "-d"]
.
Cette liste se rapproche approximativement de la commande shell /bin/chamber exec production -- /bin/service -d
. (En fait, cela concerne ce que font principalement les shells: ils prennent des “commandes” séparées par des espaces à l’invite, puis les transforment en liste d’arguments à transmettre à l’ appel système exec)
Il est important de comprendre que, dans un fichier Dockerfile
, ENTRYPOINT
,et CMD
les entrées sont toujours convertis en listes, même si vous les déclarez en tant que chaînes de caractères. (Nous recommandons toujours de les déclarer comme liste, cependant, pour éviter toute ambiguïté.)
Supposons que nous déclarions une instruction CMD
qui démarre un serveur Web comme suit:
CMD /usr/bin/httpd -DFOREGROUND
Docker convertira automatiquement CMD en une liste ressemblant à ceci:
["/bin/sh", "-c", "/usr/bin/httpd -DFOREGROUND"]
L’entrée ENTRYPOINT
fonctionne de la même manière.
Ainsi, lorsque nous déclarons à la fois un ENTRYPOINT
et une entrée CMD
, et que ENTRYPOINT
est declaré comme liste, les deux sont concaténées ensemble pour former une liste d’arguments par défaut, même si nous déclarons CMD comme chaîne de caractères.
Voici un exemple qui illustre ce point. Si nous déclarons ce qui suit:
ENTRYPOINT ["/bin/chamber", "exec", "production", "--"]
CMD "/bin/service -d"
La liste d’arguments par défaut sera ["/bin/chamber", "exec", "production", "--", "/bin/sh", "-c", "/bin/service -d"]
.
Remarque: ENTRYPOINT
et CMD
ne peuvent pas être declarés en tant que chaîne de caractères ensemble. Ils peuvent tous deux être des listes, et ENTRYPOINT
peut être une liste et CMD
peut être une chaîne de caractères; mais si ENTRYPOINT
est une chaîne de caractères, CMD
sera ignoré. Ceci est une conséquence fâcheuse mais inévitable de la façon dont les chaînes d’arguments sont converties en listes. C’est l’une des raisons pour lesquelles nous recommandons toujours de spécifier des listes autant que possible.
La spécification CMD
dans un Dockerfile simple crée une valeur par défaut: si nous passons des arguments sans option à docker run
, ils écraseront la valeur CMD
.
Pour illustrer cela, supposons que nous ayons les éléments suivants Dockerfile
et en créons une image appelée myservice
:
ENTRYPOINT ["/bin/chamber", "exec", "production", "--"]
CMD ["/bin/service", "-d"]
Si nous appelons docker runmyservice
, le conteneur sera créé avec les arguments suivants:
["/bin/chamber", "exec", "production", "--", "/bin/service", "-d"]
Si nous appelons à la place docker run myservice /bin/debug
, le conteneur sera créé avec les arguments suivants:
["/bin/chamber", "exec", "production", "--", "/bin/debug"]
Notez que CMD
est entièrement remplacé – il n’est pas ajouté.
Nous pouvons aussi facilement remplacer l’entrée ENTRYPOINT
déclarée dans un Dockerfile
. Pour ce faire, nous spécifions l’argument --entrypoint
lors de l’executiuon de la commande docker run
. Supposons, comme précédemment, que nous ayons les éléments suivants Dockerfile
et en créons une image appelée myservice
:
ENTRYPOINT ["/bin/chamber", "exec", "production", "--"]
CMD ["/bin/service", "-d"]
Maintenant, changeons l’ ENTRYPOINT
en lançant cette commande: docker run --entrypoint /bin/logwrap myservice
. Selon notre règle générale, la liste d’arguments suivante sera construite de la manière suivante :
["/bin/logwrap", "/bin/service", "-d"]
Peut-on remplacer les deux ENTRYPOINT
et CMD
?
Certainement: docker run --entrypoint /bin/logwrap myservice /bin/service -e
. Voici la liste des arguments correspondants – à ce stade, il ne devrait y avoir aucune surprise: ["/bin/logwrap", "/bin/service", "-e"]
Supposons que nous construisons notre propre Dockerfile
pour un projet. À ce stade, nous comprenons les mécanismes de fonctionnement des instructions ENTRYPOINT
et CMD
et comment ils fonctionnent ensemble pour construire une liste d’arguments par défaut pour un conteneur. Mais maintenant, nous devons savoir lequel choisir : quand est-il préférable d’utiliser ENTRYPOINT
et quand est-il préférable d’utiliser CMD
?
Le choix que vous faites est essentiellement “artistique” et dépendra beaucoup de votre cas d’utilisation. Notre expérience, cependant, est que l’entrée ENTRYPOINT
convient à presque tous les cas que nous avons rencontrés. Considérez les cas d’utilisation suivants:
Wrappers
Certaines images contiennent un «wrapper» qui décore un programme existant ou le prépare autrement à une utilisation dans un environnement conteneurisé. Par exemple, supposons que votre service ait été écrit pour lire sa configuration à partir d’un fichier plutôt qu’à partir de variables d’environnement. Dans une telle situation, vous pouvez inclure un script d’encapsuleur qui génère le fichier de configuration de l’application à partir des variables d’environnement, puis lance l’application en appelant exec /path/to/app
à la fin.
Déclarer un pointeur ENTRYPOINT
dans le wrapper est un excellent moyen de s’assurer que le wrapper est toujours exécuté, quels que soient les arguments passés docker run
.
Images à usage unique
Si votre image est conçue pour ne faire qu’une chose – par exemple, exécuter un serveur Web – utilisez l’instruction ENTRYPOINT
pour spécifier le chemin d’accès au fichier binaire du serveur et tous les arguments obligatoires. Un exemple classique est l’image nginx
, dont le seul but est d’exécuter le serveur Web nginx. Cela se prête à une ligne de commande agréable et plus naturelle pour l’invocation: docker run nginx
. Ensuite, vous pouvez ajouter des arguments de programme intuitivement sur la ligne de commande, par exemple docker run nginx -c /test.conf
, comme vous le feriez si vous exécutiez nginx sans Docker.
Images multi-mode
Il s’agit également un modèle commun pour les images qui prennent en charge plusieurs « modes » d’utiliser le premier argument pour spécifier un verbe qui mappe au mode d’execution, par exemple shell, migrate ou debug. Pour de tels cas d’utilisation, nous recommandons de définir avec ENTRYPOINT
le pointeur vers un script qui analyse l’argument et fait le bon choix en fonction de sa valeur:
ENTRYPOINT ["/bin/parse_container_args"]
Les arguments seront transmis au point d’entrée sur l’invocation avec ARGV[1..n]
, ou $1
, $2
, etc.