Docker dans une VM

https://fr.slideshare.net/Docker/docker-101-nov-2016

Vous pouvez installer Docker sur votre machine personnelle en suivant : https://docs.docker.com/engine/installation/ mais si vous ne pouvez pas être root (comme en salle de TP) ou si vous voulez laisser votre machine intacte il est possible de l’installer dans une machine Virtuelle. Cela fonctionne bien mais avec des contraintes (sur les volumes notamment).

La machine doit disposer de VirtualBox. Pour que la machine virtuelle fonctionne, la machine hôte doit disposer d’un processeur compatible. Vous pouvez le tester avec (cette commandes doit renvoyer un résultat) :
grep --color -e vmx -e svm /proc/cpuinfo

Si besoin (sur le réseau filaire universitaire), penser à configurer le proxy dans l’hôte :

export https_proxy=http://login:password@proxy.univ-tln.fr:3128/ && export http_proxy=$https_proxy 

Télécharger et installer les binaires de docker (nous n’utiliserons que le client sur l’hôte), docker-machine (le gestionnaire de VM pour le provisionning) et docker-compose (pour l’orchestration de services dans des conteneurs).

if [[ ! -d "${HOME}/bin" ]]; then mkdir -p "${HOME}/bin"; fi
export PATH=~/bin:${PATH}
cd ${HOME}/bin
curl -sL https://download.docker.com/linux/static/stable/x86_64/docker-20.10.3.tgz  | tar --strip-components=1 -zx docker/docker
 
curl -L "https://github.com/docker/compose/releases/download/1.28.2/docker-compose-$(uname -s)-$(uname -m)" -o ~/bin/docker-compose && chmod +x ~/bin/docker-compose
 
base=https://github.com/docker/machine/releases/download/v0.16.0 &&
  curl -L $base/docker-machine-$(uname -s)-$(uname -m) > ${HOME}/bin/docker-machine && chmod +x ${HOME}/bin/docker-machine

Pour simplifier l’utilisation, nous allons créer des alias pour utiliser systématiquement VirtualBox, contrôler l’emplacement des VM (option storage-path de docker-machine), utiliser un miroir du registry officiel avec les entrepôt public de l’université (–engine-registry-mirror) et on passe systématiquement certaines variables (dont le proxy).

  export DOCKER_MIROR="http://compute-lsis-2:8081/repository/docker-hub-proxy/"
  alias CMD_DM='docker-machine --storage-path /scratch/$USER'
  alias CMD_DM_C='CMD_DM create --driver virtualbox --engine-env http_proxy=${http_proxy} --engine-env https_proxy=${http_proxy} --engine-env NO_PROXY=localhost,127.0.0.0/8,compute-lsis-2.univ-tln.fr --engine-registry-mirror=$DOCKER_MIROR'

Créer une machine virtuelle en y installant docker engine, fixer les variables d’environnement dans l’hôte qui vont permettre au client docker exécuté sur l’hôte d’utiliser le moteur docker installé dans la VM :

CMD_DM_C default 
eval "$(CMD_DM env --no-proxy default)"
CMD_DM ip default

default est le nom de la VM, il est possible de le changer ou d’en créer plusieurs.

Se connecter dans la VM, et vérifier le téléchargement des images :

CMD_DM -D ssh default
docker pull hello-world
docker run --rm hello-world

Les commandes docker peuvent être lancées depuis l’hôte avec le client docker grâce à la commande précédente eval “$(CMD_DM env –no-proxy default)”). Elles seront transmises au serveur docker dans la VM, les images téléchargées et les volumes seront donc dans la VM (cf. storage-path). On peut faire des recherches, télécharger un image, l’exécuter en mode interactif depuis l’hôte.

docker search ubuntu
docker pull alpine
docker run -it --name alpine alpine sh

Il est aussi possible de passer des variables d’environnement lors de la construction de l’image (docker build) sans que celles-ci n’y soient stockées (c’est utile pour le proxy par exemple) : –build-arg HTTP_PROXY=http://...

