CFEngine 3.27.2 Ubuntu 22.04 安装指南

在 Ubuntu 22.04 上从零安装 CFEngine 3.27.2 LTS 社区版:官方 deb 包主线、本地 apt 仓库备用方案、自举首跑、systemd 单元验证、升级降级与卸载全流程,含排障实录

CFEngineCFEngineUbuntuUbuntu 22.04Linuxsystemd自动化2026/10/17

CFEngine 3.27.2 Ubuntu 22.04 安装指南

目标:在 Ubuntu 22.04 服务器上从零安装 CFEngine 3.27.2 社区版(Community),完成官方包下载安装、策略自举(bootstrap)、Masterfiles 初始化、systemd 服务验证、升级降级与彻底卸载的完整 0→1 流程。全部命令与回显均在 Ubuntu 22.04.5 LTS(x86_64)真实环境实测通过。

一、环境信息

本文所有命令在以下环境实测通过,读者可按同样配置复现:

  • 操作系统:Ubuntu 22.04.5 LTS(Jammy Jellyfish),内核 6.8.0-138-generic
  • 架构:x86_64(amd64)
  • CFEngine 版本:3.27.2(社区版 / Community Edition,3.27.x LTS 线最新版本)
  • 安装路径:/var/cfengine/(CFEngine 全部组件与数据的工作根目录)
  • systemd 单元:cfengine3.service(总控单元)+ cf-serverd.service、cf-execd.service、cf-monitord.service(子服务单元)
  • 通信端口:TCP 5308(cf-serverd 监听,策略分发与远程执行通道)
  • 用户:root

💡 说明:CFEngine 是基于「策略(policy)」声明式驱动的基础设施自动化工具,属于「配置管理(Configuration Management)」这一类技术。由 cf-agent(策略执行)、cf-serverd(策略分发服务)、cf-execd(定时调度执行)三大守护进程组成。单机场景下三种角色都装在同一台机器(本文即此场景),多机场景再增加策略服务器(policy server)角色。

💡 技术拓展:配置管理工具不止 CFEngine 一种,业界主流选择横向对比——

工具架构模型语言/ DSL特点适用场景
CFEngine代理常驻(pull)自有 promise 声明式 DSL1993 年起家、工业级成熟、C 编写极轻量(单机内存占用个位数 MB)、收敛保证大规模异构集群、对资源占用敏感的基础设施
Ansible无代理(SSH push)YAML + Jinja2上手最快、无需在被管机装守护进程中小规模、快速自动化编排
Puppet代理常驻(pull)自有 DSL生态成熟、有企业控制台传统企业 IT、异构系统多
SaltStack代理常驻/SSH 双模YAML + Jinja2消息总线(ZeroMQ)驱动、执行速度快云环境、需要高速远程执行的场景

本文采用 CFEngine 社区版:其声明式收敛模型(系统持续向策略定义的期望状态收敛,天然幂等)与极低的常驻资源开销,是这类常驻代理型工具中最典型的实现。

二、前置条件

安装前确认系统满足以下条件,逐条给出验证命令与实测回显。

2.1 操作系统与架构确认

cat /etc/os-release | head -3
uname -m

实测回显:

PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
x86_64

版本号决定后面下载哪个 deb 包(ubuntu22 对应 Ubuntu 22.04)。

2.2 磁盘空间

CFEngine 社区版安装后占用约 60 MB(/var/cfengine 约 35 MB + /usr/local/bin 符号链接),确认根分区有余量即可:

df -h / | tail -1

实测回显:

Filesystem      Size  Used Avail Use% Mounted on
overlay         786G  613G  139G  82% /

2.3 基础工具

下载与校验需要 wget(或 curl),校验 SHA256 用 sha256sum(系统自带):

apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y wget

实测回显(输出节选):

(Reading database ... 7002 files and directories currently installed.)
Preparing to unpack .../wget_1.21.2-2ubuntu1.5_amd64.deb ...
Unpacking wget (1.21.2-2ubuntu1.5) ...
Setting up wget (1.21.2-2ubuntu1.5) ...

2.4 systemd 可用性

CFEngine 的 deb 包自带 systemd 单元文件,安装后由 systemd 托管。确认系统使用 systemd:

systemctl is-system-running

实测回显:

running

⚠️ 注意:如果返回 degraded,说明系统可以正常托管服务但有个别单元启动失败,不影响 CFEngine 安装;如果返回 offline 或 systemctl 报 System has not been booted with systemd,说明当前环境没有 systemd(例如最小化环境),需要先在带 systemd 的真实服务器环境中操作。

三、版本选型说明

3.1 CFEngine 版本线与 LTS 策略

CFEngine 官方同时维护两条 LTS(长期支持)线与一条最新稳定线,版本信息由官方 releases.json 索引发布。用 curl + python3 解析(Ubuntu 22.04 自带 python3):

