Delen via


Gedistribueerde transacties gebruiken met SQL Server Linux-containers

Van toepassing op:SQL Server op Linux

In dit artikel wordt uitgelegd hoe u SQL Server Linux-containers instelt voor gedistribueerde transacties, inclusief speciale vereisten en scenario's.

Sql Server-containerinstallatiekopieën kunnen gebruikmaken van de Microsoft Distributed Transaction Coordinator (MSDTC), die vereist is voor gedistribueerde transacties. Zie How to configure the Microsoft Distributed Transaction Coordinator (MSDTC) on Linuxvoor meer informatie over de communicatievereisten voor MSDTC.

Notitie

SQL Server 2017 (14.x) wordt standaard uitgevoerd in hoofdcontainers, terwijl SQL Server 2019 (15.x) en latere containers worden uitgevoerd als een niet-hoofdgebruiker.

Configuratie

Als u MSDTC-transacties wilt inschakelen in SQL Server-containers, moet u twee nieuwe omgevingsvariabelen instellen:

  • MSSQL_RPC_PORT: de TCP-poort waarop de RPC-eindpunttoewijzingsservice bindt en luistert.
  • MSSQL_DTC_TCP_PORT: de poort waarop de MSDTC-service is geconfigureerd om te luisteren.

Trekken en rennen

In het volgende voorbeeld ziet u hoe u deze omgevingsvariabelen gebruikt om één SQL Server 2017-container op te halen en uit te voeren die is geconfigureerd voor MSDTC. Hierdoor kan het communiceren met elke toepassing op alle hosts.

Belangrijk

De omgevingsvariabele SA_PASSWORD is afgeschaft. Gebruik in plaats daarvan MSSQL_SA_PASSWORD.

docker run \
   -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=<password>' \
   -e 'MSSQL_RPC_PORT=135' -e 'MSSQL_DTC_TCP_PORT=51000' \
   -p 51433:1433 -p 135:135 -p 51000:51000  \
   -d mcr.microsoft.com/mssql/server:2017-latest
docker run `
   -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=<password>" `
   -e "MSSQL_RPC_PORT=135" -e "MSSQL_DTC_TCP_PORT=51000" `
   -p 51433:1433 -p 135:135 -p 51000:51000  `
   -d mcr.microsoft.com/mssql/server:2017-latest

In het volgende voorbeeld ziet u hoe u deze omgevingsvariabelen gebruikt om één SQL Server 2019-container (15.x) op te halen en uit te voeren die is geconfigureerd voor MSDTC. Hierdoor kan het communiceren met elke toepassing op alle hosts.

Belangrijk

De omgevingsvariabele SA_PASSWORD is afgeschaft. Gebruik in plaats daarvan MSSQL_SA_PASSWORD.

docker run \
   -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=<password>' \
   -e 'MSSQL_RPC_PORT=135' -e 'MSSQL_DTC_TCP_PORT=51000' \
   -p 51433:1433 -p 135:135 -p 51000:51000  \
   -d mcr.microsoft.com/mssql/server:2019-GA-ubuntu-20.04
docker run `
   -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=<password>" `
   -e "MSSQL_RPC_PORT=135" -e "MSSQL_DTC_TCP_PORT=51000" `
   -p 51433:1433 -p 135:135 -p 51000:51000  `
   -d mcr.microsoft.com/mssql/server:2019-GA-ubuntu-20.04

Voorzichtigheid

Uw wachtwoord moet voldoen aan het standaard wachtwoordbeleid van SQL Server . Standaard moet het wachtwoord ten minste acht tekens lang zijn en tekens bevatten uit drie van de volgende vier sets: hoofdletters, kleine letters, basis-10 cijfers en symbolen. Wachtwoorden mogen maximaal 128 tekens lang zijn. Gebruik wachtwoorden die zo lang en complex mogelijk zijn.

