News & Events
Hands On - SQL Server 2017 on Docker

Durch die Möglichkeit, Microsoft SQL Server in Docker Containern verwenden zu können, ergeben sich neue Möglichkeiten bei der Verteilung von Datenbanken.

Icon Unternehmen

Dieser Artikel widmet sich dem praktischen Einsatz von Microsoft SQL Server als Docker Container.

Um die einzelnen Schritte nachzustellen, müssen folgende Voraussetzungen erfüllt sein:

  • eine vorhandene CentOS 7.5 Installation (oder höher)
  • grundlegende Kenntnisse über Docker und SQL Server


Der Betrieb des SQL Server Docker Containers benötigt folgende Voraussetzungen:

  • Docker Engine 1.8+
  • mindestens 2GB RAM (3.25GB ab SQL Server 2017 CU2)
  • Folgende Umgebungsvariablen müssen dem Container konfiguriert werden:
    • ACCEPT_EULA=Y
    • SA_PASSWORD=<komplexes_passwort>
    • MSSQL_PID=<produkt_id> (Optional, Standard ist "Developer", weitere sind "Express", "Standard", "Enterprise", "EnterpriseCore")


Installation von Docker

Wir beginnen mit einer frischen Installation eines CentOS Linux 7. Zunächst wird das System auf die neusten Pakete aktualisiert.

Yum Update

yum update

Danach wird Docker über das offizielle Install Skript der Docker Seite installiert → get.docker.com

Install Docker

curl -fsSL get.docker.com -o get-docker.sh
sudo sh get-docker.sh

Nach der Installation, muss der Docker Daemon noch aktiviert und gestartet werden.

Start Docker

systemctl enable docker
systemctl start docker

Dann kann anschließend geprüft werden, ob der Docker Daemon funktioniert.

Check Docker

sudo docker container ls

Docker ist nun installiert und lauffähig.

Hands On - SQL Server 2017 on Docker

Individuelle SQL Server Images vorbereiten

Damit wir möglichst automatisch eine vollständige Konfiguration unserer SQL Server Installation bekommen, werden angepasste Docker Images für die Container erstellt.

Server

Zunächst wird ein Image für den SQL Server erstellt. Dazu legen wir im Projektordner einen neuen Ordner "server" an und erstellen dort ein "Dockerfile"

Dockerfile - server

FROM mcr.microsoft.com/mssql/server
RUN mkdir /sql
RUN mkdir /sql/sql_data
RUN mkdir /sql/sql_log
RUN mkdir /sql/sql_im
RUN mkdir /sql/sql_backup
COPY ./WideWorldImporters-Full.bak /tmp/WideWorldImporters-Full.bak
RUN /opt/mssql/bin/mssql-conf set sqlagent.enabled true

In der ersten Zeile wird das offizielle SQL Server Image von Microsoft referenziert. Darauf baut unser Image auf. Als nächsten erstellen wir ein paar Ordner, die wir für die spätere Dateiablage benötigen. In der vorletzten Zeile wird das Backup einer Testdatenbank in das Image kopiert. Das könnte man auch außerhalb vom Image in ein Volume für den Container legen, damit das Image kleiner wird. In der letzten Zeile aktivieren wir noch den SQL Server Agent, damit wir später automatisierte SQL Server Agent Jobs ausführen können.

Das Docker Image können wir nun mit dem "build" Befehl erstellen:

Build Image server

docker build -t server .

SQL Server Initialisierung

Für die Wiederherstellung des entsprechenden SQL Server Backups und der anschließenden Anlage von Wartungstasks erstellen wir uns ein anderes Image, dem wir die nötigen Skripte mitgeben und das sich zum SQL Server Container verbinden wird.

Dazu legen wir wieder einen neuen Ordner im Projektverzeichnis an "sql-init". Dort erstellen wir zunächst eine Datei "restore.sql"

restore.sql

IF NOT EXISTS (
  SELECT d.name,f.physical_name FROM sys.master_files f, sys.databases d WHERE f.database_id = d.database_id and d.name = 'WideWorldImporters'
) BEGIN
    RESTORE DATABASE WideWorldImporters
      FROM DISK = '/tmp/WideWorldImporters-Full.bak'
      WITH MOVE 'WWI_Primary' TO '/sql/sql_data/WideWorldImporters.mdf',
           MOVE 'WWI_UserData' TO '/sql/sql_data/WideWorldImporters_UserData.ndf',
           MOVE 'WWI_Log' TO '/sql/sql_log/WideWorldImporters.ldf',
           MOVE 'WWI_InMemory_Data_1' TO '/sql/sql_im/WideWorldImporters_InMemory_Data_1';
  END

