故障转移群集和AD域之间的交互

发布时间 2023-08-07 09:53:53作者: 十亩菠萝地

1 故障转移群集和域控简介

AD全文为Active Directory,在微软中常见到AD域服务(AD DS)和AD域控两种名词,安装了AD域角色之后,并在此服务器上创建了林和域(一个林内可以有多个域),该服务器即成为域控。 域控中存储了一系列对象,包括:用户、组、计算机、域、组织单位和安全策略。这些对象可以被网络应用程序或者服务使用,当一个域中有多个域控制器时,那每个域控制器都有它所在的整个域的目录副本,对某个域控制器上的目录所作的更改,都将复制到其它域控制器上。
image

SQL Server FCI意为SQL Server 故障转移群集实例,在Windows故障转移群集的基础上使SQL Server实例成为一个群集角色。 故障转移群集是Windows Server操作系统的高可用特性,群集技术将多台服务器(节点)形成一组独立的计算机,将原本仅在单台服务器上运行的应用程序或服务提升为群集角色,在群集角色的作用下,使该应用程序或服务其具备高可用性。如果其中一个节点出现故障,群集会在其它可用节点上启动该群集角色,群集也会主动监视群集角色是否正常运行,如果不正常,则重启或转移角色到其它可用节点。

故障转移群集必不可少的是共享存储,所有的应用程序或服务的数据必须存储在共享存储中,才能形成群集角色,比如SQL Server数据库、Hyper-V虚拟机等。共享存储可以是以主备的方式挂载,或者是以CSV群集共享卷的方式挂载,CSV群集共享卷可以在不同的主机上提供一致的分布式命名空间,从所有的节点访问共享存储,将故障终端降到最低,从SQL Server 2014及以上的版本支持使用CSV。

在创建SQL Server FCI时,必须满足AD域中的以下先决条件:

  • 所有节点都在同一个AD域中。
  • 创建群集的账户要满足以下特征:
    • 必须是域账户。
    • 该域账户对群集节点的服务器要有管理权限,可以将该域用户帐户添加到每个服务器上的本地Administrators组。
    • 该账户必须在CNO所属的容器具有“创建计算机对象”和“读取所有属性”的权限。
    • 对容器中的CNO所属的容器具有“重置密码”权限。

2 群集与域控上的CNO、VCO和SPN

服务器加入域后会自动在AD DS中创建一个与主机名相同的计算机对象。当服务器在创建故障转移群集时也会在域控中创建相应的计算机对象,这个对象称为“群集名称对象”(CNO,Cluster Name Object)或“群集名称账户”。然后当我们在群集中创建一个具备客户端访问点的群集角色时,会自动创建一个“虚拟计算机对象”(VCO,Virtual Computer Object)或“计算机对象”。不管是CNO还是VCO,在域控中均会有一个“服务主体名称“(SPN,Service Principal Name )用于标识域控中运行的应用程序,计算机对象访问域控中的SPN时,将其票据发送给域控的Kerberos进行身份验证协议,验证成功后,才具备权限来访问域控里的SPN,启动群集里面对应的应用程序。
image

  1. 这些是在服务器上创建群集后,在域控里面创建的CNO和VCO,默认的Computers容器里,并且也会为它们创建DNS条目。image

  2. 域控为计算机对象创建的DNS条目,用于名称解析image

  3. 域控内计算机对象对应的SPN

     C:\Users\Administrator>SETSPN -L SQL2008
     Registered ServicePrincipalNames 用于 CN=SQL2008,CN=Computers,DC=test,DC=com:
             MSServerClusterMgmtAPI/SQL2008.test.com
             MSServerClusterMgmtAPI/SQL2008
             MSClusterVirtualServer/SQL2008.test.com
             MSClusterVirtualServer/SQL2008
             HOST/SQL2008.test.com
             HOST/SQL2008
     
     C:\Users\Administrator>SETSPN -L WSFC2008
     Registered ServicePrincipalNames 用于 CN=WSFC2008,CN=Computers,DC=test,DC=com:
             MSServerCluster/WSFC2008.test.com
             MSServerCluster/WSFC2008
             MSServerClusterMgmtAPI/WSFC2008.test.com
             MSServerClusterMgmtAPI/WSFC2008
             MSClusterVirtualServer/WSFC2008.test.com
             MSClusterVirtualServer/WSFC2008
             HOST/WSFC2008.test.com
             HOST/WSFC2008
    

3 群集启动服务会连接域控

从上文我们了解到计算机加入域和计算机创建群集后会在域控里创建计算机对象,然后为群集中的CNO和VCO生成SPN,并且在群集的计算机对象与域控的交互过程中使用了Kerberos作为身份验证协议。群集中的服务启动过程中与域控有大量的交互:

  1. 群集节点请求启动群集服务cluster service
  2. 群集服务发起登录请求操作:CNO登录到域控
  3. CNO向域控发送登录请求(Kerberos AS-REQ)
  4. 域控验证CNO的登录凭据,返回TGT和会话密钥给CNO(Kerberos AS-REP)
  5. CNO登录成功,获得操作权限,启动群集服务cluster service
  6. 群集服务发起登录请求操作:VCO登录到域控
  7. VCO将CNO的的TGT作为凭据向域控发送登录请求(Kerberos TGS-REQ)
  8. 域控验证VCO的登录凭据,返回会话票据和会话密钥(Kerberos TGS-REP)
  9. VCO登录成功,启动VCO对应的群集角色
  10. VCO返回给启动结果给群集服务
    流程图地址)
    image

4 群集定期向域控修改CNO和VCO的凭据

