SQL Server Linux-tárolók üzembe helyezése a Kubernetesen StatefulSets használatával

A következőkre vonatkozik:SQL Server Linux rendszeren

Ez a cikk ajánlott eljárásokat és útmutatást tartalmaz az SQL Server-tárolók Kubernetesen és StatefulSets használatával való futtatásához. Javasoljuk, hogy podonként egy SQL Server-tárolót (példányt) telepítsen a Kubernetesben. Így podonként egy SQL Server-példány van üzembe helyezve a Kubernetes-fürtben.

Hasonlóképpen, az üzembehelyezési szkript ajánlása egy SQL Server-példány üzembe helyezése a replicas értékének 1beállításával. Ha 1 értékként replicas-nél nagyobb számot ad meg, akkor ennyi SQL Server-példányt kap korrelált névvel. Ha például az alábbi szkriptben a szám 2 van hozzárendelve replicasértékeként, akkor két SQL Server-podot helyezne üzembe, mssql-0 és mssql-1 névvel.

Egy másik ok, amiért üzembehelyezési szkriptenként egy SQL Servert ajánlunk, az a konfigurációs értékek, a kiadás, a nyomkövetési jelzők és más beállítások egymástól függetlenül történő módosításának engedélyezése minden üzembe helyezett SQL Server-példány esetében.

Az alábbi példában a StatefulSet számítási feladat nevének meg kell egyeznie a .spec.template.metadata.labels értékkel, amely ebben az esetben mssql. További információ: StatefulSets.

Fontos

A SA_PASSWORD környezeti változó elavult. Használjon inkább MSSQL_SA_PASSWORD.

apiVersion: apps/v1
kind: StatefulSet
metadata:
 name: mssql # name of the StatefulSet workload, the SQL Server instance name is derived from this. We suggest to keep this name same as the .spec.template.metadata.labels, .spec.selector.matchLabels and .spec.serviceName to avoid confusion.
spec:
 serviceName: "mssql" # serviceName is the name of the service that governs this StatefulSet. This service must exist before the StatefulSet, and is responsible for the network identity of the set.
 replicas: 1 # only one pod, with one SQL Server instance deployed.
 selector:
  matchLabels:
   app: mssql  # this has to be the same as .spec.template.metadata.labels
 template:
  metadata:
   labels:
    app: mssql # this has to be the same as .spec.selector.matchLabels. See <https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/>:
  spec:
   securityContext:
     fsGroup: 10001
   containers:
   - name: mssql # container name within the pod.
     image: mcr.microsoft.com/mssql/server:2022-latest
     ports:
     - containerPort: 1433
       name: tcpsql
     env:
     - name: ACCEPT_EULA
       value: "Y"
     - name: MSSQL_ENABLE_HADR
       value: "1"
     - name: MSSQL_AGENT_ENABLED
       value: "1"
     - name: MSSQL_SA_PASSWORD
       valueFrom:
         secretKeyRef:
          name: mssql
          key: MSSQL_SA_PASSWORD
     volumeMounts:
     - name: mssql
       mountPath: "/var/opt/mssql"
 volumeClaimTemplates:
   - metadata:
      name: mssql
     spec:
      accessModes:
      - ReadWriteOnce
      resources:
       requests:
        storage: 8Gi

Ha úgy dönt, hogy az SQL Server példány több replikáját is üzembe helyezi ugyanazzal a telepítéssel, ezt a forgatókönyvet a következő szakasz fogja tárgyalni. Ezek azonban különálló független SQL Server-példányok, és nem replikák (ellentétben az SQL Server rendelkezésre állási csoport replikáival).

Válassza ki a számítási feladat típusát

A megfelelő számítási feladat üzembe helyezési típusának kiválasztása nem befolyásolja a teljesítményt, de a StatefulSet identitásmegtartó követelményeket biztosít.

StatefulSet számítási feladatok

