Πώς κάνουμε εγκατάσταση SQL Server σε Linux μέσω Docker

Πώς κάνουμε εγκατάσταση SQL Server σε Linux μέσω Docker
Πώς κάνουμε εγκατάσταση SQL Server σε Linux μέσω Docker

Σε προηγούμενο άρθρο είχαμε δει την εγκατάσταση SQL Server 2019 σε Red Hat Enterprise Linux. Σε αυτό το άρθρο θα δούμε πως γίνεται να εγκαταστήσουμε SQL Server 2017 πάλι σε RHEL αλλά με μόνο 1 core και 1GB Ram με χρήση Docker container σε Ubuntu.

Ο λόγος που χρησιμοποίησα την λύση του Docker container ήτανε διότι έπρεπε να βρω έναν εύκολο τρόπο να παρακάμψω το όριο του 2GB RAM για την δημιουργία και εκκίνηση SQL Server instance.

Σε αντίθετη περίπτωση κατά την εγκατάσταση έπερνα το μήνυμα:

"sqlservr: This program requires a machine with at least 2000 megabytes of memory."

Επειδή first things first το πρώτο πράγμα που πρέπει να κάνουμε είναι να ανοίξουμε την πόρτα του SQL Server στο firewall.

sudo firewall-cmd --zone=public --add-port=1433/tcp --permanent
sudo firewall-cmd --reload

Bypass system specs

Η λύση υπάρχει από έναν τύπο που είχε το ίδιο πρόβλημα και έφτιαξε ένα Dockerfile έτοιμο ώστε να σηκωθεί container με SQL Server instance σε Docker.

Το trick ήταν η χρήση LD_PRELOAD που φορτώνει bypass βιβλιοθήκη που θα φορτώνεται πρώτη και όταν πάει να εκτελεστεί το binary του SQL Server θά παρακαμφθεί η πληροφορία με την δική μας ψεύτικη βιβλιοθήκη που θα έχει 2GB RAM.

Η πληροφορία που θέλαμε να παρακάμψουμε:

Πώς κάνουμε εγκατάσταση SQL Server σε Linux μέσω Docker

Ο κώδικας για την βιβλιοθήκη που χρειάζεται να γίνει compile (wrapper.c):

int sysinfo(struct sysinfo *info){
    // clear it
    //dlerror();
    void *pt=NULL;
    typedef int (*real_sysinfo)(struct sysinfo *info);
    // we need the real sysinfo function address
    pt = dlsym(RTLD_NEXT,"sysinfo");
    //printf("pt: %x\n", *(char *)pt);
    // call the real sysinfo system call
    int real_return_val=((real_sysinfo)pt)(info);
    // but then modify its returned totalram field if necessary
    // because sqlserver needs to believe it has "2000 megabytes"
    // physical memory
    if( info->totalram < 1000l * 1000l * 1000l * 2l){ // 2000 megabytes
        info->totalram = 1000l * 1000l * 1000l * 2l ;
    }
    return real_return_val;
}

Οπότε κάτα την εκτέλεση LD_PRELOAD=/root/wrapper.so /opt/mssql/bin/sqlservr θα ξεκινάει ο SQL Server έχοντας την ψεύτικη πληροφορία που θέλουμε.

Ώρα για εγκατάσταση Docker

Τι είναι όμως ο Docker; Είναι μια πλατφόρμα που επιτρέπει να τρέχουμε εφαρμογές σε containers που μπορεί να είναι σε οποιοδήποτε λειτουργικό ασχέτως του τι έχουμε στο μηχάνημα μας. Έτσι μας επιτρέπει να κατεβάζουμε έτοιμα images και να σηκώνουμε εφαρμογές σε πολύ γρήγορο χρόνο χωρίς καμία ιδιαίτερη επιπλέον παραμετροποίηση.

Για την εγκατάσταση του Docker:

yum install -y docker-engine

Για να ενεργοποιηθεί το service:

sudo systemctl start docker

sudo systemctl enable docker

Για να κατεβάσουμε το git με το Dockerfile και wrapper που έχει δημιουργήσει:

*Προφανώς αν έχουμε ήδη εγκατεστημένο το git, δεν χρειάζεται να το εγκαταστήσουμε πάλι…

sudo yum install git

sudo git clone https://github.com/justin2004/mssql_server_tiny.git

cd mssql_server_tiny

Τι είναι το Dockerfile

Το Dockerfile είναι ένα αρχείο κειμένου που περιέχει όλες τις εντολές ώστε να φτιάξουμε ένα image με αυτοποιημένες εντολές κατά την διάρκεια δημιουργίας και εκτέλεσης του.

