In diesem Beitrag geben wir eine kleine Einführung in die Verwendung von MSSQL mit Docker Containern geben. Die primären Ziele dabei sind die folgenden:
- das Ausführen eines SQL Servers mithilfe von Docker
- das Ausführen mehrerer SQL Server mithilfe von Docker
- das Wiederherstellen einer Datenbank auf dem zuvor erstellten SQL Server Container
- das Verbinden des MSSQL Containers mit dem .NET Core
Vorbereitungen
Als erstes muss das SQL Server Image bezogen werden. Mithilfe der folgenden PowerShell-Eingabe kann eine Übersicht der von Microsoft zur Verfügung gestellten SQL Server Images erzeugt werden:
Als nächstes, können wir die Ausgabe des zuvor ausgeführten Kommandos in einer Variable zwischenspeichern und anschließend nur den Content ausgeben lassen:
Die folgende Ausgabe sollte nun zu sehen sein:
Um nun anhand der zuvor ausgelesenen Informationen ein SQL Server Image zu downloaden, kann folgender Befehl ausgeführt werden (hier am Beispiel von SQL Server 2017 mit Cumulative Update 11):
Nach einiger Zeit (abhängig von der Geschwindigkeit der Internetverbindung) ist der Download beendet.
SQL Server mit Docker ausführen
Um einen Container mit SQL Server nutzen zu können müssen zuvor einige Parameter zur richtigen Konfiguration des Containers angegeben werden. Mit Hilfe des nächste Befehls werden die EULA akzeptiert, das Passwort für den SA Benutzer gesetzt, ein Hostname, ein Port, ein zugehöriges Volumen und der Name des Containers konfiguriert:
Der Befehl verwendet die folgenden Parameter zur Angabe dieser Informationen:
- -e: zum setzen von Umgebungsvariablen (also das SA Passwort und das Akzeptieren der Docker EULA)
- -hostname: zum Setzen des Hostnamen des Containers
- -p: zum Veröffentlichen des Ports des Containers an den Host
- -v: zum Mounten eines Volumen. Auf diesem Volumen werden die Daten, die für die SQL Server Datenbanken benötigt werden, gespeichert.
- -name: zum Setzen eines Namens für den Container
- -d: gibt an, dass der Container im Hintergrund ausgeführt werden soll
Nach der Ausführung des obigen Befehls sollte nach nur ein paar Sekunden ein Container erzeugt werden. Wir können den Status des erzeugten Containers mit dem Befehl
auslesen. An dieser Stelle muss sicher gestellt sein, dass der “STATUS” des zuvor erzeugten Containers “Up” ist.
Sobald der Container erzeugt wurde und im Hintergrund läuft, können wir T-SQL Abfragen gegen den Container ausführen. Hier eine beispielhafte Abfrage zum Auslesen der Version des SQL Servers:
Das sqlcmd Programm
Die erfolgreich verarbeitete Abfrage zeigt, dass der Container läuft und von außen erreichbar ist.
Wiederherstellen einer Datenbank
Als Nächstes können wir das Backup einer Datenbank auf den Container kopieren, um diese anschließend wiederherstellen zu können. Das Kopieren einer Datei in den Container kann mit dem docker cp Befehl umgesetzt werden:
Nachdem die Datei in den Container kopiert wurde, kann ein T-SQL Befehl verwendet werden, um das Backup auf dem bei der Erstellung des Containers angegebenen Volumen wiederherzustellen:
Bei Erfolg wird nach einer kurzen Zeit die Ausgabe “RESTORE DATABASE successfully processed…” ausgegeben. Jetzt ist unsere Datenbank wiederhergestellt!
Mehrere SQL Server Instanzen gleichzeitig verwenden
Als Nächstes wollen wir versuchen, mehrere SQL Server Instanz gleichzeitig unter Docker zu verwenden. Mit dem folgenden Befehl erzeugen wir einen weiteren Container:
Hierbei sind einige Änderungen gegenüber dem ersten Befehl zu bemerken:
- Der “Hostname” des neuen Containers wurde angepasst
- Der angegebene Port, um den Container von außen zu erreichen, wurde verändert (vorher 1401)
- Ein anderes Volumen wird verwendet
- Der “Name” des neuen Containers wurde angepasst
Nachdem der Befehl ausgeführt wurde, haben wir zwei Container gleichzeitig laufen. Mit dem docker ps -a Befehl kann der Status der Container wie zuvor überprüft werden.
Mithilfe von SSMS mit den Containern verbinden
Um zu zeigen, dass sich die erzeugten Container wie eine übliche SQL Server Installation unter Windows verhalten, werden wir uns im nächsten Schritt mit Hilfe des SQL Server Management Studios (SSMS) mit den Containern verbinden.
Nachdem SSMS gestartet wurde, muss eine Verbindung zu einer “Database Engine” mit den folgenden Konfigurationen aufgebaut werden:
Server name: localhost,1401 (oder localhost,1402)
Login: sa
Password: SecurePassword987!
Wir bauen also eine Verbindung zu dem lokalen Container auf, der auf dem Port 1401 zuhört. Nachdem die Eingaben mit einem Klick auf “Verbinden” bestätigt wurden, ist eine Verbindung zu dem Container aufgebaut.
Einer der Unterschiede zu einer “gewöhnlichen” Installation ist das zugehörige Icon im “Object Explorer” in SSMS. Da Docker Linux-basiert ist, ist der Pinguin zu sehen.
Datenbanken Updates unterschiedlicher Cumulative Update-Levels und SQL Server Upgrade
Mit unseren beiden zuvor erstellten Containern haben wir zwei SQL Server mit unterschiedlichen Update-Leveln. Als Nächstes möchte ich eine Situation simulieren, in der beispielsweise Kompatibilitätstests gegen eine Datenbank einer höheren SQL Server Version durchgeführt werden müssen.
Um einen Docker Container auf dem ein SQL Server läuft zu updaten, müssen wir folgende Schritte nacheinander durchführen:
- Der erste Container muss gestoppt werden
- Der zweite Container muss gestoppt werden
- Das Volumen mit der Datenbank muss an den zweiten Container angebunden werden
- Die Tests an der Datenbank können durchgeführt werden
Als Erstes stoppen wir also den SQL Server 2017 CU11 Container. Dafür kann der folgende Befehl verwendet werden:
Jetzt können wir einen neuen Container erstellen, der das selbe Volumen wie der Container benutzt, den wir zuvor gestoppt haben. Mit folgendem Befehl wird eine neuer Container erzeugt:
Nachdem dieser Container erzeugt wurde, dauerte es ein paar Minuten bis der Container erreichbar ist. Der SQL Server führt unmittelbar nach seinem Erzeugen ein Update aus, um die Datenbank auf die selbe Version wie die “master” Datenbank zu bringen. Nachdem das Update durchgeführt wurde, ist der Container wieder erreichbar und wir haben spielend leicht ein neues CU aufgespielt.
Genau so einfach ist es auch die SQL Server Version zu upgraden. Im Grunde läuft das Verfahren analog zum vorherigen CU Update, nur dass der neue Container die Version SQL Server 2019 benutzt:
Docker Container richtig entfernen
Nachdem wir Docker Container erzeugt haben, ist es auch wichtig zu wissen, wie sie wieder entfernt werden können, wenn wir sie nicht mehr benötigen. Zu aller erst sollten wir alle lokalen Container auflisten. Dies kann mit dem folgenden Befehl umgesetzt werden:
Die aufgelisteten Container können dann mit der Angabe einer Container-ID oder eines Namen entfernt werden:
Wenn nach dem Ausführen dieses Befehls keine weitere Ausgabe erscheint, bedeutet das, dass der Befehl erfolgreich ausgeführt wurde.
Sollte der gelöschte Container über ein Volumen verfügt haben, muss dieses ebenfalls entfernt werden. Zum Auflisten aller Volumen kann folgender Befehl verwendet werden:
Anschließend kann mit dem folgenden Befehl eines der aufgelisteten Volumen entfernt werden:
Zu guter Letzt können die lokalen Images, die verwendet wurden, entfernt werden. Um alle lokalen Images aufzulisten, muss folgender Befehl ausgeführt werden:
Um nun eines der aufgelisteten Images zu entfernen, muss die ID des Images verwendet werden:
MSSQL Container mit .NET Core verwenden
Um SQL Server Container mit .NET Core Anwendungen zu benutzen, werden wir das “entity framework”, genauer die DBContext Klasse, verwenden, um einen Kontext zu erzeugen. Eine typische Implementation der Klasse sieht dabei wie folgt aus:
Das DbSet vom Typ User repräsentiert dabei eine Entität, für die ein Äquivalent in der MSSQL Datenbank existiert. Zur besseren Veranschaulichung hier noch die Implementation dieser User Klasse:
Jetzt müssen wir noch dafür sorgen, dass die .NET Core Anwendung und der SQL Server Container miteinander kommunizieren können. Mit einer simplen PackageReference lässt sich auch dieses Problem lösen:
Zum Schluss muss nun das DbContext Objekt benutzt werden, um eine Verbindung zum Container aufzubauen. Dafür benötigen wir einen sogenannten Connection-String. Das ist eine Zeichenkette, die alle für den Verbindungsaufbau wichtigen Informationen enthält:
Dabei repräsentieren die Parameter folgende Informationen:
Wert127.0.0.1,1433my_dbsaSecurePassword987!
Der erzeugte Datenbank-Kontext kann nun in der ConfigurationServices Datei verwendet werden:
Zu guter Letzt können wir überprüfen, dass alles funktioniert. Dafür erzeugen wir eine Migration mithilfe des entity frameworks, um die Tabelle User zu erzeugen:
Dann führen wir sie aus:
Hat alles funktioniert, sollte nun die Tabelle User in der in der Verbindung angegebenen Datenbank existieren.
Fazit
Wie vermutlich leicht zu erkennen ist, bieten Docker Container eine enorm flexible und rapide Möglichkeit der Entwicklung auf unterschiedlichen SQL Server Versionen an. Der ermüdende und aufwendige Prozess, eine virtuelle Maschine bereitzustellen und zu konfigurieren, entfällt vollständig.