Az SQL Server egy adatbázis-alkalmazás, ezért leginkább StatefulSet számítási feladattípusként kell üzembe helyezni. A számítási feladatok StatefulSet-ként való üzembe helyezése olyan funkciókat biztosít, mint az egyedi hálózati azonosítók, az állandó és stabil tárolás stb. Az ilyen típusú számítási feladatokról a Kubernetes dokumentációjában talál további információt.

Amikor több SQL Server tároló-replikát telepít ugyanazzal az YAML telepítési szkripttel, mint egy StatefulSet munkaterhelés, egy fontos paramétert figyelembe kell venni: a podkezelési szabályzatokat, azaz .spec.podManagementPolicy.

Ehhez a beállításhoz két érték használható:

  • OrderedReady: Ez az alapértelmezett érték, és a viselkedés a üzembe helyezési és méretezési garanciákszerint alakul.

  • Párhuzamos: Ez az a másodlagos szabályzat, amely párhuzamosan hozza létre és indítja el a podokat (ebben az esetben az SQL Server-podokat), anélkül, hogy várnia kellene a többi pod létrehozására. Hasonlóképpen, a leállítás során az összes pod párhuzamosan törlődik. Ezt a lehetőséget akkor használhatja, ha egymástól független SQL Server-példányokat helyez üzembe, és nem kíván követni egy sorrendet az SQL Server-példányok elindításához vagy törléséhez.

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: mssql
    spec:
      serviceName: "mssql"
      replicas: 2 # two independent SQL Server instances to be deployed
      podManagementPolicy: Parallel
      selector:
        matchLabels:
          app: mssql
      template:
        metadata:
          labels:
            app: mssql
        spec:
          securityContext:
            fsGroup: 10001
          containers:
            - name: mssql
              image: mcr.microsoft.com/mssql/server:2022-latest
              ports:
                - containerPort: 1433
                  name: tcpsql
              env:
                - name: ACCEPT_EULA
                  value: "Y"
                - name: MSSQL_ENABLE_HADR
                  value: "1"
                - name: MSSQL_AGENT_ENABLED
                  value: "1"
                - name: MSSQL_SA_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      name: mssql
                      key: MSSQL_SA_PASSWORD
              volumeMounts:
                - name: mssql
                  mountPath: "/var/opt/mssql"
      volumeClaimTemplates:
        - metadata:
            name: mssql
          spec:
            accessModes:
              - ReadWriteOnce
            resources:
              requests:
                storage: 8Gi
    

Mivel a Kubernetesben üzembe helyezett SQL Server-podok függetlenek egymástól, Parallel a podManagementPolicyáltalában használt érték.

A következő minta a kubectl get allmintakimenetét mutatja, közvetlenül a podok párhuzamos irányelvvel való létrehozása után.

NAME          READY   STATUS              RESTARTS   AGE
pod/mssql-0   0/1     ContainerCreating   0          4s
pod/mssql-1   0/1     ContainerCreating   0          4s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   201.0.0.1    <none>        443/TCP   61d

NAME                     READY   AGE
statefulset.apps/mssql   1/1     4s

Üzembehelyezési munkaterhek

Az SQL Server központi telepítési típusát használhatja olyan helyzetekben, amikor az SQL Server-tárolókat állapot nélküli adatbázis-alkalmazásként szeretné üzembe helyezni, például ha az adatmegőrzés nem kritikus fontosságú. Néhány ilyen példa tesztelési/minőségbiztosítási vagy CI/CD-célokra szolgál.

Elkülönítés névtereken keresztül

A névterek lehetővé teszik az erőforrások csoportjainak elkülönítését egyetlen Kubernetes-fürtben. A névterekről és azok használatáról további információt névterekcímű témakörben talál.

