Ein Wal im Container: Wie der Microsoft SQL Server seinen Weg in meinen Kubernetes-Cluster fand
Tradition trifft Moderne
In einer Welt, in der Containerisierung und Cloud-native Architekturen zum Standard geworden sind, stellt sich zunehmend die Frage: Wie integriert man traditionelle Systeme in diese neue Welt? Eine dieser klassischen Technologien ist der Microsoft SQL Server – robust, bewährt, aber nicht gerade bekannt für seine Cloud-native-Kompatibilität.
In diesem Beitrag teile ich meine Erfahrungen darüber, wie ich einen MS SQL Server erfolgreich in einen Kubernetes-Cluster integriert habe – konkret auf einem Mac, orchestriert über Rancher und Kubernetes. Ziel war es, herauszufinden, wie gut sich ein traditioneller Datenbankdienst in eine moderne Infrastruktur einbetten lässt.
Wo Theorie und Realität kollidieren
Die größte Herausforderung bestand darin, die Persistenz der Daten sicherzustellen. In Kubernetes ist ein Pod per Definition flüchtig – ein Neustart oder ein Verschieben auf einen anderen Node darf hierbei aber nicht zum Datenverlust führen. Die Lösung bestand aus einer Kombination von Persistent Volumes (PV) und Persistent Volume Claims (PVC), um eine stabile, speicherbasierte Infrastruktur zu schaffen.
Ein zweiter kritischer Punkt war der sichere Umgang mit sensiblen Daten, insbesondere dem sa-Passwort. Hier hat sich der Einsatz von Kubernetes Secrets bewährt – nicht perfekt (vor allem was Verschlüsselung und Zugriffskontrolle betrifft), aber praktikabel und deutlich sicherer als Umgebungsvariablen oder Klartext in YAML-Files.
Warum ich azure-sql-edge gewählt habe
Ein entscheidender technischer Aspekt war die Auswahl des richtigen SQL-Server-Containers. Da ich auf einem Mac mit Apple Silicon (ARM64) arbeite, musste ich ein Image wählen, das diese Architektur nativ unterstützt.
Aus diesem Grund habe ich mich für:
image: mcr.microsoft.com/azure-sql-edge
entschieden.
Azure SQL Edge basiert technisch auf dem regulären MS SQL Server, ist aber optimiert für Edge-Geräte und ARM-Architekturen. Dieses Image funktioniert problemlos auf einem M1- oder M2-Mac im Zusammenspiel mit Kubernetes (z. B. via Rancher Desktop oder Colima).
Für andere Setups – insbesondere klassische x86_64-Architekturen oder Cloud-Deployments – kann und sollte das Standard-Image verwendet werden:
image: mcr.microsoft.com/mssql/server
YAML-Definition: Klarheit durch Code
Bevor wir auf die eigentliche YAML-Datei eingehen, erstellen wir mit den nachfolgenden Befehlen noch relativ sicher ein Kubernetes-Secret für das „SA_Passwort“.
read -s -p "Enter SA_PASSWORD: " SA_PASSWORD && echo && \ kubectl create secret generic mssql-secret --from-literal=SA_PASSWORD="$SA_PASSWORD" Enter SA_PASSWORD: secret/mssql-secret created
Im ersten Teil wird das Passwort eingelesen, ohne es anzuzeigen. Mit dem zweiten Befehl wird das Passwort sicher übergeben und als Secret abgespeichert. Später greife ich auf das erzeugte Secret zurück. (Zeilen 45-50 der YAML-Datei)
Die gesamte Infrastruktur wurde als Code definiert – konkret über die folgende YAML-Datei, die alle notwendigen Ressourcen beschreibt:
apiVersion: v1 kind: PersistentVolume metadata: name: sql-edge-pv spec: storageClassName: local-path # <--- WICHTIG: Muss zum PVC passen capacity: storage: 10Gi accessModes: - ReadWriteOnce hostPath: path: "/mnt/data/sql-edge" # <--- Lokaler Speicherpfad auf dem Node --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: sql-edge-pvc spec: storageClassName: local-path # <--- Muss exakt zum PV passen accessModes: - ReadWriteOnce resources: requests: storage: 10Gi --- apiVersion: apps/v1 kind: Deployment metadata: name: sql-edge-deployment spec: replicas: 1 selector: matchLabels: app: mssql template: metadata: labels: app: mssql spec: containers: - name: mssql image: mcr.microsoft.com/azure-sql-edge ports: - containerPort: 1433 env: - name: SA_PASSWORD valueFrom: secretKeyRef: name: mssql-secret key: SA_PASSWORD - name: ACCEPT_EULA value: "Y" volumeMounts: - mountPath: /var/opt/sql-edge name: sql-edge-storage volumes: - name: sql-edge-storage persistentVolumeClaim: claimName: sql-edge-pvc
Ressourcen deployen und löschen
kubectl apply -f ms-sql_deployment.yaml
Mit diesem Befehl wird die YAML-Datei, in der alle Ressourcen definiert sind (PersistentVolumes, Secrets, Deployment, Service usw.), auf den Cluster angewendet. Es ist der klassische „Infrastructure-as-Code“-Ansatz.
Zum Entfernen aller Ressourcen:
kubectl delete -f ms-sql_deployment.yaml
Port-Forward und Verbindung testen
kubectl port-forward svc/mssql 1433:1433
Dieser Befehl ist Gold wert, wenn lokal auf den SQL Server zugegriffen werden soll – etwa über ein SQL-Client-Tool, sqlcmd, oder eine IDE wie Azure Data Studio bzw. das SQL Server Management Studio (auf Windows-Systemen). Er leitet den Port 1433 des Services im Cluster auf den lokalen Port 1433 weiter.
Verbindung via SQLCMD
sqlcmd -S localhost,1433 -U sa -P 'securePassword1!' 1> SELECT @@Version 2> GO ---------------------------------------------------------------------------- Microsoft Azure SQL Edge Developer (RTM) - 15.0.2000.1574 (ARM64) Jan 25 2023 10:36:08 Copyright (C) 2019 Microsoft Corporation Linux (Ubuntu 18.04.6 LTS aarch64) <ARM64> (1 row affected)
Dieser Befehl verbindet einen direkt mit der SQL Server-Instanz über den NodePort. Wichtig:
- 192.168.5.15: IP-Adresse deines Kubernetes-Nodes
- 1433: Port, wie zuvor beim Forward konfiguriert
- -U/-P: Benutzername und Passwort (wie in Secret definiert)
Tipp: Wenn ihr den Port über kubectl port-forward tunneln lasst (siehe oben), könnt ihr statt IP und Port auch einfach localhost angeben.
Kundennutzen: Mehr als nur ein technischer Gag
Was auf den ersten Blick wie ein technisches Experiment aussieht, bringt bei näherer Betrachtung handfeste Vorteile:
- Höhere Verfügbarkeit: Kubernetes sorgt für automatische Wiederherstellung und Skalierung. Fällt ein Pod aus, wird er automatisch neu gestartet – ohne manuelles Eingreifen.
- Wartbarkeit: Updates lassen sich mit minimalem Risiko einspielen. Durch Rolling Updates über Rancher kann der Betrieb weitgehend störungsfrei erfolgen.
- Effizienz: Containerisierung bedeutet bessere Ressourcennutzung. Durch Isolierung und dynamische Zuweisung sinken die Betriebskosten – bei gleichzeitig höherer Auslastung der Infrastruktur.
- Zukunftssicherheit: Die Integration klassischer Systeme in moderne Plattformen ermöglicht es Unternehmen, bestehende Investitionen zu schützen und gleichzeitig von den Vorteilen der Cloud-native-Welt zu profitieren.
Fazit: Legacy muss nicht Stillstand bedeuten
Die erfolgreiche Implementierung von Microsoft SQL Server in Kubernetes zeigt, dass Cloud-native und Legacy-Technologien kein Widerspruch sein müssen – vorausgesetzt, man ist dazu bereit, sich mit den Details zu beschäftigen.
Natürlich ist der Weg nicht frei von Hürden: Die Komplexität steigt und manche Probleme (z. B. Stateful Sets, persistente Speicher im lokalen Setup) sind nicht trivial. Doch wer sich darauf einlässt, wird mit einer modernen, skalierbaren und resilienten Lösung belohnt, die auch anspruchsvolle Anwendungsszenarien unterstützt.
Hinweis: Die hier gezeigte Konfiguration ist ideal für Entwicklungs- und Testumgebungen auf lokalen Clustern (z. B. mit Rancher Desktop). Für produktive Setups empfiehlt sich der Einsatz von StatefulSets, externem Storage (z. B. NFS, Longhorn, CSI-Treiber) und besserer Secret-Verwaltung (z. B. HashiCorp Vault).
Seminarempfehlungen
KUBERNETES ESSENTIALS [KUB-01]
Mehr erfahrenADMINISTRATION EINER MICROSOFT SQL SERVER INFRASTRUKTUR [MS-SQL-02]
Mehr erfahrenMICROSOFT SQL SERVER FÜR ORACLE DBAS [MS-SQL-11]
Mehr erfahrenSenior Chief Consultant bei ORDIX
Kommentare