Hier wird zunächst geprüft, ob die Datenbank schon angelegt ist - wenn nicht wird sie aus der entsprechenden Backupdatei wiederhergestellt. Eine entsprechende Datei für die Wartungstasks haben wir uns als "MaintenanceSolution.sql" in den Ordner gelegt. Nun müssen wir eine Datei  "entrypoint.sh" in dem Ordner anlegen. Diese wird zum immer am Ende der Befehlskette vom Container gestartet.

entrypoint.sh

sleep 90s
/opt/mssql-tools/bin/sqlcmd -S sqlserver -U sa -P Geheim_1234 -i /opt/scripts/restore.sql
/opt/mssql-tools/bin/sqlcmd -S sqlserver -U sa -P Geheim_1234 -i /opt/scripts/MaintenanceSolution.sql

Eine Wartezeit von 90 Sekunden ist sinnvoll, da zunächst auf den SQL Server Container gewartet werden muss. Dieser muss verfügbar sein.
Jetzt wird noch ein "Dockerfile" benötigt:

Dockerfile - sql-init

FROM mcr.microsoft.com/mssql-tools
RUN mkdir /opt/scripts
COPY ./restore.sql /opt/scripts/restore.sql
COPY ./entrypoint.sh /opt/scripts/entrypoint.sh
COPY ./MaintenanceSolution.sql /opt/scripts/MaintenanceSolution.sql
WORKDIR /opt/scripts
CMD /bin/bash ./entrypoint.sh

Wir erstellen das Image auf der Basis des offiziellen SQL Client Tool Image von Microsoft. Danach wird wieder ein Ordner angelegt und die 3 Skriptdateien in diesen kopiert. Zum Schluss wird der aktuelle Ordner auf den "/opt/scripts" gewechselt und das Entrypoint Skript ausgeführt.
Das Image muss nun wie das vom SQL Server mit dem "build" Befehl erstellt werden:

Docker Build sql-init

docker build -t server .

Hands On - SQL Server 2017 on Docker: Build Server sql-init

Docker-Compose installieren

Da die Application und die Datenbank über docker-compose bereitgestellt werden sollen, müssen wir dieses vorher noch auf dem System installieren.

Install docker-compose

sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose


Docker-Compose Datei erstellen

Um unsere beiden Images als Container auszuführen, könnten wir "docker run" benutzen. Allerdings werden die Konfigurationen dabei nicht abgelegt und wir können es schlecht auf einen anderen Dockerhost übertragen. Darum legen wir nun eine "docker-compose.yml" Datei. Damit können mehrere Container im YAML Format definiert und durch den Befehl "docker-compose up", automatisch erstellt werden.

docker-compose.yml

version: '3'
services:
  sqlserver:
    image: server
    ports:
    - 1433:1433
    environment:
    - ACCEPT_EULA=Y
    - SA_PASSWORD=Geheim_1234
    volumes:
    - sql_data:/sql/sql_data
    - sql_log:/sql/sql_log
    - sql_im:/sql/sql_im
    - sql_backup:/sql/sql_backup
  sqlinit:
    image: sql-init
    links:
    - sqlserver
    depends_on:
    - sqlserver
volumes:
  sql_data:
  sql_log:
  sql_im:
  sql_backup:

Die Datei wird direkt im Projektordner erstellt (kann aber auch an einem anderen Ort im Dateisystem liegen). Danach führen wir den Compose Vorgang mit folgenden Befehl aus:

Ausführen

docker-compose up

Hands On - SQL Server 2017 on Docker

Verbindung zur Instanz herstellen

Nun kann die Verbindung zur Instanz hergestellt werden. Dazu kann das SQL Server Management Studio oder das Azure Data Studio genutzt werden. Dazu wird die IP Adresse des Docker Host als Zieladresse angegeben. Dort wird der Port 1433 zum Container weitergereicht.

Hands On - SQL Server 2017 on Docker - Verbindungsdetails

Wie zu sehen ist, wurde die Datenbank "WideWorldImporters" angelegt.

Hands On - SQL Server 2017 on Docker - angelegte Datenbank "WideWorldImporters"

Wir können auch Abfragen auf diese absetzen.

Hands On - SQL Server 2017 on Docker - Abfragen sind möglich

Die Wartungsjobs wurden wurden ebenfalls angelegt.

Hands On - SQL Server 2017 on Docker - Wartungsjobs sind angelegt

Fazit

Die Containerisierung vom SQL Server eröffnet neue Möglichkeiten beim Verteilen von Datenbanken und Erstellen von Anwendungen. Pakete von Anwendungen mit ihren jeweiligen Datenbanken können vorkonfiguriert und über Docker bzw. damit auch über Kubernetes deployed und verteilt werden.

Die Überwachung und Wartung von SQL Servern im Container ist allerdings noch eine Herausforderung und sollte gut durchdacht werden. Hierbei gibt es viele Fallstricke, bezüglich der Volume- oder auch Netzwerkkonfiguration zu beachten.

 


Newsletter-Archiv