Az SQL Server szempontjából, ha olyan Kubernetes-fürtön tervezi futtatni az SQL Server-podokat, amely más erőforrásokat is üzemeltet, az SQL Server-podokat a saját névterükben kell futtatnia a könnyű kezelés és felügyelet érdekében. Tegyük fel például, hogy több részleg is ugyanazt a Kubernetes-fürtöt használja, és egy SQL Server-példányt szeretne üzembe helyezni az Értékesítési csapathoz, egy másikat pedig a marketing-csapathoz. Két névteret fog létrehozni sales és marketingnéven, az alábbi példában látható módon:

kubectl create namespace sales
kubectl create namespace marketing

A névterek létrehozásának ellenőrzéséhez futtassa a kubectl get namespaces, és az alábbi kimenethez hasonló lista jelenik meg.

NAME              STATUS   AGE
default           Active   39d
kube-node-lease   Active   39d
kube-public       Active   39d
kube-system       Active   39d
marketing         Active   7s
sales             Active   26m

Most már üzembe helyezheti az SQL Server-tárolókat ezen névterek mindegyikében az alábbi példában látható YAML-minta használatával. Figyelje meg az üzembe helyezési YAML-hez hozzáadott namespace metaadatokat, így az üzembe helyezés összes tárolója és szolgáltatása a sales névtérben lesz üzembe helyezve.

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: azure-disk
provisioner: kubernetes.io/azure-disk
parameters:
  storageAccountType: Standard_LRS
  kind: Managed
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mssql-sales
  namespace: sales
  labels:
    app: mssql-sales
spec:
  serviceName: "mssql-sales"
  replicas: 1
  selector:
    matchLabels:
      app: mssql-sales
  template:
    metadata:
      labels:
        app: mssql-sales
    spec:
      securityContext:
        fsGroup: 10001
      containers:
        - name: mssql-sales
          image: mcr.microsoft.com/mssql/server:2022-latest
          ports:
            - containerPort: 1433
              name: tcpsql
          env:
            - name: ACCEPT_EULA
              value: "Y"
            - name: MSSQL_ENABLE_HADR
              value: "1"
            - name: MSSQL_AGENT_ENABLED
              value: "1"
            - name: MSSQL_SA_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mssql
                  key: MSSQL_SA_PASSWORD
          volumeMounts:
            - name: mssql
              mountPath: "/var/opt/mssql"
  volumeClaimTemplates:
    - metadata:
        name: mssql
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 8Gi
---
apiVersion: v1
kind: Service
metadata:
  name: mssql-sales-0
  namespace: sales
spec:
  type: LoadBalancer
  selector:
    statefulset.kubernetes.io/pod-name: mssql-sales-0
  ports:
    - protocol: TCP
      port: 1433
      targetPort: 1433
      name: tcpsql

Az erőforrások megtekintéséhez futtassa a kubectl get all parancsot a megadott névtérrel az erőforrások megtekintéséhez:

kubectl get all -n sales
NAME                READY   STATUS    RESTARTS   AGE
pod/mssql-sales-0   1/1     Running   0          17m

NAME                    TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/mssql-sales-0   LoadBalancer   10.0.251.120   20.23.79.52   1433:32052/TCP   17m

NAME                           READY   AGE
statefulset.apps/mssql-sales   1/1     17m

A névterek az erőforrások és podok korlátozására is használhatók, a limit tartomány és/vagy az erőforráskvóta szabályzatok alkalmazásával, a névtéren belüli teljes erőforrás-létrehozás kezeléséhez.

Pod szolgáltatásminőségének konfigurálása

Ha több podot helyez üzembe egyetlen Kubernetes-fürtön, az erőforrásokat megfelelően kell megosztania a Kubernetes-fürt hatékony futtatásához. A podokat úgy konfigurálhatja, hogy egy adott szolgáltatásminőséghez (QoS) legyenek hozzárendelve.

A Kubernetes a QoS-osztályokat használja a podok ütemezésével és kizárásával kapcsolatos döntések meghozatalához. További információ a különböző QoS-osztályokról: Podok szolgáltatásminőségének konfigurálása.

