文章目录
一种通过物理分离实现WSUS伸缩性的方案
作者在《哎,这是个 Windows 的bug》中复现了 Windows 21H2 版本中的下载服务存在bug。当时构造了一种验证场景:利用CDN缓解更新服务端流量压力。当时没有细说,这里把服务端的部署方案做一个描述,即如何实现WSUS伸缩性的方案。
背景
Windows 系列操作系统在 Windows 7 之后就开始使用一种全新的更新升级系统,用于给操作系统"打补丁"、“修漏洞"以及"更新功能”。个人用户无需关心"更新"的问题,联网的计算机会自动连接到微软的更新服务器获取更新。还有一类用户是企业组织用户,这些用户的计算机需要被管理:哪些更新需要安装、什么时候安装。所以微软推出了服务于企业组织的更新服务,Windows Server Update Services (WSUS)就是其中之一。
企业部署WSUS服务器之后,企业内部用户的计算机配置更新服务器地址为WSUS地址。管理员通过选择语言、产品、分类来对同步进行限制;通过审批、拒绝对更新包是否被应用进行设置。这样,企业内所有计算机的更新周期、频率就由企业自己来决定了。同时,企业部署 WSUS 能够很大程度上减小企业的流量消耗。
WSUS 工作基本原理
WSUS通过同步或导入的方式,将微软的 Windows 更新包作为更新数据来源为用户提供服务。客户计算机连接到WSUS服务器后,二者进行一系列报文交互,最终WSUS服务器会告知适用于该客户计算机的更新包描述信息,其中包括接下来需要下载的更新包文件url。客户计算机下载完成后,进行后续的安装过程。
WSUS 数据分类
WSUS 的数据源是 Windows 更新包,更新由两部分组成:描述更新的元数据(metadata),以及安装更新所需的文件。
metadata的主要功能是说明该更新包的适用条件以及安装该更新包后系统的状态。更新包适用条件包括:在什么平台上安装(如x64、x86、arm等),要求客户计算机的系统组件版本(如服务堆栈要大于某个版本、.net framework是某个版本等),某些配置满足要求(如注册表某键值存在、键值大小为多少等)和其他非常细致的检查条件。更新包安装后的检查条件包括:组件更新后的版本、新添加的文件、修改后的注册表键值等等。
安装更新所需的文件即更新的内容文件,主要包括一系列二进制文件、二进制文件片段和一些配置文件,这些文件是要被应用到用户计算机中的内容。
更新元数据的规模通常比更新内容文件要小很多:单个更新包的metadata数据从几十KB到几十MB,而更新内容文件最大超过1GB。
WSUS 存储数据分为两部分:一个是存储 WSUS 配置和更新元数据的数据库,另一个是存储更新文件的可选本地文件系统。 这里的"可选"是指通过配置可以指定更新文件存储在本地 WSUS 服务器上或 Microsoft 更新服务器上。
WSUS 数据存储特点
将更新同步到 WSUS 服务器时,元数据和更新文件存储在两个不同的位置。 元数据存储在 WSUS 数据库中。 更新文件可以存储在 WSUS 服务器上或 Microsoft 更新服务器上(具体取决于同步选项的配置方式)。 如果选择将更新文件存储在 WSUS 服务器上,则客户端计算机会从本地 WSUS 服务器下载批准的更新。 如果不选择这样做,客户端计算机将直接从 Microsoft 更新服务器下载批准的更新。
WSUS 基本部署方案1
WSUS 在为组织单位提供服务的时候,支持两种基本的部署方案:简单部署和层次部署。
简单 WSUS 部署
采用默认选项安装配置 WSUS 更新服务器,WSUS 直接连接到 Microsoft Update 进行同步更新,客户计算机配置WSUS为更新源。管理员审批 WSUS 上更新后就可以为客户计算机提供更新服务。
对于小规模组织单位,如果只有百八十台计算机客户端进行更新,选择简单 WSUS 部署就能够满足更新需求。
多台 WSUS 层次部署
WSUS 的一个重要功能特性是支持 WSUS 服务器之间进行更新和配置的同步,利用 WSUS 可以建立更新服务器的层次部署:当一台 WSUS(A) 从更新源获得更新后,它可以作为其他 WSUS(Others) 的更新源。A被称为上游 WSUS(upsteram WSUS),Others被称为下游 WSUS(downstream WSUS)。层次部署方式中,下游 WSUS 可以采用两种模式对更新进行管理:"自治"模式 和 "副本"模式。"自治"模式下,下游 WSUS 上的更新可以单独配置管理:单独审批、拒绝等;"副本"模式下,下游 WSUS 上的更新审批情况和上游 WSUS 服务器保持一致,无法单独操作。
大型企业需要管理的计算机客户端非常多,大多数用户计算机只要能够按时安装更新就可以了,但个别部门对于更新安装的要求很高:关键部门如财务审计部门要求计算机功能稳定,保证更新安装不会影响到财务系统的运行;IT服务支持部门要求尽快安装最新安全补丁… 对于不同部门的更新需求,管理员需要采用不同的测试、审批策略,采用层次化的 WSUS 更新系统提供更新服务可以解决这些问题。
官方建议 WSUS 的层级不超过3层。层级太多会使 WSUS 之间同步会出现很大的延迟,无法及时为计算机客户端提供服务,同时组织单位的管理维护成本较高。
隔离网环境
对于隔离网用户,所有用户计算机(包括WSUS更新服务器)不能够连接到外部网络。针对这种场景,一种方案就是配置一台能够连接到 Windows 更新服务器的 WSUS A,在更新包同步下来后,将 WSUS A 中更新包的metadata和更新内容文件导出。然后将这些导出内容导入到隔离网环境中的 WSUS B。通过 WSUS B为所有隔离网用户计算机提供更新服务。
WSUS 伸缩性方案
增强 WSUS 伸缩性主要解决 WSUS 为大量用户提供服务的能力,层次性部署方案在一定程度上实现了伸缩性,它扩大了单台 WSUS 的服务能力,尤其是它的部署能够适应树状组织结构,同时保证了各个节点可以相对独立的管理更新包的分发、安装。
但层次性部署方案存在一定限制。
基本部署方案的限制
层次性部署的限制:
- 官方建议 WSUS 层次不超过3层,否则 WSUS 间的同步延迟会造成更新无法及时下发到客户计算机
- 层次部署多台WSUS会带来管理维护成本增加
- 对于计算机上报状态带来挑战,不易汇总所有计算机状态
解决这个问题的一种方案是大部分普通用户计算机连接到同一台公共 WSUS 服务器,为有特殊要求的用户计算机进行层次部署 WSUS,通过伸缩性方案增强单台公共 WSUS 服务普通用户的能力。
接下来需要解决的问题:如何增强单台 WSUS 服务能力?
物理分离实现伸缩
默认情况下,WSUS 将 metadata 交互和更新内容分发功能集中到一身,在不改变软硬件设计的情况下,无法仅仅通过改变部署服务器数量来扩大或缩小 WSUS 的服务处理能力。所以首先需要从现有服务器中分离出部分功能和服务, 再去考虑集群的问题。
前面讲到 WSUS 数据存储特点:元数据和更新文件存储在两个不同的位置。 元数据存储在 WSUS 数据库中,更新文件可以存储在 WSUS 服务器上或 Microsoft 更新服务器上(具体取决于同步选项的配置方式)。同时,两种数据在WSUS提供服务过程中也是阶段性使用的。接下来需要将更新文件的下载功能与metadata数据同步功能分开支持,二者分别部署到不同的服务器。
网络拓扑
以下是一种demo验证。搭建如图所示的环境。
-
update server上启用 WSUS 服务,在 WSUS 管理界面的"选项"条目中,设置其更新文件"将更新文件本地存储在此服务器上"。这一步设置非常重要,它决定了用户计算机客户端拿到的更新文件的下载地址为当前服务器,而不是从Microsoft下载。
-
content server上开启http web server,将update server上
C:\Program Files\Update Services\WsusContent
目录下的内容拷贝到当前content server根目录 -
配置 nginx 反向代理,对于正常访问更新服务metadata信息的包,将其转发给update server;对于请求更新内容文件的包,返回302,将其重定向到content server。
数据请求过程
如图中红线所示,在Windows客户端拿到302的响应报文后,其中包含更新包所在的url。该url指向content server,至此,更新包内容文件的下载功能已经从原始的 WSUS 服务器分离开来。
进一步拓展
功能分离后,才能更好的利用集群实现伸缩性。在将 WSUS 的功能进行了物理分离后,下一步就可以考虑利用集群进一步实现整个更新服务的伸缩性。
接下来有两个方向:
引入 CDN
CDN是非常成熟的方案了,不再仔细描述。
但这里面的一个问题是 Windows 更新包单个内容文件都比较大,这可能会对文件缓存机制的应用带来挑战。
引入 应用服务器集群
参考 Network load balancing clusters 上的思路,可以部署多台 WSUS 服务器,这些 WSUS 服务器共用同一台数据库。通过这种方案的配置,WSUS 本身不再是服务能力的瓶颈,而是将性能瓶颈转移到了数据库服务器。
当然,数据库服务器也可以通过集群的方案来实现伸缩性,这个我就没有研究过了,大家有兴趣可以进一步探索。
思考
在做软件开发的时候,我们可能会把很多的精力放在软件的扩展性设计,比如遵守各种设计模式,面向接口编程,遵守开放封闭原则等等,尽量保证在有新的功能加入的时候,对现有软件架构不进行修改就能够扩展功能。相比而言,对于软件在系统伸缩性方面的考虑,我们思考的要少很多。
根据前面的理解,能够将不同的功能分离部署,是软件实现伸缩性的重要一步,这个可能是我们在设计开发软件的时候也要考虑的内容。
关于"设计开发应用如何兼顾伸缩性"的话题,期待更多的交流!