当今,在为 Linux 机器打补丁时,如果您问“这有多难?”,我可以原谅您。当然,一个 yum update -y 就可以快速为您解决问题。

但是对于我们这些处理多台机器的人来说,事情并没有那么简单。有时,一次更新可能会在多台机器上产生意想不到的后果,您会想知道如何将事情恢复到原来的样子。或者您可能会想,“我是否应该单独应用关键补丁,从而省去很多麻烦?”
过去面对这些挑战促使我构建了一种方法来精选所需的更新并自动化其应用。
灵活的想法
以下是流程概述

此系统不允许机器直接访问供应商补丁。相反,它们被有选择地订阅到存储库。存储库仅包含所需的补丁——尽管我建议您仔细考虑这一点,以免最终出现激增(您不会感谢自己创建的另一个管理开销)。
现在,为机器打补丁归结为 1) 它订阅的存储库和 2) 获得打补丁的“赞成”。通过使用变量来控制订阅和打补丁的权限,我们不需要篡改逻辑(剧本);我们只需要更改数据。
这是一个 Ansible 角色示例,它满足这两个要求。它管理存储库订阅,并有一个简单的变量来控制运行补丁命令。
---
# tasks file for patching
- name: Include OS version specific differences
include_vars: "{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml"
- name: Ensure Yum repositories are configured
template:
src: template.repo.j2
dest: "/etc/yum.repos.d/{{ item.label }}.repo"
owner: root
group: root
mode: 0644
when: patching_repos is defined
loop: "{{ patching_repos }}"
notify: patching-clean-metadata
- meta: flush_handlers
- name: Ensure OS shipped yum repo configs are absent
file:
path: "/etc/yum.repos.d/{{ patching_default_repo_def }}"
state: absent
# add flexibility of repos here
- name: Patch this host
shell: 'yum update -y'
args:
warn: false
when: patchme|bool
register: result
changed_when: "'No packages marked for update' not in result.stdout"
场景
在我们虚构的、大型的、全球分散的环境(由四台主机组成)中,我们有
- 两台 Web 服务器
- 两台数据库服务器
- 一个应用程序,包含每种服务器类型各一台
好的,所以机器的数量不是“企业级”的,但去掉计数,想象一下环境是多个分层的、地理上分散的应用程序。我们希望跨服务器类型、应用程序堆栈、地理位置或整个领域为堆栈元素打补丁。

仅使用变量的更改,我们能实现这种灵活性吗?有点。Ansible 的 默认行为 是覆盖哈希。在我们的示例中,由于 db1 和 web1 主机的 patching_repos 变量稍后出现在我们的清单中,因此被覆盖了。嗯,有点棘手。有两种方法可以管理这种情况
- 多个清单文件
- 更改变量行为
我选择了第一种方法,因为它保持了清晰度。一旦您开始合并变量,就很难找到哈希出现的位置以及它是如何组合在一起的。使用默认行为保持了清晰度,我建议您为了自己的理智坚持使用这种方法。
那就继续吧
让我们运行剧本,仅关注数据库服务器。
您是否注意到最后一步——为此主机打补丁——显示 跳过?那是因为我们没有设置 控制变量 来执行补丁。我们所做的是设置存储库订阅以准备就绪。
因此,让我们再次运行剧本,将其限制为 Web 服务器,并告诉它执行补丁。我运行此示例时使用了详细输出,以便您可以看到 yum 更新正在发生。
为应用程序堆栈打补丁需要另一个清单文件,如上所述。让我们重新运行剧本。
为欧洲地理区域中的主机打补丁与应用程序堆栈的情况相同,因此需要另一个清单文件。
既然所有存储库订阅都已配置,让我们只为整个领域打补丁。请注意,app1 和 emea 组不需要此处的清单——它们仅用于分隔存储库定义和设置。现在,yum update -y 为所有内容打补丁。如果您不想捕获这些存储库,可以将它们配置为 enabled=0。
结论
灵活性来自我们如何对主机进行分组。由于默认的哈希行为,我们需要考虑重叠——至少在我看来,最简单的方法是使用单独的清单。
关于存储库设置,我相信您已经对自己说,“啊,但是精选并没有那么简单!” 在此模型中,下载补丁、测试它们是否协同工作以及将它们与依赖项捆绑在存储库中需要额外的开销。借助配套工具,您可以自动化该过程,并且在大型环境中,您必须这样做。
我的一部分倾向于只应用完整的补丁集,这是一种更简单、更容易的方法;跳过精选部分,并将完整的补丁集应用于“标准构建”。我见过这种方法应用于 Unix 和 Windows 环境,并强制执行季度更新。
我很想听听您在补丁方案方面的经验,以及此处提出的方法,在下面的评论中或 通过 Twitter。
评论已关闭。