Az SQL Server szempontjából azt javasoljuk, hogy az SQL Server-podokat a QoS Guaranteed használatával helyezze üzembe termelési munkaterhelésekhez. Figyelembe véve, hogy egy SQL Server-pod csak egy SQL Server-tárolópéldánysal rendelkezik, amely a pod garantált QoS-jének eléréséhez fut, meg kell adnia a tároló processzor- és memória-kéréseit,, amelyeknek meg kell egyeznie a memória és a processzor korlátaival. Ez biztosítja, hogy a csomópontok biztosítsák és véglegesítsék az üzembe helyezés során megadott szükséges erőforrásokat, és kiszámítható teljesítménnyel rendelkezzenek az SQL Server-podok számára.

Íme egy minta üzembe helyezési YAML, amely egy SQL Server-tárolót helyez üzembe az alapértelmezett névtérben, és mivel az erőforrás-kérelmek nincsenek megadva, de a korlátokat a Garantált szolgáltatásminőség példában szereplő irányelveknek megfelelően határozták meg, azt látjuk, hogy a következő példában létrehozott pod QoS beállítása Guaranteed. Ha nem adja meg az erőforrás-igényeket, a Kubernetes az erőforrás-korlátokat az erőforrás-igényekkel megegyezőnek tekinti.

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
     name: azure-disk
provisioner: kubernetes.io/azure-disk
parameters:
  storageaccounttype: Standard_LRS
  kind: Managed
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
 name: mssql
 labels:
  app: mssql
spec:
 serviceName: "mssql"
 replicas: 1
 selector:
  matchLabels:
   app: mssql
 template:
  metadata:
   labels:
    app: mssql
  spec:
   securityContext:
     fsGroup: 10001
   containers:
   - name: mssql
     command:
       - /bin/bash
       - -c
       - cp /var/opt/config/mssql.conf /var/opt/mssql/mssql.conf && /opt/mssql/bin/sqlservr
     image: mcr.microsoft.com/mssql/server:2022-latest
     resources:
      limits:
       memory: 2Gi
       cpu: '2'
     ports:
     - containerPort: 1433
     env:
     - name: ACCEPT_EULA
       value: "Y"
     - name: MSSQL_ENABLE_HADR
       value: "1"
     - name: MSSQL_SA_PASSWORD
       valueFrom:
         secretKeyRef:
          name: mssql
          key: MSSQL_SA_PASSWORD
     volumeMounts:
     - name: mssql
       mountPath: "/var/opt/mssql"
     - name: userdata
       mountPath: "/var/opt/mssql/userdata"
     - name: userlog
       mountPath: "/var/opt/mssql/userlog"
     - name: tempdb
       mountPath: "/var/opt/mssql/tempdb"
     - name: mssql-config-volume
       mountPath: "/var/opt/config"
   volumes:
     - name: mssql-config-volume
       configMap:
        name: mssql
 volumeClaimTemplates:
   - metadata:
      name: mssql
     spec:
      accessModes:
      - ReadWriteOnce
      resources:
       requests:
        storage: 8Gi
   - metadata:
      name: userdata
     spec:
      accessModes:
      - ReadWriteOnce
      resources:
       requests:
        storage: 8Gi
   - metadata:
      name: userlog
     spec:
      accessModes:
      - ReadWriteOnce
      resources:
       requests:
        storage: 8Gi
   - metadata:
      name: tempdb
     spec:
      accessModes:
      - ReadWriteOnce
      resources:
       requests:
        storage: 8Gi

A kubectl describe pod mssql-0 parancs futtatásával megtekintheti a QoS-t Guaranteed, az alábbiakban látható kódrészlethez hasonló kimenettel.

...
QoS Class:                 Guaranteed
Node-Selectors:            <none>
Tolerations:               node.kubernetes.io/memory-pressure:NoSchedule op=Exists
                           node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                           node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
...

Nem éles számítási feladatok esetén, ahol a teljesítmény és a rendelkezésre állás nem prioritás, érdemes lehet a QoS-t Burstable vagy BestEffortértékre állítani.

