用 Cfengine 自动化基础架构管理,第 1 部分: 安装服务器和客户机

Cfengine 是一个流行的数据中心自动化解决方案,被世界各地的组织广泛采用。它可扩展至成千上万台机器,从笔记本、台式机、嵌入式设备到大型主机。在本文中,了解如何使用这个多功能的灵活技术来解决数据中心问题。

Joanne Icken, 顾问软件工程师, IBM

Joanne Icken 是 IBM 的一名软件工程师,她在系统管理、分布式环境以及为支持企业内的应用程序而采用云技术等方面很有经验。



Todd Palmer, 顾问软件工程师, IBM

Todd Palmer 是 IBM Innovation System 团队的一名软件工程师,在这个团对,他负责实现配置管理和自动化软件。之前,他曾供职于 IBM Watson Research 的 Information System Client Engineering Team。



2011 年 8 月 01 日

简介

如今,IT 数据中心必须跨多个操作系统版本提供和维护稳定性、安全性和可伸缩性服务,这类服务可在多种服务器硬件和操作系统上运行。效率很重要,管理员希望能够最小化这些服务的支持,让其成为全自动,就像自动熄灯一样。在这个两个部分系列文章 “用 Cfengine 自动化基础架构管理” 中,我们将探讨一种用于系统管理和 IT 管理的自动框架:Cfengine。

本系列第 1 部分将为您提供一个 Cfengine V3 Community Edition 概述,以及有关如何构建及配置 Cfengine 策略/发布服务器和客户机的信息。第 2 部分则会用示例说明如何使用 Cfengine 完成服务支持所涉及到的诸多日常任务。

本文假设您已经安装了基础的 UNIX® 或 Linux® 操作系统,并且非常熟悉 Cygwin 和 Linux 打包命令。


配置管理和 Cfengine

良好的配置管理可以建立和维护 IT 平台和产品及其环境的性能、功能以及物理属性的一致性。它还可用来决定适当的安全性特性并确保这些特性的正确应用。这是一项复杂的工作,有很多配置管理工具可用。

有些工具,比如 Arusha Project (ARK),可与 Cfengine 结合使用。其他工具虽然使用的是类似的系统管理概念,但以不同的编程语言编写,比如 Puppet 是用 Ruby 编写、REST 调用的,又比如 Synctool 是用 Python 编写的,再比如 SmartFrog,是基于 Java™ 技术的。而类似 opsi (Open PC Server Integration) 这样的工具则只面向 Windows® 编写。IBM® Systems Director 以及最近收购的 IBM BigFix 也能提供配置管理。

Cfengine 是一种 GNU 开源配置管理框架,用于计算机系统自动化。此框架是轻量的,可针对几乎所有平台构建。它能运行在所有常见平台上,其中包括 AIX、Linux、UNIX、Apple 和 Windows。

IT Infrastructure Library 是在全球应用最为广泛的一种 IT 服务管理方式,它定义了知识管理 作为交付服务的关键过程。知识管理确保一个人只要拥有这方面的知识就能够交付并支持业务所需的服务。前提是高效提供服务时,清晰地理解服务带来的价值,并提供所需的相关可用信息。Cfengine V3 关注管理生命周期每个阶段的知识管理。通过使用一个已定义配置,Cfengine 能够确保您拥有恰当的包、配置文件、文件权限,且进程运行在您的环境中。

Cfengine 有两个版本:一个是存在已久的社区版,另一个是商业的企业版。对于商业版,亦有几种形式:Nova、Constellation 和 Galaxy(参见 参考资料)。


生命周期管理

Cfengine 遵循的是系统生命周期管理的 Build-Deploy-Manage-Audit (BDMA) 模式。BDMA 包含系统生命周期的四个阶段:构建、部署、管理和审计。在构建阶段,需要计划策略更改、规划想要的状态承诺(promise)以及构建所建议承诺的模板,这样如果所有机器均能做出并兑现这些承诺,系统便可无缝地运行。

在部署阶段,需要向所有自主客户端(autonomous clients)发布策略,并且每个客户机都要运行一个代理,无需协助即可实现并维护这些策略。

在管理阶段,这个自主代理负责管理该系统,您只需处理不能被自动处理的极少事件。

最后,在审计阶段,对更改进行本地审计和维护。决策结果由 Cfengine 内的设计确保且可自动维护。

Cfengine 不应被视作一种转出(rollout)系统,其中人们试图剔除绝对更改并在出现错误时反转 Cfengine,需发布策略修订序列,然后继续。这些状态更改由各个客户端本地管理且不断修护以便符合策略。

