SQL Server Always On AG(WSFC)配置指南(2) - 创建和配置gMSA账号
分类: SQL Server ◆ 标签: #SQL Server #SQL Server Always on AG ◆ 发布于: 2026-03-16 18:02:39
开始本章之前请检查下述清单:
- 安装了
Windows Server - 已经配置了网络,禁止了
IPV6 - 创建了域控和
DNS - 将所有的节点都已经加入了域
- 安装了
SQL Server - 安装了故障转移集群
如果有遗漏,请补上,减少后期出错的可能性。
本章我们开始为运行SQL Server Always on AG准备运行账号,默认安装是使用本地的账号进行的,在配置多节点的集群上不推荐,容易遇到各种问题。
微软官方推荐两个方案来配置运行账号:
gMSA(Group Managed Service Account)- 专用的域账号
本章讨论gMSA
如下是基本步骤:
- 配置
kdc root Key - 创建安全组
- 添加所有
SQL节点到安全组 - 创建
gMSA账号 - 给
gMSA分配read ServicePrincipal和write servicePrincipal的权限 - 在各个
SQL节点上安装gMSA账号 - 在各个
SQL节点上为gMSA配置本地权限 - 在各个
SQL节点上为gMSA配置文件权限 - 在各个
SQL节点上为gMSA在数据库里创建login并赋予sysadmin角色 - 在各个
SQL节点上为gMSA在数据库里创建AG Endpoint的权限。 - 使用
SQL Server Configuration Manager为SQL Server和SQL Server Agent配置运行账户为gMSA - 观察
gMSA是否自动注册了SPN
以域管理员的身份登陆到域控(一定是域控), 以管理员的身份启动终端。
配置kdc root key (在域控上)
在终端里运行:
Test-KdsRootKey -KeyId (Get-KdsRootKey).KeyId
如果没有任何返回,那么我们需要创建kdc root key, 如果您的系统是一个多节点的系统,尝试使用如下的命令:
Add-KdsRootKey -EffectiveImmediately
需要注意的是:
- 多节点系统需要等待一会儿,创建完成之后可以使用
test-kdsrootkey多次测试结果。 - 如果是测试环境或者单
dc环境,请使用如下的命令创建kdc root key
Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10))
无论是哪种方法创建kdc root key都可以使用test-kdsrootkey -keyid (get-kdsrootkey).keyid来验证。
创建安全组和gMSA账户(在域控上)
运行下述命令创建安全组:
New-ADGroup -Name "grp-gmsa-sql-ag" -GroupScope Global -GroupCategory Security
安全组创建成功后,需要将所有的SQL Server节点机器加入到该安全组, 例如你的SQL Server节点的机器名字分别叫:dbserver1, dbserver2,
注意
这里的前置要求是域控已经配置完毕,SQL Server节点也已经加入到域了
Add-ADGroupMember grp-gmsa-sql-ag dbserver1$
Add-ADGroupMember grp-gmsa-sql-ag dbserver2$
注意机器名称后面要多加一个$
创建账号:
New-ADServiceAccount -Name "gmsa-sql-ag" -SamAccountName "gmsa-sql-ag" -DNSHostName "gmsa-sql-ag.yourdomain.com" -PrincipalsAllowedToRetrieveManagedPassword "grp-gmsa-sql-ag"
这里DNSHostName 主要用于kerberos/SPN。PrincipalsAllowedToRetrieveManagedPassword用于绑定服务器组
注意:
如果创建账号遇到错误:
New-ADServiceAccount : Key does not exist
At line:1 char:1
+ New-ADServiceAccount -Name "gmsa-sql-ag" -SamAccountName "gmsa-sql-ag ...
请重新创建kdc root key,使用下述语句缓解问题:Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10))
这类问题的troubleshooting的步骤:
为什么之前明明已经创建了kdc root key但是还是不起作用?可能的原因:
在非域控机器上运行的该命令
kds root key刚创建,还没有生效,微软官方文档给出的理由:- AD 需要复制 & 初始化
- 在部分环境(尤其多 DC):可能需要等待一段时间
否则 gMSA 创建会报 Key does not exist
验证是否真的“可用”:Get-KdsRootKey, 看到了KeyId才算真正存在在单域或者试验的环境中或者刚刚搭建的环境中,更稳妥的创建
kds root key的方式是:Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10)), 尤其是hyper-v环境中,微软最推荐的方式。你的用户账户不是Schema/Domain Admin
百分百能创建成功的步骤:
hostname确认是登陆的域控Get-KdsRootKey确认kdc root key的状态- 如果返回空,重新创建
kds root key:Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10)) - 再次创建
gMSA账号
在每台SQL节点上安装账号
分别在每台SQL节点上(可以考虑使用Powershell远程终端), 运行如下的命令:
Install-WindowsFeature RSAT-AD-PowerShell
Install-ADServiceAccount -Identity gmsa-sql-ag
Test-ADServiceAccount -Identity gmsa-sql-ag
如果在运行install命令出错,例如返回如下错误:
Install-ADServiceAccount : Cannot install service account. Error Message: '{Access Denied}
A process has requested access to an object, but has not been granted those access rights.'.
请使用如下的步骤缓解:
先确保命令是在“管理员 PowerShell”运行
确认:SQL 节点计算机账号确实在允许组里(域控上运行):
Get-ADGroupMember "grp-gmsa-sql-ag" | Select-Object Name, ObjectClass, 机器名是否在返回结果中, 如果不在,加进去:Add-ADGroupMember -Identity "grp-gmsa-sql-ag" -Members SQLNODE1$,SQLNODE2$,SQLNODE3$确认:gMSA 对象确实绑定了这个允许组(域控上运行):
Get-ADServiceAccount gmsa-sql-ag -Properties PrincipalsAllowedToRetrieveManagedPassword |Select-Object -ExpandProperty PrincipalsAllowedToRetrieveManagedPassword,
如果确实没有,重新设置:Set-ADServiceAccount -Identity gmsa-sql-ag -PrincipalsAllowedToRetrieveManagedPassword "grp-gmsa-sql-ag"最常见“已加组但仍 Access Denied”的修复:
刷新这台 SQL 节点的机器票据:klist purge -li 0x3e7 gpupdate /force /target:computer
再返回执行之前的账号安装命令
给gMSN赋予Read servicePrincipal和Write servicePrincipal的权限(在域控上运行)
这个部分我称之为微软最腹黑的地方,GUI操作非常反人类,直接使用PowerShell来完成,请确保在域控上,并打开了Powershell的管理员模式:
在域控上获取 gMSA DN:
$gmsa = Get-ADServiceAccount gmsa-sql-ag $gmsa.DistinguishedName样例输出:
CN=gmsa-sql-ag,OU=ServiceAccounts,DC=hong,DC=cn授予 SELF → Write servicePrincipalName
dsacls "CN=gmsa-sql-ag,OU=ServiceAccounts,DC=hong,DC=cn" /G "SELF:RPWP;servicePrincipalName"
另外一个方案,如果是大规模的SQL Server Alaways on AG 或者是IIS集群:
在 OU 上一次性委派, 如果你把 所有 gMSA 都放在一个 OU(强烈推荐):
步骤:
对 OU 执行 Delegate Control
委派对象:SELF
对象类型:Group Managed Service Account
权限:Write servicePrincipalName
- 新建的 gMSA 自动具备 SPN 自注册能力
- 大规模 SQL / AG / IIS 场景必备
这样只要gMSA加入到这个组,就自动有spn自注册能力。
在每个SQL节点上给gMSA配置login as service
启动本地策略编辑器 secpol.msc, 按照下图添加gMSA, 注意它的账号格式: HONG\gmsa-sql-ag$, 这个账号后面必须要额外添加一个$

