Provisioning d’un host Docker dans Azure

Voici le quatrième d’une série d’articles consacrée à l'utilisation conjointe de Docker et Azure, qui je l’espère vous permettra d’accélérer votre découverte de ces environnements :
Docker : les fondamentaux
Mise en place de l’environnement Docker : Installation du moteur et du client Docker
Docker et la virtualisation par container sous Windows
Mise en place de l’environnement Docker : Provisioning d’un host Docker dans Azure
Utilisation de Docker
Clusters de containers Docker

Les rôles client et serveur Docker peuvent fonctionner sur le même système (en environnement Linux ou sur Windows Server 10) ou sur deux machines différentes (Mac, Windows, Linux). Dans le cas où le moteur Docker s’exécute sur un serveur hôte différent de la machine qui exécute le client Docker, se pose la question de l’hébergement de ce serveur. La plateforme Microsoft Azure peut héberger la machine virtuelle hôte Docker permettant de déployer images et containers. Il faut donc pouvoir provisionner cet hôte Docker et nous allons voir qu’il existe de multiples solutions pour y parvenir. Dans l’immédiat, nous nous limiterons volontairement au provisioning de host Docker sous Linux.

Nouveau portail Azure et Docker

Le nouveau portail Azure offre aujourd’hui deux mécanismes permettant de faciliter le déploiement d’environnements hôtes Docker sur Azure.
Le premier de ces dispositifs est une extension qui cible les machines virtuelles Linux Ubuntu ou CoreOS. Il s’agit d’un composant installé dans l'instance de la machine virtuelle lors de sa création. Son rôle est d’installer le moteur Docker sur la machine virtuelle et de le configurer pour écouter les commandes en provenance du client Docker.
La copie d’écran présente l’ajout de cette extension pour une machine CoreOS :

Docker-Portal-Extension

La deuxième approche consiste à utiliser une image de machine virtuelle accessible via la MarketPlace. Cette image est déjà configurée pour assurer le déploiement d’une version Ubuntu Server 14.04 LTS et installer le moteur Docker via l'extension de VM précédemment évoquée.

MarketPlace_Docker

Langage de script Azure-Cli

Une alternative au portail Azure est d’utiliser le langage de script Azure Cross-Platform Command Line Interface (xplat-cli) depuis une machine cliente, par exemple une machine Ubuntu ou un Mac. Azure-cli est le langage de scripting Azure en ligne de commande pour les environnements Windows, Mac et Linux. Il est développé en javascript et nécessite l’installation de node.js. La première étape consiste donc à installer nodejs, npm, puis azure-cli.

sudo apt-get update

sudo apt-get install nodejs-legacy

sudo apt-get install npm

sudo npm install azure-cli –global

Pour configurer Azure-Cli afin d’utiliser une souscription Azure, deux approches sont possibles.
La première approche consiste à télécharger le fichier de paramètres de publication depuis l’adresse https://manage.windowsazure.com/publishsettings/index. Microsoft Azure crée un alors un nouveau certificat de gestion et attache ce certificat à l’ensemble des souscriptions Azure sur lequel le compte connecté a des droits d’administration (on peut alors le voir dans la section « Management Certificates » du module « Settings » du Portail Azure).

Certificats
LLe fichier téléchargé contient les données brutes de ce certificat (y compris la clé privée, mais non exportable). Tout outil supportant ce type de fichier, et en particulier azure-cli peut alors analyser ce fichier XML, lire les données du certificat et l’installer en local (généralement dans le magasin de certificats « Current User - Personal »).
La seconde approche consiste à se logger avec un compte d’organisation (attention les comptes Microsoft ne sont pas supportés). Dans ce deuxième cas, c’est Azure Active Directory qui est utilisé pour authentifier les paramètres d’identification de l’utilisateur.

azure login –u <compte-organisation>

Une fois authentifié par l’une ou l’autre de ces methodes, on peut alors utiliser la commande azure vm docker create dont voici l’aide.

Docker-help

La commande azure vm docker create permet de créer la machine virtuelle host Docker, d’installer l'extension de VM Docker, de générer et télécharger les certificats d’authentification pour la communication Docker.

azure vm docker create -e 22 -l 'West Europe' <machine-cible>

"b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_10-amd64-server-20141022.3-en-us-30GB" <user-name> <password>

Les certificats sont créés automatiquement lors du premier usage de cette commande. Ils sont stockés sur la machine cliente et sur le serveur hôte. Lors des exécutions suivantes, les certificats existants seront réutilisés et partagés avec le nouvel hôte. Par défaut, les certificats sont placés dans ~/.docker et le moteur Docker est configuré pour s’exécuter sur le port 4243. Il est possible d’utiliser un autre port ou un répertoire avec les options de commande suivantes :

--docker-port [port]

--docker-cert-dir [dir]

Sur le host, le démon Docker est configuré pour écouter et authentifier les connexions client sur le port spécifié avec les certificats générés. L'ordinateur client doit donc nécessairement disposer de ces certificats pour interagir avec le moteur Docker.