依赖项

Cfengine 需要 OpenSSL 和 BerkeleyDB V3.2 或更高版本。您还可选择为支持 Perl Compatible Regular Expression library (PCRE)、OpenLDAP 和 PostgreSQL 或 MySQL 而构建。有些数据库特性只在商业版本可用。在 Windows 上,Cfengine 需要 Cygwin 环境。而且,像 Subversion (SVN) 这样的版本控制软件可用来控制对配置文件的更改。

术语

  • 承诺 — 定义的动作或规则,以便系统遵循。
  • 包 — 承诺组。
  • 策略 — 定义我们所能管理的实际知识包。
  • 类 — 定义为 "on" 或 "off" 的属性/变量。
  • 策略包含承诺包。
  • 密钥 — 可以是公共或私有的,用来对可以访问服务器进行身份验证,在每个客户机上使用 cf-key 生成,然后再复制到服务器上的密钥仓库。在 IBM ,只使用服务器密钥就足以提供安全性。

准备开始

Cfengine 可运行于任何 UNIX 服务器上,若有 Cygwin 环境,也可运行在 Windows 上。在一个 UNIX 服务器上,先安装 OpenSSL、BerkeleyDB 以及上述讨论的所有附加包。Cfengine 通常从一个分布包(比如 rpm 或 deb)安装,或者,源代码也可下载和编译(参见 参考资料)。

如果计划从源代码构建 Cfengine,还将需要在 UNIX/Linux 服务器上安装额外的工具,比如 gcc、flex 和 bison。在一个 Windows 服务器上,先安装 Cygwin,然后安装 gcc、flex 和 bison 工具来编译并安装代码。

这些基本 Cfengine 文件安装在 Cfengine 工作目录 /var/cfengine 的子目录内。这个工作目录为 Cfengine 自己所用,且在构建时定义。这个路径可视为是一个安全的本地文件系统。配置文件编码后,可将其放置于所有 Cfengine 服务器上的配置分布点内(比如 /var/cfmasterfiles)。这个路径通常置于版本控制目录下。

从源代码构建 Cfengine

从 Cfengine 存储库下载源代码。作为一个非 root 用户登录到此系统并运行如下命令。

tar –zxf cfengine-x.x.x.tar.gz
cd cfengine-x.x.x
./configure --prefix=/var/cfengine 
   --sbindir=/var/cfengine/bin --localstatedir=/var/cfengine
   --with-workdir=/var/cfengine --with-openssl=/usr make

现在转到 root 用户并运行如下命令(二进制文件置于 /var/cfengine/bin 内)。

make install 
make installcheck

在 Policy/Distribution Server 上安装 Cfengine

作为 root 用户登录到系统并执行如下命令:

mkdir –p /var/cfengine/masterfiles
cp cfengine-x.x.x/inputs/update.cf to /var/cfengine/masterfiles
cp cfengine-x.x.x/inputs/promises.cf to /var/cfengine/masterfiles

用适当的电子邮件地址更新文件 promises.cf 内的 "mailto" 选项。在 promise.cf 的 "body server control" 部分添加服务器应该接受其连接的网络:

allowconnects => { "192.", "10.", "127.0.0.1" , "::1" };
allowallconnects => { "192.", "10.", "127.0.0.1" , "::1" };
trustkeysfrom => { "192.", "10.", "127.0.0.1" , "::1" };

在所有配置文件内将策略服务器更新为这个新的服务器环境:

cp cfengine-x.x.x/inputs/failsafe.cf to /var/cfengine/masterfiles
cp cfengine-x.x.x/inputs/cfengine_stdlib.cf to /var/cfengine/masterfiles

Cfengine 组件

以下列出的是 Cfengine 安装中需要注意的组件。 (注意:如果您是从一个二进制包安装的 Cfengine,或是在编译安装过程中做过定制,那么这些基础目录有可能不同。)

目录

  • /var/cfengine/bin — 具有 Cfengine 二进制文件的目录
  • /var/cfengine/inputs — 具有 Cfengine 配置文件的目录
  • /var/cfengine/outputs — 具有 Cfengine 运行报告的目录
  • /var/cfengine/ppkeys — 具有身份验证密钥的目录
  • /var/cfmasterfiles — 具有策略服务器上的主文件的目录
  • /var/cfengine/repository — 包含了重要 Cfengine 文件备份以备恢复(name/location 可配置)的目录

