你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
教程:为 Azure 中 SLES 虚拟机上的 SQL Server 配置可用性组
注意
我们在本教程中将 SQL Server 2022 (16.x) 与 SUSE Linux Enterprise Server (SLES) v15 配合使用,但可以将 SQL Server 2019 (15.x) 与 SLES v12 或 SLES v15 配合使用来配置高可用性。
本教程介绍如何执行下列操作:
- 创建新的资源组、可用性集和 Linux 虚拟机 (VM)
- 实现高可用性 (HA)
- 创建 Pacemaker 群集
- 通过创建 STONITH 设备来配置隔离代理
- 在 SLES 上安装 SQL Server 和 mssql-tools
- 配置 SQL Server Always On 可用性组
- 在 Pacemaker 群集中配置可用性组 (AG) 资源
- 测试故障转移和隔离代理
本教程使用 Azure CLI 在 Azure 中部署资源。
如果没有 Azure 订阅,请在开始之前创建一个免费帐户。
先决条件
在 Azure Cloud Shell 中使用 Bash 环境。 有关详细信息,请参阅 Azure Cloud Shell 中的 Bash 快速入门。
如需在本地运行 CLI 参考命令,请安装 Azure CLI。 如果在 Windows 或 macOS 上运行,请考虑在 Docker 容器中运行 Azure CLI。 有关详细信息,请参阅如何在 Docker 容器中运行 Azure CLI。
如果使用的是本地安装,请使用 az login 命令登录到 Azure CLI。 若要完成身份验证过程,请遵循终端中显示的步骤。 有关其他登录选项,请参阅使用 Azure CLI 登录。
出现提示时,请在首次使用时安装 Azure CLI 扩展。 有关扩展详细信息,请参阅使用 Azure CLI 的扩展。
运行 az version 以查找安装的版本和依赖库。 若要升级到最新版本,请运行 az upgrade。
- 本文需要 Azure CLI 版本 2.0.30 或更高版本。 如果使用 Azure Cloud Shell,则最新版本已安装。
创建资源组
如果你有多个订阅,请设置要将这些资源部署到的订阅。
使用以下命令在某个区域中创建资源组 <resourceGroupName>
。 请将 <resourceGroupName>
替换为所选的名称。 本教程使用 East US 2
。 有关详细信息,请参阅以下快速入门。
az group create --name <resourceGroupName> --location eastus2
创建可用性集
下一步是创建可用性集。 在 Azure Cloud Shell 中运行以下命令,并将 <resourceGroupName>
替换为你的资源组名称。 选择 <availabilitySetName>
的名称。
az vm availability-set create \
--resource-group <resourceGroupName> \
--name <availabilitySetName> \
--platform-fault-domain-count 2 \
--platform-update-domain-count 2
该命令完成后,应会获得以下结果:
{
"id": "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Compute/availabilitySets/<availabilitySetName>",
"location": "eastus2",
"name": "<availabilitySetName>",
"platformFaultDomainCount": 2,
"platformUpdateDomainCount": 2,
"proximityPlacementGroup": null,
"resourceGroup": "<resourceGroupName>",
"sku": {
"capacity": null,
"name": "Aligned",
"tier": null
},
"statuses": null,
"tags": {},
"type": "Microsoft.Compute/availabilitySets",
"virtualMachines": []
}
创建虚拟网络和子网
使用预先分配的 IP 地址范围创建一个命名子网。 在以下命令中替换这些值:
<resourceGroupName>
<vNetName>
<subnetName>
az network vnet create \ --resource-group <resourceGroupName> \ --name <vNetName> \ --address-prefix 10.1.0.0/16 \ --subnet-name <subnetName> \ --subnet-prefix 10.1.1.0/24
上一个命令创建了一个 VNet 和一个包含自定义 IP 范围的子网。
在可用性集内创建 SLES VM
获取通过 BYOS(自带订阅)提供 SLES v15 SP4 的虚拟机映像列表。 还可以使用 SUSE Enterprise Linux 15 SP4 + 修补 VM (
sles-15-sp4-basic
)。az vm image list --all --offer "sles-15-sp3-byos" # if you want to search the basic offers you could search using the command below az vm image list --all --offer "sles-15-sp3-basic"
当你搜索 BYOS 映像时,应会看到以下结果:
[ { "offer": "sles-15-sp3-byos", "publisher": "SUSE", "sku": "gen1", "urn": "SUSE:sles-15-sp3-byos:gen1:2022.05.05", "version": "2022.05.05" }, { "offer": "sles-15-sp3-byos", "publisher": "SUSE", "sku": "gen1", "urn": "SUSE:sles-15-sp3-byos:gen1:2022.07.19", "version": "2022.07.19" }, { "offer": "sles-15-sp3-byos", "publisher": "SUSE", "sku": "gen1", "urn": "SUSE:sles-15-sp3-byos:gen1:2022.11.10", "version": "2022.11.10" }, { "offer": "sles-15-sp3-byos", "publisher": "SUSE", "sku": "gen2", "urn": "SUSE:sles-15-sp3-byos:gen2:2022.05.05", "version": "2022.05.05" }, { "offer": "sles-15-sp3-byos", "publisher": "SUSE", "sku": "gen2", "urn": "SUSE:sles-15-sp3-byos:gen2:2022.07.19", "version": "2022.07.19" }, { "offer": "sles-15-sp3-byos", "publisher": "SUSE", "sku": "gen2", "urn": "SUSE:sles-15-sp3-byos:gen2:2022.11.10", "version": "2022.11.10" } ]
本教程使用
SUSE:sles-15-sp3-byos:gen1:2022.11.10
。重要
若要设置可用性组,计算机名称长度不得超过 15 个字符。 用户名不能包含大写字符,密码必须介于 12 个到 72 个字符之间。
在可用性集中创建三个 VM。 在以下命令中替换这些值:
<resourceGroupName>
<VM-basename>
<availabilitySetName>
<VM-Size>
- 例如“Standard_D16s_v3”<username>
<adminPassword>
<vNetName>
<subnetName>
for i in `seq 1 3`; do az vm create \ --resource-group <resourceGroupName> \ --name <VM-basename>$i \ --availability-set <availabilitySetName> \ --size "<VM-Size>" \ --os-disk-size-gb 128 \ --image "SUSE:sles-15-sp3-byos:gen1:2022.11.10" \ --admin-username "<username>" \ --admin-password "<adminPassword>" \ --authentication-type all \ --generate-ssh-keys \ --vnet-name "<vNetName>" \ --subnet "<subnetName>" \ --public-ip-sku Standard \ --public-ip-address "" done
前面的命令使用以前定义的 VNet 创建 VM。 有关不同配置的详细信息,请参阅 az vm create 一文。
命令还包括 --os-disk-size-gb
参数,用于创建大小为 128 GB 的自定义 OS 驱动器。 如果稍后要增加此大小,扩展相应的文件夹卷来容纳安装,可以配置逻辑卷管理器 (LVM)。
针对每个 VM 完成该命令后,应会获得如下所示的结果:
{
"fqdns": "",
"id": "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Compute/virtualMachines/sles1",
"location": "westus",
"macAddress": "<Some MAC address>",
"powerState": "VM running",
"privateIpAddress": "<IP1>",
"resourceGroup": "<resourceGroupName>",
"zones": ""
}
测试与创建的 VM 的连接
在 Azure Cloud Shell 中使用以下命令连接到各个 VM。 如果找不到 VM IP,请按照这篇有关 Azure Cloud Shell 的快速入门的说明操作。
ssh <username>@<publicIPAddress>
如果连接成功,应会看到以下表示 Linux 终端内容的输出:
[<username>@sles1 ~]$
键入 exit
退出 SSH 会话。
注册 SUSEConnect 并安装高可用性包
要完成本教程的任务,必须将 VM 注册到 SUSEConnect 才能接收更新和支持。 然后,可以安装高可用性扩展模块,或称模式,这是一组启用 HA 的包。
同时在每个 VM(节点)上打开 SSH 会话会更容易,因为在整篇文章中,都必须在每个 VM 上运行相同的命令。
如果复制并粘贴多个 sudo
命令,并按提示输入密码,则其他命令不会运行。 请单独运行每个命令。
连接到每个 VM 节点以运行以下步骤。
将 VM 注册到 SUSEConnect
若要将 VM 节点注册到 SUSEConnect,请在所有节点上的以下命令中替换这些值:
<subscriptionEmailAddress>
<registrationCode>
sudo SUSEConnect
--url=https://scc.suse.com
-e <subscriptionEmailAddress> \
-r <registrationCode>
安装高可用性扩展
若要安装高可用性扩展,请在所有节点上运行以下命令:
sudo SUSEConnect -p sle-ha/15.3/x86_64 -r <registration code for Partner Subscription for High Availability Extension>
在节点之间配置无密码 SSH 访问
使用无密码 SSH 访问,VM 可以使用 SSH 公钥相互通信。 必须在每个节点上配置 SSH 密钥,并将这些密钥复制到每个节点。
生成新 SSH 密钥
所需的 SSH 密钥大小为 4,096 位。 在每个 VM 上,更改为 /root/.ssh
文件夹,并运行以下命令:
ssh-keygen -t rsa -b 4096
在此步骤中,系统可能会提示覆盖现有的 SSH 文件。 必须同意此提示。 无需输入密码。
复制 SSH 公钥
在每个 VM 上,必须使用 ssh-copy-id
命令从刚刚创建的节点复制公钥。 如果要在目标 VM 上指定目标目录,可以使用 -i
参数。
在以下命令中,<username>
帐户可以是在创建 VM 时为每个节点配置的同一帐户。 也可以使用 root
帐户,但不建议在生产环境中使用此帐户。
sudo ssh-copy-id <username>@sles1
sudo ssh-copy-id <username>@sles2
sudo ssh-copy-id <username>@sles3
验证每个节点的无密码访问
若要确认 SSH 公钥已复制到每个节点,请从每个节点使用 ssh
命令。 如果正确复制了密钥,则系统不会提示输入密码,且连接将成功。
在本示例中,我们从第一个 VM (sles1
) 连接到第二个和第三个节点。 再次强调,<username>
帐户可以是在创建 VM 时为每个节点配置的同一帐户
ssh <username>@sles2
ssh <username>@sles3
从所有三个节点重复此过程,使每个节点都可以与其他节点通信,无需使用密码。
配置名称解析
可以使用 DNS 或通过手动编辑每个节点上的 etc/hosts
文件来配置名称解析。
有关 DNS 和 Active Directory 的详细信息,请参阅将 Linux 主机上的 SQL Server 加入 Active Directory 域。
重要
我们建议使用上一示例中的专用 IP 地址。 在此配置中使用公共 IP 地址会导致安装失败,并会向外部网络公开 VM。
本示例中使用的 VM 及其 IP 地址如下所示:
sles1
:10.0.0.85sles2
:10.0.0.86sles3
:10.0.0.87
配置群集
在本教程中,第一个 VM (sles1
) 是节点 1,第二个 VM (sles2
) 是节点 2,第三个 VM (sles3
) 是节点 3。 有关群集安装的详细信息,请参阅在 Azure 中的 SUSE Linux Enterprise Server 上设置 Pacemaker。
群集安装
运行以下命令,在节点 1 上安装
ha-cluster-bootstrap
包,然后重启节点。 在本例中,它是sles1
VM。sudo zypper install ha-cluster-bootstrap
重启节点后,运行以下命令来部署群集:
sudo crm cluster init --name sqlcluster
你将看到与以下示例类似的输出:
Do you want to continue anyway (y/n)? y Generating SSH key for root The user 'hacluster' will have the login shell configuration changed to /bin/bash Continue (y/n)? y Generating SSH key for hacluster Configuring csync2 Generating csync2 shared key (this may take a while)...done csync2 checking files...done Detected cloud platform: microsoft-azure Configure Corosync (unicast): This will configure the cluster messaging layer. You will need to specify a network address over which to communicate (default is eth0's network, but you can use the network address of any active interface). Address for ring0 [10.0.0.85] Port for ring0 [5405] Configure SBD: If you have shared storage, for example a SAN or iSCSI target, you can use it avoid split-brain scenarios by configuring SBD. This requires a 1 MB partition, accessible to all nodes in the cluster. The device path must be persistent and consistent across all nodes in the cluster, so /dev/disk/by-id/* devices are a good choice. Note that all data on the partition you specify here will be destroyed. Do you wish to use SBD (y/n)? n WARNING: Not configuring SBD - STONITH will be disabled. Hawk cluster interface is now running. To see cluster status, open: https://10.0.0.85:7630/ Log in with username 'hacluster', password 'linux' WARNING: You should change the hacluster password to something more secure! Waiting for cluster..............done Loading initial cluster configuration Configure Administration IP Address: Optionally configure an administration virtual IP address. The purpose of this IP address is to provide a single IP that can be used to interact with the cluster, rather than using the IP address of any specific cluster node. Do you wish to configure a virtual IP address (y/n)? y Virtual IP []10.0.0.89 Configuring virtual IP (10.0.0.89)....done Configure Qdevice/Qnetd: QDevice participates in quorum decisions. With the assistance of a third-party arbitrator Qnetd, it provides votes so that a cluster is able to sustain more node failures than standard quorum rules allow. It is recommended for clusters with an even number of nodes and highly recommended for 2 node clusters. Do you want to configure QDevice (y/n)? n Done (log saved to /var/log/crmsh/ha-cluster-bootstrap.log)
使用以下命令检查节点 1 上的群集状态:
sudo crm status
如果成功,输出应包含以下文本:
1 node configured 1 resource instance configured
在所有节点上,使用以下命令将
hacluster
的密码更改为更安全的内容。 此外,还必须更改root
用户密码:sudo passwd hacluster
sudo passwd root
在节点 2 和节点 3 上运行以下命令,以首先安装
crmsh
包:sudo zypper install crmsh
现在,运行以下命令以加入群集:
sudo crm cluster join
下面是一些预期的交互:
Join This Node to Cluster: You will be asked for the IP address of an existing node, from which configuration will be copied. If you have not already configured passwordless ssh between nodes, you will be prompted for the root password of the existing node. IP address or hostname of existing node (e.g.: 192.168.1.1) []10.0.0.85 Configuring SSH passwordless with root@10.0.0.85 root@10.0.0.85's password: Configuring SSH passwordless with hacluster@10.0.0.85 Configuring csync2...done Merging known_hosts WARNING: scp to sles2 failed (Exited with error code 1, Error output: The authenticity of host 'sles2 (10.1.1.5)' can't be established. ECDSA key fingerprint is SHA256:UI0iyfL5N6X1ZahxntrScxyiamtzsDZ9Ftmeg8rSBFI. Are you sure you want to continue connecting (yes/no/[fingerprint])? lost connection ), known_hosts update may be incomplete Probing for new partitions...done Address for ring0 [10.0.0.86] Hawk cluster interface is now running. To see cluster status, open: https://10.0.0.86:7630/ Log in with username 'hacluster', password 'linux' WARNING: You should change the hacluster password to something more secure! Waiting for cluster.....done Reloading cluster configuration...done Done (log saved to /var/log/crmsh/ha-cluster-bootstrap.log)
将所有计算机加入群集后,检查资源,看看是否所有 VM 都处于联机状态:
sudo crm status
您应看到以下输出:
Stack: corosync Current DC: sles1 (version 2.0.5+20201202.ba59be712-150300.4.30.3-2.0.5+20201202.ba59be712) - partition with quorum Last updated: Mon Mar 6 18:01:17 2023 Last change: Mon Mar 6 17:10:09 2023 by root via cibadmin on sles1 3 nodes configured 1 resource instance configured Online: [ sles1 sles2 sles3 ] Full list of resources: admin-ip (ocf::heartbeat:IPaddr2): Started sles1
安装群集资源组件。 在所有节点上运行以下命令。
sudo zypper in socat
安装
azure-lb
组件。 在所有节点上运行以下命令。sudo zypper in resource-agents
配置操作系统。 在所有节点上完成以下步骤。
编辑配置文件:
sudo vi /etc/systemd/system.conf
将
DefaultTasksMax
值更改为4096
:#DefaultTasksMax=512 DefaultTasksMax=4096
保存并退出 vi 编辑器。
若要激活此设置,请运行以下命令:
sudo systemctl daemon-reload
测试更改是否成功:
sudo systemctl --no-pager show | grep DefaultTasksMax
减小脏缓存的大小。 在所有节点上完成以下步骤。
编辑系统控制配置文件:
sudo vi /etc/sysctl.conf
将以下两行添加到文件中:
vm.dirty_bytes = 629145600 vm.dirty_background_bytes = 314572800
保存并退出 vi 编辑器。
使用以下命令在所有节点上安装 Azure Python SDK:
sudo zypper install fence-agents # Install the Azure Python SDK on SLES 15 or later: # You might need to activate the public cloud extension first. In this example, the SUSEConnect command is for SLES 15 SP1 SUSEConnect -p sle-module-public-cloud/15.1/x86_64 sudo zypper install python3-azure-mgmt-compute sudo zypper install python3-azure-identity
配置隔离代理
STONITH 设备提供隔离代理。 以下说明已根据本教程进行修改。 有关详细信息,请参阅创建 Azure 隔离代理 STONITH 设备。
检查 Azure 隔离代理的版本,确保它已更新。 使用以下命令:
sudo zypper info resource-agents
应会看到类似于以下示例的输出。
Information for package resource-agents:
----------------------------------------
Repository : SLE-Product-HA15-SP3-Updates
Name : resource-agents
Version : 4.8.0+git30.d0077df0-150300.8.37.1
Arch : x86_64
Vendor : SUSE LLC <https://www.suse.com/>
Support Level : Level 3
Installed Size : 2.5 MiB
Installed : Yes (automatically)
Status : up-to-date
Source package : resource-agents-4.8.0+git30.d0077df0-150300.8.37.1.src
Upstream URL : http://linux-ha.org/
Summary : HA Reusable Cluster Resource Scripts
Description : A set of scripts to interface with several services
to operate in a High Availability environment for both
Pacemaker and rgmanager service managers.
在 Microsoft Entra ID 中注册新应用程序
若要在 Microsoft Entra ID(以前称为 Azure Active Directory)中注册新应用程序,请执行以下步骤:
- 转到 https://portal.azure.com。
- 打开 Microsoft Entra ID 属性窗格并记下
Tenant ID
。 - 选择“应用注册” 。
- 选择“新注册”。
- 输入名称(如
<resourceGroupName>-app
)。 对于“受支持的帐户类型”,选择“仅此组织目录中的帐户(仅 Microsoft – 单一租户)”。 - 选择“Web”作为“重定向 URI”,然后输入 URL(例如 http://localhost),然后选择“添加”。 登录 URL可以是任何有效的 URL。 完成后,选择“注册”。
- 为新应用注册选择“证书和机密”,然后选择“新建客户端密码”。
- 输入新密钥(客户端密码)的说明,然后选择“添加”。
- 请记下机密的值。 它用作服务主体的密码。
- 选择“概述”。 记下应用程序 ID。 此 ID 用作服务主体的用户名(以下步骤中的“登录 ID”)。
为隔离代理创建自定义角色
按照教程使用 Azure CLI 创建 Azure 自定义角色。
JSON 文件应类似于以下示例。
- 将
<username>
替换为所选名称。 这是为了避免在创建此角色定义时出现任何重复。 - 请将
<subscriptionId>
替换为你的 Azure 订阅 ID。
{
"Name": "Linux Fence Agent Role-<username>",
"Id": null,
"IsCustom": true,
"Description": "Allows to power-off and start virtual machines",
"Actions": [
"Microsoft.Compute/*/read",
"Microsoft.Compute/virtualMachines/powerOff/action",
"Microsoft.Compute/virtualMachines/start/action"
],
"NotActions": [
],
"AssignableScopes": [
"/subscriptions/<subscriptionId>"
]
}
若要添加角色,请运行以下命令:
- 请将
<filename>
替换为该文件的名称。 - 如果执行该命令所在的路径不是该文件所保存到的文件夹,请在该命令中包含该文件的文件夹路径。
az role definition create --role-definition "<filename>.json"
您应看到以下输出:
{
"assignableScopes": [
"/subscriptions/<subscriptionId>"
],
"description": "Allows to power-off and start virtual machines",
"id": "/subscriptions/<subscriptionId>/providers/Microsoft.Authorization/roleDefinitions/<roleNameId>",
"name": "<roleNameId>",
"permissions": [
{
"actions": [
"Microsoft.Compute/*/read",
"Microsoft.Compute/virtualMachines/powerOff/action",
"Microsoft.Compute/virtualMachines/start/action"
],
"dataActions": [],
"notActions": [],
"notDataActions": []
}
],
"roleName": "Linux Fence Agent Role-<username>",
"roleType": "CustomRole",
"type": "Microsoft.Authorization/roleDefinitions"
}
将自定义角色分配给服务主体
将在上一步骤中创建的自定义角色 Linux Fence Agent Role-<username>
分配给服务主体。 针对所有节点重复上述步骤。
警告
从现在开始,不要再使用所有者角色。
- 转到 https://portal.azure.com
- 打开“所有资源”窗格
- 选择第一个群集节点的虚拟机
- 选择“访问控制(标识和访问管理)”
- 选择“添加角色分配”
- 从“角色”列表中选择角色
Linux Fence Agent Role-<username>
- 将“将访问权限分配给”保留为默认的“
Users, group, or service principal
”。 - 在“选择”列表中,输入前面创建的应用程序名称,例如
<resourceGroupName>-app
。 - 选择“保存”。
创建 STONITH 设备
在节点 1 上运行以下命令:
- 将
<ApplicationID>
替换为应用程序注册中的 ID 值。 - 将
<servicePrincipalPassword>
替换为客户端机密中的值。 - 将
<resourceGroupName>
替换为用于本教程的订阅中的资源组。 - 替换 Azure 订阅中的
<tenantID>
和<subscriptionId>
。
- 将
运行
crm configure
以打开 crm 提示符:sudo crm configure
在 crm 提示符中,运行以下命令以配置资源属性,这将创建名为
rsc_st_azure
的资源,如以下示例所示:primitive rsc_st_azure stonith:fence_azure_arm params subscriptionId="subscriptionID" resourceGroup="ResourceGroup_Name" tenantId="TenantID" login="ApplicationID" passwd="servicePrincipalPassword" pcmk_monitor_retries=4 pcmk_action_limit=3 power_timeout=240 pcmk_reboot_timeout=900 pcmk_host_map="sles1:sles1;sles2:sles2;sles3:sles3" op monitor interval=3600 timeout=120 commit quit
运行以下命令以配置隔离代理:
sudo crm configure property stonith-timeout=900 sudo crm configure property stonith-enabled=true sudo crm configure property concurrent-fencing=true
检查群集的状态,看看 STONITH 是否已启用:
sudo crm status
会得到类似于下面文本的输出:
Stack: corosync Current DC: sles1 (version 2.0.5+20201202.ba59be712-150300.4.30.3-2.0.5+20201202.ba59be712) - partition with quorum Last updated: Mon Mar 6 18:20:17 2023 Last change: Mon Mar 6 18:10:09 2023 by root via cibadmin on sles1 3 nodes configured 2 resource instances configured Online: [ sles1 sles2 sles3 ] Full list of resources: admin-ip (ocf::heartbeat:IPaddr2): Started sles1 rsc_st_azure (stonith:fence_azure_arm): Started sles2
安装 SQL Server 和 mssql-tools
参考以下部分安装 SQL Server 和 mssql-tools。 有关详细信息,请参阅在 SUSE Linux Enterprise Server 上安装 SQL Server。
在本部分的所有节点上执行这些步骤。
在 VM 上安装 SQL Server
使用以下命令安装 SQL Server:
下载 Microsoft SQL Server 2019 SLES 存储库配置文件:
sudo zypper addrepo -fc https://packages.microsoft.com/config/sles/15/mssql-server-2022.repo
刷新存储库。
sudo zypper --gpg-auto-import-keys refresh
若要确保你的系统上安装了 Microsoft 包签名密钥,请使用以下命令导入该密钥:
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
运行以下命令以安装 SQL Server:
sudo zypper install -y mssql-server
包安装完成后,运行
mssql-conf setup
,按照提示设置 SA 密码并选择版本。sudo /opt/mssql/bin/mssql-conf setup
注意
请确保为 SA 帐户指定强密码(最少 8 个字符,包括大写和小写字母、十进制数字和/或非字母数字符号)。
完成配置后,验证服务是否正在运行:
systemctl status mssql-server
安装 SQL Server 命令行工具
以下步骤将安装 SQL Server 命令行工具:sqlcmd 和 bcp。
将 Microsoft SQL Server 存储库添加到 Zypper。
sudo zypper addrepo -fc https://packages.microsoft.com/config/sles/15/prod.repo
刷新存储库。
sudo zypper --gpg-auto-import-keys refresh
使用
unixODBC
开发人员包安装 mssql-tools。 有关详细信息,请参阅安装 Microsoft ODBC Driver for SQL Server (Linux)。sudo zypper install -y mssql-tools unixODBC-devel
为方便起见,可以向 PATH
环境变量添加 /opt/mssql-tools/bin/
。 这样可以在不指定完整路径的情况下运行这些工具。 运行以下命令以修改登录会话和交互式/非登录会话的 PATH:
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
安装 SQL Server 高可用性代理
在所有节点上运行以下命令,为 SQL Server 安装高可用性代理包:
sudo zypper install mssql-server-ha
为高可用性服务打开端口
可以在所有节点上为 SQL Server 和高可用性服务打开以下防火墙端口:1433、2224、3121、5022、5405、21064。
sudo firewall-cmd --zone=public --add-port=1433/tcp --add-port=2224/tcp --add-port=3121/tcp --add-port=5022/tcp --add-port=5405/tcp --add-port=21064 --permanent sudo firewall-cmd --reload
配置可用性组
使用以下步骤为 VM 配置 SQL Server Always On 可用性组。 有关详细信息,请参阅配置 SQL Server Always On 可用性组以在 Linux 上实现高可用性
启用可用性组并重启 SQL Server
在托管 SQL Server 实例的每个节点上启用可用性组。 然后重启 mssql-server
服务。 在每个节点上运行以下命令:
sudo /opt/mssql/bin/mssql-conf set hadr.hadrenabled 1
sudo systemctl restart mssql-server
创建证书
Microsoft 不支持对 AG 终结点进行 Active Directory 身份验证。 因此,必须使用证书来加密 AG 终结点。
使用 SQL Server Management Studio (SSMS) 或 sqlcmd 连接到所有节点。 运行以下命令,以启用 AlwaysOn_health 会话并创建主密钥:
重要
如果远程连接到 SQL Server 实例,则需要在防火墙中打开端口 1433。 此外,需要在每个 VM 的 NSG 中允许与端口 1433 建立入站连接。 有关创建入站安全规则的详细信息,请参阅创建安全规则。
- 请将
<MasterKeyPassword>
替换为自己的密码。
ALTER EVENT SESSION AlwaysOn_health ON SERVER WITH (STARTUP_STATE = ON); GO CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<MasterKeyPassword>'; GO
- 请将
使用 SSMS 或 sqlcmd 连接到主要副本。 以下命令会在主要 SQL Server 副本上的
/var/opt/mssql/data/dbm_certificate.cer
中创建一个证书,并在var/opt/mssql/data/dbm_certificate.pvk
中创建一个私钥:- 请将
<PrivateKeyPassword>
替换为自己的密码。
CREATE CERTIFICATE dbm_certificate WITH SUBJECT = 'dbm'; GO BACKUP CERTIFICATE dbm_certificate TO FILE = '/var/opt/mssql/data/dbm_certificate.cer' WITH PRIVATE KEY ( FILE = '/var/opt/mssql/data/dbm_certificate.pvk', ENCRYPTION BY PASSWORD = '<PrivateKeyPassword>' ); GO
- 请将
运行 exit
命令退出 sqlcmd 会话,并返回到 SSH 会话。
将证书复制到次要副本并在服务器上创建证书
将创建的两个文件复制到所有要托管可用性副本的服务器上的同一位置。
在主服务器上,运行以下
scp
命令将证书复制到目标服务器:- 将
<username>
和sles2
替换为所用的用户名和目标 VM 名称。 - 针对所有次要副本运行此命令。
注意
无需运行提供根环境的
sudo -i
。 可以改为在每个命令的前面运行sudo
命令。# The below command allows you to run commands in the root environment sudo -i
scp /var/opt/mssql/data/dbm_certificate.* <username>@sles2:/home/<username>
- 将
在目标服务器上运行以下命令:
- 请将
<username>
替换为你的用户名。 mv
命令将文件或目录从一个位置移到另一个位置。chown
命令用于更改文件、目录或链接的所有者和组。- 针对所有次要副本运行这些命令。
sudo -i mv /home/<username>/dbm_certificate.* /var/opt/mssql/data/ cd /var/opt/mssql/data chown mssql:mssql dbm_certificate.*
- 请将
以下 Transact-SQL 脚本基于在主要 SQL Server 副本上创建的备份创建证书。 使用强密码更新脚本。 解密密码与前一步骤中用于创建 .pvk 文件的密码相同。 若要创建证书,请在所有辅助服务器上使用 sqlcmd 或 SSMS 运行以下脚本:
CREATE CERTIFICATE dbm_certificate FROM FILE = '/var/opt/mssql/data/dbm_certificate.cer' WITH PRIVATE KEY ( FILE = '/var/opt/mssql/data/dbm_certificate.pvk', DECRYPTION BY PASSWORD = '<PrivateKeyPassword>' ); GO
在所有副本上创建数据库镜像终结点
使用 sqlcmd 或 SSMS 在所有 SQL Server 实例上运行以下脚本:
CREATE ENDPOINT [Hadr_endpoint]
AS TCP (LISTENER_PORT = 5022)
FOR DATABASE_MIRRORING (
ROLE = ALL,
AUTHENTICATION = CERTIFICATE dbm_certificate,
ENCRYPTION = REQUIRED ALGORITHM AES
);
GO
ALTER ENDPOINT [Hadr_endpoint] STATE = STARTED;
GO
创建可用性组
使用 sqlcmd 或 SSMS 连接到托管主要副本的 SQL Server 实例。 运行以下命令来创建可用性组:
- 将
ag1
替换为所需的 AG 名称。 - 请将
sles1
、sles2
和sles3
值替换为托管副本的 SQL Server 实例的名称。
CREATE AVAILABILITY
GROUP [ag1]
WITH (
DB_FAILOVER = ON,
CLUSTER_TYPE = EXTERNAL
)
FOR REPLICA
ON N'sles1'
WITH (
ENDPOINT_URL = N'tcp://sles1:5022',
AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
FAILOVER_MODE = EXTERNAL,
SEEDING_MODE = AUTOMATIC
),
N'sles2'
WITH (
ENDPOINT_URL = N'tcp://sles2:5022',
AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
FAILOVER_MODE = EXTERNAL,
SEEDING_MODE = AUTOMATIC
),
N'sles3'
WITH (
ENDPOINT_URL = N'tcp://sles3:5022',
AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
FAILOVER_MODE = EXTERNAL,
SEEDING_MODE = AUTOMATIC
);
GO
ALTER AVAILABILITY GROUP [ag1]
GRANT CREATE ANY DATABASE;
GO
为 Pacemaker 创建 SQL Server 登录名
在所有 SQL Server 实例上,为 Pacemaker 创建 SQL Server 登录名。 以下 Transact-SQL 创建登录名。
- 请将
<password>
替换为自己的复杂密码。
USE [master]
GO
CREATE LOGIN [pacemakerLogin]
WITH PASSWORD = N'<password>';
GO
ALTER SERVER ROLE [sysadmin]
ADD MEMBER [pacemakerLogin];
GO
在所有 SQL Server 实例上,保存 SQL Server 登录名使用的凭据。
创建文件:
sudo vi /var/opt/mssql/secrets/passwd
将以下两行添加到文件中:
pacemakerLogin <password>
若要退出 vi 编辑器,请先按 Esc 键,然后输入命令
:wq
以写入文件并退出。使该文件只能由 root 用户读取:
sudo chown root:root /var/opt/mssql/secrets/passwd sudo chmod 400 /var/opt/mssql/secrets/passwd
将次要副本加入可用性组
在次要副本上,运行以下命令以将其加入 AG:
ALTER AVAILABILITY GROUP [ag1] JOIN WITH (CLUSTER_TYPE = EXTERNAL); GO ALTER AVAILABILITY GROUP [ag1] GRANT CREATE ANY DATABASE; GO
在主要副本和每个次要副本上运行以下 Transact-SQL 脚本:
GRANT ALTER, CONTROL, VIEW DEFINITION ON AVAILABILITY GROUP::ag1 TO pacemakerLogin; GO GRANT VIEW SERVER STATE TO pacemakerLogin; GO
加入次要副本后,在 SSMS 对象资源管理器中展开“Always On 高可用性”节点即可看到这些副本:
将数据库添加到可用性组
本部分将按照将数据库添加到可用性组一文执行操作。
此步骤使用以下 Transact-SQL 命令。 在主要副本上运行以下命令:
CREATE DATABASE [db1]; -- creates a database named db1
GO
ALTER DATABASE [db1] SET RECOVERY FULL; -- set the database in full recovery model
GO
BACKUP DATABASE [db1] -- backs up the database to disk
TO DISK = N'/var/opt/mssql/data/db1.bak';
GO
ALTER AVAILABILITY GROUP [ag1] ADD DATABASE [db1]; -- adds the database db1 to the AG
GO
验证是否已在辅助服务器上创建了数据库
在每个次要 SQL Server 副本上运行以下查询,查看 db1 数据库是否已创建并处于 SYNCHRONIZED(已同步)状态:
SELECT * FROM sys.databases
WHERE name = 'db1';
GO
SELECT DB_NAME(database_id) AS 'database',
synchronization_state_desc
FROM sys.dm_hadr_database_replica_states;
GO
如果 synchronization_state_desc
将 db1
的状态列为 SYNCHRONIZED,则表示副本已同步。 次要副本在主要副本中显示 db1
。
在 Pacemaker 群集中创建可用性组资源
注意
无偏差通信
本文包含对术语“从属”的引用,Microsoft 认为该术语在此上下文中存在冒犯性。 本文使用该术语的原因是,当前软件中存在该术语。 在从软件中删除该术语后,我们会将其从本文中删除。
本文参考了在 Pacemaker 群集中创建可用性组资源的指南。
启用 Pacemaker
启用 Pacemaker 以使其自动启动。
在群集的所有节点上运行以下命令。
sudo systemctl enable pacemaker
创建 AG 群集资源
运行
crm configure
以打开 crm 提示符:sudo crm configure
在 crm 提示符中,运行以下命令以配置资源属性。 以下命令在可用性组
ag1
中创建资源ag_cluster
。primitive ag_cluster ocf:mssql:ag params ag_name="ag1" meta failure-timeout=60s op start timeout=60s op stop timeout=60s op promote timeout=60s op demote timeout=10s op monitor timeout=60s interval=10s op monitor timeout=60s interval=11s role="Master" op monitor timeout=60s interval=12s role="Slave" op notify timeout=60s ms ms-ag_cluster ag_cluster meta master-max="1" master-node-max="1" clone-max="3" clone-node-max="1" notify="true" commit quit
提示
键入
quit
,以从 crm 提示符中退出。设置虚拟 IP 的主机托管约束,以在与主节点相同的节点上运行:
sudo crm configure colocation vip_on_master inf: admin-ip ms-ag_cluster: Master commit quit
添加排序约束,防止 IP 地址暂时指向具有故障转移前的次要副本的节点。 运行以下命令以创建排序约束:
sudo crm configure order ag_first inf: ms-ag_cluster:promote admin-ip:start commit quit
使用以下命令检查群集的状态:
sudo crm status
输出应如以下示例所示:
Cluster Summary: * Stack: corosync * Current DC: sles1 (version 2.0.5+20201202.ba59be712-150300.4.30.3-2.0.5+20201202.ba59be712) - partition with quorum * Last updated: Mon Mar 6 18:38:17 2023 * Last change: Mon Mar 6 18:38:09 2023 by root via cibadmin on sles1 * 3 nodes configured * 5 resource instances configured Node List: * Online: [ sles1 sles2 sles3 ] Full List of Resources: * admin-ip (ocf::heartbeat:IPaddr2): Started sles1 * rsc_st_azure (stonith:fence_azure_arm): Started sles2 * Clone Set: ms-ag_cluster [ag_cluster] (promotable): * Masters: [ sles1 ] * Slaves: [ sles2 sles3 ]
运行以下命令以查看约束:
sudo crm configure show
输出应如以下示例所示:
node 1: sles1 node 2: sles2 node 3: sles3 primitive admin-ip IPaddr2 \ params ip=10.0.0.93 \ op monitor interval=10 timeout=20 primitive ag_cluster ocf:mssql:ag \ params ag_name=ag1 \ meta failure-timeout=60s \ op start timeout=60s interval=0 \ op stop timeout=60s interval=0 \ op promote timeout=60s interval=0 \ op demote timeout=10s interval=0 \ op monitor timeout=60s interval=10s \ op monitor timeout=60s interval=11s role=Master \ op monitor timeout=60s interval=12s role=Slave \ op notify timeout=60s interval=0 primitive rsc_st_azure stonith:fence_azure_arm \ params subscriptionId=xxxxxxx resourceGroup=amvindomain tenantId=xxxxxxx login=xxxxxxx passwd="******" cmk_monitor_retries=4 pcmk_action_limit=3 power_timeout=240 pcmk_reboot_timeout=900 pcmk_host_map="sles1:sles1;les2:sles2;sles3:sles3" \ op monitor interval=3600 timeout=120 ms ms-ag_cluster ag_cluster \ meta master-max=1 master-node-max=1 clone-max=3 clone-node-max=1 notify=true order ag_first Mandatory: ms-ag_cluster:promote admin-ip:start colocation vip_on_master inf: admin-ip ms-ag_cluster:Master property cib-bootstrap-options: \ have-watchdog=false \ dc-version="2.0.5+20201202.ba59be712-150300.4.30.3-2.0.5+20201202.ba59be712" \ cluster-infrastructure=corosync \ cluster-name=sqlcluster \ stonith-enabled=true \ concurrent-fencing=true \ stonith-timeout=900 rsc_defaults rsc-options: \ resource-stickiness=1 \ migration-threshold=3 op_defaults op-options: \ timeout=600 \ record-pending=true
测试故障转移
为了确保到目前为止完成的配置能够成功,需要测试故障转移。 有关详细信息,请参阅 Linux 上的 Always On 可用性组故障转移。
运行以下命令,将主要副本手动故障转移到
sles2
。 请将sles2
替换为你的服务器名称值。sudo crm resource move ag_cluster sles2
输出应如以下示例所示:
INFO: Move constraint created for ms-ag_cluster to sles2 INFO: Use `crm resource clear ms-ag_cluster` to remove this constraint
检查群集的状态:
sudo crm status
输出应如以下示例所示:
Cluster Summary: * Stack: corosync * Current DC: sles1 (version 2.0.5+20201202.ba59be712-150300.4.30.3-2.0.5+20201202.ba59be712) - partition with quorum * Last updated: Mon Mar 6 18:40:02 2023 * Last change: Mon Mar 6 18:39:53 2023 by root via crm_resource on sles1 * 3 nodes configured * 5 resource instances configured Node List: * Online: [ sles1 sles2 sles3 ] Full List of Resources: * admin-ip (ocf::heartbeat:IPaddr2): Stopped * rsc_st_azure (stonith:fence_azure_arm): Started sles2 * Clone Set: ms-ag_cluster [ag_cluster] (promotable): * Slaves: [ sles1 sles2 sles3 ]
一段时间后,
sles2
VM 现在是主 VM,另外两个 VM 是辅助 VM。 再次运行sudo crm status
并查看输出,如以下示例所示:Cluster Summary: * Stack: corosync * Current DC: sles1 (version 2.0.5+20201202.ba59be712-150300.4.30.3-2.0.5+20201202.ba59be712) - partition with quorum * Last updated: Tue Mar 6 22:00:44 2023 * Last change: Mon Mar 6 18:42:59 2023 by root via cibadmin on sles1 * 3 nodes configured * 5 resource instances configured Node List: * Online: [ sles1 sles2 sles3 ] Full List of Resources: * admin-ip (ocf::heartbeat:IPaddr2): Started sles2 * rsc_st_azure (stonith:fence_azure_arm): Started sles2 * Clone Set: ms-ag_cluster [ag_cluster] (promotable): * Masters: [ sles2 ] * Slaves: [ sles1 sles3 ]
使用
crm config show
再次检查约束。 请注意,由于手动故障转移,又增加了另一个约束。使用以下命令删除 ID 为
cli-prefer-ag_cluster
的约束:crm configure delete cli-prefer-ms-ag_cluster commit
测试隔离
可以运行以下命令来测试 STONITH。 尝试从 sles1
对 sles3
运行以下命令。
sudo crm node fence sles3