In deze opdracht is de RPC Endpoint Mapper-service gebonden aan poort 135 en is de MSDTC--service gebonden aan poort 51000 binnen het virtuele netwerk van de container. SQL Server TDS-communicatie vindt plaats op poort 1433, ook binnen het virtuele netwerk van de container. Deze poorten worden extern blootgesteld aan de host als TDS-poort 51433, RPC-eindpunttoewijzingpoort 135 en MSDTC-poort 51000.

De RPC Endpoint Mapper- en MSDTC-poort hoeven niet hetzelfde te zijn op de host en de container. Dus terwijl de RPC Endpoint Mapper-poort is geconfigureerd voor 135 op de container, kan deze worden toegewezen aan poort 13501 of een andere beschikbare poort op de hostserver.

De firewall configureren

Als u wilt communiceren met en via de host, moet u ook de firewall configureren op de hostserver voor de containers. Open de firewall voor alle poorten die de SQL Server-container beschikbaar maakt voor externe communicatie. In het vorige voorbeeld zijn dit poorten 135, 51433 en 51000. Dit zijn de poorten op de host zelf en niet de poorten waaraan ze in de container zijn toegewezen. Dus als RPC-eindpunttoewijzingspoort 51000 van de container is toegewezen aan poort 51001 van de host, moet poort 51001 (niet 51000) worden geopend in de firewall voor communicatie met de host.

In het volgende voorbeeld ziet u hoe u deze regels maakt op Ubuntu.

sudo ufw allow from any to any port 51433 proto tcp
sudo ufw allow from any to any port 51000 proto tcp
sudo ufw allow from any to any port 135 proto tcp

In het volgende voorbeeld ziet u hoe dit kan worden gedaan op Red Hat Enterprise Linux (RHEL):

sudo firewall-cmd --zone=public --add-port=51433/tcp --permanent
sudo firewall-cmd --zone=public --add-port=51000/tcp --permanent
sudo firewall-cmd --zone=public --add-port=135/tcp --permanent
sudo firewall-cmd --reload

Poortgeleiding op de host configureren

In het vorige voorbeeld, omdat één SQL Server-container RPC-poort 135 toe wijst aan poort 135 op de host, moeten gedistribueerde transacties met de host nu werken zonder verdere configuratie. Het is mogelijk om poort 135 direct te gebruiken in containers die als root worden uitgevoerd, omdat SQL Server met verhoogde rechten in deze containers wordt uitgevoerd. Voor SQL Server buiten een container of voor niet-hoofdcontainers moet u een andere tijdelijke poort (bijvoorbeeld 13500) in de container gebruiken en moet verkeer dat is bedoeld voor poort 135, vervolgens naar die poort worden gerouteerd. U moet ook poortrouteringsregels configureren binnen de container van de containerpoort 135 naar de tijdelijke poort.

Als u besluit de poort 135 van de container toe te wijzen aan een andere poort op de host, zoals 13500, moet u poortroutering op de host configureren. Hierdoor kan de SQL Server-container deelnemen aan gedistribueerde transacties met de host en met andere externe servers.

Zie Poortroutering configurerenvoor meer informatie over routeringspoorten.

SQL Server-containers met MSDTC in Kubernetes

Als u SQL Server-containers implementeert op een Kubernetes-platform, raadpleegt u het volgende YAML-implementatiemanifest. In dit voorbeeld is het Kubernetes-platform Azure Kubernetes Service (AKS).

Scenario 1: MSDTC-client die verbinding maakt met SQL Server in een Kubernetes-container

In het volgende diagram ziet u het proces wanneer een MSDTC-client verbinding maakt met MSDTC op SQL Server die wordt uitgevoerd in een Linux-container in Kubernetes.

diagram waarin het proces wordt weergegeven wanneer een MSDTC-client verbinding maakt met MSDTC op SQL Server die wordt uitgevoerd in een Linux-container.

  1. De MSDTC-client maakt een verbinding met poort 135 op de Kubernetes-host.
  2. De verbinding wordt doorgestuurd naar poort 135 op de container.
  3. De container stuurt de verbinding door naar de RPC-eindpunttoewijzingper, die zich in dit voorbeeld op poort 13500 bevindt.
  4. De eindpunttoewijzing vertelt de MSDTC-client welke poort MSDTC in de container draait (poort 51000 in dit voorbeeld).
  5. De MSDTC-client maakt rechtstreeks verbinding met MSDTC door verbinding te maken met de host op poort 51000, die wordt doorgestuurd naar SQL Server in de container.