Docker Machine

Les fonctions de Docker Machine

Docker Machine permet de facilement créer des hosts Docker soit sur la machine locale, soit sur un service de Cloud. Cet outil proposé par Docker offre de multiples intérêts :
• Possibilité de provisionner les serveurs Docker directement dans le Cloud de son choix
• Configuration du client Docker pour qu’il puisse communiquer avec ces serveurs (il génère notamment les certificats et partage les clés assurant la sécurité des échanges).
• Exécution depuis de multiples environnements (Linux, iOS, Windows,…)
• Une fois que l’hôte Docker a été créé, il offre des commandes pour leur gestion : démarrage, arrêt, mise à jour,….

Docker Machine et Azure

Un driver Azure pour Docker Machine a été développé par Jeff Mendoza (Microsoft). Ce pilote est écrit en Go et utilise le SDK Azure proposé pour ce langage afin de communiquer avec les APIs Azure Service Management pour provisionner les machines virtuelles et installer Docker à l’aide de l’extension Docker pour les VMs Azure. Les sources et détails d’implémentation ont été publiés sur GitHub.
Le nom de l’exécutable correspondant à un Docker Machine varie suivant les environnements cibles. Je vous invite à le renommer en « docker-machine ». Ainsi vous utiliserez la même commande (simplifiée) depuis n’importe quel système d’exploitation…

Avant de pouvoir utiliser Docker Machine, il faut télécharger un fichier de paramètres de publication depuis l’adresse https://manage.windowsazure.com/publishsettings/index (cf section précedente : Langage de script Azure-Cli).

Voici donc un exemple d’une commande docker-machine permettant de créer un hôte Docker hébergé sur une machine de type « Small » dans Azure.

docker-machine -D create -d azure \

--azure-subscription-id="<souscription-id>" \

--azure-docker-port="2376" \

--azure-publish-settings-file="<souscription-publishsettingsfile>" \

--azure-location="West Europe" \

--azure-password="<password>" \

--azure-size="Small" \

--azure-ssh-port="22" \

--azure-username="<username>" \

<nom de la machine docker host>

Par défaut, c’est une Ubuntu 14.04 LTS, qui est utilisée, mais il est également possible de spécifier une version spécifique de la distribution Linux, par exemple "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_10-amd64-server-20141204-en-us-30GB", en utilisant le paramètre --azure-image

Une fois l’exécution de cette commande achevée, il est alors possible de contrôler si le host docker ainsi créé fonctionne en utilisant le client Docker avec la commande dockerinfo : on peut alors utiliser le client Docker sur les VMs hôtes Docker déployées dans Azure provisionnées avec Docker Machine comme on le ferait depuis un client Docker déployé sur Linux. La copie d’écran suivante présente les informations correspondant à la configuration de deux hosts Docker provisionnés depuis Windows.

Docker-machine-Windows
Pour utiliser Docker, il faut alors configurer l’environnement d’exécution, notamment les variables :

DOCKER_HOST=tcp://stephgoudockerfromwin.cloudapp.net:2376

DOCKER_CERT_PATH=C:\Users\stephgou\.docker\machine\machines\stephgoudockerfromwin

Ces valeurs sont obtenues à partir de la commande docker-machine env et elles doivent être injectées en tant que variables d’environnement. Etudions maintenant plus en détail la configuration de Docker Machine sur les différents systèmes Linux, Mac, et Windows.

Docker Machine sur Linux

Pour installer Docker Machine sur Linux, il suffit de télécharger le binaire depuis l’url suivante https://github.com/docker/machine/releases/download/v0.2.0/docker-machine_linux-amd64 dans un répertoire connu dans le PATH (par exemple, « /usr/local/bin ») et de le rendre exécutable.

Sous Linux, la commande suivante permet d’exporter directement les variables d’environnement Docker :
eval "$(./docker-machine env stephgoudockerfromwin)"

Docker Machine sur Mac

Pour installer Docker Machine sur Mac, il suffit de télécharger le binaire depuis l’url suivante https://github.com/docker/machine/releases/download/v0.2.0/docker-machine_darwin-amd64 dans un répertoire connu dans le PATH (par exemple, « /usr/local/bin ») et de le rendre exécutable. On pourra utiliser les commandes suivantes :

curl -L https://github.com/docker/machine/releases/download/v0.2.0/docker-machine\_darwin-amd64 > /usr/local/bin/docker-machine

chmod +x /usr/local/bin/docker-machine

Sous Mac, l’export des variables d’environnement Docker est identique à celui réalisé sur Linux :
eval "$(docker-machine env stephgoudockerfromwin)"

Docker Machine sur Windows

Pour installer Docker Machine sur Windows, il suffit de télécharger l’exécutable depuis l’url suivante https://github.com/docker/machine/releases/download/v0.2.0/docker-machine_windows-amd64.exe dans un répertoire connu dans le PATH.
Sous Windows, le fonctionnement de Docker Machine, se heurte à deux difficultés :
• La nécessité de mettre à disposition la commande OpenSSL (qui n’est pas fourni nativement dans Windows) qui est un pré-requis de l’utilisation de la commande Docker Machine
• La gestion des variables d’environnement Docker