Ουσιαστικά όπως βλέπουμε το Dockerfile στο FROM έχει τα images ** του λειτουργικού που θα κατεβάσει, στην περίπτωσή μας Ubuntu με προ-εγκατεστημένο τον SQL Server 2017, με RUN τι θα εκτελέσει κατά την δημιουργία του, με το ADD αρχείο που θα προσθέσει από τον φάκελο που είμαστε στο image και με το CMD ορίζουμε τι θα εκτελεστεί σε όποιο container το κάνει χρήση αυτό το image κατά την εκτέλεση.

Την αναζήτηση των images που μπορούμε να χρησιμοποιήσουμε στο FROM, την κάνουμε στον ιστότοπο hub.docker.com .

FROM debian:stretch-slim AS build0
WORKDIR /root
RUN apt-get update && apt-get install -y binutils gcc
ADD wrapper.c /root/
RUN gcc -shared  -ldl -fPIC -o wrapper.so wrapper.c && cp /root/wrapper.so /root/
FROM mcr.microsoft.com/mssql/server:2017-latest-ubuntu
COPY --from=build0 /root/wrapper.so /root/
CMD LD_PRELOAD=/root/wrapper.so /opt/mssql/bin/sqlservr -x

*Το -x στο τέλος το έχω βάλει ώστε να σηκωθεί (startup option) το instance με όσα λιγότερα metrics γίνεται για να γλυτώσω μνήμη. Σε περίπτωση που δεν είχαμε θέμα με τη μνήμη θα το αφαιρούσαμε.

** Ό λόγος που χρησιμοποιούμε δύο images στο FROM και όλες τις extra εντολές είναι για να κάνουμε bypass τα resource limits του SQL Server, σε περίπτωση που δεν ένοιαζε αυτό, θα χρειαζότανε μόνο η γραμμή με το FROM mcr.microsoft.com/mssql/server:2017-latest-ubuntu.

FROM mcr.microsoft.com/mssql/server:2017-latest-ubuntu

Πώς φτιάχνουμε το image

Όταν θα έχουμε έτοιμο το Dockerfile πρέπει να κάνουμε build το image με ένα όνομα. Καθώς θα δημιουργείται θα κατεβάζει και όποιο image δεν έχουμε ήδη ξανά κατεβάσει.

Για να γίνει build τρέχουμε το παρακάτω:

sudo docker build -t mssql .

sudo docker image ls
Πώς κάνουμε εγκατάσταση SQL Server σε Linux μέσω Docker

Αν θέλουμε διαγραφή του:

sudo docker image rm mssql

Η δημιουργία του container

Τώρα θέλουμε να φτιάξουμε το container που θα περιέχει το instance του SQL Server σαν μια ξεχωριστη οντότητα μέσα στο λειτουργικό.

Η εντολή γίνεται με docker run και μπορούμε να θέσουμε όλες τις παραμέτρους στο περιβάλλον του ώστε να κάνει αυτόματα όλη την εγκατάσταση. Επίσης έχω κάνει mount έναν φάκελο που εκεί θα βάζω τα αρχεία των βάσεων μου και θα τα βλέπω και εκτός container. Στο τέλος ως mssql δηλώνω το όνομα του image που θα χρησιμοποιήσω και ως –name το όνομα που θα έχει το container.

sudo docker run -d \
 -e "ACCEPT_EULA=Y" \
 -e 'MSSQL_PID=Developer' \
 -p 1433:1433 \
 -e 'SA_PASSWORD=password' \
 --mount type=bind,source=$(pwd)/dbfiles,target=/dbfiles \
 --name mssql \
 --memory-swap -1 \
 --restart unless-stopped \
 mssql

*Για να γλυτώσουμε λίγα ακόμα resources μπορούμε να βάλουμε και την έκδοση Express.

**Επειδή η μνήμη RAM είναι περιορισμένη με memory-swap -1 μπορούμε να αφήσουμε το container να κάνει χρήση όση μνήμη swap έχει το μηχάνημα που το κάνει host.

Με την παρακάτω εντολή βλέπουμε ότι έχει δημιουργηθεί το container:

sudo docker container ls -a
Πώς κάνουμε εγκατάσταση SQL Server σε Linux μέσω Docker

Αν θέλουμε διαγραφή του container:

sudo docker stop mssql

sudo docker rm /mssql

Σύνδεση στο SQL Server container

