**Configure high availability with Always On Availability Groups on Amazon RDS Custom for SQL Server** === ###### tags: `AWS` 要設置 HA 配置,您需要創建兩個 RDS Custom for SQL Server 數據庫實例作為主節點和輔助節點,以及一個Amazon Elastic Compute Cloud (Amazon EC2) 實例作為witness node。強烈建議您在同一區域的不同可用區中創建這些實例。 下圖說明了使用 Always On AG 的 HA 設置。 ![](https://i.imgur.com/V566RXj.png) 通過以下步驟實施解決方案: Create RDS Custom for SQL Server and EC2 instances. Prepare the RDS Custom for SQL Server DB instances. Set up the witness disk using iSCSI. Set up a Windows cluster. Set up an Always On AG. <style> .red { color: red; } </style> <span class="red">※您需要先擁有名稱為AWSRDSCustomInstanceProfileForRdsCustomInstance的rules,並且有設置KMS</span> ### **為 SQL Server 和 EC2 實例創建 RDS Custom** [第一步是為 SQL Server 實例啟動 RDS Custom。有關為 SQL Server 實例創建 RDS Custom 的更多詳細信息,請參閱為Amazon RDS Custom for SQL Server 創建並連接到數據庫實例。](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/custom-creating-sqlserver.html) 以下LAB演示了在同一 VPC 和安全組中啟動兩個 RDS Custom for SQL Server 實例。您需要兩個不同的數據庫子網組才能使其在不同的可用區中可用。 #### **在 ap-northeast-1c 可用區中啟動Node-1 、RDS-custom-sqlserver-1** 簡化成CLI如下 ``` aws rds create-db-instance –engine custom-sqlserver-ee –engine-version 15.00.4261.1.v1 –db-instance-identifier RDS-custom-sqlserver-1 –db-instance-class db.m5.xlarge –allocated-storage 1000 –storage-type io1 –iops 10000 –master-username admin –master-user-password <XXXXX> –kms-key-id <kms-key-id> –custom-iam-instance-profile RDSCustomIAMProfile –db-subnet-group-name RDS-custom-sng-1 –vpc-security-group-ids RDS-usw2-vpc-sg-1 –publicly-accessible –region ap-northeast-1C –profile RDS_Custom ``` #### **在 ap-northeast-1a 可用區中啟動Node-1 、RDS-custom-sqlserver-1** 簡化成CLI如下 ``` aws rds create-db-instance –engine custom-sqlserver-ee –engine-version 15.00.4261.1.v1 –db-instance-identifier RDS-custom-sqlserver-1 –db-instance-class db.m5.xlarge –allocated-storage 1000 –storage-type io1 –iops 10000 –master-username admin –master-user-password <XXXXX> –kms-key-id <kms-key-id> –custom-iam-instance-profile RDSCustomIAMProfile –db-subnet-group-name RDS-custom-sng-1 –vpc-security-group-ids RDS-usw2-vpc-sg-1 –publicly-accessible –region ap-northeast-1A –profile RDS_Custom ``` #### **接下來,我們啟動一個充當witness node的 EC2 實例** 選擇 Amazon 系統映像 (AMI)。對於本次LAB,我們使用Microsoft Windows Server 2019 Base的 AMI 。 選擇實例類型。我們使用 t2.micro 實例類型。 配置實例詳細信息: 我們使用 RDS Custom for SQL Server 數據庫實例使用的相同 VPC 網絡,但在不同的可用區 (ap-northeast-1d) 中。在前面的步驟中,我們在 ap-northeast-1c 和 ap-northeast-1a 可用區中為 SQL Server 數據庫實例啟動了 RDS Custom。 將自動分配公共 IP 設置為啟用。 添加存儲大小為 100 GB 的新卷類型 GP2。 配置VPC安全組。我們選擇與之前為 SQL Server 數據庫實例的 RDS 自定義指定的相同)。 查看實例啟動並選擇一個密鑰對。 ### **為 SQL Server 數據庫實例準備 RDS Custom** [將兩台RDS Custom暫停自動化,以免干擾本次的lab](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/custom-managing.html#custom-managing.pausing) ![](https://i.imgur.com/IAtsRNh.png) 修改完成會顯示如下 ![](https://i.imgur.com/h66wBIv.png) [需要先透過 Session Manager 開啟 RDS 的 RDP 連線,並透過 Secrets Manager 獲取RDP的登錄密碼](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/custom-creating-sqlserver.html) 在Node-1和Node-2 打開Windows Power Shell 上運行以下命令啟動MSiSCSI service: ``` net start MSiSCSI Set-Service msiscsi –StartupType "Automatic" ``` 設置 DNS 後綴。以下示例為名為 custom.com 的域創建一個 DNS 後綴: ``` Set-ItemProperty "HKLM:SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "NV Domain" -Value "custom.com" ``` 安裝故障轉移集群功能: ``` Install-WindowsFeature -Name Failover-Clustering –IncludeManagementTools ``` 確保Node-1和Node-2 的管理員密碼相同並重啟VM確保生效: ``` net user administrator XXXXXXXX Restart-Computer ``` 輸出會如下 ![](https://i.imgur.com/3WFPkwk.png) ### **使用 iSCSI 設置witness disk** 要設置witness disk,請在Node-1和Node-2以及witness node上運行命令。 #### **Witness node:** 啟動 MSiSCSI 服務: ``` net start MSiSCSI Set-Service msiscsi -StartupType "Automatic" ``` Set up the disk for quorum: ``` diskpart list disk select disk 1 ``` <span class="red">※**witness node建立時少掛一個磁碟,因此重新掛載一顆新的**</span> ![](https://i.imgur.com/EtHbsYa.png) ``` online disk noerr attribute disk clear readonly convert dynamic noerr ``` <span class="red">※**出現相同錯誤請先下clean**</span> ![](https://i.imgur.com/yD6YnHU.png) ``` create volume simple align=1024 disk=1 format fs=NTFS label=”rdsquorum01″ quick UNIT=65536 list volume select volume=0 ``` ![](https://i.imgur.com/wMxR7mu.png) ``` assign letter d noerr exit ``` #### **Install the iSCSI target server role:** ``` Add-WindowsFeature FS-iSCSITarget-Server ``` ![](https://i.imgur.com/hqd2oDK.png) 創建具有指定文件路徑和大小的 iSCSI 虛擬硬盤 (VHDX) 對象: ``` New-IscsiVirtualDisk D:\rdsquorumrdscustomquorum01.vhdx -size 512MB -UseFixed ``` ![](https://i.imgur.com/E1RZeXh.png) 我們使用以下私人IP地址: **Node-1 (RDS-custom-sqlserver-1) — 172.31.7.150** **Node-2 (RDS-custom-sqlserver-2) — 172.31.36.230** Run the following code: ``` New-IscsiServerTarget rdscustomquorum -InitiatorIds IPAddress:172.31.7.150,IPAddress:172.31.36.230 ``` ![](https://i.imgur.com/PXUQuui.png) Assign the virtual disk "D:\rdsquorumrdscustomquorum01.vhdx" to the iSCSI target rdscustomquorum: ``` Add-IscsiVirtualDiskTargetMapping rdscustomquorum D:rdsquorumrdscustomquorum01.vhdx ``` ![](https://i.imgur.com/ENIWlEg.png) ### **設置Node-1 and Node-2** Node-1 and Node-2 to add a new iSCSI target portal ``` New-IscsiTargetPortal -TargetPortalAddress rdscustomwitness Get-IscsiTarget ``` [<span class="red">出現相同錯誤的情況需開啟iSCSi的Targets設定點選connect</span>](https://github.com/dsccommunity/iSCSIDsc/issues/9) ![](https://i.imgur.com/uvWClfl.png) ### **Node-1, Node-2, and witness node** 綁定本機的host文件,並且確保彼此放行所有端口和協議再透過ping測試 <span class="red">※使用CMD輸入notepad c:\windows\system32\drivers\etc\hosts即可編輯host</span> ``` 172.31.7.150 rdsamaz-63sdoia rdsamaz-63sdoia.custom.com rdscustomnode01 172.31.36.230 rdsamaz-a1bjtfg rdsamaz-a1bjtfg.custom.com rdscustomnode02 172.31.23.17 ec2amaz-d2au9ie ec2amaz-d2au9ie.custom.com rdscustomwitness ``` ![](https://i.imgur.com/tg36gvh.png) ### **設置Windows cluster** 要設置 Windows 集群,請在Node-1和Node-2上運行命令。在Node-1上完成步驟 1–10 : ``` diskpart list disk select disk 3 online disk noerr attribute disk clear readonly convert dynamic noerr convert basic noerr create partition primary ``` ![](https://i.imgur.com/as2m9bN.png) ``` format fs=NTFS label="rdscustomquorum01″ quick UNIT=65536 exit ``` ![](https://i.imgur.com/VcgzvjG.png) 以下示例創建一個名為“rdscustomcluster”的新的獨立於域的 Windows 集群。要創建集群,請在給定的子網範圍內標識一個未分配的 IP 地址,該地址可用作集群的 IP 地址。在以下示例中,我們使用 172.31.7.152 作為 IP 地址: ``` New-Cluster -Name rdscustomcluster -AdministrativeAccessPoint DNS -NoStorage -StaticAddress 172.31.7.152 Get-ClusterAvailableDisk Get-ClusterAvailableDisk | Add-ClusterDisk Set-ClusterQuorum -NodeAndDiskMajority “Cluster Disk 1” ``` ![](https://i.imgur.com/yaZuq2V.png) 將Node-2添加到集群: ``` Add-ClusterNode rdsamaz-a1bjtfg Get-ClusterResource "Cluster IP Address"| % { $_.Name="IP Address 172.31.7.152"} Get-ClusterResource ``` ![](https://i.imgur.com/eSbHR9m.png) 為Node-2的子網添加一個新的集群資源。在以下代碼中,Node-2的私有 IP 地址為 172.31.36.230。我們可以選擇給定子網範圍內的任何可用 IP 地址,例如:172.31.36.232。 ``` Add-ClusterResource -Name "IP Address 172.31.36.232" -ResourceType "IP Address" -Group "Cluster Group" ``` ![](https://i.imgur.com/Q3zwjkL.png) 為集群資源添加Node-2控制子網的 IP 地址: ``` $res = Get-ClusterResource "IP Address 172.31.36.232" $param1 = New-Object Microsoft.FailoverClusters.PowerShell.ClusterParameter $res,Address,172.31.36.232 $param2 = New-Object Microsoft.FailoverClusters.PowerShell.ClusterParameter $res,SubnetMask,255.255.240.0 $params = $param1,$param2 $params | Set-ClusterParameter ``` ![](https://i.imgur.com/lxGMuEO.png) 將集群依賴性設置為Node-1或Node-2子網集群資源: ``` Set-ClusterResourceDependency ‘Cluster Name’ “[IP Address 172.31.36.232] or [IP Address 172.31.7.152]” ``` ![](https://i.imgur.com/WbdYU1d.png) 在Node-1和Node-2上,啟用 SQLAlways On 並重新啟動: ``` Enable-SqlAlwaysOn -Path SQLSERVER:\SQL\$env:COMPUTERNAME\DEFAULT -Force Restart-Computer ``` ![](https://i.imgur.com/y3AlhYx.png) 當執行重新開機命令時,可以看到Windows cluster已經正常運作的切換中 ![](https://i.imgur.com/kmY9KsM.png) ### **設置 Always On AG** #### **我們通過在Node-1和Node-2上執行以下步驟序列,在 SQL Server 實例的 RDS Custom 上配置 Always On AG :** 在Node-1上,創建端點和備份證書: ``` USE master; CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Aasd1234'; CREATE CERTIFICATE HOST_A_cert WITH SUBJECT = 'HOST_A certificate for database mirroring', EXPIRY_DATE = '11/30/2023'; CREATE ENDPOINT Endpoint_Mirroring STATE = STARTED AS TCP ( LISTENER_PORT=1120 , LISTENER_IP = ALL) FOR DATABASE_MIRRORING ( AUTHENTICATION = CERTIFICATE HOST_A_cert , ENCRYPTION = REQUIRED ALGORITHM AES , ROLE = ALL); BACKUP CERTIFICATE HOST_A_cert TO FILE = 'D:\rdsdbdata\BACKUP\HOST_A_cert.cer'; ``` ![](https://i.imgur.com/CFIt775.png) 路徑填寫錯誤會需要重新執行T-SQL 語句 ![](https://i.imgur.com/12b1taG.png) 在Node-2上,創建端點和備份證書: ``` CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Aasd1234'; CREATE CERTIFICATE HOST_B_cert WITH SUBJECT = 'HOST_B certificate for database mirroring', EXPIRY_DATE = '11/30/2023′; CREATE ENDPOINT Endpoint_Mirroring STATE = STARTED AS TCP (LISTENER_PORT=1120 , LISTENER_IP = ALL) FOR DATABASE_MIRRORING (AUTHENTICATION = CERTIFICATE HOST_B_cert , ENCRYPTION = REQUIRED ALGORITHM AES , ROLE = ALL); BACKUP CERTIFICATE HOST_B_cert TO FILE = 'D:\rdsdbdata\BACKUP\HOST_B_cert.cer'; ``` ![](https://i.imgur.com/Qdm7ULU.png) <span class="red">※先將Node-1上的證書A複製到Node-2主機,Node-2上的證書B複製到Node-1上 在Node-1上,使用Node-2的備份證書創建證書: ``` USE master; CREATE LOGIN HOST_B_login WITH PASSWORD = 'Aasd1234'; CREATE USER HOST_B_user FOR LOGIN HOST_B_login; CREATE CERTIFICATE HOST_B_cert AUTHORIZATION HOST_B_user FROM FILE = 'D:\rdsdbdata\BACKUP\HOST_B_cert.cer'; GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_B_login]; ``` ![](https://i.imgur.com/kd8dlcT.png) 在Node-2上,使用Node-1的備份證書創建證書: ``` USE master; CREATE LOGIN HOST_A_login WITH PASSWORD = 'Aasd1234'; CREATE USER HOST_A_user FOR LOGIN HOST_A_login; CREATE CERTIFICATE HOST_A_cert AUTHORIZATION HOST_A_user FROM FILE = 'D:\rdsdbdata\BACKUP\HOST_A_cert.cer'; GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [HOST_A_login]; ``` ![](https://i.imgur.com/kipyk8I.png) 在Node-1上,創建一個availability group: ``` create availability group customag1 with ( automated_backup_preference = primary, db_failover = on, dtc_support = none ) for replica on 'rdsamaz-63sdoia' with ( endpoint_url = 'tcp://rdsamaz-63sdoia:1120', failover_mode = automatic, availability_mode = synchronous_commit, seeding_mode = automatic, secondary_role ( allow_connections = all ) ), 'rdsamaz-a1bjtfg' with ( endpoint_url = 'tcp://rdsamaz-a1bjtfg:1120', failover_mode = automatic, availability_mode = synchronous_commit, seeding_mode = automatic, secondary_role ( allow_connections = all ) ) go ``` ![](https://i.imgur.com/9gS6Nnv.png) ![](https://i.imgur.com/AmNHf6d.png) ### **新建database並添加到availability group** 在Node-1上,創建一個database: ``` create database test; backup database test to disk ='D:\rdsdbdata\backup\test.bak'; alter availability group customag1 add database test; ``` ![](https://i.imgur.com/ATZttTX.png) 在Node-2上,加入availability group: ``` alter availability group customag1 join; alter availability group customag1 grant create any database; ``` ![](https://i.imgur.com/q41o314.png) ### **從Node-2點選availability replicas點選rdsamaz-63sdoia(Node-1)進行connect是成功的** ![](https://i.imgur.com/iVPNNwy.png) ### **透過Fail Over Availability Group進行Connect To Replica進行connect成功** ![](https://i.imgur.com/NK6vaSf.png) --- ## **摘要** #### **在上述的Lab中,解釋如何使用 Always On AG 在 RDS Custom 上為 SQL Server 數據庫實例配置 HA。**