Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
              gäller för:SQL Server – Linux
Den här artikeln innehåller metodtips och vägledning för att köra SQL Server-containrar på Kubernetes med StatefulSets. Vi rekommenderar att du distribuerar en SQL Server-container (instans) per podd i Kubernetes. Därför har du en SQL Server-instans distribuerad per podd i Kubernetes-klustret.
På samma sätt är rekommendationen för distributionsskriptet att distribuera en SQL Server-instans genom att ange värdet replicas till 1. Om du anger ett tal som är större än 1 som replicas värde får du så många SQL Server-instanser med korrelerade namn. Om du till exempel har tilldelat numret 2 som värde för replicasi skriptet nedan distribuerar du två SQL Server-poddar med namnen mssql-0 respektive mssql-1.
En annan anledning till att vi rekommenderar en SQL Server per distributionsskript är att tillåta att ändringar i konfigurationsvärden, utgåva, spårningsflaggor och andra inställningar görs separat för varje SQL Server-instans som distribueras.
I följande exempel ska arbetsbelastningsnamnet StatefulSet matcha värdet .spec.template.metadata.labels, vilket i det här fallet är mssql. Mer information finns i StatefulSets.
Viktig
Miljövariabeln SA_PASSWORD är inaktuell. Använd MSSQL_SA_PASSWORD i stället.
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, as documented [here](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
Om du fortfarande väljer att distribuera mer än en replik av SQL Server-instansen med samma distribution beskrivs det scenariot i nästa avsnitt. Dessa är dock separata oberoende SQL Server-instanser och inte repliker (till skillnad från tillgänglighetsgrupprepliker i SQL Server).
Välj arbetsbelastningstyp
Att välja rätt arbetsbelastningsdistributionstyp påverkar inte prestanda, men StatefulSet tillhandahåller krav på identitetsspinne.
StatefulSet-arbetsbelastningar
SQL Server är ett databasprogram och bör därför främst distribueras som en StatefulSet arbetsbelastningstyp. Att distribuera arbetsbelastningar som StatefulSet hjälper dig att tillhandahålla funktioner som unika nätverksidentifierare, beständig och stabil lagring med mera. Mer information om den här typen av arbetsbelastning finns i Kubernetes-dokumentationen.
När du distribuerar mer än en replik av SQL Server-containrar med samma YAML-distributionsskript som en StatefulSet-arbetsbelastning är en viktig parameter att tänka på poddhanteringsprinciper, det vill säga .spec.podManagementPolicy.
Det finns två möjliga värden för den här inställningen:
OrderedReady: Detta är standardvärdet, och beteendet beskrivs i driftsättnings- och skalningsgarantierna.
Parallell: Det här är den alternativa princip som skapar och startar poddarna (i det här fallet SQL Server-poddar) parallellt, utan att vänta på att andra poddar ska skapas på samma sätt, alla poddar tas bort parallellt under avslutningen. Du kan använda det här alternativet när du distribuerar SQL Server-instanser som är oberoende av varandra och när du inte tänker följa en order för att starta eller ta bort SQL Server-instanserna.
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
Eftersom SQL Server-poddarna som distribueras på Kubernetes är oberoende av varandra är Parallel det värde som normalt används för podManagementPolicy.
Följande exempel är exempelutdata för kubectl get all, precis efter att poddarna har skapats med en parallell princip:
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
Distributionsarbetsbelastningar
Du kan använda distributionstyp för SQL Server, i scenarier där du vill distribuera SQL Server-containrar som tillståndslösa databastillämpningar, till exempel när datalagring inte är kritiskt. Några sådana exempel är för test-/QA- eller CI/CD-ändamål.
Isolering via namnområden
Namnområden ger en mekanism för att isolera grupper av resurser i ett enda Kubernetes-kluster. Mer information om namnområden och när du ska använda dem finns i Namnområden.
Om du planerar att köra SQL Server-poddar på ett Kubernetes-kluster som också är värd för andra resurser, bör du köra SQL Server-poddarna i deras eget namnområde för enkel hantering och administration. Anta till exempel att du har flera avdelningar som delar samma Kubernetes-kluster och du vill distribuera en SQL Server-instans för säljteamet och en annan för marknadsföringsteamet. Du skapar två namnområden med namnet sales och marketing, enligt följande exempel:
kubectl create namespace sales
kubectl create namespace marketing
Om du vill kontrollera att namnrymderna har skapats kör du kubectl get namespaces, så visas en lista som liknar följande utdata.
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
Nu kan du distribuera SQL Server-containrar i vart och ett av dessa namnområden med hjälp av yaml-exemplet som visas i följande exempel. Observera namespace metadata som lagts till i distributionens YAML, så att alla containrar och tjänster i den här distributionen distribueras i sales namnrymd.
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
Om du vill se resurserna kan du köra kommandot kubectl get all med det angivna namnområdet för att se följande resurser:
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
Namnområden kan också användas för att begränsa de resurser och poddar som skapas inom ett namnområde med hjälp av gränsintervall och/eller resurskvotprinciper för att hantera den övergripande resursanvändningen inom ett namnområde.
Konfigurera poddens tjänstkvalitet
När du distribuerar flera poddar i ett enda Kubernetes-kluster måste du dela resurser på lämpligt sätt för att säkerställa effektiv körning av Kubernetes-klustret. Du kan konfigurera poddar så att de tilldelas en viss tjänstkvalitet (QoS).
Kubernetes använder QoS-klasser för att fatta beslut om schemaläggning och borttagning av poddar. Mer information om de olika QoS-klasserna finns i Konfigurera tjänstkvalitet för poddar.
Ur ett SQL Server-perspektiv rekommenderar vi att du implementerar SQL Server-poddar med hjälp av QoS-nivå Guaranteed för arbetsbelastningar i produktionsmiljö. Med tanke på att en SQL Server-podd bara har en SQL Server-containerinstans som körs för att uppnå garanterad QoS för podden, måste du ange processorn och minnet begäranden för containern som ska vara lika med minnes- och CPU-gränser. Detta säkerställer att noderna tillhandahåller och reserverar de resurser som anges under distributionen och har förutsägbar prestanda för SQL Server-poddarna.
Här är ett exempel på en YAML-exempeldistribution som distribuerar en SQL Server-container i standardnamnområdet, och eftersom resursbegäranden inte angavs men gränserna angavs enligt riktlinjerna i garanterad tjänstkvalitet exempel ser vi att podden som skapas i följande exempel har QoS inställt som Guaranteed. När du inte anger resursbegäranden anser Kubernetes att resursen begränsningar lika med resursen begäranden.
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
Du kan köra kommandot kubectl describe pod mssql-0 för att visa QoS som Guaranteed, med utdata som liknar följande kodfragment.
...
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
...
För icke-produktionsarbetsbelastningar, där prestanda och tillgänglighet inte har hög prioritet, kan du överväga att ställa in QoS på Burstable eller BestEffort.
Exempel på burstbar QoS
Om du vill definiera ett Burstable YAML-exempel anger du resursen begäranden, inte resursen gränser; eller så anger du gränser, vilket är högre än begäranden. Följande kod visar bara skillnaden från föregående exempel för att definiera en skalbar arbetsbelastning.
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'
Du kan köra kommandot kubectl describe pod mssql-0 för att visa QoS som Burstable, med utdata som liknar följande kodfragment.
...
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
...
QoS-exempel för bästa insats
Om du vill definiera ett BestEffort YAML-exempel tar du bort resursen begäranden och resursbegränsningar . Du får BestEffort QoS enligt definitionen i Skapa en podd som får en QoS-klass av BestEffort. Precis som tidigare visar följande kod bara skillnaden från Guaranteed-exemplen för att definiera en bästa möjliga insats arbetsbelastning. Det här är de minst rekommenderade alternativen för SQL Server-poddar, eftersom de förmodligen är de första som avslutas vid resurskonkurrering. Även för test- och QA-scenarier rekommenderar vi att du använder alternativet Burstable för SQL Server.
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
Du kan köra kommandot kubectl describe pod mssql-0 för att visa QoS som BestEffort, med utdata som liknar följande kodfragment.
...
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
...
Konfigurera minnesgränser med kontrollgrupp (cgroup) v2
Från och med SQL Server 2025 (17.x) Förhandsversion och SQL Server 2022 (16.x) CU 20 identifierar och respekterar SQL Server kontrollgruppsbegränsningar (cgroup) v2, vilket förbättrar prestandastabiliteten och resursisoleringen i Docker-, Kubernetes- och OpenShift-miljöer. Kontrollgrupper möjliggör detaljerad kontroll i Linux-kerneln över systemresurser som CPU och minne.
Med stöd för cgroup v2 minimerar SQL Server minnesfel (OOM) som tidigare observerats i containerbaserade distributioner, särskilt i Kubernetes-kluster (till exempel AKS v1.25+), där minnesgränser som definierats i containerspecifikationer inte tillämpades.
Kontrollera cgroup-versionen
stat -fc %T /sys/fs/cgroup
Resultatet är följande:
| Result | Description | 
|---|---|
cgroup2fs | 
Du använder cgroup v2 | 
cgroup | 
Du använder cgroup v1 | 
Växla till cgroup v2
Den enklaste sökvägen är att välja en distribution som stöder cgroup v2 direkt.
Om du behöver växla manuellt lägger du till följande rad i GRUB-konfigurationen:
systemd.unified_cgroup_hierarchy=1
Kör sedan följande kommando för att uppdatera GRUB:
sudo update-grub
Mer information finns i följande resurser:
- snabbstart: Distribuera en SQL Server Linux-container till Kubernetes med hjälp av Helm-diagram
 - Dokumentation om Linux Kernel cgroup v2
 - Kontrollgrupp v2