SQL Server mit Docker

In diesem Beitrag wollen wir uns genau anschauen, wie wir SQL Server in Kombination mit Docker Containern verwenden und alle nötigen Konfigurationen und Installationen durchführen können. Hierbei wollen wir

  • SQL Server Images von DockerHub herunterladen,
  • SQL Server auf Docker ausführen,
  • mehrere SQL Server Instanzen mit Docker konfigurieren,
  • unsere Instanzen mit SQL Server Management Studio (SSMS) verwalten,
  • eine Datenbank mithilfe von Docker wiederherstellen und
  • ein Datenbank Upgrade zwischen verschiedenen kumulativen Updates durchführen

Bevor wir diese Reise gemeinsam antreten und Sie den hier vorgeführten Beispielen problemlos folgen können, muss Docker richtig konfiguriert werden. Stellen Sie also sicher, dass Sie Docker auf Ihrem System wie hier beschrieben konfiguriert haben, bevor Sie beginnen.

Nachdem nun alles korrekt installiert und konfiguriert ist, kann es endlich losgehen.

Herunterladen des SQL Server Images

Als ersten Schritt überprüfen wir, welche SQL Server Images auf der Microsoft Website zur Verfügung stehen. Hierfür führen wir folgendes PowerShell Kommando aus:

 invoke-webrequest https://mcr.microsoft.com/v2/mssql/server/tags/list

Wir erhalten nun folgenden Output:

Als zweiten Schritt speichern wir den Output des Kommandos in der Variable §repository und überprüfen anschließend die Content-Eigenschaft:

$repository = invoke-webrequest https://mcr.microsoft.com/v2/mssql/server/tags/list
$repository.Content

Der anschließende Output sollte nun so aussehen:

Wir wollen nun in unserem Beispiel keine reine Installation von SQL Server 2017 vornehmen, sondern bereits ein Kumulatives Update mit installieren. Um eine spezifische Version eines SQL Server Binaries zu installieren (in unserem Fall mit dem Kumulativen Update 12) führen wir folgendes Kommando aus:

docker pull mcr.microsoft.com/mssql/server:2017-CU12

Nach einer kurzen Zeit sollten wir folgenden Output erhalten:

SQL Server mit Docker ausführen

Um SQL Server mithilfe von Docker zu starten und auszuführen, müssen wir eine Reihe von Parametern angeben. So können wir SQL Server erlauben mit der Welt außerhalb von Docker zu kommunizieren. Wir setzen die Parameter wie folgt:

docker run -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=Passwort123' `
--hostname sql2017cu11 `
-p 1401:1433 `
-v sqlvolume:/var/opt/mssql `
--name sql2017cu11 -d mcr.microsoft.com/mssql/server:2017-CU11-ubuntu
  • -e Setzt die Umgebungsvariablen. In unserem Fall akzeptieren wir hier die Lizenzbedingungen und das Passwort für den sa Benutzer.
  • -hostname Gibt dem Container einen Namen. Lassen wir diese Variable aus, erstellt Docker einen eigenen Namen für den Container.
  • -p Mit diesem Parameter können wir einen Port auf dem Host festlegen, welcher den Datenverkehr an einen bestimmten Port innerhalb des Containers weiterleitet. In diesem Fall leiten wir den Verkehr von Port 1401 auf dem Host an den Port 1433 innerhalb des Containers.
  • -v Bindet ein Volume an den Container.
  • -name Gibt dem Container einen Namen.
  • -d Lässt den Container im Hintergrund laufen und gibt die Container ID aus.

Nach ein paar Sekunden sollte ein neuer Container mit SQL Server erscheinen. Mit dem Kommando

docker ps -a

können wir alle laufenden Container einsehen:

Versuchen wir nun einmal, ein T-SQL Kommando auf dem Container auszuführen. Dies können wir mithilfe des cmdlet sqlcmd erreichen. So können wir beispielsweise dieses SQL Kommando ausführen:

sqlcmd '-Usa' '-Slocalhost,1401' '-Q"SELECT @@VERSION"' '-PPasswort123''

Wir sollten nun folgenden Output erhalten:

Wir können sehen, dass das Erstellen des Containers mit unserer gewünschten Version erfolgreich war.

Wiederherstellen einer Datenbank mit Docker

Da wir nun unseren Container mit SQL Server erstellt und konfiguriert haben, wird es Zeit ein paar Datenbanken Operationen durchzuführen. Hierfür werden wir jetzt ein Datenbanken-Backup auf unseren Container kopieren und dieses dann mithilfe von Docker wiederherstellen.

Um das Backup in unseren Container zu kopieren, führen wir folgendes Kommando aus:

docker cp C:\SQL_Backup\WideWorldImporters-Full.bak sql2017cu11:/var/opt/mssql

Das Backup sollte nach wenigen Sekunden erfolgreich in den Container kopiert worden sein.

Mit dem Backup innerhalb unseres Containers können wir nun ein T-SQL Kommando ausführen und das Backup auf dem Volume, welches wir vorher konfiguriert haben, wiederherstellen:

docker exec sql2017cu11 /opt/mssql-tools/bin/sqlcmd `
-S localhost `
-U sa `
-P 'Passwort123' `
-Q"`
RESTORE DATABASE WideWorldImporters `
FROM DISK = '/var/opt/mssql/WideWorldImporters-Full.bak' `
WITH MOVE 'WWI_Primary' TO '/var/opt/mssql/data/WideWorldImporters.mdf', `
MOVE 'WWI_UserData' TO '/var/opt/mssql/data/WideWorldImporters_userdata.ndf', `
MOVE 'WWI_Log' TO '/var/opt/mssql/data/WideWorldImporters.ldf', `
MOVE 'WWI_InMemory_Data_1' TO '/var/opt/mssql/data/WideWorldImporters_InMemory_Data_1'"

Nach einer kurzen Zeit sollten wir nun einen Output erhalten, der uns die Wiederherstellung bestätigt:

Wir verfügen nun also über einen SQL Server Container mit wiederhergestellter WideWorldImporters Datenbank.

Mehrere SQL Server Instanzen mit Docker konfigurieren

Nachdem wir bereits erfolgreich einen SQL Server Container mit wiederhergestellter Datenbank erstellt haben, wollen wir nun einen zweiten SQL Server Container mit der letzten SQL Server Version erstellen:

docker run -e 'ACCEPT_EULA=Y' -e '[email protected]' `
--hostname sql2017latest `
-p 1402:1433 `
-v sqlvolume2:/var/opt/mssql `
--name sql2017latest `
-d mcr.microsoft.com/mssql/server:2017-latest