Par défaut la machine virtuelle n’a que peux de ressources il est possible d’en donner plus.

CMD_DM stop
VBoxManage modifyvm default --cpus 2
VBoxManage modifyvm default --memory 4096
CMD_DM start
docker run --rm -p 80:80 nginx
echo Le serveur web est accessible sur le port 80 de la VM
firefox `CMD_DM ip default`

Après avoir arrêté la VM il est possible d’ajouter une règle NAT pour permettre l’accès au port de la VM depuis l’hôte et donc depuis le réseau local.

VBoxManage controlvm "default" natpf1 "web,tcp,,8080,,80"

Et maintenant sur le port 8080 de l’hôte et donc accessible du réseau local.

firefox localhost:8080
firefox `hostname -I|cut -d ' ' -f 1`:8080

Il est très fortement conseillé d’utiliser des volumes nommés.

Sinon il est possible de les monter avec docker-machine https://docs.docker.com/machine/reference/mount/

mkdir ~/docker-data
CMD_DM ssh default mkdir host-data
CMD_DM mount default:/home/docker/host-data ~/docker-data
 
touch ~/docker-data/bar
CMD_DM ssh default ls host-data
 
docker run -v /home/docker/host-data:/tmp/host-data alpine "ls /tmp/host-data"
docker run -v /home/docker/host-data:/tmp/host-data alpine "echo ok >> /tmp/host-data/ok.txt"

Ou à la main, l’idée est d’exporter un répertoire dans la VM, ce répertoire pourra ensuite être connecté aux conteneurs.

Depuis l’hôte, créer un répertoire et ajouter un partage à VirtualBox :

if [[ ! -d "${HOME}/MY_DOCKER_DATA" ]]; then mkdir ${HOME}/MY_DOCKER_DATA; fi
CMD_DM stop default
VBoxManage sharedfolder add default --name dockerhome --hostpath  `echo ${HOME}`/MY_DOCKER_DATA
CMD_DM start default
eval "$(CMD_DM env --no-proxy default)"

Dans la VM, monter le partage (le dossier d’origine ~/MY_DOCKER_DATA) dans un répertoire de la VM (HOME).

CMD_DM -D ssh default "sudo umount /home/docker/HOME ; rm -rf /home/docker/HOME ; mkdir /home/docker/HOME"
CMD_DM -D ssh default "sudo mount -o defaults,uid=`id -u`,gid=`id -g` -t vboxsf dockerhome HOME"

sudo mount -t vboxsf -o defaults,uid=`id -u docker`,gid=`id -g docker` src /mnt/src

Maintenant vous pouvez créer des fichiers dans le “même” répertoire sur l’hôte (${HOME}/MY_DOCKER_DATA) et dans la VM (/home/docker/HOME). Le répertoire /home/docker/HOME peut maintenant être utilisé comme premier paramètre de run -v …’’ pour utiliser des fichiers de l’hôte dans les conteneurs. Il faut faire attention aux droits par défaut (root).

docker run -d --name mysql1 -v /home/docker/HOME/mysql1:/var/lib/mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=secret mysql
 
docker logs mysql1
docker logs -f mysql1
 
docker run --name mysql2 -v /home/docker/HOME/mysql2:/var/lib/mysql -p 3308:3306 -e MYSQL_ROOT_PASSWORD=secret mysql

On peut par exemple utiliser maven dans docker pour instancier un archetype (noter la création de l’alias ‘CMD_DR’). Les artefacts seront stocké dans le volume monté et donc suivront à chaque exécution.

cd /home/perso/bruno/DOCKER
mkdir m2
mkdir -p src/app
alias CMD_DR="docker run -it --rm \
  -v /home/docker/HOME/src/app:/usr/src/app \
  -v /home/docker/HOME/m2:/home/user/.m2"
 