二进制文件

  • /var/cfengine/bin/cf-promises — 检查承诺语法的命令
  • /var/cfengine/bin/cf-agent — 维护共同做出的承诺及有关系统状态的代理包的命令
  • /var/cfengine/bin/cf-serverd — 用来将策略或数据文件发布到客户端并就来自 cf-runagent 的请求进行响应的服务器(守护进程)
  • /var/cfengine/bin/cf-execd — 负责运行 cf-agent 的调度守护进程
  • /var/cfengine/bin/cf-runagent — 在远端机器上运行 cf-agent 的命令
  • /var/cfengine/bin/cf-monitord — 负责收集有关系统状态信息的守护进程
  • /var/cfengine/bin/cf-report — 从 Cfengine 嵌入数据库生成摘要和其他报告的命令
  • /var/cfengine/bin/cf-know — 从大量承诺(知识建模代理)生成一个 ISO 标准的 Topic Map 的命令
  • /var/cfengine/bin/cf-key — 在每个主机上运行一次来创建用于安全通信的公共/私有密钥对的密钥生成工具

配置文件

  • /var/cfengine/inputs/promises.cf — cf-agent 所使用的主要配置文件
  • /var/cfengine/inputs/library.cf — 包含了可重用代码集的社区库;对于 V3.1.x 发布版,最好使用这个社区库

首次启动 Cfengine Policy Server

在该服务器上运行如下命令:

/var/cfengine/bin/cf-key
mkdir /var/cfmasterfiles/ppkeys
cp /var/cfengine/ppkey/localhost.pub /var/cfmasterfiles/ppkeys/root-<servername or ip>.pub
cp /var/cfengine/ppkey/localhost.priv \
/var/cfmasterfiles/ppkeys/root-<servername or ip>.priv
cp /var/cfmasterfiles/inputs/update.cf /var/cfengine/inputs/
cp /var/cfmasterfiles/inputs/failsafe.cf /var/cfengine/inputs/
/var/cfengine/bin/cf-agent –bootstrap

Cfengine Policy 服务器现已配置。为了准备 Cfengine 来充当远端客户机,执行如下命令: start cf-server

在大多数环境内,可以通过配置运行 cf-serverd。其他时候,最好是为服务器配置准备一个独立的配置文件。如果进程意外终止,这可以提供一个位置供外部进程重新启动 cf-serverd。我们还可以用一个 watchdog 脚本来重新启用 cf-serverd。要从命令行运行它:

/var/cfengine/bin/cf-serverd
/var/Cfengine/bin/cf-serverd –f
/var/cfmasterfiles/prod/server/server.cf

客户端的初始设置

  1. /var/cfengine/inputs/failsafe.cf
  2. /var/cfengine/inputs/update.cf
  3. /var/cfengine/ppkeys/root-<server>.pub

通过执行如下命令首次启动 Cfengine 客户端:

/var/cfengine/bin/cf-key
/var/cfengine/bin/cf-agent –K –bootstrap

为您的环境创建一个二进制包

此时,您可能会想要创建 APT 或 RPM 包用来配置您的客户端。其中的一个包包含 Cfengine 二进制文件,而另外一个包则包含了最低限度的 Cfengine 配置文件及服务器公钥来引导 Cfengine,此外,还有 cf-key 以及如上所列的 cf-agent 命令。构建了这两个包后,通过安装这些包来配置 Cfengine 的客户机就显得十分简单了。

我们接下来将会展示如何针对 Red Hat 环境创建二进制包。(要创建一个 Debian 包,请参考 UbuntuForums.org。)不同发布版对创建二进制包有不同的要求。查阅您环境的参考文档,了解如何适当准备此信息。

准备一个 RPM

RPM 以一个 spec 文件开始,内含有关此包的信息。清单 1 显示了 Red Hat RPM Spec 文件的一个例子。

清单 1. Cfengine V3 Red Hat RPM spec 文件
%define debug_package %{nil}
%define bin_path \
"/bin:/usr/bin:/usr/sbin:/usr/bin/X11:/sbin:\
/opt/cfengine/bin:/
opt/cfengine/bin:/opt/freeware/bin/:/usr/gnu/bin"
Name : cfengine
Summary : A tool to maintain complicated networks
Version : 3.1.4
Release : 1
URL : http://www.cfengine.org
Vendor : %{__spec_vendor}
License : GPL
Group : System Environment/Client Management
Packager : <your name> <your email address >
Distribution : %{__spec_distribution}
Source : %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
%ifos linux
Requires : db4 openssl coreutils pcre
#libacl zlib libattr e2fsprogs-libs keyutils-libs
BuildRequires : db4 db4-devel openssl openssl-devel pcre-devel
#libacl libacl-devel openssl openssl-devel pcre-devel zlib zlib-devel
                libattr libattr-devel e2fsprogs-libs keyutils-libs libselinux libsepol