Wir vergeben hier einen anderen Hostnamen, passend zu den SQL Server Binaries. Weiterhin wählen wir den Port 1402 zum Weiterleiten des Datenflusses, sodass wir uns mit beiden Instanzen gleichzeitig verbinden können. Als letztes konfigurieren wir noch ein anderes Volume.

Mit dem Kommando

docker ps -a

können wir nun beide Container einsehen:

Nachdem wir nun eine kleine SQL Server Umgebung eingerichtet haben, wollen wir uns im nächsten Schritt ansehen, ob sich diese Instanzen tatsächlich wie gewöhnliche SQL Server Instanzen verhalten. Dafür stellen wir eine Verbindung zu den Instanzen mit SQL Server Management Studio (SSMS) her.

Zugriff auf SQL Server Container mit SQL Server Management Studio (SSMS)

Um uns nun via SSMS mit unserem SQL Server Container zu verbinden, geben wir wie bei einer gewöhnlichen SQL Server Instanz den Host sowie den Port an. Im Falle unseres ersten Containers also localhost und 1401.

Nach einem Klick auf Connect, sind wir dann mit unserer Instanz verbunden. Nun können wir mithilfe von T-SQL den Inhalt der WideWolrdImporters Datenbank einsehen, welche wir auf dem Container wiederhergestellt haben.

Anhand dieses Beispiels können wir also sehen, dass wir mit einem SQL Server Docker Container genauso gut arbeiten und Datenbankoperationen durchführen können, wie bei einer gewöhnlichen SQL Server Instanz.

Ausführen von Updates und Upgraden auf eine neuere SQL Server Version mithilfe von Docker

Bis jetzt verfügen wir über zwei SQL Server Container mit zwei verschiedenen Binaries. In diesem Abschnitt wollen wir nun ein paar Kompatibilitätstests durchführen und auf eine neue SQL Server Version upgraden.

Als ersten Schritt stoppen wir den SQL Server Container mit der Version 2017 CU10. Hierfür führen wir folgendes Kommando aus:

docker stop sql2017cu11

Nun erstellen wir einen neuen SQL Server Container zum Testen:

docker run -e 'ACCEPT_EULA=Y' -e '[email protected]' `
--hostname sql2017test `
-p 1401:1433 `
-v sqlvolume:/var/opt/mssql `
--name sql2017test `
-d mcr.microsoft.com/mssql/server:2017-latest

Betrachten wir nun den SQL Server Log, können wir sehen, dass das Upgrade Skript zum Updaten einer Instanz auf unser gewünschtes CU Level durchgeführt wurde.

Ein Upgrade auf ein höheres CU Level ist mit Docker also einfach umzusetzen. Doch wie sieht es aus, wenn wir von SQL Server 2017 auf SQL Server 2019 upgraden wollen? Auch das lässt sich mit Docker sehr einfach realisieren. Hierfür stoppen wir als Erstes den momentan laufenden Container, sql2017test:

docker stop sql2017test

Als nächstes starten wir einen neuen Container mit SQL Server 2019:

docker run -e 'ACCEPT_EULA=Y' -e '[email protected]' `
--hostname sql2019 `
-p 1402:1433 `
-v sqlvolume:/var/opt/mssql `
--name sql2019 `
-d mcr.microsoft.com/mssql/server:2019-latest