CMD_DR --name maven-app-generator \
  -w /usr/src/app \
  maven \
  mvn archetype:generate \
   -Duser.home=/home/user \
   -DarchetypeGroupId=org.apache.maven.archetypes \
   -DarchetypeArtifactId=maven-archetype-quickstart \
   -DarchetypeVersion=1.1 \
   -DgroupId=fr.univtln.login \
   -DartifactId=MyApp \
   -Dversion=1.0-SNAPSHOT

De la même manière, il est possible de compiler et d’exécuter une application java avec Maven.

CMD_DR --name maven-app-package \
  -w /usr/src/app/MyApp \
  maven \
  mvn -Duser.home=/home/user \
  package
 
CMD_DR --name maven-app-run \
  -w /usr/src/app/MyApp \
  maven \
  mvn -Duser.home=/home/user \
  exec:java -Dexec.mainClass="fr.univtln.login.App"

==== Docker dans le cloud ==== Il est très simple d’utiliser docker dans le cloud. Par exemple, en utilisant Microsoft Azure (après avoir créé un abonnement, pour les étudiants du département d’informatique demander un code pour 6 mois à bruno@univ-tln.fr). Suivez le tutoriel https://azure.microsoft.com/fr-fr/documentation/articles/virtual-machines-docker-machine/ et créer la machine virtuelle avec : <cli> docker-machine create \ -d azure \ –azure-subscription-id=“ VOTRE ID AZURE ” \ –azure-subscription-cert=“mycert.pem” \ –azure-location=“West Europe” \ defaultazure eval “$(docker-machine env defaultazure)” </cli> ensuite tout est identique à une VM virtualbox : Avoir l’IP de la machine et se connecter en ssh : docker-machine ip defaultazure docker-machine -D ssh defaultazure Démarrer un serveur Web puis un serveur de base de données, votre application Java, … dans la VM dans le cloud : docker run –name nginx -d -p 8080:80 nginx docker run –name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=ArraujUrb4 -d mysql … Rendre les ports accessibles depuis internet (installez la commande azure avec le tutoriel précédent) : azure login azure vm endpoint create defaultazure 8080 8080 … Vos services sont maintenant accessibles depuis internet à l’adresse IP de la VM…

if [[ ! -d "${HOME}/bin" ]]; then mkdir -p "${HOME}/bin"; fi
export PATH=~/bin:${PATH}
cd ${HOME}/bin
curl -sL https://download.docker.com/linux/static/stable/x86_64/docker-18.09.0.tgz | tar --strip-components=1 -zx docker/docker   
curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o ~/bin/docker-compose && chmod +x ~/bin/docker-compose
base=https://github.com/docker/machine/releases/download/v0.16.0 &&
  curl -L $base/docker-machine-$(uname -s)-$(uname -m) > ${HOME}/bin/docker-machine && chmod +x ${HOME}/bin/docker-machine

dans le .bashrc

export https_proxy=http://LOGIN:PASSWORD@proxy.univ-tln.fr:3128/ && export http_proxy=${https_proxy} 
alias CMD_DM="docker-machine --storage-path /scratch/$USER"
alias CMD_DM_C="CMD_DM create \
                  --driver virtualbox \
                  --engine-env http_proxy=${http_proxy} \
                  --engine-env https_proxy=${http_proxy} \
                  --engine-env NO_PROXY=localhost,127.0.0.0/8,docker.lsis.univ-tln.fr \
                  --engine-registry-mirror=https://hub-docker.lsis.univ-tln.fr"

Création de la machine default

CMD_DM_C default
eval "$(CMD_DM env --no-proxy default)"

Docker peut maintenant être utilisé depuis l’hôte :

  docker ps
 
  docker run --name postgres1 -v postgres1data:/var/lib/postgresql/data -e POSTGRES_PASSWORD=mysecretpassword -d postgres
 
  docker run -it --rm --link postgres1:postgres postgres psql -h postgres -U postgres

—- dataentry page —- type : Howto enseignement_tags : D35 technologie_tags : Docker theme_tags : Composants