ExclusiveArch : i386 x86_64 ppc ppc64
%endif
%descriptionCfengine is the standalone, open-source datacenter 
management platform run by leading enterprises since 1993. 
Customize your IT systems, align to network, business and 
regulatory needs, monitor problems, automatically repair 
and maintain systems more effectively than with proprietary 
software. Cope with new and legacy systems and adopt on a 
phased basis. Cfengine yields reduced costs, improved 
efficiency and higher return on investment for the lowest 
cost of adoption in the industry!
Authors:
--------
Mark Burgess
%prep
[ -d %{buildroot} -a "%{buildroot}" != "" ] && rm -rf %{buildroot}
mkdir -p %{buildroot}
%setup -q
%build
export CFLAGS="-g -O2 -D_FORTIFY_SOURCE=0"
%configure \
--prefix=/var/cfengine \
--sbindir=/var/cfengine/bin \
--localstatedir=/var/cfengine \
--with-workdir=/var/cfengine \
--libdir=%{_libdir} \
--with-berkeleydb=%{_libdir} \
--with-openssl=/usr \
--with-pcre
make
make DESTDIR=${RPM_BUILD_ROOT} install
%files
%defattr(-,root,root)
%{_mandir}/man?/*
/var/cfengine/*
%{_libdir}/libpromises.la
%{_libdir}/libpromises.so*
%pre
export PATH=$PATH:%bin_path
%post
export PATH=$PATH:%bin_path

RPM 构建过程

  1. 将源代码下载到 /usr/src/redhat/SOURCES/ 文件夹。
  2. 将此 spec 文件放置于 /usr/src/redhat/SPECS/ 文件夹。
  3. 运行命令 rpmbuild –ba /usr/src/redhat/SPECS/cfengine.spec 来构建二进制 RPM 和源 RPM。
  4. 通过运行 rpm –ivh <RPM name> 安装并测试这个新的 RPM。通过运行 rpm –e <RPM name> 测试 RPM 的删除。

Cfengine 的第一步

初始化后,cf-agent 可自动识别主机上的很多属性。从这些属性,定义了 “硬类”。随着过程的运行,其他要定义的类就是所谓的 “软类”。最初的执行开始于从 cron 或命令行调用 cf-execd –Fcf-execd 读取 cf-promise 文件,由它进行语法检查。如果发现错误, cf-agent 就会中止当前的配置,并转而运行 /var/cfengine/inputs/failsafe.cf 配置。

图 1 以图解的方式解释了 Cfengine 过程。

图 1. Cfengine 过程
此图显示了没有问题时 promise.cf 的流程以及检测到错误时退到 failsafe.cf

示例配置

为了方便您熟悉 Cfengine,清单 2-6 显示了将要放置于 /var/cfengine/inputs 内的示例配置文件。要验证语法是否正确,运行 cf-promises –f ./test.cf。若要使用此配置执行,运行 cf-agent –Kiv -f ./test .cf

清单 2. 示例 failsafe.cf
########################################################
# failsafe.cf
########################################################
body common control
{
 bundlesequence => { "update" };
 inputs => { "update.cf" };
 version => "1.2.3";
}
bundle agent failsafe
{
 classes:
  "failsafe" not => "bootstrap_mode";
}
清单 3. 示例 promises.cf
#######################################################
# Copyright (C) Cfengine AS
# This file is part of Cfengine 3 - written and maintained by Cfengine AS.
#######################################################
# promises.cf
#######################################################
body common control
{
 bundlesequence => { 
   "update",
   "garbage_collection",
   "main"
};
inputs => {
 "update.cf",
 "site.cf"
};
}
#######################################################
body agent control
{
 ifelapsed => "15";
}
#######################################################
body executor control
{
 splaytime => "1";
 mailto => "username@localhost.localdomain";
 smtpserver => "localhost";
 mailmaxlines => "30";
 # Instead of a separate update script, now do this
 exec_command => "$(sys.workdir)/bin/cf-agent -f failsafe.cf && 
         $(sys.workdir)/bin/cf-agent";
}
#######################################################
body reporter control
{
 reports => { "performance", "last_seen", "monitor_history" };
 build_directory => "$(sys.workdir)/reports";
 report_output => "html
}
#######################################################
body server control 
{
 allowconnects => { "192.", "10.", "127.0.0.1" , "::1" };
 allowallconnects => { "192.", "10.", "127.0.0.1" , "::1" };
 trustkeysfrom => { "192.", "10.", "127.0.0.1" , "::1" };
 # Makes updates and runs happen in one
 cfruncommand => "$(sys.workdir)/bin/cf-agent -f failsafe.cf && 
         $(sys.workdir)/bin/cf-agent";
 allowusers => { "root" };
}
#######################################################
# Server configuration
#######################################################
bundle server access_rules()
{
 access:
  "/var/cfmasterfiles"
  admit => { "192.", "10.", "127.0.0.1" , "::1" };
 roles:
  ".*" authorize => { "root" };
}
body action local_immediate
{
 ifelapsed => "0";
 action_policy => "fix";
}
#######################################################
## To avoid namespace conflict and reduce file footprint
#######################################################
body depth_search local_recurse(d)
{
 depth => "$(d)";
 xdev => "true";
}
body delete local_tidy
{
 dirlinks => "delete";
 rmdirs => "true";
}
body file_select local_days_old(days)
{
 mtime => irange(0,ago(0,0,"$(days)",0,0,0));
 file_result => "mtime";
}
body classes local_define(class,alert)
{
 promise_repaired => { "$(class)" };
 repair_failed => { "$(alert)" };
}
清单 4. 示例 update.cf
#######################################################
### update.cf – config file used by the base delivery system
#######################################################
bundle agent update
{
vars:
 "master_inputs" string => "/var/cfmasterfiles/inputs";
 "master_scripts" string => "/var/cfmasterfiles/scripts";
 "master_ppkeys" string => "/var/cfmasterfiles/ppkeys";
 "master_server" slist => { "localhost" };
 redhat|centos::
 "update_crontab" string => "/var/spool/cron/root";
 SuSE::
 "update_crontab" string => "/var/spool/cron/tabs/root";
 #define others as needed (darwin, macOSX should support below)
 (!SuSE).(!redhat)::
 "update_crontab" string => "/var/spool/cron/crontabs/root";
classes:
 "exec_fix" not => regline(".*cf-execd.*","$(update_crontab)");
files:
 "/var/cfengine/inputs" 
 handle => "update_inputs",
 comment => "Update the base inputs directory for client",
 perms => u_p("600"),
 copy_from => update_scp("$(master_inputs)","$(master_server)"),
 depth_search => recurse_svn("inf"),
 file_select => cf3_config,
 action => update_immediate;
 "/var/cfengine/scripts" 
 handle => "update_scripts",
 comment => "Update the base scripts directory for client",
 perms => u_p("750"),
 copy_from => update_scp("$(master_scripts)","$(master_server)"),
 depth_search => recurse_svn("inf"),
 file_select => cf3_scripts,
 action => update_immediate; "/var/cfengine/ppkeys" 
 handle => "update_ppkeys",
 comment => "Update the base ppkeys directory for client",
 perms => u_p("600"),
copy_from => update_scppubs("$(master_ppkeys)","$(master_server)"),
 depth_search => recurse_svn("inf"),
 file_select => cf3_pub,
action => update_immediate;
 exec_fix::
 "$(update_crontab)"
 handle => "update_cron",
 comment => "Ensure that cron entry exists",
 create => "true",
 action => update_immediate,
 edit_line => update_add2cron,
 classes => update_repaired("updated_cron");
commands:
 bootstrap_mode::
 "/bin/echo"
 args => "Running Bootstrap, version: $(sys.cf_version) Workdir is: $(sys.workdir) ",
 handle => "callback_bootstrap",
 comment => "Callback Bootstrap happened",
 action => update_immediate;
 failsafe::
 "/bin/echo"
 args => "Running Failsafe, version: $(sys.cf_version) Workdir is: $(sys.workdir) ",
 handle => "callback_failsafe",
 comment => "Callback Failsafe happened",
 action => update_immediate;
 !bootstap.!failsafe::
 "/bin/echo"
 args => "Running Normal, version: $(sys.cf_version) Workdir is: $(sys.workdir)",
 handle => "callback_normalrun",
 comment => "Callback Normal Run Happened",
 contain => update_root,
 action => update_immediate;
}
############################################
body perms u_p(p)
{
 mode => "$(p)";
}
body depth_search recurse_svn(d) 
{ 
 depth => "$(d)"; 
 exclude_dirs => { "\.svn" }; 
}
############################################
 add_cron::
 "Added a 15 minute schedule to crontab";
}
body file_select cf3_config
{
 leaf_name => { "^.svn", ".*\.cf" , ".*\.sh" };
 file_result => "leaf_name";
}
body file_select cf3_scripts
{
 leaf_name => { ".*\.sh", ".*.py" };
 file_result => "leaf_name";
}
body file_select cf3_pub
{
 leaf_name => { "^localhost*", ".*\.pub" };
 file_result => "leaf_name";
}
#########################################################
body copy_from update_scp(from,server)
{
 source => "$(from)";
 servers => { "$(server)" };
 compare => "digest";
 verify => "true";
 purge => "true";
 trustkey => "true";
}
body copy_from update_scppubs(from,server)
{
 source => "$(from)";
 servers => { "$(server)" };
 compare => "digest";
 verify => "true";
 purge => "false";
 trustkey => "true";
} body action update_immediate
{
 ifelapsed => "0";
}
body classes update_repaired(class)
{
 promise_repaired => { "$(class)" };
}
body action update_background
{
 ifelapsed => "0";
 action_policy => "fix";
}
body contain update_root
{
 exec_owner => "root";
 useshell => "true";
}
#########################################################
# bundle for bodies
#########################################################
bundle edit_line update_add2cron {
 classes: 
 "add_cron" not => regline("^#*[CF3 normal run]","$(edit.filename)");
 insert_lines:
 add_cron::
 "5,15,30,45 * * * * /var/cfengine/bin/cf-execd -F #CF3 normal run";
 reports:
add_cron::
 "Added a 15 minute schedule to crontab";
}
清单 5. 示例 site.cf
#######################################################
# Copyright (C) Cfengine AS
# This file is part of Cfengine 3 # site.cf - Site specific promises
#######################################################
bundle common g
{
vars:
 !failsafe||!bootstrap::
 "message" string => "All Looks good";
 bootstrap::
 "message" string => "Running bootstrap";
 failsafe::
 "message" string => "Running Failsafe";
}
#######################################################
# General site issues can be in bundles like this one
#######################################################
bundle agent main
{
### This would be a place to add something new!
commands:
 cfengine_3_1_4::
 "/bin/echo"
 args => "Example Command with message param: '$(g.message)'",
 handle => "echo_command",
 comment => "Example of the echo command",
 action => local_immediate,
 classes => local_define("cmd_1","life");
}
#######################################################
# Garbage collection issues
#######################################################
bundle agent garbage_collection
{
files:
 "$(sys.workdir)/outputs" 
 delete => local_tidy,
 file_select => local_days_old("5"),
 depth_search => local_recurse("inf");
}
清单 6. 示例测试执行
############################################################
#
# Simple test execution – test.cf
#
###########################################################
body common control 
{ 
bundlesequence => { "testbundle" }; 
} 
###########################################################
bundle agent testbundle 
{ 
vars: 
 "size" int => "46k"; 
 "rand" int => randomint("33","$(size)");
commands: 
 "/bin/echo" 
 args => "Hello world - $(size)/$(rand)", 
 contain => standard, 
 classes => cdefine("followup","alert");
 followup:: 
 "/bin/ls"
 contain => standard;
reports:
 alert::
 "What happened?";
}
###########################################################
body contain standard
{
 exec_owner => "mark";
 useshell => "true";
}
###########################################################
body classes cdefine(class,alert)
{
 promise_repaired => { "$(class)" };
 repair_failed => { "$(alert)" };
}

结束语

在本文中,您了解了如何初始化一个 Cfengine V3 策略/发布服务器以及 Cfengine V3 客户端。您可以安装二进制包,也可以从源代码编译。您还了解了如何使用下载的代码为您的环境构建二进制包。另外,您也了解了一些样例配置文件来运行 Cfengine,也学习了如何检查它们的准确性以及如何将它们应用到您的运行环境。

这个例子,虽然十分简单,但却可以用来测试您的环境。“用 Cfengine 自动化基础架构管理” 系列的第 2 部分将会包含系统管理的更多示例。

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Open source, Linux
ArticleID=750010
ArticleTitle=用 Cfengine 自动化基础架构管理,第 1 部分: 安装服务器和客户机
publish-date=08012011