Überprüfen wir jetzt jedoch unsere laufenden Container, sehen wir, dass der SQL Server 2019 Container gestoppt ist.

Schauen wir uns einmal den Log des Containers an. Dieser verrät uns vielleicht den Grund für dieses Verhalten. Mit dem Kommando

docker logs sql2019

können wir den Log für den Container sql2019 einsehen.

Und in der Tat können wir mit einem kurzen Blick auf den Log unser Problem ausmachen. Uns fehlt die Erlaubnis zum Starten des Containers. Wir können dieses Problem beheben, in dem wir wie folgt vorgehen:

  1. Starten einer früheren Version des Containers (in unserem Fall SQL Server 2017 CU17)
  2. Ändern der Besitzrechte des Verzeichnisses in dem Datenbanken gespeichert werden, sodass Benutzer aus der Root-Gruppe auf dieses zugreifen können
  3. Kopieren der Zugriffsberechtigungen in das Verzeichnis, in dem die Datenbanken gespeichert werden
docker start sql2017test
docker exec -it sql2017test "bash"
chgrp -R 0 /var/opt/mssql
chmod -R g=u /var/opt/mssql
exit

Versuchen wir nun ein Upgrade auf SQL Server 2019:

docker stop sql2017test
docker start sql2019
docker ps -a

Und tatsächlich haben wir erfolgreich einen SQL Server 2019 Container erstellt:

Doch wie sieht es aus, wenn wir uns in die entgegengesetzte Richtung bewegen und ein Downgrade vornehmen wollen? Schauen wir uns einmal an, wie wir von SQL Server 2019, zurück zu SQL Server 2017 kommen können. Hierfür führen wir folgende Schritte durch:

  1. Stoppen des SQL Server 2019 Containers
  2. Starten des SQL Server 2017 Containers
  3. Verbinden mit der Instanz und anschließendes Abfragen der Datenbank

Folgende Kommando müssen dafür ausgeführt werden:

docker stop sql2019
docker start sql2017test
docker ps -a

Schauen wir uns den Output an, können wir sehen dass sql2017test gestartet, aber nach einer sehr kurzen Zeit wieder gestoppt wurde:

Wie bei unserem vorherigen Beispiel, werfen wir auch hier einen Blick auf den Log:

docker logs sql2017test

Dieser verrät uns, dass ein Downgrade eines SQL Server Containers auf eine frühere Version leider nicht möglich ist. Wir können also lediglich Upgrades auf höhere Versionen durchführen.

Aufräumen

Da laufende Container CPU Leistung und Images Festplattenspeicher verbrauchen, wollen wir unsere erstellen Container nun wieder löschen. Um einen laufenden Container zu löschen, muss dieser erst einmal gestoppt werden. Schauen wir uns also noch einmal unsere Container an und stoppen alle noch laufenden:

docker ps -a

Da alle unsere Container bereits gestoppt sind, können wir mit dem Löschen beginnen. Wir können einen Container mit dem Befehl:

docker rm <containername>

entfernen. Erhalten wir nach dem Ausführen dieses Kommandos keinen Output, wurde der Container erfolgreich gelöscht.

Nachdem wir unsere Container entfernt haben, entfernen wir noch unsere Volumes. Ähnlich wie bei den Containern, führen wir hier folgendes Kommando aus:

docker volume rm sqlvolume
docker volume rm sqlvolume2

Als letzten Schritt wollen wir nun auch die Images löschen, welche wir vom Repository heruntergeladen haben. Mit dem Befehl:

docker images

können wir alle Images einsehen, die auf unserem Rechner gespeichert sind.

Zum Entfernen eines Images, folgendes Kommando ausführen:

docker rmi <ImageID>

Nachdem wir nun auch die Images gelöscht haben, sind wir mit dem Aufräumen fertig.

Anhand unserer Beispiele haben wir gesehen, dass wir mithilfe von Docker sehr schnell viele SQL Server Instanzen erstellen und diese wie gewöhnliche SQL Server Installationen verwenden können. Wir können Upgrades durchführen und uns in kurzer Zeit eine geeignete Umgebung für die Produktion, die Entwicklung oder einfach nur zum Spaß, erstellen.