Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Применимо к:SQL Server в Linux
В этой статье показано, как настроить контейнеры SQL Server в Linux для распределенных транзакций, включая специальные требования и сценарии.
Образы контейнеров SQL Server могут использовать координатор распределенных транзакций Майкрософт (MSDTC), необходимый для распределенных транзакций. Сведения о требованиях к связи для MSDTC см. в статье Настройка координатора распределенных транзакций Майкрософт (MSDTC) в Linux.
Примечание.
SQL Server 2017 (14.x) выполняется в корневых контейнерах по умолчанию, в то время как SQL Server 2019 (15.x) и более поздние контейнеры выполняются как не корневой пользователь.
Настройка
Чтобы включить транзакцию MSDTC в контейнерах SQL Server, необходимо задать две новые переменные среды:
-
MSSQL_RPC_PORT: TCP-порт, к которому привязывается служба сопоставления конечных точек RPC и прослушивает его. -
MSSQL_DTC_TCP_PORT: порт, на который настроена служба MSDTC для прослушивания.
Извлечение и запуск
В приведенном ниже примере показано, как использовать эти переменные среды для извлечения и запуска одиночного контейнера SQL Server 2017, настроенного для MSDTC. Это позволяет ему взаимодействовать с любым приложением на любых узлах.
Внимание
Переменная среды SA_PASSWORD является устаревшей. Вместо этого используйте 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
В следующем примере показано, как использовать эти переменные среды для извлечения и запуска одного контейнера SQL Server 2019 (15.x), настроенного для MSDTC. Это позволяет ему взаимодействовать с любым приложением на любых узлах.
Внимание
Переменная среды SA_PASSWORD является устаревшей. Вместо этого используйте 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
Внимание
Пароль должен соответствовать политике паролей по умолчанию SQL Server. По умолчанию пароль должен быть не короче восьми символов и содержать три вида символов из следующих: прописные буквы, строчные буквы, десятичные цифры, специальные символы. Пароли могут иметь длину до 128 символов. Рекомендуется использовать максимально длинные и сложные пароли.
В этой команде служба сопоставления конечных точек RPC привязана к порту 135, а служба MSDTC привязана к порту 51000 в виртуальной сети контейнера. Коммуникации TDS в SQL Server проходят через порт 1433 также в виртуальной сети контейнера. Эти порты открыты для хоста как порт TDS 51433, порт сопоставителя конечных точек RPC 135 и порт MSDTC 51000.
Сопоставитель конечных точек RPC и порт MSDTC могут не совпадать на узле и в контейнере. Хотя порт сопоставителя конечных точек RPC был настроен на порте 135 в контейнере, он может быть сопоставлен с портом 13501 или с любым другим доступным портом на сервере узла.
Настройка брандмауэра
Чтобы взаимодействовать с узлом и через него, необходимо также настроить брандмауэр на сервере узла для контейнеров. Откройте брандмауэр для всех портов, которые контейнер SQL Server открывает для внешнего обмена данными. В предыдущем примере это порты 135, 51433 и 51000. Это порты на самом хосте, а не порты, с которыми они сопоставлены в контейнере. Таким образом, если порт сопоставления конечных точек RPC 51000 контейнера сопоставлен с портом узла 51001, то порт 51001 (не 51000) должен быть открыт в брандмауэре для связи с узлом.
В следующем примере показано, как создать эти правила в 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
В следующем примере показано, как это можно сделать в 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
Настройка маршрутизации портов на узле
В предыдущем примере, так как контейнер SQL Server сопоставляет RPC-порт 135 с портом 135 на узле, распределенные транзакции с этим узлом теперь должны выполняться без дальнейшей настройки. Можно использовать порт 135 напрямую в контейнерах, работающих от имени пользователя root, потому что SQL Server в таких контейнерах работает с повышенными привилегиями. Для SQL Server за пределами контейнера или для некорневых контейнеров необходимо использовать другой эфемерный порт (например, 13500) в контейнере, а трафик, предназначенный для порта 135, должен затем направляться на этот порт. Кроме того, необходимо настроить правила маршрутизации портов в контейнере с порта контейнера 135 на временный порт.
Однако если вы решили связать порт 135 контейнера с другим портом на узле, например 13500, необходимо настроить маршрутизацию портов на узле. Это позволяет контейнеру SQL Server участвовать в распределенных транзакциях с узлом и другими внешними серверами.
Дополнительные сведения о маршрутизации портов см. в разделе Настройка маршрутизации портов.
Контейнеры SQL Server с MSDTC в Kubernetes
Если вы развертываете контейнеры SQL Server на платформе Kubernetes, ознакомьтесь со следующим примером манифеста развертывания YAML. В этом примере платформа Kubernetes — это служба Azure Kubernetes (AKS).
Сценарий 1. Подключение клиента MSDTC к SQL Server в контейнере Kubernetes
На следующей схеме показан процесс, когда клиент MSDTC подключается к MSDTC на SQL Server, работающем внутри контейнера Linux в Kubernetes.
- Клиент MSDTC выполняет подключение к порту 135 на узле Kubernetes.
- Подключение перенаправлено на порт 135 в контейнере.
- Контейнер перенаправляет подключение к маршрутизатору конечных точек RPC, который в этом примере находится на порту 13500.
- Средство сопоставления конечных точек сообщает клиенту MSDTC, какой порт MSDTC выполняется внутри контейнера (порт 51000 в этом примере).
- Клиент MSDTC подключается непосредственно к MSDTC путем подключения к узлу через порт 51000, который пересылается в SQL Server внутри контейнера.
Сценарий 2. Подключение SQL Server к SQL Server в контейнере Kubernetes
На следующей схеме показано, как один контейнер SQL Server Linux подключается к MSDTC во втором контейнере Linux SQL Server в Kubernetes.
- Первый экземпляр SQL Server делает подключение к порту 135 на узле Kubernetes второго экземпляра SQL Server.
- Подключение перенаправлено в порт 135 в контейнере второго экземпляра.
- Контейнер перенаправляет подключение к маршрутизатору конечных точек RPC, который в этом примере находится на порту 13500.
- Сопоставитель конечных точек сообщает первому экземпляру SQL Server, на каком порту (порт 51000) запущен MSDTC во втором контейнере.
- Первый экземпляр SQL Server подключается непосредственно к MSDTC во втором экземпляре, подключаясь ко второму узлу через порт 51000, который пересылается в SQL Server внутри контейнера.
Развертывание контейнеров SQL Server с настроенным MSDTC на платформе Kubernetes
Перед запуском примера скрипта YAML развертывания создайте необходимый секрет для хранения sa пароля, выполнив следующую команду:
kubectl create secret generic mssql --from-literal=MSSQL_SA_PASSWORD="<password>"
Внимание
Пароль должен соответствовать политике паролей по умолчанию SQL Server. По умолчанию пароль должен быть не короче восьми символов и содержать три вида символов из следующих: прописные буквы, строчные буквы, десятичные цифры, специальные символы. Пароли могут иметь длину до 128 символов. Рекомендуется использовать максимально длинные и сложные пароли.
Обратите внимание на следующие моменты в файле манифеста:
В кластере мы создадим следующие объекты:
StorageClassдва модуля pod SQL Server, развернутые в качествеstatefulsetразвертываний, и две службы подсистемы балансировки нагрузки для подключения к соответствующим экземплярам SQL Server.Вы также замечаете, что службы балансировщика нагрузки развертываются со статическими IP-адресами, которые можно настроить в Azure Kubernetes Service. Дополнительные сведения см. в статье Использование статического общедоступного IP-адреса и DNS-метки с подсистемой балансировки нагрузки Службы Azure Kubernetes (AKS). Создание служб балансировки нагрузки со статическими IP-адресами гарантирует, что внешний IP-адрес не изменится при удалении и повторном создании службы балансировки нагрузки.
В следующем сценарии можно увидеть, что порт 13500 используется для переменной
MSSQL_RPC_PORTсреды и порт 51000 дляMSSQL_DTC_TCP_PORTпеременной среды, оба из которых необходимы для MSDTC.Маршрутизация портов (то есть маршрутизация порта 135 на 13500) настраивается в скрипте балансировщика нагрузки посредством правильной настройки
portиtargetPort, как показано в следующем примере:
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
Если вы создали ресурс в пространстве имен по умолчанию, при выполнении kubectl get all команды после предыдущего развертывания, чтобы просмотреть все созданные ресурсы, вы увидите выходные данные, показанные в следующем примере.
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
С помощью таких средств, как SQL Server Management Studio (SSMS), можно подключиться к обоим предыдущим экземплярам SQL Server и запустить пример транзакции DTC. В этом примере подключитесь к mssql-1 (10.72.137.129) и создадите связанный сервер mssql-0 (10.88.213.209), чтобы запустить распределенную транзакцию, как показано в следующем примере.
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
Внимание
Пароль должен соответствовать политике паролей по умолчанию SQL Server. По умолчанию пароль должен быть не короче восьми символов и содержать три вида символов из следующих: прописные буквы, строчные буквы, десятичные цифры, специальные символы. Пароли могут иметь длину до 128 символов. Рекомендуется использовать максимально длинные и сложные пароли.
Теперь вы можете запустить распределенную транзакцию, и в этом примере кода показано, как sys.sysprocesses это сделать из экземпляра mssql-0 :
SET XACT_ABORT ON;
BEGIN DISTRIBUTED TRANSACTION;
SELECT *
FROM [10.88.213.209].master.dbo.sysprocesses;
COMMIT TRANSACTION;
GO