在Ubuntu 20.04上安装和使用CFEngine社区版的方法
引言
CFEngine 是一款可扩展的IT基础设施配置管理工具。CFEngine 允许您使用相同的工具和策略语言来管理基础设施中的所有内容:Linux、Mac、Windows、BSD、Solaris、IBM AIX、HP-UX以及其他系统。您只需在要管理的每台机器上安装一个代理程序(使用 C 编写)。CFEngine 支持多种平台,并且适用于资源受限的环境,例如大型基础设施或小型物联网 (IoT) 设备。
在本教程中,您将在Ubuntu 20.04上安装CFEngine Community Edition 3.21,编写示例策略文件,并自动化您的策略运行。
先决条件
完成本教程,你需要准备以下材料:
- One Ubuntu 20.04 server with a non-root sudo user. To set this up, follow our guide Initial Server Setup with Ubuntu 20.04.
- A way of running shell commands (including sudo), such as ssh.
- A text editor. This tutorial uses nano.
第一步—安装CFEngine
在这个步骤中,您将使用apt和软件包仓库安装CFEngine。使用apt进行安装的主要优势是以后可以使用apt来更新CFEngine。
有其他安装 CFEngine 的方式适用于不同的使用场景。
- cf-remote is a flexible choice that handles installing on multiple machines, different versions of CFEngine, and nightly builds.
- The quick-install shell script is a good choice for a single machine. You can install by copying a single command into the terminal.
- You can also download the packages directly from the website.
如果您使用这些替代方法之一来安装CFEngine社区版或企业版,请跳到第2步——安装后启动CFEngine,或者在引导之后转到第3步——创建您的第一个策略。
添加CFEngine的公钥
要使用apt安装CFEngine,需要使apt能够访问存储库。第一步是将CFEngine公共GPG密钥添加到apt密钥集合中,以便apt可以信任存储库中的软件包。
用这个命令下载密钥。
- wget https://cfengine.com/pub/gpg.key -O ~/cfengine-gpg.key
然后使用apt-key添加它。
- sudo apt-key add ~/cfengine-gpg.key
添加CFEngine软件包仓库
接下来,您需要使用以下命令将CFEngine存储库添加为apt源。
- sudo sh -c “echo ‘deb https://cfengine-package-repos.s3.amazonaws.com/pub/apt/packages stable main’ > /etc/apt/sources.list.d/cfengine-community.list”
这个命令将CFEngine仓库添加到apt源列表目录中的一个文件中。
没有指定sh参数和-c选项,该命令将会出现“权限被拒绝”的错误,因为sudo并没有执行输出重定向操作。为了解决这个问题,你可以使用sh命令通过sudo运行一个shell,并通过-c选项将命令传递给它。
现在,运行更新命令,使apt能够看到来自CFEngine仓库的新包。
- sudo apt update
使用apt安装软件包
现在CFEngine软件包已经在apt中注册,您可以使用apt安装CFEngine。
- sudo apt install cfengine-community
如果你收到关于该软件包在不同(较旧)操作系统上构建的警告,你可以忽略它。该软件包仍然可以正常使用。
验证安装
当安装完成后,您将在 /var/cfengine/bin 中看到组成 CFEngine 的各个组件。其中,代理(cf-agent)是您将最常与之互动的组件。该二进制文件评估您编写的策略,对系统进行更改,并记录所执行的操作。默认情况下,代理将每五分钟唤醒一次,如果需要,获取新的策略并强制执行。
请使用以下命令来检查代理程序是否成功安装:
- sudo cf-agent –version
版本号将被打印到屏幕上。
CFEngine Core 3.21.0
Note
如果cf-agent命令无效,请检查您的PATH变量中是否包含/var/cfengine/bin/,以及该目录中是否存在cf-agent。
您还可以在/var/log/CFEngine-Install.log中查看安装日志文件,获取一些关于出错原因的提示。
第二步 – 启动CFEngine
要启动CFEngine,您需要引导代理。使用以下命令来执行此操作:
- sudo cf-agent –bootstrap 127.0.0.1
这个命令告诉代理启动CFEngine组件,并从本机(127.0.0.1)获取策略。
将来,您将希望多台机器从同一台服务器中获取策略。在这种情况下,127.0.0.1将被该服务器的IP地址所代替。然而,在本教程中为了入门和学习CFEngine,您将只使用一台机器和127.0.0.1。
您现在已经在服务器上安装并运行了CFEngine。下一步是开始编写策略。
第三步 – 创建您的第一个策略
使用CFEngine自动化系统管理任务,您将创建一个策略文件,该文件使用CFEngine自己的领域专用语言(DSL)编写。要了解有关策略语言的更多信息,例如它可以做什么以及结构如何,可以查阅CFEngine参考文档。
策略文件与脚本不同,它们是声明性的:您描述系统的期望状态,CFEngine将检查是否已经达到,并仅在必要时进行更改。一些可能需要表达在策略中的事例有:
- Ensure the user sammy exists.
- Keep the curl package updated (and installed).
- Ensure telnet is not installed.
- Render a script file from a template and some data.
- Stop a process, like httpd, if it’s running.
- Enforce strict permissions on the /usr/bin folder.
在所有这些情况下,您都需要编写策略并将其放在服务器的正确位置(/var/cfengine/masterfiles)。然后,CFEngine会:
- Automate distribution of the policy file by transferring it to your other bootstrapped hosts.
- Enforce your requirements regularly (running the policy every five minutes by default). For example, if someone deleted the user sammy, or changed the permissions on /usr/bin, these changes would be restored automatically within five minutes.
- Only make changes, such as writing to a file, if it’s necessary (that is, if the state is not already as desired).
- Handle many platform differences for you (for example, the commands used to install packages, create users, and other operations vary depending on the operating system).
在这一步骤中,您将创建一个“Hello World”策略,将文本“Hello!”输出到终端上。
使用nano或你最喜欢的文本编辑器创建一个新文件,~/hello_world.cf。
- nano ~/hello_world.cf
在文件中添加以下内容。
bundle agent main
{
reports:
"Hello!";
}
CFEngine的策略是声明性的,不是从上到下进行评估。
在CFEngine策略语言中,您对您正在管理的内容进行的每个声明都被称为承诺。承诺被组织成捆绑。捆绑非常有用,因为它们允许您选择运行策略的哪些部分(以及哪些部分不运行)以及它们的运行顺序。
在这个策略中,报告是一种承诺类型,负责将消息打印到终端。在bundle之后使用了代理关键字,表示这个bundle是给cf-agent组件使用的。这个bundle的名称是main。bundle序列指定了要评估的bundles。默认情况下,它包含了main bundle,所以你不需要改动它。
保存并关闭文件。在使用nano时,按下CTRL+X退出,按Y保存,按ENTER确认文件名并关闭文件。
由于CFEngine通常以root用户身份运行,所以它试图通过在策略文件上要求严格的权限来防止未经授权的系统更改。(允许其他用户编辑CFEngine运行的策略文件将使他们能够以特权用户的身份对系统进行更改)您可以使用chmod来编辑文件权限,从而防止其他用户编辑此文件。
- chmod 600 hello_world.cf
运行该策略时,请使用以下命令:
- sudo cf-agent ~/hello_world.cf
CFEngine代理程序根据主名称找到您的包,检查其中的承诺并评估它们。在评估承诺时,代理程序会检查是否需要对系统进行修改。在这种情况下,只有一个承诺,代理程序确定需要在终端打印一条消息来满足它。
你将收到以下输出:
R: Hello!
默认情况下,CFEngine会跟踪已完成的操作,并跳过最近评估的承诺(在最后一分钟内)。如果您尝试重新运行策略,它不会打印任何内容。您可以使用 –no-lock 命令行选项来禁用此锁定。
- sudo cf-agent –no-lock hello_world.cf
你已经创建并运行了你的第一个策略。虽然能够在控制台上输出很有用,但这个策略实际上并没有改变系统。在下一步中,你将会进行改变。
第四步 — 编写管理文本文件内容的策略
在之前的步骤中,您创建了一个策略,用于在终端打印一条消息。然而,更实际的用例是确保在基础设施的所有主机上存在一个带有特定内容的文件。在这一步中,您将编写一个策略,创建一个名为(/tmp/my_file.txt)的文本文件,其内容为“Hello, CFEngine!”。
打开一个新的策略文件,~/file_management.cf。
- nano ~/file_management.cf
请添加以下内容:
bundle agent manage_my_file
{
files:
"/tmp/my_file.txt"
content => "Hello, CFEngine!$(const.n)";
}
这个捆绑包的名称是manage_my_file,而不是main。当你编写更多的策略时,你应该给每个捆绑包取一个独特且描述性的名称。只能有一个主要的捆绑包。
由于该策略管理文件,所以承诺类型是文件。content属性用于文件承诺,表明该文件的内容应该是什么。字符串的最后部分$(const.n)展开了一个特殊变量const.n,结果是文件末尾有一个新行。
保存并关闭文件。
与以前相同,在策略文件上设置严格的权限。
- chmod 600 file_management.cf
现在用一些附加的命令行选项运行该文件。
- sudo cf-agent –no-lock –info ~/file_management.cf –bundle manage_my_file
由于不再有主要捆绑包,所以必须使用 –bundle manage_my_file 来指定捆绑包。
—info选项使CFEngine打印关于其对系统所做更改的信息性消息。
该命令的输出将含有关于这些变化的信息。
info: Using command line specified bundlesequence info: Created file ‘/tmp/my_file.txt’, mode 0600 info: Updated file ‘/tmp/my_file.txt’ with content ‘Hello, CFEngine!
这个输出表明CFEngine在/tmp目录下创建了一个名为my_file.txt的文本文件,其内容为Hello, CFEngine!。
如果您再次运行相同的命令,关于创建和更新文件的消息将不会再显示。CFEngine 会识别到文件的内容已经是正确的,并且不会进行任何更改。
Note
现在你已经有了一个工作的系统策略,你可能想在没有你的监督下运行它。你将在下一步中完成这个任务。
步骤5 — 自动化政策执行
你可能并不想一直在命令行中手动运行策略。CFEngine包括自动化功能来处理这个问题。
在这一步中,您将通过将策略文件放置在预期位置并更新JSON文件来自动运行策略。该JSON文件定期地告诉CFEngine组件在后台执行何种操作,而无需您明确地手动从命令行运行命令。
使用以下命令将您在上一步骤中创建的策略文件复制到推荐位置:
- sudo cp file_management.cf /var/cfengine/masterfiles/services/
所有的CFEngine策略都位于/var/cfengine/masterfiles/目录下。这包括了CFEngine自带的但您并没有编写的策略文件。为了将您的自定义策略与默认策略分开,建议将您的策略文件放在services/子目录中。
当CFEngine代理获取新的策略文件时,它们会将其从主控机上的这个目录复制过来。即使您只使用一台机器,代理的工作方式仍然相同:它会在/var/cfengine/masterfiles中查找文件,并将其复制到/var/cfengine/inputs中。对于新用户来说,最好使用这些路径。自定义路径或将策略文件放在其他位置需要更多工作,因为您必须确保权限、复制和查找文件的正确性。
接下来,创建一个增量JSON文件来指定策略文件的位置以及应该运行的包。
- sudo nano /var/cfengine/masterfiles/def.json
将以下内容添加到该文件中:
{
"inputs": [ "services/file_management.cf" ],
"vars": {
"control_common_bundlesequence_end": [ "manage_my_file" ]
}
}
要使你的策略定期运行(每五分钟一次),需要两个步骤:确保代理人找到并读取文件,并确保代理人运行你的捆绑程序。
在def.json中的inputs键会告诉智能体要读取哪些策略文件。在这种情况下,智能体会读取你在上一步中创建的策略文件,即file_management.cf。
vars关键字可以用于定义变量。control_common_bundlesequence_end变量在默认策略中使用,因此您在那里放置的任何束名称都将添加到bundlesequence的末尾,并在所有默认束之后进行评估。这两个信息一起意味着cf-agent在不必从命令行指定这些内容的情况下,知道要读取哪些策略文件以及其中的哪些束进行评估。
在这一点上,你正在/var/cfengine/masterfiles/中编辑策略,自动化会处理其余的事情。更具体地说,cf-agent会定期唤醒并获取你编写的新策略文件。代理将读取和评估策略,并根据需要执行所有承诺,并对机器进行必要的更改(例如编辑文件和创建用户)。
根据您在本教程中编写的策略,每次代理程序运行时,它都会确保/tmp/my_file.txt文件存在且其内容符合策略文件中的规定。
保存并关闭文件。
为确认自动化正在运行,请删除在您首次运行文件管理策略时创建的文本文件。
- sudo rm /tmp/my_file.txt
五分钟后,你可以确认CFEngine是否在后台重新创建了my_file.txt。
- cat /tmp/my_file.txt
Hello, CFEngine.
或者,您还可以强制更早地创建文件。
- sudo rm /tmp/my_file.txt ; sudo cf-agent -Kf update.cf ; sudo cf-agent -KI
rm命令会删除文件,因此CFEngine会认为需要进行更改。
第一个cf-agent命令会更新策略文件,将其从/var/cfengine/masterfiles复制到/var/cfengine/inputs。
最后的cf-agent命令强制执行您的策略,使其寻找/tmp/my_file.txt文件,必要时创建并编辑它。
在这种情况下,你在删除文件后立即运行代理程序,所以cf-agent应该打印出它创建了该文件。(这两个命令之间后台运行代理程序的机会几乎没有。)
Note
在这一步中,您已经使用CFEngine自动化了您的第一个系统管理任务。虽然本例重点是创建和编辑文件,但对于其他任务的过程是相同的:编写策略,放置在正确的目录中,然后相应地更新def.json文件。
结论是
你现在已经在一台服务器上安装并启动了CFEngine。你编写了你的第一个策略,并设置它自动运行。
下一步,您可以查看CFEngine官方文档,比如关于文件管理的教程:创建、修改和删除文件。
如果您有任何问题或需要帮助,请随时在CFEngine的GitHub讨论区中发布。