SQL Server avec Docker sur Windows

Cet article est une introduction à Docker sur Windows et présente comment mettre en oeuvre SQL Server dans un container docker à des fins de tests et développement.

SQL Server est relativement lourd à installer « à l’ancienne », c’est donc un bon exemple pour illustrer l’intérêt de Docker. C’est ce que j’ai fait sur mon poste de développement (je n’ai pas encore utilisé SQL Server avec docker en production).

J’ai essayé de rester relativement concis dans cet article. Je vous conseille donc de lire les détails donnés sur les pages référencées. D’autant qu’entre la rédaction de cet article (décembre 2017, docker version 17.09) et aujourd’hui, les choses peuvent avoir évolué. Tenez également compte de la date de la documentation que vous lisez car docker sur Windows est encore relativement jeune.

Pré-requis

Le cas d’utilisation de cet article est l’installation de SQL Server pour Windows, installé dans un container Windows Server sur une machine hôte Windows 10 Pro.

Sur une machine hôte de version antérieure à Windows 10, il est aussi possible d’installer SQL Server, mais vous devrez utiliser une image SQL Server pour Linux (oui oui), et vous devrez installer une ancienne version de Docker pour Windows: Docker Toolbox.

Installez Docker sur Windows

Téléchargez et installez Docker à partir de cette page:

https://www.docker.com/docker-windows

Avant d’installer docker, vous pouvez vérifier s’il est déjà installé, ouvrez une session Powershell et tapez

docker version

Une fois l’installation terminée, vous devriez trouver l’icône du client docker en bas à droite dans la barre de Windows.

Passer en mode Windows Containers (Hyper-V)

Switcher vers le mode Windows Containers

Ouvrez le menu contextuel du client docker pour vérifier que le mode Windows Containers est activé. Si le menu propose « Switch to Windows Containers », cliquez dessus et attendez le temps du changement de mode (qui consiste à passer d’une machine virtuelle Linux au mode Hyper-V). Sinon c’est que le mode est bien actif.

Le mode Windows Containers sur Windows 10 consiste à utiliser le mode d’isolation Hyper-V

Ce mode est essentiellement une machine virtuelle optimisée gérée par Hyper-V. Si vous allez dans Hyper-V Manager, il est normal de ne pas y voir de machine virtuelle Windows, celle-ci étant gérée de façon transparente. En mode Linux Containers, vous verrez bien une machine virtuelle listée dans Hyper-V Manager.

Les containers lancés en mode d’isolation Hyper-V sont aussi appelés Hyper-V Containers, par opposition à Windows Server Containers.

Hyper-V Containers vs Windows Server Containers

Un container Windows Server est le container le plus fidèle à la philosophie Docker sur Windows, sans surcouche.

Un container Hyper-V est isolé dans une machine virtuelle Windows Server optimisée.

Vous voudrez surement vous orienter vers un container Windows Server, sans isolation Hyper-V. Sur Windows 10, vous n’avez pas ce choix. Vous pouvez choisir entre les deux modes sur Windows Server 2016. Ceci n’est pas une limitation, c’est une fonctionnalité. En effet, l’idée de supporter docker sur Windows 10 est de faciliter les tests et la préparation du déploiement de containers sur un serveur de production Windows Server. Comme un container s’appuie sur une image de base qui représente l’OS, un container basé sur Windows 10 ne serait pas optimal pour fonctionner sur un hôte Windows Server (une machine virtuelle intermédiaire serait requise).

Il est également à noter que ce choix est fait au lancement (runtime) du container, et non à la création de son image.

Test d’un container Windows

Docker est fonctionnel, en mode Windows. Testons un serveur IIS.

Lancer un container IIS

Dans une session Powershell en mode admin, exécutez cette commande:

docker run -p 80:80 --name iis microsoft/iis:nanoserver

Comme l’image n’existe pas encore sur votre poste, elle va être téléchargée. Notez que nous utilisons ici la version nanoserver (la plus légère). Pour voir toutes les versions, regardez sur le hub public de docker.

Si la commande précédente ne vous rend pas la main, appuyez sur CTRL+C pour sortir de son contexte. Vous reviendrez à l’invite de commande. Le container iis sera toujours en fonctionnement. Vous pouvez le vérifier avec la commande:

docker ps

L’option -name sert à nommer notre container. Autrement un nom aléatoire lui sera donné. Vous pourrez identifier le container soit avec son identifiant (hachage), même partiel, soit avec son nom complet.

L’option -p 80:80 sert à exposer le port TCP 80 du container IIS sur le port 80 de la machine hôte. Si le port 80 est déjà utilisé sur votre machine, vous pouvez utiliser un autre port, par exemple le port TCP 81 avec -p 81:80.

Tester le bon fonctionnement du serveur IIS

Pour tester le bon fonctionnement du serveur IIS, ouvrez un navigateur sur votre machine hôte, et allez à la page http://localhost:80

Si cela ne fonctionne pas, c’est normal.

Il semble que la gestion réseau de docker sur Windows soit différente de Linux (ou d’une machine virtuelle Linux). L’interface loopback aurait fonctionné sur Linux, mais elle ne fonctionne pas sur Windows. C’est la raison pour laquelle vous ne pouvez pas pointer un container à partir du nom localhost ou de l’adresse IP 127.0.0.1

Il faut donc trouver votre adresse IP (commande ipconfig) et l’utiliser à la place de localhost. Cela devrait fonctionner et vous afficher la page d’accueil de IIS !

Réseau des containers docker

