CentOS 7停服后,很多团队把跳板机或Ansible控制节点迁移到了Rocky Linux或Ubuntu上。迁移本身不复杂,但真正的麻烦在于,原本通过PowerShell远程管理的Windows补丁流程,现在需要无缝接入新的Ansible环境。直接解决问题的方法就是:在Linux控制节点上配置Kerberos认证,通过WinRM协议打通Ansible与Windows Server的连接,然后编写Playbook实现补丁扫描、下载、安装和重启的全自动化编排。
环境现状与认证准备迁移后的控制节点通常是Rocky Linux 8/9或Ubuntu 22.04/24.04。Windows服务器端需要启用WinRM服务,并且配置为支持CredSSP或Kerberos认证。如果你的环境有Active Directory域,强烈建议使用Kerberos,因为这种认证方式支持双跳,在补丁安装过程中如果需要从文件服务器获取更新包,不会出现权限问题。
先在Windows服务器上确认WinRM状态。在PowerShell中执行以下命令快速配置:
Enable-PSRemoting -Force Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*" -Force Set-Item WSMan:\localhost\Service\Auth\Basic -Value $true Set-Item WSMan:\localhost\Service\Auth\CredSSP -Value $true
生产环境不建议使用Basic认证,这里只是为了快速验证。实际部署时,应当配置HTTPS监听器,并使用AD域账号进行Kerberos认证。
Linux控制节点的Kerberos配置在Rocky Linux上安装必要的包:
dnf install -y python3 python3-pip krb5-workstation krb5-devel pip3 install pywinrm[kerberos] pip3 install ansible
配置/etc/krb5.conf文件,指向你的域控制器:
[libdefaults]
default_realm = YOURDOMAIN.COM
dns_lookup_realm = true
dns_lookup_kdc = true
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
[realms]
YOURDOMAIN.COM = {
kdc = dc01.yourdomain.com
admin_server = dc01.yourdomain.com
}
[domain_realm]
.yourdomain.com = YOURDOMAIN.COM
yourdomain.com = YOURDOMAIN.COM
验证Kerberos是否正常工作,使用kinit获取票据:
kinit administrator@YOURDOMAIN.COM klist
看到票据信息就说明认证通道已经建立。这一步是整个方案的基础,很多人在迁移后遇到“401 Unauthorized”错误,根本原因就是Kerberos配置不完整,或者时间不同步导致票据验证失败。务必确保所有服务器的时间差不超过5分钟,建议统一使用NTP服务。
Ansible Inventory与WinRM连接配置在Ansible的hosts文件中定义Windows服务器组:
[windows_servers] win-srv-01 ansible_host=192.168.1.101 win-srv-02 ansible_host=192.168.1.102 [windows_servers:vars] ansible_user = administrator@YOURDOMAIN.COM ansible_connection = winrm ansible_winrm_transport = kerberos ansible_winrm_server_cert_validation = ignore ansible_port = 5986 ansible_winrm_scheme = https
这里有一个关键点:ansible_winrm_transport设置为kerberos后,Ansible会使用之前kinit获取的票据进行认证,不再需要明文密码。如果控制节点重启或票据过期,需要重新执行kinit。可以通过crontab定时执行kinit -R来续期票据,或者使用keytab文件实现无人工干预的自动认证。
补丁管理Playbook设计思路Windows补丁管理不像Linux那样简单地yum update就能解决。需要考虑几个维度:补丁分类(安全更新、关键更新、功能更新)、安装时间窗口、重启策略、以及失败回滚机制。Ansible提供了win_updates模块,但这个模块在早期版本中存在超时和卡死的问题,目前Ansible 2.14以上版本已经比较稳定。
一个生产级别的补丁更新Playbook应该包含以下阶段:
- name: Windows补丁自动化管理
hosts: windows_servers
gather_facts: yes
strategy: free
serial: 1
tasks:
- name: 检查可用更新
ansible.windows.win_updates:
category_names:
- SecurityUpdates
- CriticalUpdates
state: searched
register: available_updates
- name: 显示可用更新数量
ansible.builtin.debug:
msg: "发现 {{ available_updates.updates | length }} 个可用更新"
- name: 下载并安装更新
ansible.windows.win_updates:
category_names:
- SecurityUpdates
- CriticalUpdates
state: installed
reboot: false
log_path: C:\ansible_wu_log.txt
register: update_result
when: available_updates.updates | length > 0
- name: 检查是否需要重启
ansible.windows.win_reboot:
reboot_timeout: 1800
post_reboot_delay: 120
when: update_result.reboot_required
使用serial: 1确保一次只操作一台服务器,避免批量重启导致服务中断。strategy: free让每台服务器独立执行任务,不会因为某台服务器卡住而阻塞整个流程。
处理补丁安装的常见坑win_updates模块底层调用Windows Update API,这个API本身就很慢,而且容易卡在下载阶段。如果服务器长时间没有更新,第一次扫描可能需要30分钟以上。解决方案是在任务上设置合理的超时时间,并且使用async异步执行:
- name: 异步安装更新
ansible.windows.win_updates:
category_names: "{{ update_categories }}"
state: installed
reboot: false
async: 7200
poll: 30
register: async_update
另一个常见问题是某些更新需要前置依赖,单独安装会失败。win_updates模块会自动处理依赖关系,但如果遇到反复失败的更新,建议先在测试环境手动排查,确认是否是微软已知问题。可以在Playbook中添加白名单或黑名单机制,跳过特定KB编号的更新:
- name: 安装更新但排除特定KB
ansible.windows.win_updates:
category_names:
- SecurityUpdates
reject_list:
- KB5009557
state: installed
补丁合规性报告与审计
运维团队需要知道哪些服务器安装了哪些补丁,哪些存在风险敞口。可以编写一个专门的扫描Playbook,定期生成补丁合规报告:
- name: 补丁合规性扫描
hosts: windows_servers
gather_facts: yes
tasks:
- name: 获取已安装更新列表
ansible.windows.win_shell: |
Get-HotFix | Select-Object HotFixID,InstalledOn,InstalledBy | ConvertTo-Json
register: installed_hotfixes
- name: 获取缺失的安全更新
ansible.windows.win_updates:
category_names:
- SecurityUpdates
- CriticalUpdates
state: searched
register: missing_updates
- name: 生成报告
ansible.builtin.copy:
content: |
服务器: {{ inventory_hostname }}
已安装补丁数: {{ (installed_hotfixes.stdout | from_json) | length }}
缺失安全更新数: {{ missing_updates.updates | length }}
缺失更新列表:
{% for update in missing_updates.updates %}
- {{ update.title }} ({{ update.kb | join(', ') }})
{% endfor %}
dest: /var/reports/{{ inventory_hostname }}_patch_report.txt
delegate_to: localhost
这份报告可以接入现有的监控系统或发送到企业微信、钉钉等通知渠道。关键是形成闭环:扫描、安装、验证、报告,四个环节缺一不可。
多台Windows服务器的分组策略生产环境中不可能一次性把所有服务器都更新,需要按照业务角色分组,分批次执行。可以在Inventory中定义不同的组和变量:
[web_servers] web-01 ansible_host=10.0.1.11 web-02 ansible_host=10.0.1.12 [db_servers] db-01 ansible_host=10.0.2.21 db-02 ansible_host=10.0.2.22 [all_windows:children] web_servers db_servers [web_servers:vars] maintenance_window = "03:00-05:00" reboot_allowed = true [db_servers:vars] maintenance_window = "01:00-03:00" reboot_allowed = false
结合Ansible的when条件判断,可以在Playbook中实现只在维护窗口内执行更新,或者对数据库服务器只下载不安装,等人工确认后再执行重启。这种灵活性是传统WSUS或SCCM难以快速实现的。
利用Ansible Roles组织代码当Playbook越来越复杂,建议使用Roles来组织代码结构。创建一个名为windows_patch_management的Role:
roles/windows_patch_management/
├── defaults
│ └── main.yml
├── tasks
│ ├── main.yml
│ ├── scan.yml
│ ├── install.yml
│ └── report.yml
├── handlers
│ └── main.yml
├── templates
│ └── report.j2
└── vars
└── main.yml
defaults/main.yml定义默认变量,比如更新类别、重启超时时间、日志路径等。vars/main.yml存放具体环境的值。tasks按功能拆分成scan、install、report三个文件,main.yml中通过include_tasks按需调用。这样结构清晰,新同事接手也能快速理解。
补丁回滚与异常处理不是每次更新都一帆风顺。Windows补丁偶尔会导致应用异常,这时候需要快速回滚。Ansible可以调用win_shell执行卸载命令:
- name: 卸载指定补丁
ansible.windows.win_shell: |
$patch = Get-HotFix -Id "{{ kb_number }}"
if ($patch) {
wusa /uninstall /kb:{{ kb_number }} /quiet /norestart
}
args:
executable: powershell.exe
register: uninstall_result
ignore_errors: yes
更稳妥的做法是在安装补丁前创建系统还原点,或者在虚拟化环境中提前打快照。Ansible可以调用VMware或Hyper-V的模块在更新前自动创建快照,更新验证通过后再删除。这套组合拳下来,补丁管理的风险就降到了最低。
持续优化与自动化调度把所有Playbook接入AWX或Ansible Tower,设置定时任务,比如每月第二个周三凌晨执行安全更新。利用AWX的Survey功能,让运维人员在执行前选择更新类别、目标服务器组、是否允许重启,既保证了标准化,又保留了灵活性。
监控方面,可以把补丁安装结果通过回调插件发送到Prometheus或ELK,建立仪表盘展示各服务器的补丁状态。当发现某台服务器连续多次更新失败,自动创建工单通知对应负责人。从CentOS迁移到新平台后,这套基于Ansible的Windows补丁管理体系不仅没有中断,反而因为统一了Linux和Windows的自动化工具,运维效率有了明显提升。
整个方案的核心在于:Kerberos认证是基础,WinRM是通道,win_updates模块是执行器,Roles是组织方式,AWX是调度中枢。把这五个环节理顺,Windows服务器的补丁管理就能真正实现无人值守。
