Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Aplica-se a:SQL Server em Linux
Este artigo explica como configurar contêineres do SQL Server Linux para transações distribuídas, incluindo requisitos e cenários especiais.
As imagens de contêiner do SQL Server podem usar o Microsoft Distributed Transaction Coordinator (MSDTC), que é necessário para transações distribuídas. Para entender os requisitos de comunicação para MSDTC, consulte Como configurar o Microsoft Distributed Transaction Coordinator (MSDTC) no Linux.
Observação
O SQL Server 2017 (14.x) é executado em contêineres raiz por padrão, enquanto o SQL Server 2019 (15.x) e contêineres posteriores são executados como um usuário não raiz.
Configuração
Para habilitar a transação MSDTC em contêineres do SQL Server, você deve definir duas novas variáveis de ambiente:
-
MSSQL_RPC_PORT: a porta TCP à qual o serviço de mapeador de pontos de extremidade RPC se liga e escuta. -
MSSQL_DTC_TCP_PORT: a porta na qual o serviço MSDTC está configurado para escutar.
Puxe e corra
O exemplo a seguir mostra como usar essas variáveis de ambiente para extrair e executar um único contêiner do SQL Server 2017 configurado para MSDTC. Isso permite que ele se comunique com qualquer aplicativo em qualquer host.
Importante
A variável de ambiente SA_PASSWORD foi preterida. Use MSSQL_SA_PASSWORD em vez disso.
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
O exemplo a seguir mostra como usar essas variáveis de ambiente para extrair e executar um único contêiner do SQL Server 2019 (15.x) configurado para MSDTC. Isso permite que ele se comunique com qualquer aplicativo em qualquer host.
Importante
A variável de ambiente SA_PASSWORD foi preterida. Use MSSQL_SA_PASSWORD em vez disso.
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
Atenção
Sua senha deve seguir a política de senha de padrão do SQL Server. Por padrão, a senha deve ter pelo menos oito caracteres e conter caracteres de três dos quatro conjuntos a seguir: letras maiúsculas, letras minúsculas, dígitos de base 10 e símbolos. As palavras-passe podem ter até 128 caracteres. Use senhas tão longas e complexas quanto possível.
Neste comando, o serviço Mapeador de Pontos de Extremidade RPC está vinculado à porta 135 e o serviço MSDTC está vinculado à porta 51000 dentro da rede virtual do contentor. A comunicação TDS do SQL Server ocorre na porta 1433, também dentro da rede virtual do contêiner. Essas portas são expostas externamente ao host como porta TDS 51433, porta 135 do mapeador de ponto de extremidade RPC e porta MSDTC 51000.
O Mapeador de Pontos de Extremidade RPC e a porta MSDTC não têm de ser iguais no host e no contentor. Portanto, embora a porta do Mapeador de Pontos de Extremidade RPC tenha sido configurada para ser 135 no contêiner, ela poderia ser potencialmente mapeada para a porta 13501 ou qualquer outra porta disponível no servidor host.
Configurar o firewall
Para se comunicar com e através do host, você também deve configurar o firewall no servidor host para os contêineres. Abra o firewall para todas as portas que o contêiner do SQL Server expõe para comunicação externa. No exemplo anterior, seriam as portas 135, 51433 e 51000. Estas são as portas que estão no próprio host e não as portas para as quais são mapeadas no contentor. Portanto, se a porta 51000 do mapeador de ponto de extremidade RPC do contêiner foi mapeada para a porta 51001 do host, a porta 51001 (não 51000) deve ser aberta no firewall para comunicação com o host.
O exemplo a seguir mostra como criar essas regras no 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
O exemplo a seguir mostra como isso pode ser feito no 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
Configurar o roteamento de porta no host
No exemplo anterior, como um único contêiner do SQL Server mapeia a porta RPC 135 para a porta 135 no host, as transações distribuídas com o host agora devem funcionar sem nenhuma configuração adicional. É possível usar a porta 135 diretamente em contêineres executados como raiz, porque o SQL Server é executado com privilégios elevados nesses contêineres. Para o SQL Server fora de um contêiner ou para contêineres não raiz, você deve usar uma porta efêmera diferente (por exemplo, 13500) no contêiner, e o tráfego destinado à porta 135 deve ser roteado para essa porta. Você também precisaria configurar regras de roteamento de porta dentro do contêiner da porta de contêiner 135 para a porta efêmera.
Além disso, se você decidir mapear a porta 135 do contêiner para uma porta diferente no host, como 13500, será necessário configurar o roteamento de porta no host. Isso permite que o contêiner do SQL Server participe de transações distribuídas com o host e com outros servidores externos.
Para obter mais informações sobre portas de roteamento, consulte Configurar o roteamento de porta.
Contêineres do SQL Server com MSDTC no Kubernetes
Se você estiver implantando contêineres do SQL Server em uma plataforma Kubernetes, consulte o exemplo de manifesto de implantação do YAML a seguir. Neste exemplo, a plataforma Kubernetes é o Serviço Kubernetes do Azure (AKS).
Cenário 1: Cliente MSDTC conectando-se ao SQL Server em um contêiner do Kubernetes
O diagrama a seguir mostra o processo quando um cliente MSDTC se conecta ao MSDTC no SQL Server em execução dentro de um contêiner Linux no Kubernetes.
- O cliente MSDTC faz uma conexão com a porta 135 no host Kubernetes.
- A conexão é encaminhada para a porta 135 no contêiner.
- O contêiner encaminha a conexão para o mapeador de ponto de extremidade RPC, que está na porta 13500 neste exemplo.
- O mapeador de endpoint informa ao cliente MSDTC em qual porta o MSDTC está a ser executado dentro do contêiner (porta 51000 neste exemplo).
- O cliente MSDTC faz uma conexão diretamente com o MSDTC conectando-se ao host na porta 51000, que é encaminhado para o SQL Server dentro do contêiner.
Cenário 2: SQL Server conectando-se ao SQL Server em um contêiner do Kubernetes
O diagrama a seguir mostra o processo quando um contêiner do SQL Server Linux se conecta ao MSDTC em um segundo contêiner do SQL Server Linux, no Kubernetes.
- A primeira instância do SQL Server estabelece uma ligação com a porta 135 no computador anfitrião Kubernetes da segunda instância do SQL Server.
- A conexão é encaminhada para a porta 135 no contêiner da segunda instância.
- O contêiner encaminha a conexão para o mapeador de ponto de extremidade RPC, que está na porta 13500 neste exemplo.
- O mapeador de ponto de extremidade informa à primeira instância do SQL Server qual porta MSDTC está sendo executada dentro do segundo contêiner (porta 51000 neste exemplo).
- A primeira instância do SQL Server faz uma conexão diretamente com o MSDTC na segunda instância, conectando-se ao segundo host na porta 51000, que é encaminhado para o SQL Server dentro do contêiner.
Implantar contêineres do SQL Server com MSDTC configurado em uma plataforma Kubernetes
Antes de executar o script YAML de implantação de exemplo, crie o segredo necessário para armazenar a senha sa, usando o seguinte comando de exemplo:
kubectl create secret generic mssql --from-literal=MSSQL_SA_PASSWORD="<password>"
Atenção
Sua senha deve seguir a política de senha de padrão do SQL Server. Por padrão, a senha deve ter pelo menos oito caracteres e conter caracteres de três dos quatro conjuntos a seguir: letras maiúsculas, letras minúsculas, dígitos de base 10 e símbolos. As palavras-passe podem ter até 128 caracteres. Use senhas tão longas e complexas quanto possível.
Observe os seguintes pontos no arquivo de manifesto:
No cluster, criamos os seguintes objetos:
StorageClass, dois pods do SQL Server implantados como implantaçõesstatefulsete dois serviços de balanceador de carga para se conectar às respetivas instâncias do SQL Server.Você também observa que os serviços de balanceador de carga são implantados com endereços IP estáticos, que podem ser configurados no Serviço Kubernetes do Azure. Veja Usar um endereço IP público estático e um rótulo DNS com o balanceador de carga do Serviço de Kubernetes do Azure (AKS). A criação dos serviços do balanceador de carga com endereços IP estáticos garante que o endereço IP externo não seja alterado se o serviço do balanceador de carga for excluído e recriado.
No script a seguir, você pode ver que a porta 13500 é usada para a variável de ambiente
MSSQL_RPC_PORTe a porta 51000 para a variável de ambienteMSSQL_DTC_TCP_PORT, ambas necessárias para MSDTC.O roteamento de porta (ou seja, a porta de roteamento 135 a 13500) é configurado no script do balanceador de carga configurando adequadamente o
porte otargetPortconforme mostrado no exemplo a seguir:
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
Supondo que você criou o recurso no namespace padrão, quando você executa o comando kubectl get all após a implantação anterior para ver todos os recursos criados, você deve ver a saída mostrada no exemplo a seguir.
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
Você pode usar ferramentas como o SQL Server Management Studio (SSMS) para se conectar a qualquer uma das duas instâncias anteriores do SQL Server e executar uma transação DTC de exemplo. Neste exemplo, você se conecta ao mssql-1 (10.72.137.129) e cria o servidor vinculado ao mssql-0 (10.88.213.209) para executar a transação distribuída, conforme mostrado no exemplo a seguir.
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
Atenção
Sua senha deve seguir a política de senha de padrão do SQL Server. Por padrão, a senha deve ter pelo menos oito caracteres e conter caracteres de três dos quatro conjuntos a seguir: letras maiúsculas, letras minúsculas, dígitos de base 10 e símbolos. As palavras-passe podem ter até 128 caracteres. Use senhas tão longas e complexas quanto possível.
Agora podes iniciar a transação distribuída; este exemplo de código mostra o sys.sysprocesses a partir da instância mssql-0:
SET XACT_ABORT ON;
BEGIN DISTRIBUTED TRANSACTION;
SELECT *
FROM [10.88.213.209].master.dbo.sysprocesses;
COMMIT TRANSACTION;
GO