curl -sL "https://cfengine-package-repos.s3.amazonaws.com/release-data/community/releases.json" | python3 -c "
import json,sys
d=json.load(sys.stdin)
for b in d[\"lts_branches\"]:
    print(b[\"branch_name\"], \"->\", b[\"supported_until\"])
print(\"---releases---\")
for r in d[\"releases\"]:
    if r.get(\"release_date\") not in (None, \"nightly\") and r[\"version\"].startswith(\"3.2\"):
        flags = []
        if r.get(\"lts_branch\"): flags.append(\"LTS:\"+r[\"lts_branch\"])
        if r.get(\"latestLTS\"): flags.append(\"latestLTS\")
        if r.get(\"latest_stable\"): flags.append(\"latest_stable\")
        print(r[\"version\"], r[\"release_date\"], \" \".join(flags))
"

实测回显(输出节选,保留 LTS 分支段与 3.2x 版本段):

nightly-3.27.x -> 2028-12
3.27.x -> 2028-12
nightly-3.24.x -> 2027-08
3.24.x -> 2027-08
nightly-3.21.x -> 2025-12
3.21.x -> 2025-12
nightly-3.18.x -> 2024-08
3.18.x -> 2024-08
---releases---
3.28.0 2026-07-10 latest_stable
3.27.2 2026-10-15 LTS:3.27.x latestLTS
3.27.1 2026-05-08 LTS:3.27.x
3.27.0 2026-01-12 LTS:3.27.x
3.26.0 2025-05-20
3.25.0 2025-01-06
3.24.5 2026-10-15 LTS:3.24.x
3.24.0 2024-08-02 LTS:3.24.x
3.21.8 2025-12-12 LTS:3.21.x
3.21.0 2022-12-21 LTS:3.21.x

3.27.x LTS 线上的正式版本:

版本发布日期说明
3.27.02026-01-123.27 LTS 首个版本
3.27.12026-05-08例行维护版本
3.27.22026-10-153.27 LTS 最新版本,官方标记 latestLTS(本文采用)

3.28.0(2026-07-10 发布)是当前最新稳定线版本,官方标记 latest_stable,非 LTS。本文选 3.27.2 LTS:生产环境优先 LTS,支持周期至 2028-12。

3.2 官方包下载页与包命名规则

社区版(Community,免费开源)的 deb/rpm 包通过官方「release-data」索引发布。先取 3.27.2 的包清单(每版本一个 JSON):

curl -sL "https://cfengine-package-repos.s3.amazonaws.com/release-data/community/3.27.2.json" | python3 -c "
import json,sys
d=json.load(sys.stdin)
print('version:', d['version'])
for a in d['artifacts']['Binary packages']:
    if a['Title'] in ('Ubuntu 22.04','Ubuntu 24.04','Debian 12','Red Hat / CentOS 8') and a['Arch']=='x86_64':
        print(a['Title'], '|', a['SHA256'][:16], '|', a['URL'].split('/')[-1])
"

实测回显:

version: 3.27.2 LTS
Debian 12 | d1736c4a274853fc | cfengine-community_3.27.2-1.debian12_amd64.deb
Ubuntu 22.04 | 220707471bc337cc | cfengine-community_3.27.2-1.ubuntu22_amd64.deb
Ubuntu 24.04 | 1465f5ecbdc0061a | cfengine-community_3.27.2-1.ubuntu24_amd64.deb
Red Hat / CentOS 8 | 690a00eb8b94c16f | cfengine-community-3.27.2-1.el8.x86_64.rpm

关键差异与解读:包名规则为 cfengine-community_<版本>-1.<平台标签>_<架构>.deb,Ubuntu 22.04 的平台标签是 ubuntu22;官方同时提供 Ubuntu 20.04/22.04/24.04/26.04、Debian 12/13 与 RHEL/CentOS 7/8/9/10 的包,交叉发行版不可混用。每条目都带官方 SHA256,下载后务必校验(见 4.1)。

3.3 社区版与 Enterprise 版差异

维度Community(本文)Enterprise(免费 25 节点)
价格免费开源25 台主机以内免费,超出需授权
策略执行(cf-agent/cf-serverd/cf-execd)有有
企业 hub 管理台(Web UI、cf-hub)无有
企业报表组件(cf-report、报表数据库)无有
适用场景单机/自管理策略的节点集群需要集中管控台与报表的大规模集群

关键差异:核心执行引擎完全一致;Enterprise 增加集中管理(hub + Web UI + 报表)。本文以社区版单机模式为主线,多机部署(policy server 与客户端)见《CFEngine 3.27.2 进阶实战与运维》。

四、安装方案 A:官方 deb 包下载安装(推荐主线)

这是官方安装文档给社区版的标准方式:从官方包仓库下载 deb 包,dpkg -i 安装。CFEngine 曾经通过 packagecloud 提供在线 apt 源,现已停用(排障实录见 10.1),因此当前主线上是「下载单包 + dpkg 安装」。

4.1 下载 deb 包并校验

cd /tmp
wget https://cfengine-package-repos.s3.amazonaws.com/community_binaries/Community-3.27.2/agent_ubuntu22_x86_64/cfengine-community_3.27.2-1.ubuntu22_amd64.deb

实测回显(输出节选,实测首尾):

--2026-10-17 00:35:31--  https://cfengine-package-repos.s3.amazonaws.com/community_binaries/Community-3.27.2/agent_ubuntu22_x86_64/cfengine-community_3.27.2-1.ubuntu22_amd64.deb
Resolving cfengine-package-repos.s3.amazonaws.com (cfengine-package-repos.s3.amazonaws.com)... 54.231.228.42, 16.15.213.76, 16.15.214.46, ...
Connecting to cfengine-package-repos.s3.amazonaws.com (cfengine-package-repos.s3.amazonaws.com)|54.231.228.42|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 6662426 (6.4M) [application/vnd.debian.binary-package]
Saving to: 'cfengine-community_3.27.2-1.ubuntu22_amd64.deb'
     0K .......... .......... .......... .......... ..........  0%  212K 31s
  6500K ......                                                100%  251M=1.7s

2026-10-17 00:35:34 (3.75 MB/s) - 'cfengine-community_3.27.2-1.ubuntu22_amd64.deb' saved [6662426/6662426]

校验 SHA256(官方 3.27.2.json 中给出的值):

sha256sum cfengine-community_3.27.2-1.ubuntu22_amd64.deb

实测回显:

220707471bc337cc9c08e021e845b5e1fbfddf78cd77ea277cda8f2857d49edc  cfengine-community_3.27.2-1.ubuntu22_amd64.deb

与官方 3.27.2.json 中 Ubuntu 22.04 x86_64 条目的 SHA256 一致(220707471bc337cc... 开头),包完整可信。

4.2 安装

dpkg -i cfengine-community_3.27.2-1.ubuntu22_amd64.deb

实测回显:

Selecting previously unselected package cfengine-community.
(Reading database ... 7012 files and directories currently installed.)
Preparing to unpack cfengine-community_3.27.2-1.ubuntu22_amd64.deb ...
Unpacking cfengine-community (3.27.2-1.ubuntu22) ...
Setting up cfengine-community (3.27.2-1.ubuntu22) ...

安装立即完成,无交互。此时二进制已就位但策略尚未初始化——CFEngine 与传统服务不同,装完必须先执行「自举(bootstrap)」才能运行(见 4.4)。

4.3 安装产物与目录结构

确认版本与安装目录:

/var/cfengine/bin/cf-agent --version
/var/cfengine/bin/cf-promises --version
ls /var/cfengine/

实测回显:

CFEngine Core 3.27.2
CFEngine Core 3.27.2
bin
inputs
lastseen
lib
masterfiles
modules
outputs
ppkeys
randseed
reports
share
state

目录逐项说明:

目录作用
bin/全部二进制(cf-agent、cf-serverd、cf-execd、cf-key、cf-promises、cf-runagent、cf-net、cf-monitord 等)
inputs/当前生效的策略输入目录(从 masterfiles 同步而来)
masterfiles/主策略库(权威源,修改在这里做,自动同步到 inputs)
modules/模块脚本(用于 usemodule 自定义 inventory/数据源)
ppkeys/主机密钥对(localhost.priv/localhost.pub,首次运行生成)
state/运行状态数据库(lmdb:lastseen、performance 等状态)
outputs/agent 运行输出捕获
reports/报告数据目录(企业版报表数据库位置,社区版基本为空)
lastseen/与远端连接记录(谁连过我、我连过谁)

二进制清单:

ls /var/cfengine/bin/ | head -22

实测回显:

cf-agent
cf-check
cf-execd
cf-key
cf-monitord
cf-net
cf-promises
cf-runagent
cf-secret
cf-serverd
cf-support
cf-upgrade
cmp
diff
diff3
getfacl
lmdump
lmmgr
mdb_copy
mdb_dump
mdb_load
mdb_stat

💡 说明:列表后半段(cmp/diff/getfacl/mdb_* 等)是 CFEngine 自带的实用工具集(基于 busybox/lmdb),供策略与运维脚本使用,避免依赖系统工具的版本差异。完整清单还有 sdiff,共 23 个文件。社区版没有 cf-report 与 cf-hub(企业版专属组件)。

4.4 自举(bootstrap):初始化策略并确定角色

自举是 CFEngine 的「开机初始化」:向一台策略服务器建立信任关系,单机场景自举到自己(127.0.0.1),本机即策略服务器(policy server)。

/var/cfengine/bin/cf-agent --bootstrap 127.0.0.1

实测回显:

 warning: Bootstrapping to loopback interface (localhost), other hosts will not be able to bootstrap to this server
R: Bootstrapping from host '127.0.0.1' via built-in policy '/var/cfengine/inputs/failsafe.cf'
R: This host assumes the role of policy server
R: Updated local policy from policy server
R: Triggered an initial run of the policy
R: Restarted systemd unit cfengine3
  notice: Bootstrap to '127.0.0.1' completed successfully!

逐行解读:

  • warning: Bootstrapping to loopback ...:提示自举目标是环回地址,本机是「单机模式」的策略服务器,其他主机无法向本机自举(多机部署时用真实 IP 自举,见《CFEngine 3.27.2 进阶实战与运维》)。
  • R: This host assumes the role of policy server:本机确定角色为策略服务器。
  • R: Updated local policy from policy server:从策略服务器拉取 Masterfiles 到 inputs——Masterfiles 初始化就在这一步自动完成。
  • R: Triggered an initial run of the policy:立即执行了一次完整策略。
  • notice: ... completed successfully!:自举成功。

自举后 inputs 与 masterfiles 内容一致(策略已就位):

ls /var/cfengine/masterfiles/

实测回显:

cf_promises_release_id
cf_promises_validated
cfe_internal
controls
inventory
lib
modules
promises.cf
services
standalone_self_upgrade.cf
templates
update.cf
ls /var/cfengine/inputs/

实测回显:

cf_promises_release_id
cf_promises_validated
cfe_internal
controls
inventory
lib
modules
promises.cf
services
standalone_self_upgrade.cf
templates
update.cf

五、systemd 单元验证

安装包注册了 4 个 systemd 单元,安装后 cfengine3 默认开机自启。

5.1 单元清单

systemctl list-unit-files | grep -E "^cf"

实测回显:

cf-execd.service                       disabled        enabled
cf-monitord.service                    disabled        enabled
cf-serverd.service                     disabled        enabled
cfengine3.service                      enabled         enabled

解读:cfengine3.service 是「总控伞形单元」(enabled 开机自启),三个子单元显式 disabled 是设计如此——它们由 cfengine3 通过 Wants= 拉起,不需要单独 enable。查看伞形单元定义:

systemctl cat cfengine3.service

实测回显:

# /lib/systemd/system/cfengine3.service
[Unit]
Description=CFEngine 3 umbrella service
Documentation=https://docs.cfengine.com/ https://northerntech.atlassian.net
After=syslog.target

# Try to start all the sub-services. 'Wants' is fault-tolerant so if some are
# missing or impossible to start, no big deal.
Wants=cf-serverd.service
Wants=cf-execd.service
Wants=cf-monitord.service
Wants=cf-postgres.service
Wants=cf-php-fpm.service
Wants=cf-apache.service
Wants=cf-hub.service
Wants=cf-reactor.service

# Ensure synchronous stop behavior
Before=cf-serverd.service
Before=cf-execd.service
Before=cf-monitord.service
Before=cf-postgres.service
Before=cf-php-fpm.service
Before=cf-apache.service
Before=cf-hub.service
Before=cf-reactor.service

[Install]
WantedBy=multi-user.target

[Service]
Type=oneshot
RemainAfterExit=yes

# Nothing to do here, we just need to make sure the specific services to be
# started/stopped.
ExecStart=/bin/true
ExecStop=/bin/true

解读:Wants= 容错拉起 8 个子单元(社区版只有 cf-serverd/cf-execd/cf-monitord 三个存在,cf-postgres/cf-apache/cf-hub 等企业版单元不存在则跳过);Before= 保证停止时伞形单元先于子单元动作;Type=oneshot + ExecStart=/bin/true 说明它只负责启停编排,真正的进程由各子单元承载。

5.2 服务状态与进程验证

systemctl status cfengine3 --no-pager | head -8

实测回显:

● cfengine3.service - CFEngine 3 umbrella service
     Loaded: loaded (/lib/systemd/system/cfengine3.service; enabled; vendor preset: enabled)
     Active: active (exited) since Sat 2026-10-17 00:35:34 UTC; 2s ago
       Docs: https://docs.cfengine.com/
             https://northerntech.atlassian.net
    Process: 5666 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
   Main PID: 5666 (code=exited, status=0/SUCCESS)
        CPU: 1ms

三个子单元逐个确认状态(systemctl 每次只操作一个单元):

systemctl is-active cf-serverd
systemctl is-active cf-execd
systemctl is-active cf-monitord

实测回显:

active
active
active

进程核实:

ps aux | grep -E "cf-(serverd|execd|monitord)" | grep -v grep

实测回显:

root        5668  4.0  0.0  92668 13180 ?        Ss   00:35   0:00 /var/cfengine/bin/cf-execd --no-fork
root        5669 10.0  0.0  93468 15380 ?        Ss   00:35   0:00 /var/cfengine/bin/cf-monitord --no-fork
root        5670  5.5  0.0  93384 14756 ?        Ss   00:35   0:00 /var/cfengine/bin/cf-serverd --no-fork

三个守护进程均已运行:cf-execd(每 5 分钟调度 cf-agent 执行策略)、cf-monitord(采集系统指标供策略使用)、cf-serverd(监听 5308 提供策略分发)。

5.3 端口监听验证

⚠️ 注意:最小化安装的系统可能没有 ss 命令(iproute2 包),先补装:apt-get install -y iproute2。

ss -tlnp | grep 5308

实测回显:

LISTEN 0      128                *:5308            *:*    users:(("cf-serverd",pid=5670,fd=5))

cf-serverd 在 5308 端口监听(CFEngine 协议默认端口,TLS 加密)。

5.4 定时调度验证

cf-execd 按默认调度(每小时每 5 分钟:Min00/Min05/.../Min55)自动执行 cf-agent。查看调度执行日志:

journalctl -u cf-execd --no-pager | tail -5

实测回显:

Oct 16 17:53:46 3b46438779b5 systemd[1]: Started CFEngine Execution Scheduler.
Oct 16 18:11:38 3b46438779b5 cf-agent[4912]: CFEngine(agent)  R: custom bundle ran on host 3b46438779b5
Oct 16 18:11:38 3b46438779b5 cf-agent[4912]: CFEngine(agent)  R: second autorun bundle is alive
Oct 16 18:11:38 3b46438779b5 cf-execd[4902]:    error: Mail report: unable to lookup smtp service. (getservbyname: No such file or directory)
Oct 16 18:11:38 3b46438779b5 cf-execd[4902]: CFEngine(executor)  Mail report: unable to lookup smtp service. (getservbyname: No such file or directory)

R: 行说明调度执行的 cf-agent 真实运行了策略(其中的自定义策略输出见《CFEngine 3.27.2 快速入门与策略编写示例》;末尾的 mail 报错处置见 10.3)。

六、安装方案 B:本地 apt 仓库(内网批量部署备用方案)

当多台 Ubuntu 内网机器需要统一安装、且不能逐台 wget 官方地址时,把官方 deb 包做成一个本地 apt 仓库,各机器通过 file:// 或 HTTP 访问。本节在 Ubuntu 22.04 上完整实测。

6.1 仓库机:准备包与索引

apt-get install -y dpkg-dev
mkdir -p /opt/cfengine-repo
cp /tmp/cfengine-community_3.27.2-1.ubuntu22_amd64.deb /opt/cfengine-repo/
cd /opt/cfengine-repo
dpkg-scanpackages --multiversion . > Packages
gzip -9kf Packages
ls -la

实测回显(输出节选):

dpkg-scanpackages: info: Wrote 1 entries to output Packages file.
total 6524
drwxr-xr-x 2 root root    4096 Oct 17 00:14 .
drwxr-xr-x 1 root root    4096 Oct 17 00:14 ..
-rw-r--r-- 1 root root     955 Oct 17 00:14 Packages
-rw-r--r-- 1 root root     594 Oct 17 00:14 Packages.gz
-rw-r--r-- 1 root root 6662426 Oct 17 00:14 cfengine-community_3.27.2-1.ubuntu22_amd64.deb

⚠️ 注意:dpkg-scanpackages 在 dpkg-dev 包里,最小化系统默认没有,直接执行会报 dpkg-scanpackages: command not found(实测踩坑),先装 dpkg-dev。

6.2 客户端:配置本地源并安装

在尚未安装 CFEngine 的机器上配置本地源:

echo "deb [trusted=yes] file:/opt/cfengine-repo ./" > /etc/apt/sources.list.d/cfengine-local.list
apt-get update

实测回显(apt-get update 节选):

Get:1 file:/opt/cfengine-repo ./ InRelease
Ign:1 file:/opt/cfengine-repo ./ InRelease
Get:2 file:/opt/cfengine-repo ./ Release
Ign:2 file:/opt/cfengine-repo ./ Release
Get:3 file:/opt/cfengine-repo ./ Packages [594 B]

确认候选版本来自本地源:

apt-cache policy cfengine-community

实测回显:

cfengine-community:
  Installed: 3.27.2-1.ubuntu22
  Candidate: 3.27.2-1.ubuntu22
  Version table:
 *** 3.27.2-1.ubuntu22 500
        500 file:/opt/cfengine-repo ./ Packages
        100 /var/lib/dpkg/status

解读:Installed 行非 none 时表示该机器已装(本文实测机即如此);*** 指向 Candidate=3.27.2-1.ubuntu22,来源 500 file:/opt/cfengine-repo ./ Packages 即本地仓库。在尚未安装 CFEngine 的新机器上,Installed: 显示 (none),其余行相同。

执行安装:

apt-get install -y cfengine-community

实测回显(输出节选):

Preparing to unpack .../cfengine-community_3.27.2-1.ubuntu22_amd64.deb ...
Unpacking cfengine-community (3.27.2-1.ubuntu22) ...
Setting up cfengine-community (3.27.2-1.ubuntu22) ...

验证:

/var/cfengine/bin/cf-agent --version

实测回显:

CFEngine Core 3.27.2

💡 说明:[trusted=yes] 跳过 GPG 签名校验,适合内部测试仓库;生产建议用 apt-ftparchive + 签名生成 Release.gpg。多机共享时把 /opt/cfengine-repo 用 nginx/apache 发布为 HTTP 目录,客户端源改写为 deb [trusted=yes] http://<仓库机IP>/cfengine-repo ./ 即可。后续新版本只需把新 deb 放进目录重跑 6.1 的两条索引命令。

已装同版本的机器上再执行 apt-get install -y cfengine-community 不会重装,实测提示 cfengine-community is already the newest version (3.27.2-1.ubuntu22).;需要强制重装时用 apt-get install --reinstall -y cfengine-community,实测回显出现 Unpacking cfengine-community (3.27.2-1.ubuntu22) over (3.27.2-1.ubuntu22) ...。

七、方案对比与选择建议

维度方案 A:官方 deb + dpkg方案 B:本地 apt 仓库
前置网络需访问官方 S3 包仓库仅内网
安装命令dpkg -i <deb>apt-get install cfengine-community
依赖处理手工(本包无外部依赖,22.04 直接可装)apt 自动解析
批量升级逐台下载新 deb仓库机放新包后全端 apt-get upgrade
适用场景单机/少量机器、快速验证多台机器、内网隔离、版本统一管控

选择建议:一台到几台机器直接用方案 A(最贴近官方);内网多机或禁止直连外网的环境用方案 B。两种方案安装出的二进制与目录完全一致,可混用(先用 A 装首台,再把它下载的 deb 做成 B 的仓库)。

八、安装后基础验证

8.1 手动执行一次策略

自举后可手动触发一次完整策略运行(-K 忽略锁、-I 只显示变更):

/var/cfengine/bin/cf-agent -KI

实测回显(系统已收敛时无变更输出):

(无输出)
echo $?

实测回显:

0

💡 说明:CFEngine 策略是声明式、幂等的——系统已满足策略时重复执行不做任何变更,这是它与传统脚本运维的核心区别。给系统制造一个漂移再跑一次,会看到修复动作(完整演示见《CFEngine 3.27.2 快速入门与策略编写示例》)。

8.2 主机身份与密钥

自举过程中 cf-key 生成了本机密钥对:

ls /var/cfengine/ppkeys/

实测回显:

localhost.priv
localhost.pub
root-MD5=8838cc78c7fda5865f8b959ed260e7c6.pub

localhost.priv/localhost.pub 是本机身份密钥;root-MD5=....pub 是信任的远端公钥(自举到自己,所以存的是本机 root 的公钥,MD5 值每台机器不同)。

九、升级与降级

9.1 准备旧版本包(3.27.1)

升级/降级演示需要两个版本的包。旧版本包的地址同样从官方清单取(https://cfengine-package-repos.s3.amazonaws.com/release-data/community/3.27.1.json),下载并校验:

cd /tmp
wget -q https://cfengine-package-repos.s3.amazonaws.com/community_binaries/Community-3.27.1/agent_ubuntu22_x86_64/cfengine-community_3.27.1-1.ubuntu22_amd64.deb
sha256sum cfengine-community_3.27.1-1.ubuntu22_amd64.deb

实测回显:

3a4ab74097569316be6837ab44f4193f9d6d8cd540786e001e9cac38286ee5df  cfengine-community_3.27.1-1.ubuntu22_amd64.deb

与官方 3.27.1.json 中 Ubuntu 22.04 条目一致。

9.2 升级(3.27.1 → 3.27.2 实测)

在已运行 3.27.1 的机器上(本章先按 9.3 的降级方式构造该环境,实测中已验证),直接用新版本 deb 包覆盖安装,配置与数据全部保留:

dpkg -i cfengine-community_3.27.2-1.ubuntu22_amd64.deb

实测回显:

(Reading database ... 16983 files and directories currently installed.)
Preparing to unpack .../cfengine-community_3.27.2-1.ubuntu22_amd64.deb ...
Unpacking cfengine-community (3.27.2-1.ubuntu22) over (3.27.1-1.ubuntu22) ...
Setting up cfengine-community (3.27.2-1.ubuntu22) ...
Installing new version of config file /etc/profile.d/cfengine3.sh ...

验证升级生效且服务未中断:

/var/cfengine/bin/cf-agent --version
systemctl is-active cfengine3
systemctl is-active cf-serverd
systemctl is-active cf-execd

实测回显:

CFEngine Core 3.27.2
active
active
active

⚠️ 注意:升级覆盖了二进制但 /var/cfengine/masterfiles 下的策略是旧版本时,官方建议升级后用新包自带的 Masterfiles 重新同步(对照《CFEngine 3.27.2 配置参数详解》中 masterfiles 与 inputs 的同步机制)。跨大版本升级(如 3.21 → 3.27)先在测试机验证策略兼容性。

9.3 降级

dpkg 对安装更低版本的包不禁止、仅提示 warning,可直接安装(实测从 3.27.2 降回 3.27.1,构造 9.2 的升级演示环境即用此方式):

dpkg -i cfengine-community_3.27.1-1.ubuntu22_amd64.deb

实测回显:

dpkg: warning: downgrading cfengine-community from 3.27.2-1.ubuntu22 to 3.27.1-1.ubuntu22
(Reading database ... 16983 files and directories currently installed.)
Preparing to unpack .../cfengine-community_3.27.1-1.ubuntu22_amd64.deb ...
Unpacking cfengine-community (3.27.1-1.ubuntu22) over (3.27.2-1.ubuntu22) ...
Setting up cfengine-community (3.27.1-1.ubuntu22) ...
Installing new version of config file /etc/profile.d/cfengine3.sh ...
/var/cfengine/bin/cf-agent --version

实测回显:

CFEngine Core 3.27.1

--force-downgrade 显式声明同样可用,效果一致(用于脚本中明确表达降级意图):

dpkg -i --force-downgrade cfengine-community_3.27.1-1.ubuntu22_amd64.deb

实测回显:

(Reading database ... 16983 files and directories currently installed.)
Preparing to unpack .../cfengine-community_3.27.1-1.ubuntu22_amd64.deb ...
Unpacking cfengine-community (3.27.1-1.ubuntu22) over (3.27.1-1.ubuntu22) ...
Setting up cfengine-community (3.27.1-1.ubuntu22) ...

降级前备份 /var/cfengine/masterfiles 与 /var/cfengine/inputs(策略语法若用到了新版特性,旧版 agent 无法解析)。多版本共存时,把不同版本 deb 都放入方案 B 的本地仓库,用 apt-get install cfengine-community=<版本号> 指定版本安装,例如 apt-get install cfengine-community=3.27.1-1.ubuntu22。

十、常见问题(FAQ)

10.1 官方 apt 源不可用:packagecloud 返回 404

现象:按老教程执行 curl -s https://packagecloud.io/install/repositories/cfengine/community/script.deb.sh | bash 配置在线 apt 源失败。

实测复现:

curl -s https://packagecloud.io/install/repositories/cfengine/community/script.deb.sh | head -8
curl -s -o /dev/null -w "%{http_code}\n" https://packagecloud.io/install/repositories/cfengine/community/script.deb.sh

实测回显:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Not found">
    <meta name="title" content="404 Not Found | Packagecloud">
    <title>404 Not Found | Packagecloud</title>

404

定位与解决:CFEngine 官方已下线 packagecloud 的 apt/rpm 源(HTTP 404 实测确认),官方包仓库迁移到 S3(cfengine-package-repos.s3.amazonaws.com),社区版分发方式改为「按版本直接下载 deb/rpm 包」。老教程里的 apt 源配置方式一律弃用,改用本文方案 A;需要 apt 管理的用方案 B 自建本地仓库。

10.2 自举失败:无法解析策略服务器

现象:cf-agent --bootstrap <IP> 报错退出,提示连接失败或 no input file at '/var/cfengine/inputs/promises.cf' after bootstrap。

定位:按序检查——(1) 服务器侧 cf-serverd 是否监听 5308:ss -tlnp | grep 5308;(2) 服务器防火墙是否放行 5308/TCP;(3) 服务器 ACL 是否放行客户端网段(社区版默认 ACL 只允许本机与策略服务器所在网段推导值,多机部署必须在服务器的 /var/cfengine/masterfiles/def.json 中用 variables.acl 放行客户端网段,实测排障全过程见《CFEngine 3.27.2 进阶实战与运维》)。

解决:修复对应项后重试自举;单机自举(--bootstrap 127.0.0.1)不依赖网络,报错时优先检查系统时间是否准确(TLS 握手对时钟敏感,偏差过大会失败)。

10.3 cf-execd 日志报错:unable to lookup smtp service

现象:journalctl -u cf-execd 中每次调度执行后出现:

error: Mail report: unable to lookup smtp service. (getservbyname: No such file or directory)

定位:MPF(Masterfiles Policy Framework)默认开启「agent 运行结果邮件通知」(mailto=root@、smtpserver=localhost,见《CFEngine 3.27.2 配置参数详解》对 body executor control 的解析),系统没有 smtp 服务时该报错每次执行都会出现。功能不影响策略执行,但污染日志。实测复现:在未修复的机器上执行 /var/cfengine/bin/cf-execd -FO(前台单次运行),立即输出上述 error 行。

解决:在 /var/cfengine/masterfiles/def.json 的 classes 中加入 cfengine_internal_disable_agent_email(实测验证有效):

{
  "classes": {
    "cfengine_internal_disable_agent_email": ["any"]
  }
}

同步策略并重启后验证(单次前台运行无 error 输出、退出码 0 即为修复成功):

/var/cfengine/bin/cf-agent -KIf /var/cfengine/inputs/update.cf --define validated_updates_ready
systemctl restart cfengine3
/var/cfengine/bin/cf-execd -FO
echo $?

实测回显(同步阶段输出节选 + 最终验证):

    info: Updated '/var/cfengine/inputs/def.json' from source '/var/cfengine/masterfiles/def.json' on 'localhost'
(cf-execd -FO 无输出)
0

def.json 的完整机制见《CFEngine 3.27.2 配置参数详解》。

10.4 卸载重装后自举报密钥错误

现象:dpkg -P 卸载并重装后再次 --bootstrap 失败或连接被拒。

定位:dpkg -P 不删除 /var/cfengine(数据目录,见十一),旧的 ppkeys、policy_server.dat、state 残留可能与新装身份冲突。

解决:确认不再需要旧数据后彻底清理再重装自举:

rm -rf /var/cfengine
dpkg -i cfengine-community_3.27.2-1.ubuntu22_amd64.deb
/var/cfengine/bin/cf-agent --bootstrap 127.0.0.1

实测回显(重装阶段,输出节选):

Selecting previously unselected package cfengine-community.
(Reading database ... 16311 files and directories currently installed.)
Preparing to unpack .../cfengine-community_3.27.2-1.ubuntu22_amd64.deb ...
Unpacking cfengine-community (3.27.2-1.ubuntu22) ...
Setting up cfengine-community (3.27.2-1.ubuntu22) ...

实测中发现一个真实的二次自举坑:重装后紧接着自举,可能因 cf-execd 单元尚未就绪而失败:

R: Triggered an initial run of the policy
R: Restarted systemd unit cfengine3
   error: Bootstrapping failed, cf-execd is not running

处置:等待数秒后重新执行同一条 --bootstrap 127.0.0.1,实测第二次即成功(此时服务已在运行,回显中不再出现 R: Restarted systemd unit cfengine3 行):

 warning: Bootstrapping to loopback interface (localhost), other hosts will not be able to bootstrap to this server
R: Bootstrapping from host '127.0.0.1' via built-in policy '/var/cfengine/inputs/failsafe.cf'
R: This host assumes the role of policy server
R: Updated local policy from policy server
R: Triggered an initial run of the policy
  notice: Bootstrap to '127.0.0.1' completed successfully!
/var/cfengine/bin/cf-agent --version
systemctl is-active cfengine3

实测回显:

CFEngine Core 3.27.2
active

十一、卸载与清理

11.1 仅卸载软件包(保留数据)

dpkg -r cfengine-community

实测回显:

(Reading database ... 16983 files and directories currently installed.)
Removing cfengine-community (3.27.2-1.ubuntu22) ...

卸载后验证:服务停止、数据保留:

systemctl is-active cfengine3
ls /var/cfengine/ | head -6

实测回显:

inactive
backups
bin
bootstrap_id.dat
cfagent.ed7ec493a76a.log
inputs
lastseen

/var/cfengine 下的策略、密钥、状态数据全部保留(便于重装恢复)。

11.2 彻底清除

dpkg -P cfengine-community

实测回显(输出节选):

(Reading database ... 16321 files and directories currently installed.)
Purging configuration files for cfengine-community (3.27.2-1.ubuntu22) ...
dpkg: warning: while removing cfengine-community, directory '/var/cfengine/ppkeys' not empty so not removed
dpkg: warning: while removing cfengine-community, directory '/var/cfengine/outputs' not empty so not removed
dpkg: warning: while removing cfengine-community, directory '/var/cfengine/modules' not empty so not removed
dpkg: warning: while removing cfengine-community, directory '/var/cfengine/inputs' not empty so not removed
dpkg: warning: while removing cfengine-community, directory '/var/cfengine/bin' not empty so not removed
dpkg: warning: while removing cfengine-community, directory '/usr/lib/systemd/system' not empty so not removed

⚠️ 注意:这些 warning 说明 /var/cfengine 仍残留(dpkg 不删非空数据目录),确认无需保留后手工删除:

rm -rf /var/cfengine
systemctl list-unit-files | grep cfengine
ps aux | grep cf- | grep -v grep | wc -l

实测回显:

0

单元已注销(systemctl list-unit-files | grep cfengine 无输出)、无残留进程(计数 0),卸载完成。

十二、参考链接