SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

SQL Server on Azure VM の AlwaysOn 可用性グループで DNN がサポートされました

without comments

DNN については、以前、Lift and Shift Always On SQL Server Failover Cluster Instance (SQL FCI) to Azure VMs で、SQL Server 2019 CU2 を適用することで、Failover Cluster Instance のサポートが行われていました。

今回、Released: Support for Dynamic Network Names (DNN) Listeners for Always On Availability Groups でアナウンスがあり、SQL Server 2019 CU8 を適用することで、SQL Server on Azure VM で AlwaysOn 可用性グループを構築する際に、可用性グループのリスナーで DNN (Dynamic Network Names) Listeners がサポートされるようになりました。

これにより、AlwaysOn 可用性グループにアクセスする際にロードバランサーを使用することなくアクセスができるようになります。
関連情報は次のドキュメントとなります。(投稿を書いている時点では、英語版にのみ情報が公開されています)

VNN リスナーと DNN リスナー

SQL Server 2019 CU8 以降では、VNN リスナーDNN リスナーの 2 種類がサポートされるようになります。

VNN (Virtual Network Name) リスナー

VNN リスナーは従来型のものとなり、Azure のロードバランサーを使用することで構成します。

可用性グループのリスナーに Azure のロードバランサーと同一の IP アドレスを設定し、Probe ポート (一般的には TCP : 59999) による死活監視で接続するノードを切り替える方式となります。

この方法は、従来からの構成として使用できるものであり、SQL Server のバージョンを選ばずに使用することができます。

SQL Server 2019 CU8 を適用しても従来と同じように次のようなクエリでリスナーを作成した場合には、VNN リスナーが作成されます。

ALTER AVAILABILITY GROUP [AG01]
ADD LISTENER N'SQLVM-LN' (
WITH IP((N'10.1.1.11', N'255.255.255.0'))
, PORT=1433)


VNN リスナーと DNN リスナーは共存することができるため、どちらの方法でも接続できるようにすることはできます。

DNN (Dynamic Network Names / Distributed Network Name) リスナー

DNN リスナーが SQL Server 2019 CU8 から提供された新しいリスナーとなります。

この方式を使用した場合、Azure のロードバランサーを使用することなく、DNS の名前解決を使用して、可用性グループのプライマリーサーバーに接続を行うことができるようになります。

DNN リスナーは、SQL Server のすべての機能はサポートしていません。

サポートされる機能については、Feature interoperability with AG and DNN listener に記載されています。

可用性については、「分散型可用性グループ」は現状サポートしていませんので、複数の可用性グループ間を接続する必要がある場合は、従来型の VNN リスナーを使用する必要があります。(分散型可用性グループを作成する場合は、VNN リスナーと DNN リスナーを共存させることも考えられるかと)

DNN リスナーを作成する場合は、PowerShell で作成を行います。

$Ag = "AG01"
$Dns = "SQLVM-LN"
$Port = "1433"

Write-Host "Add a DNN listener for availability group $Ag with DNS name $Dns and port $Port"

$ErrorActionPreference = "Stop"

# create the DNN resource with the port as the resource name
Add-ClusterResource -Name $Port -ResourceType "Distributed Network Name" -Group $Ag 

# set the DNS name of the DNN resource
Get-ClusterResource -Name $Port | Set-ClusterParameter -Name DnsName -Value $Dns 

# start the DNN resource
Start-ClusterResource -Name $Port


$Dep = Get-ClusterResourceDependency -Resource $Ag
if ( $Dep.DependencyExpression -match '\s*\((.*)\)\s*' )
{
$DepStr = "$($Matches.1) or [$Port]"
}
else
{
$DepStr = "[$Port]"
}

Write-Host "$DepStr"

# add the Dependency from availability group resource to the DNN resource
Set-ClusterResourceDependency -Resource $Ag -Dependency "$DepStr"


#bounce the AG resource
Stop-ClusterResource -Name $Ag
Start-ClusterResource -Name $Ag

 

DNN リスナーの基本的な仕組み

DNN リスナーは「DNS による名前解決」を使用して、可用性グループリスナーへの接続を行います。

VNN リスナーの場合、DNS には、「VNN リスナーの仮想 IP アドレス = Azure ロードバランサーの IP アドレス」が登録されます。

image

DNN リスナーの場合は、次のようなレコードが登録されます。