Scenario 2: SQL Server die verbinding maakt met SQL Server in een Kubernetes-container

In het volgende diagram ziet u het proces wanneer een SQL Server Linux-container verbinding maakt met MSDTC in een tweede SQL Server Linux-container in Kubernetes.

diagram waarin het proces wordt weergegeven wanneer één SQL Server Linux-container verbinding maakt met MSDTC op een tweede SQL Server Linux-container.

  1. Het eerste SQL Server-exemplaar maakt een verbinding met poort 135 op de Kubernetes-host van het tweede SQL Server-exemplaar.
  2. De verbinding wordt doorgestuurd naar poort 135 op de container van het tweede exemplaar.
  3. De container stuurt de verbinding door naar de RPC-eindpunttoewijzingper, die zich in dit voorbeeld op poort 13500 bevindt.
  4. De eindpunttoewijzer vertelt het eerste SQL Server-exemplaar op welke poort MSDTC draait in de tweede container (in dit voorbeeld poort 51000).
  5. Het eerste SQL Server-exemplaar maakt rechtstreeks verbinding met MSDTC op het tweede exemplaar door verbinding te maken met de tweede host op poort 51000, die wordt doorgestuurd naar SQL Server in de container.

SQL Server-containers implementeren met MSDTC geconfigureerd op een Kubernetes-platform

Voordat u het YAML-voorbeeldscript voor de implementatie uitvoert, maakt u het benodigde geheim voor het opslaan van het sa wachtwoord met behulp van de volgende voorbeeldopdracht:

kubectl create secret generic mssql --from-literal=MSSQL_SA_PASSWORD="<password>"

Voorzichtigheid

Uw wachtwoord moet voldoen aan het standaard wachtwoordbeleid van SQL Server . Standaard moet het wachtwoord ten minste acht tekens lang zijn en tekens bevatten uit drie van de volgende vier sets: hoofdletters, kleine letters, basis-10 cijfers en symbolen. Wachtwoorden mogen maximaal 128 tekens lang zijn. Gebruik wachtwoorden die zo lang en complex mogelijk zijn.

U ziet de volgende punten in het manifestbestand:

  1. In het cluster maken we de volgende objecten: StorageClass, twee SQL Server-pods die zijn geïmplementeerd als statefulset-implementaties en twee load balancer-services om verbinding te maken met de respectieve SQL Server-exemplaren.

  2. U ziet ook dat de load balancer-services worden geïmplementeerd met statische IP-adressen, die kunnen worden geconfigureerd in Azure Kubernetes Service. Zie Een statisch openbaar IP-adres en DNS-label gebruiken met de load balancer van Azure Kubernetes Service (AKS). Het maken van de load balancer-services met statische IP-adressen zorgt ervoor dat het externe IP-adres niet verandert als de load balancer-service wordt verwijderd en opnieuw wordt gemaakt.

  3. In het volgende script ziet u dat poort 13500 wordt gebruikt voor de omgevingsvariabele MSSQL_RPC_PORT en poort 51000 voor de omgevingsvariabele MSSQL_DTC_TCP_PORT, die beide vereist zijn voor MSDTC.

  4. De poortroutering (dat wil gezegd poort 135 tot en met 13500) is geconfigureerd in het load balancer-script door de port en targetPort op de juiste manier te configureren, zoals wordt weergegeven in het volgende voorbeeld:

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: 2
 selector:
  matchLabels:
   app: mssql
 template:
  metadata:
   labels:
    app: mssql
  spec:
   securityContext:
     fsGroup: 10001
   containers:
   - name: mssql
     image: mcr.microsoft.com/mssql/server:2019-latest
     ports:
     - containerPort: 1433
       name: tcpsql
     - containerPort: 13500
       name: dtcport
     - containerPort: 51000
       name: dtctcpport
     env:
     - name: ACCEPT_EULA
       value: "Y"
     - name: MSSQL_ENABLE_HADR
       value: "1"
     - name: MSSQL_AGENT_ENABLED
       value: "1"
     - name: MSSQL_RPC_PORT
       value: "13500"
     - name: MSSQL_DTC_TCP_PORT
       value: "51000"
     - 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-0
