> For the complete documentation index, see [llms.txt](https://freebsd-journal-cn.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://freebsd-journal-cn.bsdcn.org/20170304-pei-zhi-guan-li/the-configuration-management-pipe-dream.md).

# 配置管理的白日梦

作者：MICHAEL W LUCAS

配置管理是一场梦。一场辉煌而美妙的梦。在一个中央数据库里定义你所有的服务器特征！按工作负载部署云服务器！它们全部一模一样！行为完全一致！一切都能正常运转！绝对的复现性，绝对的可预测性！

听起来妙极了。可在现实世界里，生活没这么简单。

我的大部分职业生涯都在大型企业里度过：有时是员工，但更多时候是受雇的顾问。这些公司里，控制门锁的服务器还在跑 Novell NetWare，因为 1993 年那会儿他们确实知道怎么造硬盘。这些组织部署应用来解决特定问题，大多数时候是从供应商那里购买应用，供应商承诺程序只需极少定制。有些应用有专门的系统管理员团队悉心照料，另一些则被善意地忽视，直到崩溃死亡、惊动全公司。所有这些应用有一个共同点：服务器都是专门为那个应用搭建的。销售会告诉管理层：“我们的包治百病 ERP 软件需要一台 Sun Megajillion，配 40 gadzook 的 REM，至于你们的工作负载嘛，要加一块 crystal meth 协处理器。”技术人员尽力把销售话术翻译成实际的软硬件需求，然后按说明书配置设备。公平地说，规格也不总是那么含糊。有些精确得令人不安，要求的硬件几年前就停产了。而供应商总会提到，如果我们公司的技术人员理解不了他们清清楚楚的需求——无论是工作太忙还是脑子不太好使——他们 500 美元一小时的顾问可以登门，交付一台配置完毕的主机。当然，那台主机会用 telnet 管理，硬盘没有任何冗余，但应用本身会跑得好好的。再加上读写 SNMP 字符串设的是“public”，公司里任何人都能调优服务器，所以我们这些懒骨头想搞砸也不容易。

所以并非每个应用都是特别的雪花。有些是特别的飓风。或者带着特别狂犬病的特别野狗。“手工匠人式的系统管理”听起来像个笑话，但感觉起来却像冷冰冰的现实。在这种环境里谈配置管理是可笑的。它和“如果从头开始、从零搭建，一切都会完美”归为同一类。不，我们不得不为每台主机维护独特的配置。这些组织倒是有标准，要知道。安全和系统管理团队维护着各种手册、策略文档或标准文档，用通俗易懂的英语记录每个服务该如何配置。通俗易懂的英语未必能直接翻译成 **/etc/rc.conf** 的设置。更不用说 Red Hat 不支持 pam\_mkhomedir，或者那个依赖 PHP 2 和 MySQL 3 点几的要命应用、跑在这台改作他用的 FreeBSD 4.4 桌面上，它非得用 SSH 1.1 不可。¹

系统管理员尽量遵守标准。我们尽可能把每台机器调到最佳。然后祈祷。每天都要祈祷一大把。我的上一份工作，在某种意义上是这种管理哲学的极端病态案例。一家小型、友善的公司看起来是个不错的转变。人很好——其中一些我私下认识多年，有些甚至几十年。每个人都清楚自己的职责范围，又愿意帮助他人。老板技术过硬，深知最简单的事也可能出差错。如果我要在凌晨恶时恶刻冲进数据中心，没人指望一两天内能听到我的消息。公司总裁把冰箱里塞满咖啡因视为自己最重要的职责。着装要求？“你得穿着衣服。”至于技术标准，完全没有。“我需要 X 服务？好，我给它开个虚拟机。这台虚拟机服务器看起来还有余量。我听说 Mint 是新潮流，看看怎么回事。能用，太好了，就这么用上八年！”“哦嘿，这里有台 Itanium 机器！插上电看看能跑什么！Asterisk 能跑吗？酷，这个客户有麻烦，把他们的电话路由过来试试能不能帮上忙。”“全公司都用 Apache，但我听说 nginx 不错……”他们大概 15 年前有过一套连贯的设计。但多年的增长、扩张和采购把那套设计埋在了层层基础设施之下。没有人花时间去自动化任何东西。IT 地狱入口处挂着的那块牌子上写着：“每一个决定在当时看起来都是合理的。”

然后“在下”——新任系统管理一把手——登场了。我拿到了一份公司所有服务器的清单。准确地说，是当时所有人能想到的所有服务器。接下来几周，这份清单每天都在变长。之后几个月，每周都在变长。其中一台服务器在我入职一年多后才冒出来。我推着 crash cart 穿梭在各个数据中心，把控制台一台接一台地插上去，搞清楚它到底是什么。可惜我从没发现过跑 VMS 或 Ultrix 的机器，赌输了。

一个人不可能真的管好这一切。这根本做不到。而每个人对从操作系统到软件版本的一切都有自己的偏好。公司的既定政策就是迁就这些偏好。奇怪的是，公司士气不错。挫败感很高，但士气不错。我抓起抓包工具，开始理清这团乱麻。我从最明显的入手——散布在网络各处的大约 15 台无人维护的域名服务器。我部署了三台权威服务器和三台递归服务器，合理分布在网络中。我更新了每台服务器的 resolv.conf。是我知道的所有服务器。当我关掉那些无人维护的域名服务器时，其他服务器才暴露出来。于是：把它们加到服务器清单上，处理客户的连锁反应，向被我搅乱一天的工程师道歉。员工理解我在做什么，要知道。他们知道状况需要改善……但这不代表他们非得喜欢这不可避免的阵痛。我部署了集中认证。一台服务器接着一台服务器。跨多个操作系统。你只有亲手在 87 个不同的操作系统上各装一遍九种不同的 LDAP 认证模块，一台一台地装，才算没白活。显然，总得有所改变。但集中认证打开了新的可能。这就到了配置管理登场的地方。

配置管理不只是针对整个企业的。配置管理可以从小处起步，看似不起眼。如果你的组织真的没有配置管理，一个人也能把它启动起来。一个配置管理的倡导者可以为自己的那部分地盘实现一套方案。耐心和切实的成效会替你完成剩下的工作。我又架了一台主机，跑 Ansible。（我选了对我来说最合理的软件。挑选最适合你的环境和需求的那个就好。）我没有从通过云部署整台机器开始。相反，我把我刚刚架好的所有基础设施机器上的 **/etc/resolv.conf** 的内容集中起来。这让我得以解决尝试新事物时总会冒出来的那些零碎小问题。然后我把 sshd\_config 纳入了配置管理。突然之间，我只需编辑一个文件、运行一条命令，就能向新的基础设施服务器部署一项变更。SSH 不是那种需要频繁改动的服务，但手动改动几十台服务器足以毁掉整天。差不多就在那时，我们发现有人入侵了一些服务器。入侵者似乎对破坏我们的系统不感兴趣，只是在跑一些 IRC 机器人。尽管如此，入侵者必须走。据我判断，入侵者是通过 SSH 进来的。没错，有些主机仍在使用密码认证。而有些密码，怎么说呢……选得不怎么样。结果这也不是第一次发生了。员工终于决定 SSH 密码不可接受，我们只能使用基于密钥的认证。我恭喜他们加入了 20 世纪 90 年代，运行了一条 Ansible 命令，然后报告我的新服务器都已更新，但其余的还需要更多时间。这开启了关于配置管理的讨论。

每个被管理的 sshd\_config 看起来都有点怪。它们没有那些常见的注释掉的配置项，而是大致长这样：

```sh
# 由 Ansible 管理的配置
# 手动修改将被覆盖
# 警告过了
Port 22422
PasswordAuthentication no
Subsystem       sftp    /usr/libexec/sftp-server
```

配置文件不需要那些注释掉的默认值，因为没有人会在这台主机上编辑这个配置文件来改动什么。任何需要的修改都应在配置管理主机上进行。讨论很快转向“我们怎么到处都这么干？”

而这是部署配置管理最棘手的部分。你绝不能说“让我去干吧”。你要说：“我可以在每台通过 LDAP 认证的主机上这么做，但我需要所有人同意，他们不再自行配置 SSH 服务器。一旦我把某台主机的 SSH 纳入配置管理，它就留在那里。一切都记录在配置管理系统中。这不再是你的问题，但你也别再碰它了。”“可要是哪天深夜出了大问题而你不在呢？”“那你就自己修，第二天早上再告诉我。但下次我部署配置更新时，你的改动会被抹掉，我可不听你抱怨。”事情没这么简单。每个 sshd\_config 都得根据操作系统加入或排除某些配置项，以应对每个操作系统的特性。这个小项目还暴露了几台没有接入 LDAP 的主机——不是因为我不了解它们，而是系统无法承受切换所需的停机时间。说来奇怪，当你能证明某项改动会减少工程师的工作量，他们就变得非常配合。那些原本无法承受任何停机时间来切换 LDAP 的主机突然变得可用了。是的，是在某个周日凌晨 3 点，但总之可用了。

我们并没有在自动部署虚拟机。但把哪怕一个服务纳入配置管理就改变了一切。“你能把我的 authorized\_keys 推送到我所有的主机上吗？“”当然可以。你看，没人愿意到处上传新的 authorized\_keys。不如我来接手所有 authorized\_keys 的维护？而且大家都知道，让用户编辑自己的密钥文件可能存在安全风险。我们可以把它们移到 **/etc/ssh/keys**，把这些主机再锁紧一点。“大家变得比每十年一次更频繁地生成客户端密钥。一台主机的名字服务出问题，于是把所有机器的 resolv.conf 都纳入了配置管理。LDAP 有变动？把客户端 LDAP 配置也纳入配置管理。

我原本以为会有人慢慢来问我们能不能把某些服务纳入配置管理。事实证明我低估了同事的智慧。某一天，配置管理还是白日梦。第二天，几乎所有人都让我把那些管子铺到一切能到的地方。

把完整的配置管理改造到既有的手工匠人式系统上并不容易。其实相当糟糕。直接开新的虚拟机并部署到它们上面要容易得多。那些杂七杂八的主机大多反正也该换了。只是配置服务太痛苦，所以没人愿意碰。最妙的是，我们确切知道某些问题不再是问题了。老板最新爱说的话变成了“这个问题我们已经解决了。”（没错，定期可乐外卖那种事他也这么说，但那不是重点。）士气保持良好。挫败程度依旧，但大家为之懊恼的是不同的事。这里的教训是，有些人不挫败就不开心。然后我们都过上了幸福快乐的日子。除了我们又部署了一大堆虚拟机那部分——因为自动化让管理它们变得轻而易举。但披萨和工资都到位，所以，嗯，还是挺幸福的。

奇怪的是，不只我一个系统管理员有这种经历。每个从配置管理起步的人，哪怕规模很小，都会发现这是一个强大得难以置信的工具。你不需要从一个崭新的空白环境开始。从你自己的痛点开始。也许你有一大堆 Apache 服务器，需要确保每台都有最新的 TLS includes 文件。也许你想确保你管理的每台服务器都安装了某份特定的软件包清单，或者 sudo 软件包始终是最新版本。我们的大脑都知道自动化让一切更轻松。但运行第一条命令，看着你的更新流过你的网络，会把那种认知烙进你的骨头。

配置管理并不完美。配置管理系统能用以太网的速度部署错误。（在互联网上搜索“sudo bake me a cake”可以找到 Jan-Piet Mens 那个有趣的 sudo 管理翻车案例。之所以好笑，是因为那不是我。）使用配置管理让测试变得更加重要。如今连便宜的笔记本都能跑一群虚拟机，测试只是时间和注意力的问题——两者总是稀缺，没错，但总比需要时间、注意力再加上几千美元硬件强。

最棒的是，管理者会注意到配置管理带来的帮助。配置管理减少了人为不一致导致的宕机。它有助于暴露问题。最终你会听到老板对销售说：“听起来不错，但我们能用 Ansible/Puppet/Chef/别的什么来管理它吗？”然后你就可以集中精力解释“40 gadzook 的 REM”不是真东西，任何这么说的销售都不称职。本期收录了关于 Vagrant、Puppet、SaltStack 和 CFEngine 的文章。它们都与 FreeBSD 配合良好，无论是作为服务器还是客户端。这些工具正是“力量倍增器”的绝佳范例，让一个系统管理员能支持比过去多得多的服务器。是的，那个有幸从空白起步的幸运儿可能支持几百台按需的云服务器，但我们其余的人也能让自己最乏味的任务消失。一旦你触碰了配置管理这场白日梦，你会在余下的职业生涯里紧抓不放。

> ¹ 我真希望我是在开玩笑。

***

**MICHAEL W LUCAS** 著有多本 FreeBSD 书籍，包括《Absolute FreeBSD》和《FreeBSD Mastery》系列。更多信息见 <[www.michaelwlucas.com>。](https://freebsd-journal-cn.bsdcn.org/20170304-pei-zhi-guan-li/http:/www.michaelwlucas.com>。)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://freebsd-journal-cn.bsdcn.org/20170304-pei-zhi-guan-li/the-configuration-management-pipe-dream.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
