Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Применимо к:SQL Server в Linux
В этой статье показано, как настроить контейнеры SQL Server в Linux для распределенных транзакций, включая специальные требования и сценарии.
Образы контейнеров SQL Server могут использовать координатор распределенных транзакций Майкрософт (MSDTC), необходимый для распределенных транзакций. Сведения о требованиях к связи для MSDTC см. в статье Настройка координатора распределенных транзакций Майкрософт (MSDTC) в Linux.
Note
SQL Server 2017 (14.x) выполняется в корневых контейнерах по умолчанию, в то время как SQL Server 2019 (15.x) и более поздние контейнеры выполняются как не корневой пользователь.
Конфигурация
Чтобы активировать транзакции MSDTC в контейнерах SQL Server, необходимо установить две переменные среды:
-
MSSQL_RPC_PORT: TCP-порт, к которому привязывается служба RPC Endpoint Mapper и который она прослушивает. -
MSSQL_DTC_TCP_PORT: порт, который служба MSDTC настроена прослушивать.
Извлечение и запуск
В приведенном ниже примере показано, как использовать эти переменные среды для извлечения и запуска одиночного контейнера SQL Server 2017, настроенного для MSDTC. Это позволяет ему взаимодействовать с любым приложением на любом хосте.
Important
Переменная среды 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. Это позволяет ему взаимодействовать с любым приложением на любом хосте.
Important
Переменная среды 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
Caution
Пароль должен соответствовать политике паролей по умолчанию SQL Server. По умолчанию пароль должен быть не короче восьми символов и содержать три вида символов из следующих: прописные буквы, строчные буквы, десятичные цифры, специальные символы. Пароли могут иметь длину до 128 символов. Рекомендуется использовать максимально длинные и сложные пароли.
В этой команде служба сопоставления конечных точек RPC привязана к порту 135, а служба MSDTC привязана к порту 51000 в виртуальной сети контейнера. Коммуникации TDS в SQL Server проходят через порт 1433 также в виртуальной сети контейнера. Эти порты внешне доступны хосту как TDS-порт 51433, порт RPC endpoint mapper порт 135 и MSDTC порт 51000.
Порты RPC Endpoint Mapper и MSDTC не обязательно должны быть одинаковыми на хосте и контейнере. Таким образом, хотя порт RPC Endpoint Mapper был настроен на 135 в контейнере, его потенциально можно было бы сопоставить с портом 13501 или любым другим доступным портом хост-сервера.
Настройка брандмауэра
Чтобы взаимодействовать с узлом и через него, необходимо также настроить брандмауэр на сервере узла для контейнеров. Откройте брандмауэр для всех портов, которые контейнер SQL Server открывает для внешнего обмена данными. В предыдущем примере это порты 135, 51433 и 51000. Это порты на самом хосте, а не порты, с которыми они сопоставлены в контейнере. То есть, если порт MSDTC 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
Следующая схема показывает процесс, когда один контейнер Linux SQL Server подключается к MSDTC на втором контейнере SQL Server Linux на 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>"
Caution
Пароль должен соответствовать политике паролей по умолчанию SQL Server. По умолчанию пароль должен быть не короче восьми символов и содержать три вида символов из следующих: прописные буквы, строчные буквы, десятичные цифры, специальные символы. Пароли могут иметь длину до 128 символов. Рекомендуется использовать максимально длинные и сложные пароли.
Обратите внимание на следующие моменты в файле манифеста:
Манифест создаёт следующие объекты:
StorageClass, два пода SQL Server, развёрнутые с помощьюStatefulSet, и две службы балансировки нагрузки для подключения к соответствующим экземплярам SQL Server.Вы также замечаете, что службы балансировщика нагрузки развертываются со статическими IP-адресами, которые можно настроить в Служба Azure Kubernetes. Дополнительные сведения см. в статье Использование статического общедоступного 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
Caution
Пароль должен соответствовать политике паролей по умолчанию 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