在Windows Server 2008以上的版本中,为了保证群集间通信的安全,故障转移群集会根据域策略的pwdLastSet参数值的75%来定期修改CNO和VCO的凭据(密码),例如默认设置是30天,那群集会在第23天的时候修改CNO和VCO的密码,例如这是从群集日志中看到群集检测到CNO和VCO的密码超过了22天,将尝试在域控中修改密码。

2022/09/30-11:35:49.577 INFO  [RES] Network Name <群集名称>: NetName's password Last changed at 2022/09/08-10:16:10 and age is more than the maximum age 22 days (1900800 seconds). Trying to change the password for computer object in the DC
2022/10/23-11:35:34.760 INFO  [RES] Network Name <群集名称>: NetName's password Last changed at 2022/09/30-11:35:50 and age is more than the maximum age 22 days (1900800 seconds). Trying to change the password for computer object in the DC
2023/05/04-16:27:02.757 INFO  [RES] Network Name <群集名称>: NetName's password Last changed at 2023/03/31-14:45:53 and age is more than the maximum age 22 days (1900800 seconds). Trying to change the password for computer object in the DC
2023/05/04-20:50:33.768 INFO  [RES] Network Name <srvhisDtc>: NetName's password Last changed at 2023/04/03-13:10:29 and age is more than the maximum age 22 days (1900800 seconds). Trying to change the password for computer object in the DC
2023/05/04-20:55:31.420 INFO  [RES] Network Name <srvhisdb>: NetName's password Last changed at 2023/03/30-14:06:46 and age is more than the maximum age 22 days (1900800 seconds). Trying to change the password for computer object in the DC

在一些特殊场景中,比如多域控的情况下,承载FSOM角色的域控故障了,但此时刚好密码期限达到了22天,而群集在第23天向域控发起更改CNO和VCO密码的请求,但是其余存活的域控无法响应更改密码的请求,在达到第30天之后,如果承载FSOM角色的域控仍然没有恢复正常,那群集会自动将请求切换到其它可用的域控,但这时候由于没有FSOM角色响应CNO和VCO的密码修改请求,非常容易导致群集资源出现死锁。

2023/05/04-15:21:06.892 INFO  [RES] Network Name <群集名称>: NetName's password Last changed at 2023/03/31-14:45:53 and age is more than the maximum age 22 days (1900800 seconds). Trying to change the password for computer object in 
2023/05/04-15:21:06.908 INFO  [RES] Network Name <群集名称>: About to try to change password (Version: 1 IsProposed: 1).
2023/05/04-15:21:06.955 INFO  [RES] Network Name <群集名称>: Got new Logon Session.
2023/05/04-15:21:06.955 INFO  [RES] Network Name <群集名称>: Trying to find computer account SRVHIS object GUID(c3a7b1fc0b9a454c8b7245bc6f5b6f01) on any available domain controller.
2023/05/04-15:21:06.970 INFO  [RES] Network Name <群集名称>: Found computer account SRVHIS on domain controller \\INDC02.xxxx.com.
2023/05/04-15:21:06.970 INFO  [RES] Network Name <群集名称>: Trying to obtain the VSToken for Core Cluster Name resource
2023/05/04-15:21:06.986 INFO  [RES] Network Name <群集名称>: GetCoreNetnameObject_VSToken returning status 0
2023/05/04-15:21:06.986 INFO  [RES] Network Name <群集名称>: Obtained the security token for cluster name account.
…………………………
2023/05/04-15:30:13.004 ERR   [RHS] RhsCall::DeadlockMonitor: Call LOOKSALIVE timed out for resource '群集名称'.
2023/05/04-15:30:13.004 INFO  [RHS] Enabling RHS termination watchdog with timeout 1200000 and recovery action 3.
2023/05/04-15:30:13.004 ERR   [RHS] Resource 群集名称 handling deadlock. Cleaning current operation and terminating RHS process.

如果想要避免禁止群集自动更新CNO和VCO的密码,可以在群集服务器上修改注册表策略的DisablePasswordChange值为1,但这毫无疑问存在一些安全风险,当然如果内网是绝对安全的,或者说说域控无人维护的情况下,可以考虑禁止群集自动更新CNO和VCO的密码,从而降低域控故障后导致群集资源发生死锁的概率。

5 文章总结

Windows 故障转移群集和域控之间的通讯和依赖是比较复杂的,除了在群集间会采用TCP和UDP3343、TCP135、UDP137和高位TCP的49152 和 65535 之间的随机端口号通讯外,群集还需要访问域控的DNS、LDAP、RPC、全局编录等端口,本文也是在故障和群集架构的基础上上来了解这些故障转移群集和域控之间的通信。总之在一般情况下,故障转移群集对域控的依赖是非常大。
但是,从Windows Server 2012以上的版本开始,可以仅使用域控的DNS解析来搭建故障转移群集,要求群集节点在加入域的情况下,创建故障转移群集时不会在域控中创建CNO和VCO,可以在这种群集上搭建SQL Server FCI和AlwaysOn高可用性保护组,降低对域控的依赖;而在Windows Server 2016以上的版本中,能够创建基于工作组的故障转移群集,但仅支持搭建SQL Server AlwaysOn高可用性保护组,并不支持SQL Server FCI。相信在未来的版本中,SQ Server FCI能够完全脱离域控,在基于工作组的故障转移群集中实现高可用,完全脱离对域控的依赖。

6 参考

禁用计算机帐户密码更改 - Windows Server | Microsoft Learn

Identifying Stale Cluster Computer Objects - Microsoft Community Hub