Rugalmasságú QoS-minta

Egy Burstable YAML-példa definiálásához az erőforrás-kéréseketkell megadnia, nem pedig az erőforrás korlátait; vagy megadhatja a korlátokat, amely magasabb, mint kérések. Az alábbi kód csak az előző példához képest fennálló különbséget mutatja be, egy rugalmas kapacitású számítási feladat meghatározása érdekében.

apiVersion: apps/v1
kind: StatefulSet
metadata:
 name: mssql
 labels:
  app: mssql
spec:
 serviceName: "mssql"
 replicas: 1
 selector:
  matchLabels:
   app: mssql
 template:
  metadata:
   labels:
    app: mssql
  spec:
   securityContext:
     fsGroup: 10001
   containers:
   - name: mssql
     command:
       - /bin/bash
       - -c
       - cp /var/opt/config/mssql.conf /var/opt/mssql/mssql.conf && /opt/mssql/bin/sqlservr
     image: mcr.microsoft.com/mssql/server:2022-latest
     resources:
      requests:
       memory: 2Gi
       cpu: '2'

A kubectl describe pod mssql-0 parancs futtatásával megtekintheti a QoS-t Burstable, az alábbiakban látható kódrészlethez hasonló kimenettel.

...
QoS Class:                 Burstable
Node-Selectors:            <none>
Tolerations:               node.kubernetes.io/memory-pressure:NoSchedule op=Exists
                           node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                           node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
...

Legjobb erőfeszítés Szolgáltatásminőségi minta (QoS)

Egy BestEffort YAML-példa definiálásához távolítsa el az erőforrás-kéréseket és az erőforrás korlátait. A BestEffort erőfeszítésű QoS lesz, ahogyan az A BestEffort QoS-osztályához hozzárendelt pod létrehozása esetén meghatározásra kerül. A korábbiakhoz hasonlóan a következő kód csak a -példától való eltérést jeleníti meg a számítási feladatok legjobb munkamennyiségének meghatározásához. Ezek a legkevésbé ajánlott lehetőségek az SQL Server-podokhoz, mivel valószínűleg ezek lesznek az elsők, amelyeket le kell zárni erőforrás-versengés esetén. Még tesztelési és minőségbiztosítási forgatókönyvek esetén is javasoljuk, hogy használja a Burstable lehetőséget az SQL Serverhez.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mssql
  labels:
    app: mssql
spec:
  serviceName: "mssql"
  replicas: 1
  selector:
    matchLabels:
      app: mssql
  template:
    metadata:
      labels:
        app: mssql
    spec:
      securityContext:
        fsGroup: 10001
      containers:
        - name: mssql
          command:
            - /bin/bash
            - -c
            - cp /var/opt/config/mssql.conf /var/opt/mssql/mssql.conf && /opt/mssql/bin/sqlservr
          image: mcr.microsoft.com/mssql/server:2022-latest
          ports:
            - containerPort: 1433

A kubectl describe pod mssql-0 parancs futtatásával megtekintheti a QoS-t BestEffort, az alábbiakban látható kódrészlethez hasonló kimenettel.

...
QoS Class:                 BestEffort
Node-Selectors:            <none>
Tolerations:               node.kubernetes.io/memory-pressure:NoSchedule op=Exists
                           node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                           node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
...

A csoportvezérlő (cgroup) v2 támogatása

SQL Server a vezérlőcsoport (cgroup) v2 korlátozásait észleli és tiszteletben tartja a 2025-ös (17.x) verziótól kezdődően, valamint a 2022-es (16.x) SQL Server 20-as kumulatív frissítésétől (CU) kezdve. Ezek a korlátozások részletes vezérlést biztosítanak a Linux-kernelben a PROCESSZOR- és memóriaerőforrások felett, és javítják az erőforrások elkülönítését Docker-, Kubernetes- és OpenShift-környezetekben.