spec:
  type: LoadBalancer
  loadBalancerIP: 10.88.213.209
  selector:
    statefulset.kubernetes.io/pod-name: mssql-0
  ports:
  - protocol: TCP
    port: 1433
    targetPort: 1433
    name: tcpsql
  - protocol: TCP
    port: 51000
    targetPort: 51000
    name: dtctcpport
  - protocol: TCP
    port: 135
    targetPort: 13500
    name: nonrootport
---
apiVersion: v1
kind: Service
metadata:
  name: mssql-1
spec:
  type: LoadBalancer
  loadBalancerIP: 10.72.137.129
  selector:
    statefulset.kubernetes.io/pod-name: mssql-1
  ports:
  - protocol: TCP
    port: 1433
    targetPort: 1433
    name: tcpsql
  - protocol: TCP
    port: 51000
    targetPort: 51000
    name: dtctcpport
  - protocol: TCP
    port: 135
    targetPort: 13500
    name: nonrootport

Ervan uitgaande dat u de resource in de standaardnaamruimte hebt gemaakt, ziet u de uitvoer in het volgende voorbeeld wanneer u de opdracht kubectl get all uitvoert na de vorige implementatie om alle gemaakte resources weer te geven.

NAME          READY   STATUS    RESTARTS   AGE
pod/mssql-0   1/1     Running   0          4d22h
pod/mssql-1   1/1     Running   0          4d22h

NAME                 TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)                                        AGE
service/kubernetes   ClusterIP      10.0.0.1      <none>          443/TCP                                        6d6h
service/mssql-0      LoadBalancer   10.0.18.186   10.88.213.209   1433:31875/TCP,51000:31219/TCP,135:30044/TCP   2d6h
service/mssql-1      LoadBalancer   10.0.16.180   10.72.137.129   1433:30353/TCP,51000:32734/TCP,135:31239/TCP   2d6h

NAME                     READY   AGE
statefulset.apps/mssql   2/2     5d1h

U kunt hulpprogramma's zoals SQL Server Management Studio (SSMS) gebruiken om verbinding te maken met een van de vorige twee SQL Server-exemplaren en een DTC-voorbeeldtransactie uit te voeren. In dit voorbeeld maakt u verbinding met mssql-1 (10.72.137.129) en maakt u de gekoppelde server met mssql-0 (10.88.213.209) om de gedistribueerde transactie uit te voeren, zoals wordt weergegeven in het volgende voorbeeld.

USE [master];
GO

EXECUTE master.dbo.sp_addlinkedserver
    @server = N'10.88.213.209',
    @srvproduct = N'SQL Server';
GO

EXECUTE master.dbo.sp_addlinkedsrvlogin
    @rmtsrvname = N'10.88.213.209',
    @rmtuser = 'sa',
    @rmtpassword = '<password>',
    @useself = N'False';
GO

Voorzichtigheid

Uw wachtwoord moet voldoen aan het standaard wachtwoordbeleid van SQL Server . Standaard moet het wachtwoord ten minste acht tekens lang zijn en tekens bevatten uit drie van de volgende vier sets: hoofdletters, kleine letters, basis-10 cijfers en symbolen. Wachtwoorden mogen maximaal 128 tekens lang zijn. Gebruik wachtwoorden die zo lang en complex mogelijk zijn.

U kunt nu de gedistribueerde transactie starten en in dit codevoorbeeld ziet u de sys.sysprocesses van het mssql-0 exemplaar:

SET XACT_ABORT ON;

BEGIN DISTRIBUTED TRANSACTION;

SELECT *
FROM [10.88.213.209].master.dbo.sysprocesses;

COMMIT TRANSACTION;
GO