在每个SQL节点上给gMSA分配文件权限
icacls "C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA" /grant 'HONG\gmsa-sql-ag$:(OI)(CI)F'
icacls “C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\Backup" /grant 'HONG\gmsa-sql-ag$:(OI)(CI)F'
需要注意的是,上述的目录路径是SQL Server的默认安装路径,C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA 将数据文件和日志文件放在了一起,如果你安装SQL Server的时候,将数据文件目录,日志目录,备份目录分开了放,上述路径根据需要更改。
命令解析:
'HONG\gmsa-sql-ag$:(OI)(CI)F'
- HONG\gmsa-sql-ag$ —— 权限主体(Security Principal)
- HONG\:域名
- gmsa-sql-ag:gMSA账号。gMSA在域里是一个“托管服务账号”,命名上通常以 结尾(就像计算机账号 SQLNODE1$ 一样)。
也就是说:你在给 这个 gMSA 服务账号授权,让 SQL Server 服务运行时能访问目录。
:(OI)(CI)F —— 继承范围 + 权限级别
冒号 ::分隔“主体”和“权限/继承标志”
(OI) Object Inherit(对象继承)
表示:子文件会继承这条权限。(CI) Container Inherit(容器继承)
表示:子文件夹会继承这条权限。
组合起来 (OI)(CI) 的效果是:该目录下现有 & 将来新建的文件/子目录,都会继承这条权限。F Full Control(完全控制)F表示Full access(完全控制)。在icacls的“简单权限”里,F/M/RX/R/W是常见的简写,其中F权限最高
在SQL Server里添加gMSA作为Login, 并赋予权限(每个SQL节点上)
使用工具,例如SSMS登陆到SQL Server, 运行下述命令:
CREATE LOGIN [HONG\gmsa-sql-ag$] FROM WINDOWS;
ALTER SERVER ROLE sysadmin ADD MEMBER [HONG\gmsa-sql-ag$];
赋予AG Endpoint权限
GRANT CONNECT ON ENDPOINT::[Hadr_endpoint]
TO [HONG\gmsa-sql-ag$];
将SQL Server和SQL Server Agent的运行账号更改为gMSA
如下图配置:

配置完成后需要重启SQL Server
明天继续介绍另外一个方案,使用专用的域账号来配置