
Docker
Docker est un logiciel libre permettant de lancer des applications dans des conteneurs.
C'est est un outil qui peut empaqueter une application et ses dépendances dans un conteneur isolé, qui pourra être exécuté sur n'importe quel serveur. Il ne s'agit pas de virtualisation, mais de conteneurisation, une forme plus légère qui s'appuie sur certaines parties de la machine hôte pour son fonctionnement. Cette approche permet d'accroître la flexibilité et la portabilité d’exécution d'une application, laquelle va pouvoir tourner de façon fiable et prévisible sur une grande variété de machines hôtes, que ce soit sur la machine locale, un cloud privé ou public, une machine nue, etc...
Contrairement aux machines virtuelles traditionnelles, un conteneur Docker n'inclut pas de système d'exploitation, mais s'appuie au contraire sur les fonctionnalités du système d’exploitation fournies par la machine hôte.
J'ai trouvé sur youtube une excellente série de vidéos que je vais essayer de mettre en pratique, commenter et éventuellement mettre à jour.
1) Installation de docker
L'installation ci-dessous va utiliser les repositories Docker officiels (au lieu des repositories Raspbian qui ne sont pas toujours à jour).# Install some required packages first sudo apt update sudo apt install -y \ apt-transport-https \ ca-certificates \ curl \ gnupg2 \ software-properties-common # Get the Docker signing key for packages curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | sudo apt-key add - # Add the Docker official repos echo "deb [arch=armhf] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \ $(lsb_release -cs) stable" | \ sudo tee /etc/apt/sources.list.d/docker.list # Install Docker # The aufs package, part of the "recommended" packages, won't install on Buster just yet, because of missing pre-compiled kernel modules. # We can work around that issue by using "--no-install-recommends" sudo apt update sudo apt install -y --no-install-recommends \ docker-ce \ cgroupfs-mount # Pour démarrer automatiquement Docker au démarrage de la machine sudo systemctl enable docker # Quelques commandes utiles pour arrêter, démarrer, redémarrer ou vérifier le statut de Docker sudo systemctl stop docker sudo systemctl start docker sudo systemctl restart docker sudo systemctl status docker # Pour tester que Docker fonctionne bien pi@raspberrypi2:~ $ sudo docker run --rm arm32v7/hello-world Unable to find image 'arm32v7/hello-world:latest' locally latest: Pulling from arm32v7/hello-world c1eda109e4da: Pull complete Digest: sha256:07e995a680212a0a8a01e181b3fff128d44b8fe0c11426b638ec3cde7273f0a3 Status: Downloaded newer image for arm32v7/hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (arm32v7) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/ pi@raspberrypi2:~ $
2) Quelques commandes indispensables
La vidéo suivante montre quelques commandes basiques, pour manipuler les images et containers ainsi que des commandes systèmes.
3) Exécuter Jenkins dans un container Docker
La vidéo suivante explique comment exécuter Jenkins dans un container Docker, et comment créer et utiliser les volumes.
Mise en pratique
# On télécharge l'image jenkins/jenkins:lts depuis le Docker Hub (https://hub.docker.com/r/jenkins/jenkins) prabou@prabou-VPCZ23C5E:~$ sudo docker pull jenkins/jenkins:lts lts: Pulling from jenkins/jenkins 092586df9206: Pull complete ef599477fae0: Pull complete 4530c6472b5d: Pull complete d34d61487075: Pull complete 272f46008219: Pull complete 12ff6ccfe7a6: Pull complete f26b99e1adb1: Pull complete b5a7230f28ac: Pull complete d19ccd039899: Pull complete 0cd916c5652e: Pull complete e7f33481e423: Pull complete 3c8f6834c187: Pull complete aed304377df9: Pull complete 841ddf9b4483: Pull complete 84beffd862a8: Pull complete 2643324effeb: Pull complete 2b8c3739eb59: Pull complete 42423eff2b9e: Pull complete ce3c0ae47fcb: Pull complete Digest: sha256:bf741663dff2c5c163bd16706d4d1b9e6f86fa7b92e365257e170239d0bfb24f Status: Downloaded newer image for jenkins/jenkins:lts docker.io/jenkins/jenkins:lts # On affiche les images disponibles prabou@prabou-VPCZ23C5E:~$ sudo docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE jenkins/jenkins lts 5721a6cac43c 2 weeks ago 572MB prabou@prabou-VPCZ23C5E:~$ prabou@prabou-VPCZ23C5E:~$ mkdir jenkins_home prabou@prabou-VPCZ23C5E:~$ sudo chmod 777 jenkins_home # On démarre un container à partir de cette image tout en créant le volume /home/prabou/jenkins_home sur le système hôte prabou@prabou-VPCZ23C5E:~$ sudo docker run --name container_prabou1 -p 8080:8080 -p 50000:50000 -v /home/prabou/jenkins_home:/var/jenkins_home jenkins/jenkins:lts Running from: /usr/share/jenkins/jenkins.war webroot: EnvVars.masterEnvVars.get("JENKINS_HOME") 2019-10-16 20:33:33.692+0000 [id=1] INFO org.eclipse.jetty.util.log.Log#initialized: Logging initialized @659ms to org.eclipse.jetty.util.log.JavaUtilLog 2019-10-16 20:33:33.849+0000 [id=1] INFO winstone.Logger#logInternal: Beginning extraction from war file 2019-10-16 20:33:35.466+0000 [id=1] WARNING o.e.j.s.handler.ContextHandler#setContextPath: Empty contextPath 2019-10-16 20:33:35.529+0000 [id=1] INFO org.eclipse.jetty.server.Server#doStart: jetty-9.4.z-SNAPSHOT; built: 2019-05-02T00:04:53.875Z; git: e1bc35120a6617ee3df052294e433f3a25ce7097; jvm 1.8.0_222-b10 2019-10-16 20:33:35.925+0000 [id=1] INFO o.e.j.w.StandardDescriptorProcessor#visitServlet: NO JSP Support for /, did not find org.eclipse.jetty.jsp.JettyJspServlet 2019-10-16 20:33:35.996+0000 [id=1] INFO o.e.j.s.s.DefaultSessionIdManager#doStart: DefaultSessionIdManager workerName=node0 2019-10-16 20:33:35.997+0000 [id=1] INFO o.e.j.s.s.DefaultSessionIdManager#doStart: No SessionScavenger set, using defaults 2019-10-16 20:33:36.003+0000 [id=1] INFO o.e.j.server.session.HouseKeeper#startScavenging: node0 Scavenging every 660000ms Jenkins home directory: /var/jenkins_home found at: EnvVars.masterEnvVars.get("JENKINS_HOME") 2019-10-16 20:33:36.598+0000 [id=1] INFO o.e.j.s.handler.ContextHandler#doStart: Started w.@53499d85{Jenkins v2.190.1,/,file:///var/jenkins_home/war/,AVAILABLE}{/var/jenkins_home/war} 2019-10-16 20:33:36.623+0000 [id=1] INFO o.e.j.server.AbstractConnector#doStart: Started ServerConnector@302c971f{HTTP/1.1,[http/1.1]}{0.0.0.0:8080} 2019-10-16 20:33:36.624+0000 [id=1] INFO org.eclipse.jetty.server.Server#doStart: Started @3592ms 2019-10-16 20:33:36.624+0000 [id=21] INFO winstone.Logger#logInternal: Winstone Servlet Engine v4.0 running: controlPort=disabled 2019-10-16 20:33:38.717+0000 [id=28] INFO jenkins.InitReactorRunner$1#onAttained: Started initialization 2019-10-16 20:33:38.759+0000 [id=28] INFO jenkins.InitReactorRunner$1#onAttained: Listed all plugins 2019-10-16 20:33:40.354+0000 [id=33] INFO jenkins.InitReactorRunner$1#onAttained: Prepared all plugins 2019-10-16 20:33:40.362+0000 [id=33] INFO jenkins.InitReactorRunner$1#onAttained: Started all plugins 2019-10-16 20:33:40.378+0000 [id=28] INFO jenkins.InitReactorRunner$1#onAttained: Augmented all extensions 2019-10-16 20:33:41.193+0000 [id=27] INFO jenkins.InitReactorRunner$1#onAttained: Loaded all jobs 2019-10-16 20:33:41.238+0000 [id=46] INFO hudson.model.AsyncPeriodicWork$1#run: Started Download metadata 2019-10-16 20:33:41.251+0000 [id=46] INFO hudson.util.Retrier#start: Attempt #1 to do the action check updates server 2019-10-16 20:33:42.470+0000 [id=28] INFO o.s.c.s.AbstractApplicationContext#prepareRefresh: Refreshing org.springframework.web.context.support.StaticWebApplicationContext@6df25b1b: display name [Root WebApplicationContext]; startup date [Wed Oct 16 20:33:42 UTC 2019]; root of context hierarchy 2019-10-16 20:33:42.471+0000 [id=28] INFO o.s.c.s.AbstractApplicationContext#obtainFreshBeanFactory: Bean factory for application context [org.springframework.web.context.support.StaticWebApplicationContext@6df25b1b]: org.springframework.beans.factory.support.DefaultListableBeanFactory@7d1dc4b8 2019-10-16 20:33:42.489+0000 [id=28] INFO o.s.b.f.s.DefaultListableBeanFactory#preInstantiateSingletons: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@7d1dc4b8: defining beans [authenticationManager]; root of factory hierarchy 2019-10-16 20:33:42.778+0000 [id=28] INFO o.s.c.s.AbstractApplicationContext#prepareRefresh: Refreshing org.springframework.web.context.support.StaticWebApplicationContext@3a996d27: display name [Root WebApplicationContext]; startup date [Wed Oct 16 20:33:42 UTC 2019]; root of context hierarchy 2019-10-16 20:33:42.779+0000 [id=28] INFO o.s.c.s.AbstractApplicationContext#obtainFreshBeanFactory: Bean factory for application context [org.springframework.web.context.support.StaticWebApplicationContext@3a996d27]: org.springframework.beans.factory.support.DefaultListableBeanFactory@10ff9cb 2019-10-16 20:33:42.780+0000 [id=28] INFO o.s.b.f.s.DefaultListableBeanFactory#preInstantiateSingletons: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@10ff9cb: defining beans [filter,legacy]; root of factory hierarchy 2019-10-16 20:33:43.190+0000 [id=28] INFO jenkins.install.SetupWizard#init: ************************************************************* ************************************************************* ************************************************************* Jenkins initial setup is required. An admin user has been created and a password generated. Please use the following password to proceed to installation: 82c337f27cd14033be4cecc913d4b775 This may also be found at: /var/jenkins_home/secrets/initialAdminPassword ************************************************************* ************************************************************* ************************************************************* 2019-10-16 20:33:49.974+0000 [id=46] INFO hudson.model.UpdateSite#updateData: Obtained the latest update center data file for UpdateSource default 2019-10-16 20:33:51.318+0000 [id=46] INFO h.m.DownloadService$Downloadable#load: Obtained the updated data file for hudson.tasks.Maven.MavenInstaller 2019-10-16 20:33:51.320+0000 [id=46] INFO hudson.util.Retrier#start: Performed the action check updates server successfully at the attempt #1 2019-10-16 20:33:51.323+0000 [id=46] INFO hudson.model.AsyncPeriodicWork$1#run: Finished Download metadata. 10,084 ms 2019-10-16 20:33:51.592+0000 [id=28] INFO hudson.model.UpdateSite#updateData: Obtained the latest update center data file for UpdateSource default 2019-10-16 20:33:51.816+0000 [id=33] INFO jenkins.InitReactorRunner$1#onAttained: Completed initialization 2019-10-16 20:33:51.841+0000 [id=20] INFO hudson.WebAppMain$3#run: Jenkins is fully up and running
Maintenant que Jenkins est prêt, on ouvre Firefox à l'url http://localhost:8080/







Lorsqu'un container est supprimé, l'ensemble des fichiers présents à l'intérieur le sont également.
C'est pour cette raison que nous avons créé un volume (externe au container) qui contiendra toute la configuration Jenkins. La création d'un volume consiste soit à monter un répertoire du système d’exploitation hôte, soit un "vrai" volume completement géré par Docker ce qui a plusieurs avantages.
Parmi les avantages on peut citer:
- les volumes sont plus faciles à sauvegarder que les montages de répertoires (de la machine hôte ou ailleurs)
- la possibilité de gérer les volumes avec Docker CLI ou l'API Docker.
- les volumes fonctionent aussi bien avec les containers Linux que Windows.
- les volumes peuvent être partagés de façon sécurisée entre plusieurs containers.
- les volumes drivers permettent de stocker les volumes sur un hôte distant ou un cloud, d'encrypter le contenu des volumes ou encore d'ajouter d'autres fonctionnalités
- les nouveaux volumes peuvent avoir leur contenu pre-populé par un conteneur.
4) Dockerfile
5) Sources
Si vous chercher des livres ou des sites internet pour vous documenter sur Docker, voici quelques références:
- Learning Docker - Optimize the power of Docker to run your applications quickly and easily (livre)