Mise à disposition de la commande OpenSSL

Il existe de multiples façons d’obtenir OpenSSL sur Windows. L’une d’elle est d’utiliser l’application « Git for Windows » dont je vous ai déjà parlé dans un précédent article.
• La commande OpenSSL est directement disponible depuis le shell Mingw32 fourni avec « Git Bash ». Son usage dans cet environnement d’exécution impose le respect de certaines conventions liées à un système Unix (comme l’illustre la gestion des variables d’environnements que je traiterai un peu plus loin…).
• Une alternative à cette approche est d’ajouter dans le path de Windows le répertoire dans lequel est installé OpenSsl et d’utiliser directement le Shell Windows (cf copie d’écran suivante).

OpenSSL-Path

Suivant la version de « Git Bash » que vous aurez installé, vous serez amené ou non à rencontrer l’erreur « Error creating machine: exit status 1 » lors de l’utilisation de docker-machine sous Windows. Avec une version 1.8.x, ce dysfonctionnement ne se produisait pas. Avec la dernière version (j’utilise la version 1.9.5-preview20150319), on évite cette erreur en positionnant la variable d’environnement OPENSSL_CONF avec comme valeur le chemin d’accès au fichier openssl.cnf :

• Si l’on exécute ses commandes depuis le shell Windows, cela se traduit donc par la commande :

set OPENSSL_CONF=C:\Program Files(x86)\Git\ssl\openssl.cnf

• Si l’on exécute ses commandes depuis le shell Mingw32, il faut utiliser quelques séquences d’échappement pour parvenir au résultat souhaité :

export OPENSSL_CONF=/C/Program\ Files\ \(x86\)/Git/ssl/openssl.cnf

Gestion des variables d’environnement

Comme vu précédemment pour Linux et pour Mac, il nous faut positionner les variables d’environnement retournées par la commande docker-machine env ou docker-machine env <nom de la machine>.
Lorsqu’on utilise le shell Windows, la commande docker-machine env fournit les variables en les préfixant d’un « export », il nous faut donc explicitement positionner les valeurs affichées en remplaçant les commandes « export » par des « set ».
Lorsqu’on utilise le shell Mingw32, quoique la commande « eval » et les « export » résultant de l’appel à cette commande soit supportés, on ne peut pas comme sous Linux ou Mac se contenter d’exécuter la ligne eval eval "$(docker-machine env stephgoudockerfromwin)". En effet, la commande docker-machine env expose la variable d’environnement DOCKER_CERT_PATH au format « C:\Users\… ». Il nous faudra donc veiller à ce que la variable DOCKER_CERT_PATH soit au format « C/Users/stephgou/docker/machine/machine/… ». Si l’on est amené à répéter fréquemment ces déclarations, une façon de procéder est alors de lancer avec la commande source setenv.sh un fichier setenv.sh dans lequel on « adapte » ces variables d’environnement de la façon suivante :

export DOCKER_TLS_VERIFY=yes

export DOCKER_HOST=tcp:// stephgoudockerfromwin.cloudapp.net:2376

export DOCKER_CERT_PATH= C/Users/stephgou/.docker/machine/machines/ stephgoudockerfromwin

Template Azure Resource Manager

 « Azure Resource Manager » permet de déclarer une entité de gestion dans laquelle sont intégrés des regroupements de multiples ressources Azure de même type ou non. L’appartenance à un groupe de ressources est exclusive. Les ressources peuvent être multi-régions. Dans ce contexte, un groupe de ressources est un conteneur logique destiné à faciliter la gestion du cycle de vie d’un regroupement de multiples ressources, comme dans le cas d’une application construite autour d’un site Web, d’une base SQL Database et d’une machine virtuelle.

La solution proposée pour le déploiement et la configuration d’un groupe de ressources est déclarative afin de faciliter la configuration des ressources, de leurs dépendances, de leurs interconnexions, de leur contrôle d’accès, et de leur facturation. Elle se fonde sur l’utilisation d’un modèle baptisé « Azure Template » qui va permettre de garantir l’idempotence, simplifier l’orchestration, la gestion du cycle déploiement, ou le retour sur une version antérieure. Ces modèles sont implémentés en JSON et peuvent donc être gérés dans un contrôleur de code source.

Une librairie de templates de déploiement Azure est publiée sur GitHub. Parmi les modèles disponibles, le modèle « docker-containers-vm-resource-loops » permet de créer N machines virtuelles et déployer deux container docker [nginx et redis] sur chaque VM.

Deploy-Docker-Containers-Template

Le bouton « Deploy to Azure » permet de configurer les paramètres requis pour déployer ce modèle sur votre souscription.

Deploy-To-Azure

Le template correspondant est fondé sur l’utilisation de l’extension Docker.

Docker-JSON-Template