Docker dans Azure


Azure Loves Linux, comme je disais Smile
L’article suivant est la contribution 100% de mon collègue Maxime Launay, enthousiaste et passionné du Cloud Azure.
Voici cet article dans son intégralité – Merci Maxime !



Cet article présente la mise en place, en ligne de commande, d’une plateforme de développement hébergée sur Microsoft Azure et utilisant Redmine, Jenkins et Gitlab via la technologie de conteneur Docker. Attention, il ne présente pas la création d’un container Docker, uniquement son utilisation.

Contexte

Fin 2014, un client m’a sollicité pour mettre en place une plateforme de développement Open Source. Ces besoins étaient très précis :
- Déployer rapidement ;
- Utiliser git comme contrôleur de code source ;
- Utiliser Jenkins comme outils d’Intégration Continue ;
- Utiliser Redmine comme bug tracker ;
- Conserver « la main » sur les environnements ;
- Limiter les coûts de mise en place et d’exploitation ;
- Avoir des procédures d’installation simples permettant une reconstruction rapide de l’environnement.
Pour l’hébergement, l’utilisation du Cloud Public m’a semblé parfaitement adaptée aux besoins et comme le client avait des affinités avec Microsoft Azure, la décision fut rapide. Pour répondre aux autres besoins, j’ai tout de suite pensé à l’utilisation d’un « petit » projet qui monte, Docker. Je me décidais donc à franchir le pas pour vérifier l’intérêt du couple Azure / Docker.



Qu’est-ce que Docker ?

Docker est un logiciel Open Source qui permet de packager une application et ses dépendances dans un conteneur virtuel Linux de type LXC. Docker permet notamment le déploiement rapide d’applications construite avec Docker (appelées “images”) et l’exécution de manière autonome de ces applications. Cela signifie que plusieurs versions d’une même application peuvent être déployées sur un même système et sans conflit.
Microsoft étant fortement intéressé par Docker, les annonces autour d’Azure et de Docker sont régulières depuis quelques mois. Par exemple, depuis Janvier, il est possible de créer un VM Azure Docker directement depuis le portail. Il s’agit pour le moment de simple VM Linux intégrant Docker par défaut.

clip_image002[4]


Néanmoins, étant un adepte de l’automatisation, le déploiement via le portail ne m’intéresse pas. Je vais donc décrire le moyen de déployer une VM Linux et des conteneurs Docker directement depuis un shell Linux. Cette description sera effectuée en plusieurs étapes :
- Configuration d’une Virtual Machine Ubuntu 14.04 sous Virtual Box ;
- Configuration et déploiement d’une Virtual Machine Linux/Docker sous Azure ;
- Adaptation du déploiement des conteneurs Docker pour être déployer sous Azure.

Objectif à mettre en place

Comme indiqué avant, l’objectif est d’installer une plateforme d’Intégration Continue utilisant Redmine, Jenkins et Gitlab. Un des avantages liés à l’utilisation de Docker, les images Docker de ces outils existent déjà, à savoir :
- Redmine : sameersbn/docker-redmine
- Jenkins : Official Jenkins Docker image
- Gitlab : sameersbn/docker-gitlab
En complément, Redmine et Gitlab utilisent une base de données comme PostgreSQL ; Gitlab nécessite également redis. Là encore, des conteneurs pour ces deux produits existent déjà :
- Redis : sameersbn/redis
- PostgreSQL : sameersbn/postgresql
Enfin, pour la Virtual Machine Linux (en local ou sous Azure), j’utiliserai la distribution Ubuntu 14.04.
Le schéma ci-dessous représente l’architecture mise en place.

clip_image003


Configuration de la Virtual Machine en local

Je commence d’abord par la configuration de la Virtual Machine Ubuntu. Pour cela, j’installe Virtual Box. Ensuite, j’installe une distribution Ubuntu 14.04 64 bits (les conteneurs Docker ne sont pas compatibles 32 bits) comme par exemple celle disponible chez Ubuntu-fr.
Ensuite, j’ajoute le package Azure Cross-Platform Command-Line Interface. Pour cela, il faut installer node.js, puis npm et enfin le client azure.
sudo apt-get install nodejs-legacy
sudo apt-get install npm
sudo npm install -g azure-cli

