简介:这份 Puppet 管理模块面向配置管理与 DevOps 工程师,用于安装和管理 Puppet Master、The Foreman 与 smart-proxy,并支持一体机(aio)、目录服务(catalog)和 CA 服务(ca)三种 Master 角色,可按需单独部署目录或证书节点。与常见基于 yum 包和系统 Ruby 的同类方案不同,它使用 RVM、git 仓库与 gem 管理整套软件栈,模块化程度更高,升级和 Ruby 安全补丁维护也更可控。压缩包为 zip 格式,共 60 个文件、约 64KB,主要包括 Puppet 清单(.pp)、ERB 模板(.erb)、Ruby 脚本(.rb)和 YAML 配置,前两类分别用于声明资源状态与生成服务配置,适合直接改造成自己的部署基线。目录按 foreman、smartproxy、puppet 等角色组织,附带 spec 测试、Rakefile 与 Gemfile,可串联自动化测试和依赖管理;已有 133 人学习下载,适合希望摆脱系统 Ruby 限制、对 Puppet 栈做精细化版本控制的团队参考。
1. puppet_stack 这个名字,为什么把三件套放在一起才有意义
puppet_stack 把 Puppet Master、The Foreman 和 smart-proxy 三个词绑在同一个标题里,很多人第一反应是“装一个 Master 就够了”。真到生产环境里批量加节点、区分开发与生产环境、处理证书续期时,你会发现光有一个会编译目录的 Master 远远不够。这套栈真正提供的是一条完整链路:配置能发出去、证书有人签、节点有人管、基础设施操作有统一出口。下面从组件职责讲到安装命令,再落到日常维护和几个高频事故,适合手上已经有三五十台到上千台 Linux 主机、正在为配置管理工具本身发愁的从业者。
2. 职责边界:Puppet Master、The Foreman、smart-proxy 各自在管什么
2.1 Puppet Master 负责配置编译,但不是管理入口
Puppet Master(有些部署方式下叫 Puppet Server)是整个栈里唯一真正编译目录、给 Agent 下发的角色。它不面向运维人员提供操作界面,也不负责审批,本质上是一个后端服务。Agent 按约定时间来找它请求 catalog,Master 编译后返回,Agent 在本地执行并回传报表。这个模型的好处是幂等,坏处是运维对“谁来了、谁还没来、证书是否有效”没有任何直观感受。Master 端口固定是 8140,日志一般在 /var/log/puppetlabs/puppetserver/ 下。
针对 Master 的资源,我的建议是单独准备一台机器,内存视节点规模决定。节点数到几百台之后,编译线程数和 JVM 堆需要按比例调。我一般会把 puppetserver 的-Xmx和-Xms设成同一个值,避免运行中反复调整堆大小带来额外停顿。节点的请求频率也要控制,默认 30 分钟一个周期是常见配置,不要为了“实时生效”把所有 Agent 的runinterval调成 1 分钟,那会把 Master 编译队列直接打满。
2.2 The Foreman:把主机生命周期和证书审批收口到网页
The Foreman 不是一个来和 Puppet 抢活的配置引擎,它是管理控制面。Foreman 提供主机登记、主机组归类、组织与位置划分、用户权限、以及最关键的报表查看。所谓“组织与位置”,你可以理解成顶层隔离:同一个 Foreman 里可以同时放多个客户或机房,主机按组织归属,主机组按位置归属,互不串数据。还有一个能力在大量使用后会非常刚需:它和 Puppet 的 CA 集成,让证书审批可以在页面上点击完成,不用在每个 Master 上都保留一批命令行活。
几十台实验机的情况不装 Foreman 也能活着。节点一旦过百,或者需要分环境、分团队,让非核心运维也能自助看报表和触发任务,Foreman 的价值就非常明显。它的 Web 服务走 443 端口,和 Master 的 8140 分开;API 也走同一套 HTTPS,日常自动化脚本都可以直接对接。它解决的其实是一个很原始的问题:配置管理原本的入口近乎为零,而 Foreman 把入口补上了。
2.3 smart-proxy 是 Foreman 的“手”,不是网络出口
这个组件是标题里最容易被误解的部分。smart-proxy 是 Foreman 的一组扩展服务,用来操作 DNS、DHCP、TFTP 等基础设施,同时承担证书签发的 relay 功能。比如在 Foreman 页面上给新主机分配网段并让它从 TFTP 启动,这些动作最终通过 smart-proxy 在对应服务器上真实执行。它的 API 端口通常是 8443,和 Foreman 的 443、Master 的 8140 并立。
官方默认的安装器会按模块把证书、DHCP、DNS、TFTP 拆开。实操中我建议先只开证书模块跑通,后续真需要 DHCP/DNS 联动,再逐个模块打开。很多人的页面一片红,就是因为默认把全部模块启用,但底层服务根本没有或权限不合,报警滚成一片反而掩盖了真问题。还要注意,smart-proxy 可以直接和 Foreman 装在同一台机器上,也可以放在某个目标网段的服务器上,关键是它必须能被 Foreman 用可信的证书或 token 访问。
2.4 选型考量:单独 Master 与完整 puppet_stack 的边界
| 能力 | 单独 Puppet Master | 完整 puppet_stack |
|---|---|---|
| 配置下发 | 有 | 有 |
| 证书签发入口 | 命令行 | Foreman 页面 + API |
| 主机与主机组管理 | 没有 | 有 |
| 报表与历史检索 | 没有 | 有 |
| 多环境切换的操作入口 | 手动改目录 | 主机组映射 |
| DHCP/DNS/TFTP 联动 | 做不到 | smart-proxy 对应模块 |
由此可以得出一个比较简单的判断:只有几台实验机、不区分环境,单独 Master 更快;生产环境里,“证书到期”“环境切换”“新节点上线”这三件事会反复出现,靠命令行处理每一次都做不干净,累积成本会随时间上升。还建议不要在同一个组织里混用两套方案,否则 Master 上手工操作的证书记录和 Foreman 的管理记录会脱节,后面排查会怀疑人生。
2.5 组件之间的信任关系,决定了很多坑的根源
Puppet Agent 找 Master 要目录时,采用的是 Puppet 自己的 CA 体系,证书在 Agent 首次运行后生成,必须经过 Master 或 Foreman 签名才有效。Foreman 和 Master 之间的通信,用的是同一台机器上安装器自动生成的本地证书,靠配置里的 SSL 参数互相校验;Foreman 访问 smart-proxy 时,则依赖代理侧预先注册的证书或 token。这三层信任链互相独立又彼此纠缠,是后续绝大多数证书类报错的根源。
实际排查时,脚本里遇到的“connection reset”“certificate verify failed”“http 401”,都不是同一个层面的问题,需要先判断是 Agent 与 Master 的 CA 信任断了,还是 Foreman 访问 smart-proxy 的凭证失效。这一步判断错了,后面所有处理都是白做。
3. 空服务器上跑通 puppet_stack:安装步骤与第一个 Agent 上线
3.1 环境准备:主机名、DNS、时间约束
安装前我会先处理三个基础项,这三项不做好,后面证书大概率出问题。第一是主机名必须固定为完整 FQDN 格式,最好把 IP 也写进 /etc/hosts;第二是每台机器都要启用时间同步;第三是放行 8140、443、8443 三个端口。
# 设置 FQDN 主机名,改为你规划的正式名称 hostnamectl set-hostname master01.example.internal echo "192.0.2.10 master01.example.internal" >> /etc/hosts # 启用时间同步,证书签发强依赖时钟偏差不能太大 systemctl enable --now chronyd chronyc tracking | head -5 # 放行核心端口,按实际使用的防火墙管理方式调整 firewall-cmd --permanent --add-port={8140/tcp,443/tcp,8443/tcp} firewall-cmd --reload主机名写在 hosts 里是保底方案,避免内网 DNS 解析不可用时 Agent 找不到 Master。时间同步常被忽略,但证书有效期判断和请求时间戳都建立在对时之上,偏差超过几分钟就会看到各种难以理解的握手失败。
3.2 添加软件源并安装 foreman-installer
安装这套栈的入口不是分别装三个包,而是装 foreman-installer,由它在最后统一生成配置并拉起服务。先确认当前发行版支持哪种软件源方式,再用包管理器安装安装器本体。
# 先安装扩展包,部分依赖组件在扩展源里 sudo dnf install -y epel-release # 添加对应发行版的 foreman 软件源并刷新缓存 sudo dnf install -y foreman-release sudo dnf update -y这里要强调的是:官方安装器只负责把 Foreman、Puppet Master、smart-proxy 组合起来,它不负责替你决定哪些模块要开。如果你在前面没有想清楚证书、DHCP、DNS 哪些要启用,安装后大概率要往回改配置,那时候每一步都牵一发动全身。
3.3 执行安装器,最小化参数先跑通
首次安装一定要做最小化。把组织、位置定了,再显式关闭用不到的基础设施模块。
sudo foreman-installer \ --foreman-initial-organization myorg \ --foreman-initial-location myloc \ --puppet-server true \ --foreman-proxy-puppet true \ --foreman-proxy-register-in-foreman true \ --enable-foreman-proxy-plugin-dhcp false \ --enable-foreman-proxy-plugin-dns false \ --enable-foreman-proxy-plugin-tftp falseorganization 和 location 是 Foreman 的顶层隔离维度,后面可以在页面里继续建,但初始值最好一次写对。puppet-server true 让本机把 Master 一起拉起来;三个 plugin 全 false,是因为这一阶段目标是证明链路能走通。安装过程通常要几分钟到十几分钟,结束时会打印默认 admin 密码和访问地址,先保存好再关窗口。
提示:安装完成后不要立刻重启机器,等证书全部生成、服务先跑一遍正常了再做重启验证。
3.4 首次登录与健康检查
安装器结束后,第一步是先看服务状态,而不是急着打开页面。
# 分别查看三个核心服务的状态 systemctl status httpd --no-pager -l systemctl status puppetserver --no-pager -l systemctl status foreman-proxy --no-pager -l # 确认三个端口都在监听 ss -lntp | grep -E ':(8140|8443|443)\b'如果 8140 没出现,说明 puppetserver 没有正常起来,大概率是 JVM 内存参数或主机名解析问题。8443 缺失则去查 foreman-proxy 的日志;最直观的判断方式就是这三个端口必须同时存在。页面访问用 https://master01.example.internal/,首次登录时用安装器打印的 admin 账号密码,系统会要求改掉初始密码,这一步在自动化脚本里经常被落下,导致后面所有 API 调用一直返回 401 认证失败。
3.5 接入第一个 Agent:从证书请求到完成首次运行
Agent 端的接入套路是从安装 puppet-agent 包开始,先配好 server 地址,再触发一次预演。
# 在目标节点上安装并指向 Master sudo dnf install -y puppet-agent sudo vim /etc/puppetlabs/puppet/puppet.conf # [main] # server = master01.example.internal # 第一次运行用预演模式,目的是触发证书请求 sudo /opt/puppetlabs/bin/puppet agent -t --noop第一次运行大概率会卡在“等待证书签发”的状态,这很正常,因为服务端还没有放行。此时回到 Master 端查看待签列表并完成签发:
# 查看待签名证书,确认识别出真实节点 /opt/puppetlabs/bin/puppet cert list # 确认无误后签发对应名称的证书 /opt/puppetlabs/bin/puppet cert sign agent01.example.internal签发完成后,再次执行puppet agent -t应该就能拿到 catalog 并按目录完成预演。这里的 agent 名称默认取自节点主机名,所以主机名在安装前就固化下来非常关键;临时换过名的节点,证书签发后往往出现名称不匹配,只能清掉重签。
4. 日常管理:证书、环境、主机组和 smart-proxy 健康检查
4.1 用一组命令管理 Agent 证书的完整生命周期
证书是这个栈里最不能靠感觉处理的资产。日常无非四类操作:查看、签发、撤销、清理重签,我习惯全部用命令行兜底,虽然 Foreman 页面也能做,但脚本和自查时命令行更快。
# 查看所有证书,带 --all 才会同时显示已签发和待签发 /opt/puppetlabs/bin/puppet cert list --all # 撤销并移除某节点的证书记录 /opt/puppetlabs/bin/puppet cert clean agent01.example.internal # 重新签发(节点端必须先清空旧证书) /opt/puppetlabs/bin/puppet cert sign agent01.example.internalcert clean删除的是服务端记录,节点端还握着旧证书和私钥,如果不去清节点端 SSLDir,下一次请求会报出各种验证失败。常见做法是登录节点后删除 /etc/puppetlabs/puppet/ssl 整个目录,再重新跑puppet agent -t生成新请求。较新版本也可以直接用puppet ssl bootstrap重置,但旧路径同样可行,优先用目录清理法最稳。
4.2 Foreman 里的主机组和环境划分
Foreman 的管理基本单元是主机组。常见做法是建一个 base 主机组放通用配置,再在它下面派生 dev、staging、production 子组,把 Puppet environment 映射到各子组。这样新增节点时只要选对主机组,环境归属就自动正确,不需要在 Agent 端手动改配置文件。
# 用 API 建主机时指定主机组和环境(示例结构) curl -k -u admin:password \ -H 'Content-Type: application/json' \ -d '{"host":{"name":"app01","hostgroup_id":9,"environment_id":3}}' \ https://master01.example.internal/api/hosts在页面操作时,主机组和环境都是下拉选项。要注意 Agent 端 /etc/puppetlabs/puppet/puppet.conf 里的 environment 必须和主机组一致,否则会陷入“我明明改了环境,节点跑完还是旧配置”的困惑。API 里的环境字段实际上对应 environment id,这个 id 可以在页面或 API 里查。
4.3 分清 puppetserver、foreman、foreman-proxy 三类日志
| 服务 | 日志路径 | 常见问题 |
|---|---|---|
| puppetserver | /var/log/puppetlabs/puppetserver/ | 编译报错、CA 异常 |
| foreman | /var/log/foreman/production.log | 页面报错、API 401 |
| foreman-proxy | /var/log/foreman-proxy/proxy.log | 证书 relay、DHCP/DNS 操作失败 |
遇到 Agent 报错时,先看 Agent 端日志,再往 Master 侧看,这个顺序不能反。大多数时候服务端其实是正常的,问题出在证书或环境名不匹配。快速确认 smart-proxy 状态可以用:
# 输出各模块启用状态和监听情况,比页面上的红色警告更快定位 sudo foreman-proxy status这套栈的三段日志里,foreman-proxy 的日志最容易被忽略。它的报错大多会有明确的 timeout 或 connection refused,先看它,能迅速把问题边界从“Foreman 坏了”缩小到“某个模块没起来”。
4.4 用 runinterval 控制 Agent 的请求节奏
Agent 默认每 30 分钟连接一次 Master,我在生产上不会把这个值调得太小。瞬时大量节点同时来请求,Master 的编译线程会被占满,表现是页面正常但节点全部超时。
# Agent 端配置示例 [agent] runinterval = 1800 splay = true splaylimit = 300runinterval 单位是秒,1800 就是半小时。splay 让各节点在区间内随机分散启动,避免所有机器在同一秒发起请求;splaylimit 限制随机范围的上限。不要图省事在高峰期大批量手动触发puppet agent -t,一定要分批次,比如拆成每批五十台间隔几分钟。Foreman 页面的远程执行功能在设计上是按主机组或主机列表分发的,适合定向操作,不适合全量刷。
5. 上线后最常见的五个坑:现象、原因、排查顺序
5.1 证书过期后 Agent 重签不生效
现象:Agent 报证书过期,运维在 Master 端执行 clean 后重新 sign,节点仍然报无法连接。
原因:服务端记录删了,但节点端 SSLDir 里还是旧证书和旧私钥。节点再次请求时拿着旧身份,Master 按新签发的记录校验不通过。
处理:先清理节点端旧证书,再触发新请求。
# 节点端先清,顺序不能反 rm -rf /etc/puppetlabs/puppet/ssl /opt/puppetlabs/bin/puppet agent -t执行完再回 Master 端 sign 一次。顺序是关键:先节点端清理、再服务端清理、最后重签。反过来操作时,表面上每次都能“签成功”,但节点一直用旧身份连接,问题会反复出现。
5.2 页面一片红:smart-proxy 模块全开但服务没起来
现象:Foreman 页面里 Smart Proxies 列表大面积红色,只有证书模块正常。
原因:安装时没有显式关闭用不到的模块,默认把 DHCP、DNS、TFTP 相关模块全部启用了,但对应服务或权限并未准备。
处理:编辑 /etc/foreman-proxy/settings.d/ 下对应模块的配置文件,把 enabled 改为 false,再重启 foreman-proxy。用不到的模块一定要关干净,半关闭状态会让页面持续报警,反而掩盖证书模块之外的真实故障。
5.3 改了 Foreman 里的环境,节点却不动
现象:在页面把节点从 dev 主机组切到 prod 主机组,Agent 跑完后节点配置还是 dev 的。
原因:environment 最终以 Agent 配置文件里的 environment 字段为准,主机组只是管理侧标注,并不会自动改写 Agent 端的配置。
处理:在节点上打开 /etc/puppetlabs/puppet/puppet.conf,把 environment 改成和主机组一致;改完再验证 /etc/puppetlabs/code/environments/ 下是否存在对应名称的目录。目录不存在时 Master 会退回 production 环境,这也是环境切换无效的另一半原因。
5.4 报表不更新,但 Agent run 是成功的
现象:节点配置生效,Agent 运行也报 Completed,但 Foreman 的 Reports 页面已经几天没新数据。
原因:报表上报链路上出了问题。常见是 Master 的 report 配置仍指向 localhost,没有指向 Foreman,或者 report 功能被关掉了。
处理:
# 在 Master 上检查 report 与上报地址 /opt/puppetlabs/bin/puppet config print report report_server如果 report 不是 true,或者 report_server 是 localhost、空值,就修改 puppet.conf 的 [master] 段,把 report 打开并指向 Foreman 的 FQDN,然后重启 puppetserver。报表功能恢复后,历史数据一般会陆续补回,不用手工干预。
5.5 服务重启顺序有讲究
现象:维护或升级后,Agent 全部连接失败,Foreman 页面也登录不上,但逐个查看服务状态又是正常。
原因:三个服务之间互相依赖,启动顺序错了会陷入证书与注册状态互相等不到的局面。最常见的是把 Web 服务放在最前,导致 Foreman 启动时以错误的凭证去访问 smart-proxy。
处理:按我这个顺序重启一次。
systemctl restart foreman-proxy systemctl restart puppetserver systemctl restart httpd先让 smart-proxy 的证书通道就绪,再拉起 Master,最后让 Foreman 通过 Web 端口对外服务。这是我在某内部管理项目里连续踩了两次跟头才固定的顺序,之后每次维护都按它执行,没有再出现过“服务全正常但整体瘫痪”的怪状态。
6. 进阶一步:把环境划分和代码入库做成常规流程
6.1 环境目录与主机组静态映射
多环境的基础是目录,不是配置文件。我在 Master 上维护 /etc/puppetlabs/code/environments/ 下的 dev、staging、production 三个目录,每个目录里都有独立的 manifests/site.pp 和 hieradata,Foreman 的主机组名与它们一一对应。新增节点的动作就收敛为两步:在 Foreman 建主机、选主机组。第一次 run 会自动进入对应环境,人工干预点只剩“建组、选组”两个地方。
6.2 发布前先做三层检查
改代码不能直接丢进生产目录。我一般先做语法校验,再做预演,最后才同步。
cd /etc/puppetlabs/code/environments/staging /opt/puppetlabs/bin/puppet parser validate manifests/site.pp /opt/puppetlabs/bin/puppet apply --noop manifests/site.pp --modulepath modulesparser validate 负责语法层,预演模式会列出将要变更的资源。看预演结果时,如果只有一两个操作,说明改动可控;如果显示要动几十甚至上百处文件,必须回到代码里找原因。版本控制工具可以按团队习惯选,关键是生产目录不能被直接手改。我曾因为贪图省事,把 dev 目录的代码直接软链到 production,第二天所有生产节点都跑上了未验证配置。从那以后我坚持目录分离和预演,并希望帮到你。
本文还有配套的精品资源,点击获取