A korábbi verziókban a Kubernetes klasztereken végzett konténerizált üzembe helyezések (például Azure Kubernetes Service v1.25+) memóriahiány (OOM) hibákat tapasztalhattak, mert a SQL Server nem érvényesítette a konténer specifikációiban meghatározott memóriakorlátokat. A cgroup v2 támogatása elhárítja ezt a problémát.

A cgroup verziójának ellenőrzése

stat -fc %T /sys/fs/cgroup

Az eredmények a következők:

Result Description
cgroup2fs A cgroup v2-t használja
cgroup A cgroup 1-et használja

Váltás cgroup v2-re

A legegyszerűbb út egy olyan disztribúció kiválasztása, amely a dobozon kívül támogatja a cgroup v2-t.

Ha manuálisan kell váltania, adja hozzá a következő paramétert a GRUB-konfigurációhoz:

systemd.unified_cgroup_hierarchy=1

Ezután frissítse a GRUB-t. Például futtassa az alábbit Ubuntu alatt:

sudo update-grub

Red Hat Enterprise Linuxon (RHEL) futtassa a következőt:

sudo grub2-mkconfig -o /boot/grub2/grub.cfg

CPU-korlát jelentése a cgroup v2 használatával

Ha a cgroup v2 használatával konfigurálja a CPU-korlátokat, SQL Server nem jeleníti meg a konfigurált processzormagok számát a hibanaplóban. Ehelyett továbbra is a gazdagép CPU-k teljes számát jelenti meg.

Ha SQL Server ütemezőt és lekérdezési terveket (például párhuzamossági döntéseket) a cgroup v2-ben meghatározott processzorszámhoz szeretné igazítani, alkalmazza az alábbi konfigurációt.

Processzor-affinitás konfigurálása

Explicit módon állítsa be SQL Server processzor-affinitást a csoport végrehajtási kvótájának megfelelőre. A következő példában a csoportkvóta négy processzor egy nyolcmagos gazdagépen:

ALTER SERVER CONFIGURATION
SET PROCESS AFFINITY CPU = 0 TO 3;

Ez a konfiguráció biztosítja, hogy SQL Server csak a kívánt processzorszámhoz hozza létre az ütemezőket. További információ: ALTER SERVER CONFIGURATION és Használja a PROCESS AFFINITY-t csomóponthoz és/vagy CPU-khoz.

Engedélyezze a 8002-es nyomkövetési jelzőt az SQLPAL-rétegen a puha affinitás használatához:

sudo /opt/mssql/bin/mssql-conf traceflag 8002 on

Alapértelmezés szerint az ütemezők az affinitási maszkban meghatározott meghatározott CPU-khoz vannak kötve. A nyomkövetési jelző 8002 lehetővé teszi az ütemezők számára, hogy inkább a cpu-k között mozogjanak, ami általában javítja a teljesítményt, miközben továbbra is tiszteletben tartja az affinitást és a csoportkorlátozásokat. További információ: DBCC TRACEON – Nyomkövetési jelzők.

A nyomkövetési jelző engedélyezése után indítsa újra SQL Server.

Várható viselkedés

Újraindítás után:

  • SQL Server csak az affinitási beállítás által meghatározott ütemezők számát hozza létre (például négy ütemezőt).

  • A Linux kernel továbbra is kikényszeríti a cgroup v2 cpu végrehajtási kvótát.

  • A lekérdezésoptimalizálási és párhuzamossági döntések a kívánt processzorszámon alapulnak, nem pedig a teljes gazdagép CPU-ján.

Note

Előfordulhat, hogy a SQL Server hibanapló továbbra is megjeleníti a gazdagép teljes CPU-számát. Ez a naplózási és megjelenítési viselkedés nem befolyásolja a processzor tényleges használatát, az ütemező létrehozását vagy a processzorfelügyeletet a cgroup v2 és a processzor-affinitás által.

További információt a következő források tartalmaznak: