[SQL][AlwaysOn] 在沒有網域的環境下架設 SQL Server AlwaysOn 的環境

SQL Server 2016 含以後的版本 , 搭配 Windows Server 2016 以後的作業系統 , 可以在 Windows 環境下沒有 AD 也可以運行了

基本上 SQL Server 架設 AlwaysON 可以不需要搭配 Windows AD 來做架設,基本上這已經是在 SQL Server 2016 以後就已經可以實現的功能,由於之前在安裝的時候,還是比較習慣使用 Windows AD 並且搭配 Managed Service Account,因此即便知道可以這樣架設,但也就沒有特別去注意和使用。剛好這幾天有學長詢問到類似的問題,雖然可以透過 ChatGPT 或者是網路爬文可以找到資料,但還是想說還是自己安裝一遍紀錄一下,免得遇到問題也不知道該怎麼來做處理。

首先我先準備兩個 VM 的環境,基本上就是 Windows Server 2022 Standard 搭配 SQL Server 2022 Develop,然後這兩個 VM 都是使用工作群組,並沒有加入到網域環境之下。

Windows 環境設定 : 

因為沒有加入到網域內,且測試環境下沒有特別安裝 DNS 的服務,因此我們利用 Hosts 的設定來做名稱解析,因此我們會在兩台 VM 下面的 C:\Windows\System32\Drivers\etc 的目錄下,將以下設定放入到 Hosts 的設定內,這裡我們設定兩台 VM 的 IP,和預計的叢集名稱和 AlwaysON Listener 的 IP 對應。

預備好環境之後,首先我們在兩台 VM 上先安裝叢集服務,這裡我就偷懶一點直接用 PowerShell 來做處理

# 安裝 Failover Clustering 功能
Install-WindowsFeature Failover-Clustering -IncludeManagementTools

安裝完畢之後,我們就可以利用叢集管理員來建立叢集,這裡要注意因為在無網域的環境下,因此一定要先在 DNS 或者是 Hosts 做好叢集名稱和 IP 的對應設定,否則這裡就會有問題

這裡基本上只要前面的環境預備是順利的,那麼到這裡就基本上都沒有甚麼問題了。

而因為當你要架設 SQL AlwaysON 的時候這兩台 VM 勢必會相互連接,因此這裡我也用 PowerShell 來調整防火牆的設定

# 開啟一般 SQL 連線所使用的 TCP 1433 Port
New-NetFirewallRule -DisplayName "TSQL" `
    -Direction Inbound `
    -Protocol TCP `
    -LocalPort 1433 `
    -Action Allow `
    -Profile Any


# 開啟兩台 SQL 之間連線所使用的 TCP 5022 Port
New-NetFirewallRule -DisplayName "Mirror" `
    -Direction Inbound `
    -Protocol TCP `
    -LocalPort 5022 `
    -Action Allow `
    -Profile Any

Windows 下的 SQL 伺服器環境設定 : 

完成作業系統的設定,接下來我們要來調整 SQL Server 的設定,首先是因為目前 SQL Server 安裝的時候,如果沒有特別設定的話,預設都會採用服務帳號來執行,而這裡我是先在兩台 VM 環境下都先建立好一個用來啟動 SQL Server 服務的帳號 SQLAdmin,不直接採用 Administrator 的帳號來啟動 SQL Server,所以這裡我們用 SQL Server 設定管理員來做調整。

而在前面因為 Windows 環境已經設定好叢集管理的服務,所以在前面「登入」設定完成之後,接下來就要進來「Always On 可用性群組」的頁簽內,將「啟用 Always On 可用性群組」的選項也要一併記得勾選起來。

這裡設定好之後,就直接把 SQL Server 的服務給重新啟動

SQL 相關帳號與權限設定

因為後續我們兩台 SQL 會相互串接,在沒有網域的環境下,我們要設定透過憑證來做登入,這要兩台 SQL Server 就還是可以透過憑證來做身分驗證

這裡我先準備 SQL1 主機上要執行的 SQL 語法


-- 建立 Master Key
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'YourStrongPassword!';
GO

-- 建立 SQL1 要使用的憑證
CREATE CERTIFICATE SQL1Cert
WITH SUBJECT = 'SQL1CertSubject',
	START_DATE = '2024-01-01',
	EXPIRY_DATE = '2030-12-31';
GO

-- 備份憑證用來將憑證複製到 SQL2 的環境上
BACKUP CERTIFICATE SQL1Cert
TO FILE = 'C:\Tools\SQL1Cert.cer'
WITH PRIVATE KEY
(
    FILE = 'C:\Tools\SQL1PrivateKey.pvk',
    ENCRYPTION BY PASSWORD = 'StrongPassword'
);
GO

同樣的我們在 SQL2  上面也要執行一對類似的語法


-- 建立 Master Key
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'YourStrongPassword!';
GO

-- 建立 SQL2 要使用的憑證
CREATE CERTIFICATE SQL2Cert
WITH SUBJECT = 'SQL2CertSubject',
	START_DATE = '2024-01-01',
	EXPIRY_DATE = '2030-12-31';
GO

-- 備份憑證用來將憑證複製到 SQL1 的環境上
BACKUP CERTIFICATE SQL2Cert
TO FILE = 'C:\Tools\SQL2Cert.cer'
WITH PRIVATE KEY
(
    FILE = 'C:\Tools\SQL2PrivateKey.pvk',
    ENCRYPTION BY PASSWORD = 'P@ssw0rd'
);
GO

而接下來我們就要把 SQL1 的憑證複製到 SQL2 ,同樣也把 SQL2 的憑證複製到 SQL1。完成相關檔案複製後,接下來又要執行語法,主要是把兩台的憑證給對方,並且存入對方的 SQL Server 內,所以這裡我們先執行 SQL1 上所要執行的語法

-- 匯入 SQL2 憑證
CREATE CERTIFICATE SQL2Cert
FROM FILE = 'C:\Tools\SQL2Cert.cer'
WITH PRIVATE KEY
(
    FILE = 'C:\Tools\SQL2PrivateKey.pvk',
    DECRYPTION BY PASSWORD = 'P@ssw0rd'
);

-- 在 SQL1 上建立端點,並使用憑證進行身份驗證
CREATE ENDPOINT [Hadr_endpoint]
    STATE = STARTED
    AS TCP (LISTENER_PORT = 5022)
    FOR DATABASE_MIRRORING (ROLE = ALL, AUTHENTICATION = CERTIFICATE SQL1Cert, ENCRYPTION = REQUIRED ALGORITHM AES);
GO

-- 在 SQL1 上建立一個對應 SQL2 的使用者,並授權其連接權限
CREATE LOGIN SQL2Login FROM CERTIFICATE SQL2Cert;
GO

GRANT CONNECT ON ENDPOINT::Hadr_endpoint TO SQL2Login;
GO

同樣的在 SQL2 也要執行類似的語法

-- 匯入 SQL1 憑證
CREATE CERTIFICATE SQL1Cert
FROM FILE = 'C:\Tools\SQL1Cert.cer'
WITH PRIVATE KEY
(
    FILE = 'C:\Tools\SQL1PrivateKey.pvk',
    DECRYPTION BY PASSWORD = 'P@ssw0rd'
);

-- 在 SQL2 上建立端點,並使用憑證進行身份驗證
CREATE ENDPOINT [Hadr_endpoint]
    STATE = STARTED
    AS TCP (LISTENER_PORT = 5022)
    FOR DATABASE_MIRRORING (ROLE = ALL, AUTHENTICATION = CERTIFICATE SQL2Cert, ENCRYPTION = REQUIRED ALGORITHM AES);
GO

-- 在 SQL2 上建立一個對應 SQL1 的使用者,並授權其連接權限
CREATE LOGIN SQL1Login FROM CERTIFICATE SQL1Cert;
GO

GRANT CONNECT ON ENDPOINT::Hadr_endpoint TO SQL1Login;
GO

進行可用性群組設定

這裡我就直接用可用性群組精靈來幫我建立可用性群組

這裡可以把 SQL1 和 SQL2 都加入到複本

再端點這裡就要注意幾個小細節

  1. SQL Server 所使用的 TCP 5022 port ,在之前 Windows 環境下,是否有開啟該防火牆的限制。
  2. SQL Server 的服務帳號是否有改變,不是使用服務帳號來做啟動。

然後到「接聽」的部分,要把之前我們在 DNS 或 Hosts 上所設定的名稱給指定上去

基本上相關設定只要之前步驟沒有遺漏,應該都會很正常的就建立起來可用性群組了

測試

當完成前面相關步驟,也建立好可用性群組,此時我們用 SSMS 來做查看,看起來建立都還蠻順利的

並且配合可用性群組的儀表板,也可以看到運作狀況都很 OK

後續

基本上基本設定透過上述步驟,都可以很容易完成,但是在我們的步驟中,因為目前叢集只有兩個節點,所以只能用標準仲裁,因此最好再多一個可存取的磁碟或者是 LUN,這樣就可以達到叢集仲裁見證的奇數表決了。另外在唯讀路由的部分,因為這一篇我只想做基本安裝設定的說明,如果有興趣的朋友可以參考 AlwaysON 的唯讀路由設定 ,這裡就不重覆寫了。

另外會寫這一篇主要是參考 建立網域獨立的可用性群組 這篇微軟官方文件的說明去實作的,有興趣了解相關細節的朋友可以參考該篇文章。