Nota
L'accesso a questa pagina richiede l'autorizzazione. Puoi provare ad accedere o a cambiare directory.
L'accesso a questa pagina richiede l'autorizzazione. Puoi provare a cambiare directory.
Si applica a:SQL Server - Linux
Questo articolo illustra come configurare contenitori SQL Server in Linux per le transazioni distribuite, inclusi gli scenari e i requisiti speciali.
Le immagini del contenitore di SQL Server possono usare Microsoft Distributed Transaction Coordinator (MSDTC), necessario per le transazioni distribuite. Per informazioni sui requisiti di comunicazione per MSDTC, vedere Come configurare Microsoft Distributed Transaction Coordinator (MSDTC) in Linux.
Nota
SQL Server 2017 (14.x) viene eseguito in contenitori root per impostazione predefinita, mentre i contenitori di SQL Server 2019 (15.x) e successivi vengono eseguiti come utenti non root.
Impostazione
Per abilitare le transazioni MSDTC nei contenitori SQL Server, è necessario impostare due nuove variabili di ambiente:
-
MSSQL_RPC_PORT: la porta TCP a cui il servizio mapper di endpoint RPC si associa e ascolta. -
MSSQL_DTC_TCP_PORT: la porta su cui è configurato il servizio MSDTC per l'ascolto.
Scarica ed esegui
L'esempio seguente illustra come usare queste variabili di ambiente per il pull e l'esecuzione di un singolo contenitore di SQL Server 2017 configurato per MSDTC. Ciò consente le comunicazioni con qualsiasi applicazione su qualsiasi host.
Importante
La variabile di ambiente SA_PASSWORD è deprecata. Utilizzare invece 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
L'esempio seguente illustra come usare queste variabili di ambiente per il pull e l'esecuzione di un singolo contenitore di SQL Server 2019 (15x.) configurato per MSDTC. Ciò consente le comunicazioni con qualsiasi applicazione su qualsiasi host.
Importante
La variabile di ambiente SA_PASSWORD è deprecata. Utilizzare invece 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
Attenzione
La password deve seguire i criteri password predefiniti di SQL Server. Per impostazione predefinita, la password deve essere composta da almeno otto caratteri e contenere caratteri di tre delle quattro categorie seguenti: lettere maiuscole, lettere minuscole, cifre in base 10 e simboli. Le password possono contenere fino a 128 caratteri. Usare password il più possibile lunghe e complesse.
In questo comando il servizio mapper di endpoint RPC è associato alla porta 135 e il servizio MSDTC è associato alla porta 51000 nella rete virtuale del contenitore. Le comunicazioni TDS di SQL Server avvengono sulla porta 1433 all'interno della rete virtuale del contenitore. Queste porte sono esposte esternamente all'host come porta TDS 51433, porta del mapper di endpoint RPC 135 e porta MSDTC 51000.
Le porte del mapper di endpoint RPC e dell'MSDTC non devono necessariamente coincidere tra l'host e il contenitore. Sebbene la porta del mapper di endpoint RPC sia stata configurata come 135 nel contenitore, potrebbe essere potenzialmente mappata sulla porta 13501 o su qualsiasi altra porta disponibile sul server host.
Configurare il firewall
Per comunicare con e tramite l'host, è anche necessario configurare il firewall nel server host per i contenitori. Aprire il firewall per tutte le porte esposte dal contenitore SQL Server per le comunicazioni esterne. Nell'esempio precedente si tratta delle porte 135, 51433 e 51000. Queste sono le porte nell'host stesso e non le porte a cui sono mappate nel contenitore. Di conseguenza, se è stato eseguito il mapping della porta del mapper di endpoint RPC 51000 del contenitore alla porta 51001 dell'host, per le comunicazioni con l'host deve essere aperta la porta 51001 (non 51000) nel firewall.
L'esempio seguente mostra come creare queste regole in 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
L'esempio seguente mostra come eseguire questa operazione in 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
Configurare il routing delle porte nell'host
Nell'esempio precedente, dato che un singolo contenitore SQL Server esegue il mapping della porta RPC 135 alla porta 135 nell'host, le transazioni distribuite con l'host dovrebbero ora funzionare senza ulteriori configurazioni. È possibile usare direttamente la porta 135 in contenitori in esecuzione come radice, perché in tali contenitori SQL Server viene eseguito con privilegi elevati. Per SQL Server all'esterno di un contenitore o in contenitori non radice, è necessario usare una porta temporanea diversa, ad esempio la porta 13500, nel contenitore e il traffico destinato alla porta 135 deve quindi essere indirizzato alla porta temporanea. È anche necessario configurare regole di routing delle porte all'interno del contenitore dalla porta 135 alla porta temporanea.
Se si decide di eseguire il mapping della porta 135 del contenitore a una porta diversa nell'host, ad esempio alla porta 13500, è anche necessario configurare il routing delle porte nell'host. Ciò consente al contenitore SQL Server di partecipare alle transazioni distribuite con l'host e con altri server esterni.
Per altre informazioni sulle porte di routing, vedere Configurare il routing delle porte.
Contenitori SQL Server con MSDTC in Kubernetes
Se si distribuiscono contenitori SQL Server in una piattaforma Kubernetes, vedere il manifesto della distribuzione YAML di esempio seguente. In questo esempio la piattaforma Kubernetes è il servizio Azure Kubernetes.
Scenario 1: client MSDTC che si connette a SQL Server in un contenitore Kubernetes
Il diagramma seguente illustra il processo in cui un client MSDTC si connette a MSDTC in SQL Server in esecuzione all'interno di un contenitore Linux in Kubernetes.
- Il client MSDTC effettua una connessione alla porta 135 nell'host Kubernetes.
- La connessione viene inoltrata alla porta 135 nel contenitore.
- Il contenitore inoltra la connessione al mapper dell'endpoint RPC, che si trova sulla porta 13500 in questo esempio.
- Il mapper dell'endpoint indica al client MSDTC quale porta sia utilizzata da MSDTC all'interno del contenitore (porta 51000 in questo esempio).
- Il client MSDTC effettua una connessione direttamente a MSDTC connettendosi all'host sulla porta 51000, che viene inoltrata a SQL Server all'interno del contenitore.
Scenario 2: La connessione di SQL Server a SQL Server in un contenitore Kubernetes
Il diagramma seguente illustra il processo in cui un contenitore SQL Server Linux si connette a MSDTC in un secondo contenitore SQL Server Linux in Kubernetes.
- La prima istanza di SQL Server stabilisce una connessione alla porta 135 nell'host Kubernetes della seconda istanza di SQL Server.
- La connessione viene inoltrata alla porta 135 nel contenitore della seconda istanza.
- Il contenitore inoltra la connessione al mapper dell'endpoint RPC, che si trova sulla porta 13500 in questo esempio.
- Il mapper di endpoint indica alla prima istanza di SQL Server su quale porta è in esecuzione MSDTC all'interno del secondo contenitore (porta 51000 in questo esempio).
- La prima istanza di SQL Server effettua una connessione direttamente a MSDTC nella seconda istanza connettendosi al secondo host sulla porta 51000, che viene inoltrata a SQL Server all'interno del contenitore.
Distribuire contenitori SQL Server con MSDTC configurato in una piattaforma Kubernetes
Prima di eseguire lo script YAML di distribuzione di esempio, creare il segreto necessario per archiviare la password sa, usando il comando di esempio seguente:
kubectl create secret generic mssql --from-literal=MSSQL_SA_PASSWORD="<password>"
Attenzione
La password deve seguire i criteri password predefiniti di SQL Server. Per impostazione predefinita, la password deve essere composta da almeno otto caratteri e contenere caratteri di tre delle quattro categorie seguenti: lettere maiuscole, lettere minuscole, cifre in base 10 e simboli. Le password possono contenere fino a 128 caratteri. Usare password il più possibile lunghe e complesse.
Si possono notare i punti seguenti nel file manifesto:
Nel cluster vengono creati gli oggetti seguenti:
StorageClass, due pod SQL Server distribuiti come distribuzionistatefulsete due servizi di bilanciamento del carico per connettersi alle rispettive istanze di SQL Server.È possibile notare anche che i servizi di bilanciamento del carico vengono distribuiti con indirizzi IP statici, che possono essere configurati nel servizio Azure Kubernetes. Consulta l'uso di un indirizzo IP pubblico statico e di un'etichetta DNS con il load balancer di Azure Kubernetes Service (AKS). La creazione dei servizi di bilanciamento del carico con indirizzi IP statici garantisce che l'indirizzo IP esterno non cambi se il servizio di bilanciamento del carico viene eliminato e ricreato.
Nello script seguente è possibile notare che la porta 13500 viene usata per la variabile di ambiente
MSSQL_RPC_PORTe la porta 51000 per la variabile di ambienteMSSQL_DTC_TCP_PORT, entrambe necessarie per MSDTC.Il routing delle porte, ovvero il routing della porta da 135 a 13500, viene configurato nello script del servizio di bilanciamento del carico configurando in modo appropriato
portetargetPortcome illustrato nell'esempio seguente:
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
Supponendo di aver creato la risorsa nello spazio dei nomi predefinito, quando si esegue il comando kubectl get all dopo la distribuzione precedente per visualizzare tutte le risorse create, verrà visualizzato l'output illustrato nell'esempio seguente.
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
È possibile usare strumenti come SQL Server Management Studio (SSMS) per connettersi a una delle due istanze di SQL Server precedenti ed eseguire una transazione DTC di esempio. In questo esempio ci si connette a mssql-1 (10.72.137.129) e si crea il server collegato a mssql-0 (10.88.213.209) per eseguire la transazione distribuita, come illustrato nell'esempio seguente.
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
Attenzione
La password deve seguire i criteri password predefiniti di SQL Server. Per impostazione predefinita, la password deve essere composta da almeno otto caratteri e contenere caratteri di tre delle quattro categorie seguenti: lettere maiuscole, lettere minuscole, cifre in base 10 e simboli. Le password possono contenere fino a 128 caratteri. Usare password il più possibile lunghe e complesse.
A questo punto è possibile avviare la transazione distribuita e questo esempio di codice mostra l'oggetto sys.sysprocesses dall'istanza mssql-0:
SET XACT_ABORT ON;
BEGIN DISTRIBUTED TRANSACTION;
SELECT *
FROM [10.88.213.209].master.dbo.sysprocesses;
COMMIT TRANSACTION;
GO