Une fois le client Azure installé, je télécharge (http://go.microsoft.com/fwlink/?LinkId=254432) le fichier de publication Azure, puis j’importe ce fichier.
azure account download
azure account import "chemin du fichier de publication"

Si vous avez plusieurs comptes azure, il faut configurer la bonne souscription. Tout d’abord exécuter la commande azure account list pour voir la liste des souscriptions définies sur votre profile utilisateur.

clip_image005

Puis exécuter la commande azure account set "Nom de la souscription"
clip_image007

Les paramètres des souscriptions sont stockés dans le répertoire .azure de la home directory, il est donc conseillé de crypter celle-ci.
Le client Azure pour Linux est désormais installé et configuré ; j’installe maintenant Docker. J’ajoute tout d’abord le repository Docker dans la liste des sources apt.
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
sudo sh -c "echo deb http://get.docker.com/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
sudo apt-get update

Puis j’installe Docker:
sudo apt-get install lxc-docker
 


Quelques paramètres pour ce faciliter le travail

Mon environnement est désormais prêt à l’emploi. Je vais désormais installer la Virtual Machine et les différents conteneurs. On commence par définir quelques variables Shell :
- VM_NAME='myDockerVM' # Nom de la VM
- VM_NAME_FQDN=${VM_NAME}".cloudapp.net" # FQDN de la VM
- AZURE_LOCATION='West Europe' # Datacenter Azure sur lequel installé la VM
- AZURE_VM_ACCOUNT='myAccount' # compte utilisateur de la VM
- AZURE_VM_PASSWORD='myPassword' # mot de passe du compte utilisateur de la VM
- AZURE_VM_SIZE="Medium" # Taille de la VM
- AZURE_LINUX_IMAGE="$(azure vm image list | grep Ubuntu-14_04 | awk -F" " '{print $2}' | tail -n 1)" # Dernière image Ubuntu 14.04 publiée sur Azure
- DOCKER_HOST="tcp://"${VM_NAME_FQDN}":4243" # Nom de l’host public
- DOCKER_DNS="95.44.206.168" # Serveur DNS public
- SMTP_DOMAIN='yourSMTPDomain' # Domain SMTP
- SMTP_HOST='yourSMTPServer' # Serveur SMTP
- SMTP_PORT='yourSMTPServerPort' # Port du Server SMTP
- SMTP_USER='user' # Compte d’accès au serveur SMTP
- SMTP_PASS='password' # mot de passe du compte d’accès au serveur SMTP


Installation de la VM Azure

Ensuite, je créé la Virtual Machine. Cette action va créer une Virtual Linux Ubuntu 14.04 avec Docker d’installé, et les ports 22 (SSH) et 4243 (Docker) ouverts. Elle va également créer automatiquement les certificats permettant de gérer Docker sur cette VM ; ces certificats sont situés dans le répertoire .docker de la home directory.
azure vm docker create -e 22 -l "${AZURE_LOCATION}" "${VM_NAME}" "${AZURE_LINUX_IMAGE}" "${AZURE_VM_ACCOUNT}" "${AZURE_VM_PASSWORD}" -z ${AZURE_VM_SIZE}
La VM est créée en quelques minutes seulement :

clip_image009

La commande suivante permet de tester la bonne installation de la Virtual Machine :
sudo docker --tls -H ${DOCKER_HOST} info
clip_image011

J’ajoute ensuite un disque de data supplémentaire. Celui-ci sera en effet très utile pour gérer les data persistantes des conteneurs Docker. Je créé le disque dans Azure :
azure vm disk attach-new ${VM_NAME} 20
Puis je configure le disque au niveau Linux. Pour cela je me connecte en SSH et j’exécute un fdisk :
sudo ssh ${AZURE_VM_ACCOUNT}@${VM_NAME_FQDN}
sudo mkdir -p /data
sudo fdisk /dev/sdc


(verifier bien que le disque ajouté est bien le sdc =>
* taper n
* taper p
* taper 1
* taper ENTER
* taper ENTER
* taper w)

Je formate ensuite la partition et je la monte sur le répertoire /data
sudo mkfs -t ext4 /dev/sdc1
sudo mount /dev/sdc1 /data

Enfin, je mets à jour à jour la fstab pour que le fileset soit monté automatiquement au démarrage
sudo -i blkid | grep /dev/sdc1 => récupérer l'UUID
sudo vi /etc/fstab …et ajouter la ligne suivante dans le fstab :
 UUID=%UUID% /data ext4 defaults 1 2
clip_image013

Pour tester l’opération, il suffit d’exécuter les deux commandes suivantes. Si celles-ci ne renvoient pas d’erreurs, la configuration est correcte.
sudo umount /data
sudo mount /data

Enfin, j’ouvre les endpoints 80 (gitlab), 8080 (Jenkins) et 20080 (redmine) de la VM pour les différentes applications :
azure vm endpoint create "${VM_NAME}" 8080 8080
azure vm endpoint create "${VM_NAME}" 80 80
azure vm endpoint create "${VM_NAME}" 20080 20080


Installation des conteneurs Docker

Passons maintenant à l’installation des conteneurs (PS : n’oubliez pas de vous déconnecter la de VM Azure). Tout d’abord, j’installe redis pour gitlab :
sudo docker --tls -H ${DOCKER_HOST} run --name=redis --restart=on-failure:10 -d sameersbn/redis:latest
clip_image015

Les packages sont téléchargés et Redis est installé et configuré, le tout moins de 2 minutes. Je vais maintenant essayer de vous décrire ce que cette commande : « je lance docker en mode superutilisateur (sudo docker), en utilisant l’encryptage tls (--tls), pour me connecter à l’host docker ${DOCKER_HOST} (-H ${DOCKER_HOST}), pour télécharger et installer un conteneur (run), que j’appellerais redis (-name=redis), qui redémarrera 10 fois en cas d’erreur (--restart=on-failure:10), qui s’exécutera en tant que deamon (-d) et qui utilisera l’image redis publiée par sameersbn (sameersbn/redis) dans sa dernière version (:latest). »

Il est possible de vérifier que le conteneur s’exécute bien via la commande suivante qui affiche les conteneurs actifs sur une instance Docker :
sudo docker --tls -H ${DOCKER_HOST} ps
clip_image017

On installe ensuite PostgreSQL :
sudo docker --tls -H ${DOCKER_HOST} run --name=postgresqlgitlab --restart=on-failure:10 -d -e 'DB_NAME=gitlabhq_production' -e 'DB_USER=gitlab' -e 'DB_PASS=password' -v /data/postgresqlgitlab:/var/lib/postgresql sameersbn/postgresql:latest
Quelques explications :
- Le switch –e permet de configurer des paramètres pour l’exécution du conteneur
- Le switch –v permet de créer un volume persistant, c’est-à-dire que les données contenues dans /var/lib/postgresql ne sont pas simplement liées au conteneur, mais également (et surtout) présentent sur le fileset /data/postgresqlgitlab de l’host, facilitant la sauvegarde de celles-ci.

Je peux désormais installer Gitlab :
sudo docker --tls -H ${DOCKER_HOST} run --name=gitlab --restart=on-failure:10 -d --link postgresqlgitlab:postgresql --link redis:redisio -e 'SMTP_DOMAIN='${SMTP_DOMAIN} -e 'SMTP_HOST='${SMTP_HOST} -e 'SMTP_PORT='${SMTP_PORT} -e 'SMTP_USER='${SMTP_USER} -e 'SMTP_PASS='${SMTP_PASS} -e 'DB_TYPE=postgres' -e 'GITLAB_HOST='${VM_NAME_FQDN} -e 'GITLAB_PORT=80' -p 80:80 -v /data/gitlab:/home/git/data --dns=${DOCKER_DNS} sameersbn/gitlab:latest
Encore quelques explications :
- Le switch –p permet de lié un port réseau entre le conteneur et l’host. Dans le cas de gitlab, on connecte le port 80 de l’host au port 80 du conteneur.
- Le switch –link permet de lier un conteneur à un autre conteneur, c’est-à-dire que les données du conteneur source sont accessibles au conteneur cible. Dans l’exemple ci-dessous, le conteneur gitlab peut désormais accéder aux données (paramètres, applications, etc.) des conteneurs redis (qu’il verra avec le nom redisio) et postgresqlgitlab (qu’il verra le nom postgresql). Concrètement, à partir du conteneur gitlab, il est possible de faire un ping du conteneur redis.
- Le switch –dns permet de fixer le DNS dans le fichier /etc/resolv.conf du conteneur. Dans azure, c’est option est obligatoire car par défaut, Docker utilise la configuration de l’hôte lors de l’initialisation du conteneur, mais ne met plus à jour cette configuration par la suite. Or, en cas d’arrêt de la VM (status Stopped :deallocated) puis d’un redémarrage, cette configuration risque de changer. Le conteneur ne résout alors plus les noms, ce qui est embêtant dans le cadre d’une application comme gitlab qui envoie des mails via un serveur SMTP.

J’installe ensuite Jenkins :
sudo docker --tls -H ${DOCKER_HOST} run --name=jenkins --restart=on-failure:10 -d --link gitlab:${VM_NAME_FQDN} -u root -p 8080:8080 -v /data/jenkins:/var/jenkins_home --dns=${DOCKER_DNS} jenkins
Quelques explications :
Le switch –u permet de préciser l’utilisateur exécutant l’application dans le conteneur.

Enfin, on installe PostgreSQL pour redmine, et ensuite redmine
sudo docker --tls -H ${DOCKER_HOST} run --name=postgresqlredmine --restart=on-failure:10 -d -e 'DB_NAME=redmine_production' -e 'DB_USER=redmine' -e 'DB_PASS=password' -v /data/postgresqlredmine:/var/lib/postgresql sameersbn/postgresql:latest
sudo docker --tls -H ${DOCKER_HOST} run --name=redmine --restart=on-failure:10 -d --link postgresqlredmine:postgresql --volumes-from=gitlab -e 'SMTP_DOMAIN='${SMTP_DOMAIN} -e 'SMTP_HOST='${SMTP_HOST} -e 'SMTP_PORT='${SMTP_PORT} -e 'SMTP_USER='${SMTP_USER} -e 'SMTP_PASS='${SMTP_PASS} -e 'REDMINE_PORT=20080' -e 'DB_TYPE=postgres' -p 20080:80 -v /data/redmine:/home/redmine/data --dns=${DOCKER_DNS} sameersbn/redmine:2.6.0-1
On peut maintenant vérifier que les conteneurs sont bien en cours exécution :

clip_image019

On peut désormais accéder aux différentes applications. Il ne reste plus qu’à les configurer et la plateforme de développement est prête à l’emploi :

Gitlab:
clip_image021

Jenkins:
clip_image023

Redmine:














Et en local ?

Pour finir, il est intéressant de noter que cette configuration peut être très facilement reproduite en local. Il suffit d’enlever les switchs –tls et –H des différentes lignes de commande. Ainsi, si vous souhaitez dupliquer la VM créée précédemment, il faut exporter le fileset /data de la VM (un tar –zcvf suffit). Ensuite, il suffit d’importer la sauvegarde sur votre système, puis de redéployer les différents conteneurs Docker en remplaçant, via un bon notepad++, «--tls -H ${DOCKER_HOST}» par «».

Conclusion

Azure et Docker forment un couple vraiment très intéressant. Dans l’exemple ci-dessus, la création d’une plateforme de développement prend moins d’une heure. De plus, la maintenabilité et la reproductibilité de l’opération sont améliorées. Plus globalement, l’intérêt porté par la majeure partie des acteurs de l’IT est totalement fondé ; Docker est vraiment l’un des projets les plus existants de ces dernières années. Microsoft investit énormément dans cette solution et c’est pourquoi, selon toute vraisemblance, cette technologie sera intégrée et fonctionnelle pour des applications Windows dans la prochaine version de Windows. Azure est bien évidemment en avance sur ces planning et j’aimerais voir arriver d’ici peu des conteneurs Docker fonctionnant sur le même modèle que les Cloud Services, à savoir avec un système d’exploitation « transparent » pour les utilisateurs.

Quelques liens utiles

- https://www.docker.com/
- http://azure.microsoft.com/en-us/documentation/articles/xplat-cli/
- http://azure.microsoft.com/en-us/documentation/articles/virtual-machines-docker-vm-extension/


Aucun commentaire:

Publier un commentaire