Πριν πάμε να συνδεθούμε πρέπει να δούμε αν σηκώθηκε το instance. Για να δούμε τα logs του SQL Server container απλά εκτελούμε την εντολή:

sudo docker logs mssql
Πώς κάνουμε εγκατάσταση SQL Server σε Linux μέσω Docker

Αν κάτι δεν πάει καλά κάνουμε stop / start το container:

sudo docker stop mssql
sudo docker start mssql

Αφού ολοκληρωθεί μπορούμε να συνδεθούμε με sqlcmd απευθείας από docker command:

sudo docker exec -it mssql /opt/mssql-tools/bin/sqlcmd -S localhost -USA -Pkwdikos -e

Είτε να συνδεθούμε στο container πρώτα και έπειτα να καλέσουμε το sqlcmd:

sudo docker exec -it mssql bash

/opt/mssql-tools/bin/sqlcmd -S localhost -Usa -Pkwdikos -e
Πώς κάνουμε εγκατάσταση SQL Server σε Linux μέσω Docker

Είτε από άλλον υπολογιστή, βάζοντας το hostname και την πόρτα του θα κάνει redirect στο container (την πόρτα την ορίσαμε στην δημιουργία του container πιο πάνω):

Πώς κάνουμε εγκατάσταση SQL Server σε Linux μέσω Docker
Πώς κάνουμε εγκατάσταση SQL Server σε Linux μέσω Docker

Χρήσιμες εντολές SQL Server σε Docker

Για να κάνουμε επανεκκίνηση του SQL Server με χρήση docker ανεβοκατεβαζουμε όλο το container:

sudo docker stop mssql
sudo docker start mssql

Για να ενεργοποιήσουμε κάποιο traceflag με χρήση docker:

sudo docker exec -it mssql /opt/mssql/bin/mssql-conf traceflag 7412 on

Για να ενεργοποιήσουμε των SQL Server Agent με χρήση docker:

sudo docker exec -it mssql /opt/mssql/bin/mssql-conf set sqlagent.ena                                               bled on

Για να αλλάξουμε το collation σε docker:

docker exec -it mssql /opt/mssql/bin/mssql-conf set-collation

Κλείνοντας

Φυσικά μέσα από όλο αυτόν τον κόπο ο χρόνος δεν πήγε χαμένος, από την άλλη φυσικά με τόσους περιορισμούς σε μνήμη του resource pool πολλά queries δεν τρέχουν με την πρώτη προσπάθεια. Σαν πρώτη προσπάθεια είχα δοκιμάσει να βάλω SQL Server 2019 image αντί του 2017 και τα πράγματα ήταν πολύ χειρότερα. Θεωρώ όμως ότι είναι λειτουργικό.

Πηγές:

Μοιράσου το

2 σκέψεις σχετικά με το "Πώς κάνουμε εγκατάσταση SQL Server σε Linux μέσω Docker"

  1. Καλησπέρα Στρατό,
    κυρίως μέσω linkedin περνώ την αφορμή για να διαβάσω κάποια άρθρα σου ,δεν είμαι τόσο σχετικός με το docker και θα ήθελα να ρωτήσω το εξής ,στο dockerfile σε περίπτωση που έχουμε σαν λειτουργικο στον υπολογιστή μας τα windows 10,μπορούμε στο FROM να αναφέρεται καποια έκδοση των ubuntu,δεν έχω καταλάβει πρέπει το basic layer του image να συμβαδίζει πάντα με το λειτουργικό σύστημα ? Ουσιαστικά κάθε container στο image θα είναι και μια ξεχωριστή διεργασία με το δικό του ξεχωριστό file system απ’ ότι εχω καταλάβει και με κάποιες συγκεκριμένες ιδιότητες …

    1. Καλημέρα Σπύρο,

      Το νόημα των containers είναι ότι μπορεις να χρησιμοποιήσεις ότι λειτουργικό θες στο image, ανεξαρτήτως του λειτουργικού που τρέχει ο docker.

      Μην σε μπερδεύει που χρησιμοποίησα 2 FROM, αυτό το έκανα για να κάνω bypass τα resource limits που έχει ο SQL Server.

      Τα images που μπορείς να χρησιμοποιήσεις στο docker θα τα βρεις εδώ: https://hub.docker.com/search?q=&type=image

      Κάποια είναι images με “σκέτα” λειτουργικά και κάποια άλλα έχουν προεγκατεστημένες εφαρμογές όπως π.χ. εδώ τον SQL Server.

Αφήστε μία απάντηση