Cela fonctionne parce que l’on a exposé le port 80 du container sur le port 80 de l’hôte grâce à la translation d’adresse (ou NAT). C’est une fonction typique sur un routeur réseau, et c’est exactement ce qu’a mis en place l’installation de docker. On peut le voir avec la commande ipconfig qui devrait afficher un adaptateur réseau nommé « nat » en plus de l’adaptateur par défaut.

Le container a lui-même sa propre adresse IP que vous pouvez obtenir grâce à la commande docker inspect iis (trouvez la ligne « IPAddress »). Vous pouvez donc utiliser dans votre navigateur l’adresse IP du container au lieu de celle de l’hôte.

Si vous souhaitez accéder au container à partir de son adresse IP, il est alors inutile d’utiliser le forwarding de port (paramètre -p). Sans le forwarding, le container ne peut être accédé que depuis l’hôte et pas depuis un ordinateur distant. Avec le forwarding, l’accès distant peut fonctionner grâce à l’adaptateur réseau virtuel « nat » (n’oubliez pas de configurer votre pare-feu pour autoriser des ordinateurs distants à utiliser le port exposé sur l’hôte).

Arrêter le container IIS

Pour lister les containers en fonctionnement, utilisez la commande:

docker ps

Vous devriez voir votre container IIS. Il suffit d’utiliser les premiers caractères de son identifiant ou bien son nom complet pour identifier le container à arrêter avec la commande suivante:

docker stop iis

Détruire le container

La commande docker ps ne devrait plus retourner notre container. Celui-ci existe toujours, il est simplement arrêté. Pour le voir, utilisez la commande:

docker ps -a

Vous voyez tous les containers, même ceux arrêtés. Pour détruire notre container arrêté, utilisez la commande:

docker rm iis

Il reste possible d’instancier un nouveau container IIS car l’image existe toujours. Pour voir les images disponibles sur l’hôte, tapez la commande:

docker images

Supprimer l’image

Pour supprimer une image, utilisez la commande (remplacez « [id] » par les premiers caractères de l’identifiant de l’image):

docker rmi [id]

Après cette commande, la prochaine fois que vous voudrez lancer le container IIS, son image devra de nouveau être téléchargée.

Télécharger le container SQL Server

La commande docker run va télécharger l’image si elle n’existe pas localement, puis instancier à container à partir de celle-ci. Vous pouvez aussi télécharger manuellement l’image avant de l’utiliser, avec la commande docker pull.

Commencez par identifier l’image SQL Server que vous souhaitez utiliser en recherchant microsoft/mssql sur le hub docker.

Par exemple, pour la version SQL Server Express pour Windows:

docker pull microsoft/mssql-server-windows-express:latest

Notez l’existence des images SQL Server Developer Edition et de SQL Server pour Linux. Cette dernière pourra vous intéresser sur une version antérieure à Windows 10 qui ne supporte pas des containers Windows.

Lancez un container SQL Server

Utilisez la commande suivante pour lancer SQL Server (adaptez le nom de l’image si vous avez téléchargé une autre édition que l’image SQL Server Express):

docker run -e "ACCEPT_EULA=Y" -e SA_PASSWORD=test@123 --name sql -d microsoft/mssql-server-windows-express:latest

Les options -e sont des variables d’environnement que l’on définit dans le container.

Lire les logs d’un container

La commande suivante permet d’afficher la sortie console de notre container nommé « sql »:

docker logs sql

Vous devriez obtenir quelque chose tel que:

VERBOSE: Starting SQL Server
VERBOSE: Changing SA login credentials
VERBOSE: Started SQL Server.

Si vous n’obtenez rien, attendez quelques instants le temps que le serveur démarre.

Si la ligne Changing SA login credentials n’apparait pas, il y a probablement une erreur dans la commande qui instancie le container avec le mot de passe du compte SA de SQL Server. J’ai mis un certain temps à comprendre pourquoi l’authentification à venir ne fonctionnait pas chez moi. Cela à cause de documentation pas à jour, il semble en effet que le paramètre « MSSQL_SA_PASSWORD » soit devenu « SA_PASSWORD ». Vous pouvez vérifier cela en amont avec la commande docker inspect microsoft/mssql-server-windows-express:latest et en regardant la ligne préfixée par « "Env": » (dans mon cas, la variable est bien nommée sa_password).

Se connecter à SQL Server depuis l’extérieur du container

Commencez par identifier l’adresse IP du container avec la commande:

docker inspect sql

Trouvez la ligne « IPAddress ».

Avec SQL Management Studio (SSMS), renseignez le nom de serveur avec l’adresse IP du container. SSMS utilisera le port par défaut de SQL Server (1433).

La connexion devrait fonctionner comme avec n’importe quel serveur SQL.

Si vous avez utilisé le paramètre -p (port forwarding), vous pouvez alors utiliser l’adresse IP de l’hôte pour vous connecter. Notez que lors de mes tests, j’ai eu des comportements anormaux dans SSMS, pour créer une base par exemple (timeout). Sans le port forwarding (c’est-à-dire en utilisant l’adresse IP du container), je n’ai pas eu de problème. Ce problème est lié à SSMS car je n’ai pas remarqué cela avec l’outil en ligne de commande sqlcmd. Il y a sans doute un paramétrage manquant et mal documenté pour le bon fonctionnement de SSMS…

A suivre…

Cela cloture cet article.

Attention, nous n’avons pas configuré de persistence de données sur notre container: à sa suppression, vous perdrez toutes les bases de données créées à l’intérieur de celui-ci. Chaque fois qu’un container est instancié, il repart vierge à partir de son image. C’est tout l’intérêt des containers, mais pour SQL Server, il faut donc configurer le container pour que l’emplacement de stockage des bases se trouve hors du container.