image

VNN リスナーの場合は、可用性グループリスナーの仮想 IP アドレスが、リスナーの A レコードとして登録されていました。

DNN リスナーの場合は、可用性グループの各ノードの IP アドレスが、リスナーの A レコードとして登録が行われます。

VNN リスナーと DNN リスナーでは作成されるクラスターのリソースが異なっているようですね。

VNN リスナーの場合は、Client Access Point として作成が行われています。

image

DNN リスナーの場合は Distributed Network Name として作成が行われています。

image

これらのリソースの違いが DNS の登録にも影響してきているのでしょうか。

DNN リスナーの場合は、リスナー名の A レコードとして、各ノードの IP アドレスが登録されます。

これにより、リスナーの名前解決が各ノードとなり、プライマリとして起動しているサーバーに接続が行われます。

接続の確認として、次のようなスクリプトを同一の DNS を参照している環境から実行してみます。

今回は、MultiSubnetFailover を接続文字列として使用しています。

$con = New-Object System.Data.SqlClient.SqlConnection("Server=SQLVM-LN.alwayson.local;Integrated Security=SSPI;Database=AGDB01;MultiSubnetFailover=True;Connection Timeout=5")
while($true){
    try{
        $con.Open()
        $cmd = $con.CreateCommand()
        $cmd.CommandText = "SELECT @@SERVERNAME AS servername"
        $reader = $cmd.ExecuteReader()
        [void]$reader.Read()

         Write-Host ("{0} : {1}" -f (Get-Date), $reader["servername"]) 
        $reader.Close()
        $con.Close()
    }catch{
        Write-Host ("{0} : {1}" -f (Get-Date), "Error") -ForegroundColor Red
    }finally{
        Start-Sleep -Seconds 1
    }
}

 

次の画像は、上記のスクリプトを実行している状態でフェールオーバーを実施したものとなります。

image

DNN リスナーに接続をしているのですが、フェールオーバーを実施したことで、接続先のサーバーが変わっていることが確認できますね。

DNN リスナーを使用することで、このようにロードバランサーを使用しないで可用性グループのリスナーに接続することができるようになります。

Azure プライベート DNS の利用

上述の検証は、Windows Server の DNS を動的登録を可能にした環境で構築をしていました。

今の SQL Server は、ドメインに依存しない可用性グループ を構築することができ、ワークグループ環境で自動フェールオーバーが可能な AlwaysOn 可用性グループを作成することができるようになっています。

今回の検証でもワークグループクラスターで可用性グループを作成しています。

Azure 上でワークグループクラスターの可用性グループを構築しようとするとベースの WSFC を構築する際にいくつかエラーが発生する可能性があります。

これについては、こちら で構築用のスクリプトを公開していますので、このスクリプトを参考にしてみてください。

DNN リスナーは DNS の名前解決をベースとしたリスナーへの接続となります。

ワークグループクラスターで AlwaysOn 可用性グループを作成した場合、AD DS が不要となりますので、AD DS 用途の VM を構築する必要はありません。

DNS のための VM を構築するのもアレなので、Azure プライベート DNS を使用することができるかも確認してみました。

確認の結果としては、Azure プライベート DNS でも対応できそうです。

Azure プライベート DNS では、DNS ゾーンを仮想ネットワークにリンクする際に、「自動登録を有効にする」という設定があります。

image

この設定は「VNET に接続している環境の IP アドレスを自動的に登録する」機能となるのですが、DNS の動的登録 (動的更新) の機能は含んでいないため、DNN リスナーにより作成される A レコードを自動的に登録するということはできないようです。

ということで、手動で A レコードを登録します。

image

この設定でテスト用スクリプトを実行した場合、動的登録が可能な DNS と同様の挙動となっていましたので、動的登録ができない DNS の場合は、手動で A レコードを登録しておけばよさそうです。

image

 

 

DNN リスナーは、DNS の名前解決を使用したリスナーとなります。

DNS の設定が柔軟にできない環境から接続が必要な場合には、従来の VNN リスナーを使用して、可用性グループのプライマリにロードバランサー経由で接続する方法を検討する必要があるかと。

最新の SQL Server を使用する必要がありますが、可用性グループの構成の柔軟性が向上したのはうれしいですね。

Written by Masayuki.Ozawa

10月 20th, 2020 at 9:34 pm

Leave a Reply