DevOps工具介绍连载(5)——CFEngine

Stella981
• 阅读 348

顾翔老师近期推出一对一入职面试辅导。有兴趣者可加微信xianggu19720625与我联系。先要提供简历初选,合适者进一步洽谈。

顾翔老师的《软件测试技术实战设计、工具及管理》网上购买地址:

https://item.jd.com/34295655089.html

《基于Django的电子商务网站》网上购买地址:

https://item.jd.com/12082665.html

店铺二维码:

DevOps工具介绍连载(5)——CFEngine

作者:whyreal
链接:https://www.jianshu.com/p/97db5cd55d61
来源:简书

本文档基于 CFEngine Core 3.9.1

Cfengine 是历史最悠久的配置管理软件. 虽然受到了来自众多后起之秀(puppet, saltstack, Chef...)的挑战, 但是 CFE 还是成功的活了下来. 相对于其他配置管理软件, CFE 最明显的优势有:

  • 依赖少, 部署方便.

    当前版本只需要安装一个包, 执行一个命令即可完成部署.

  • 运行开销小, 效率高

    CFE 使用 c/c++ 编写, 运行效率毋庸置疑.

  • 架构简单

    最核心的组件只有 cf-agent 一个, 其他的组件其实都是可选的.

    cf-serverd 通常只是一个提供策略文件下载的文件服务器. 策略文件的解析是在 agent 端进行的. 所以, 相对于其他配置管理软件, CFE 的 server 端能够管理更多的 agent 端.

    cf-execd 也不过是个定时器.

    所以, 如果你用 rsync 同步策略文件, 用 crond 定期执行 cf-agent, 完全可以不启动 cf-agent 和 cf-serverd.

  • DSL不依赖于特定编程语言.

  • 安全

    外部只能触发 cf-agent 执行, 以及类的定义. 无法利用 cf-agent 执行策略文件之外的命令.

Install

参考官方文档

软件安装完成后, 需要执行/var/cfengine/bin/cf-agent --bootstrap <IP address of policy server>来进行初始化.

COMPONENT

cf-execd

周期性触发 cf-agent 执行. 默认间隔 5 分钟.

cf-runagent

cf-runagent 可以远程批量触发 cf-agent 运行(通过 cf-serverd). 在这个过程中, 可以通过 --define-class, -D value 选项来定义 cf-agent 执行时候的 class; 可以通过 --select-class, -s value 来筛选需要被触发的 cf-agent. 实际使用的时候, 这些机制大概有两方面的作用:

  1. 测试. 通过指定 class 可以在目标机器上应用任意的策略.

  2. 可以远程批量触发命令执行, 从而部分替代批量执行工具, 例如: ansible. 但是通过这种方式触发的命令需要在策略文件中预先定义, 而且无法传递参数, 所以灵活性上稍有欠缺.

Modules

用法有两种

  1. Set variables and classes based on command output
  • ^context=xyz sets the module context to xyz instead of the default

  • ^meta=a,b,c sets the class and variable tags for any following definitions to a, b, and c

  • lines which begin with a ^ are protocol extensions

  • lines which begin with a + are treated as classes to be defined (like -D)

  • lines which begin with a - are treated as classes to be undefined (like -N)

  • lines which begin with = are scalar variables to be defined

  • lines which begin with = and include [] are array variables to be defined

  • lines which begin with @ are lists.

  • lines which begin with % are data containers. The value needs to be valid JSON and will be decoded.

  1. usemodule()

Promis

Command

Files

edit_line

虽然 edit_line 可以很灵活的控制文件内容, 尤其是以"行"为单位的/简单的配置文件. 但是对于复杂的, 结构化的配置文件就显得力不从心.

另一个问题是, 基于 edit_line 来控制文件内容, 很难控制配置文件的完整内容, 配置难以收敛. 所以强烈不推荐使用 edit_line.

edit template

  • template_method => "cfengine", native-CFEngine template format, default. v3.3.0

  • template_method => "mustache". v3.6.0

edit_template 是多年来一直希望添加的功能. 但是即便是在不支持模板的 cfengine2 时代, 也不是实现不了, 只是稍微麻烦一点而已.

edit_xml

有了模板其实就不需要这个东西了, 和 edit_line 问题一样, 无法控制配置的完整内容, 配置难以收敛.

Q&A

如何确定 policy_server.

/var/cfengine/policy_server.dat 中保存着 policy_server 的地址.

default:cfe_autorun_inventory_cmdb.sys#policy_hub 192.168.80.136           source=agentdefault:def.policy_servers                {"192.168.80.136"}               source=promisedefault:def.sys#policy_hub               192.168.80.136                    source=agentdefault:sys.policy_hub                   192.168.80.136                    source=bootstrap

这些变量的值都是通过policy_server.dat的内容决定的.

默认情况下policy file 是如何更新的?

controls/cf_serverd.cf

!windows::  # last single quote in cfruncommand is left open, so that  # arguments (like -K and --remote-bundles) are properly appended.  cfruncommand => "$(def.cf_runagent_shell) -c \'                       $(sys.cf_agent) -I -D cfruncommand -f $(sys.update_policy_path)  ;                       $(sys.cf_agent) -I -D cfruncommand";

controls/cf_execd.cf

!windows::  exec_command => "$(sys.cf_agent) -Dfrom_cfexecd,cf_execd_initiated -f \"$(sys.update_policy_path)\" ; $(sys.cf_agent) -Dfrom_cfexecd,cf_execd_initiated";

从 cf_serverd.cf 和 cf_execd.cf 中我们可以看到, 不管是通过 cf_serverd 还是 cf_execd 执行 cf_agent 都会先执行sys.update_policy_path中的策略来更新策略文件. 那么sys.update_policy_path是谁呢? 我们可以通过下面的命令查看.

$ cf-promises --show-vars |grep update.cfdefault:sys.update_policy_path           /var/cfengine/inputs/update.cf              source=agent

/var/cfengine/inputs/update.cf 引入了大量更新相关的策略文件

body common control{      bundlesequence => {                          "update_def",                          "u_cfengine_enterprise",                          @(u_cfengine_enterprise.def),                          "cfe_internal_dc_workflow",                          "cfe_internal_bins",                          "cfe_internal_update_policy",                          "cfe_internal_update_bins",                          "cfe_internal_update_processes",      };      version => "update.cf $(update_def.current_version)";      inputs => {                  @(cfengine_update_controls.update_def_inputs),                  "cfe_internal/update/update_bins.cf",                  "cfe_internal/update/cfe_internal_dc_workflow.cf",                  "cfe_internal/update/cfe_internal_local_git_remote.cf",                  "cfe_internal/update/cfe_internal_update_from_repository.cf",                  "cfe_internal/update/update_policy.cf",                  "cfe_internal/update/update_processes.cf"      };}

主要的更新逻辑包含在 cfe_internal/update/update_policy.cf 中.

!am_policy_hub::  # policy hub should not alter inputs/ uneccessary  "$(inputs_dir)/cf_promises_validated"  comment => "Check whether a validation stamp is available for a new policy update to reduce the distributed load",  handle => "cfe_internal_update_policy_check_valid_update",  copy_from => u_rcp("$(master_location)/cf_promises_validated", @(update_def.policy_servers)),  action => u_immediate,  classes => u_if_repaired("validated_updates_ready");

这一段通过检查policy_servers 上的 cf_promises_validated 是否更新, 来确定policy_servers 上的策略文件是否有变化.

am_policy_hub|validated_updates_ready::  # policy hub should always put masterfiles in inputs in order to check new policy  "$(inputs_dir)"  comment => "Copy policy updates from master source on policy server if a new validation was acquired",  handle => "cfe_internal_update_policy_files_inputs_dir",  copy_from => u_rcp("$(master_location)", @(update_def.policy_servers)),  depth_search => u_recurse("inf"),  file_select  => u_input_files,  action => u_immediate;

如果policy_server 上的策略文件有变化, 则更新本地的策略文件. 这里我们看到客户端 和 policy_server 本身的更新逻辑是相同的.

  "validated_updates_ready"    expression => "cfengine_internal_disable_cf_promises_validated",    comment => "If cf_promises_validated is disabled, then updates are                always considered validated.";

cfengine_internal_disable_cf_promises_validated 如果被设置, 那么无论服务器端的 cf_promises_validated 文件是否有变化, validated_updates_ready 这个类都会被设置, 也就是说: 会触发客户端进行更新.

  "cfengine_internal_disable_cf_promises_validated"    expression => "!any",    comment => "When cf_promises_validated is disabled remote agents will               always scan all of masterfiles for changes. Disabling this               is not recomended as it will increase the load on the policy               server and increases the possibility for remote agents to               recieve broken policy.";

但是在 controls/update_def.cf 中我们可以看到 cfengine_internal_disable_cf_promises_validated 默认情况下是不被设置的, 也就是说默认情况下需要通过 cf_promises_validated 文件的状态来判断是否更新.

body copy_from u_rcp(from,server){      source      => "$(from)";      compare     => "digest";      trustkey    => "false";    !am_policy_hub::      servers => { "$(server)" };    cfengine_internal_encrypt_transfers::      encrypt => "true";    cfengine_internal_purge_policies::      purge => "true";    cfengine_internal_preserve_permissions::      preserve => "true";}

在 copy_from u_rcp 的定义中我们看到, 客户端更新时 servers 属性(policy_server) 被设置为传入的参数, 但是没有指定 policy_server 更新时的 servers. 实际上, copy_from 的默认 servers 是 localhost, policy_server 更新的时候是从本机同步文件, 所以无需指定.

Link

  • Hard and Soft Classes

  • common attributes

顾翔老师与云测学院联合推出:软件测试分析与设计,请点击https://v.youku.com/v\_show/id\_XNDQ3MzkyNjk3Ng==.html?spm=a2hzp.8244740.0.0,收看。有不同观念欢迎与顾翔老师交流!

DevOps工具介绍连载(5)——CFEngine

本文分享自微信公众号 - 软件测试培训(iTestTrain)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
Stella981 Stella981
2年前
Golang学习——基于Gin框架进行httptest单元测试
顾翔老师的《软件测试技术实战设计、工具及管理》网上购买地址:https://item.jd.com/34295655089.html《基于Django的电子商务网站》网上购买地址:https://item.jd.com/12082665.html店铺二维码:!(https://oscimg.oschina.net/oscnet/c96
Stella981 Stella981
2年前
DevOps工具介绍连载(46)——OSSEC
顾翔老师的《软件测试技术实战设计、工具及管理》网上购买地址:https://item.jd.com/34295655089.html《基于Django的电子商务网站》网上购买地址:https://item.jd.com/12082665.html店铺二维码:!(https://oscimg.oschina.net/os
Stella981 Stella981
2年前
Diffblue关于英国测试行业情况的研究
顾翔老师的《软件测试技术实战设计、工具及管理》网上购买地址:https://item.jd.com/34295655089.html《基于Django的电子商务网站》网上购买地址:https://item.jd.com/12082665.html店铺二维码:!(https://oscimg.oschina.net/oscnet/f1d
Stella981 Stella981
2年前
DevOps工具介绍连载(31)——Microsoft Team Foundation Server(TFS)
顾老师安全测试新课,报名地址:http://www.hbz100.com/pc/course/courseInfo.do?courseId182320200226121405459。疫情期间,您在注意身体安全的同时,关注身体安全了吗?500元工作几天的薪酬,让你薪资翻几倍。顾翔老师的《软件测试技术实战设计、工具及管理》网上购买地址:ht
Stella981 Stella981
2年前
DevOps工具介绍连载(17)——Debian
顾老师安全测试新课,报名地址:http://www.hbz100.com/pc/course/courseInfo.do?courseId182320200226121405459。疫情期间,您在注意身体安全的同时,关注身体安全了吗?500元工作几天的薪酬,让你薪资翻几倍。顾翔老师的《软件测试技术实战设计、工具及管理》网上购买地址:ht
Stella981 Stella981
2年前
DevOps工具介绍连载(30)——Atlassian Bamboo
顾老师安全测试新课,报名地址:http://www.hbz100.com/pc/course/courseInfo.do?courseId182320200226121405459。疫情期间,您在注意身体安全的同时,关注身体安全了吗?500元工作几天的薪酬,让你薪资翻几倍。顾翔老师的《软件测试技术实战设计、工具及管理》网上购买地址:ht
Stella981 Stella981
2年前
DevOps工具介绍连载(39)——LeanKit
顾老师安全测试新课,报名地址:http://www.hbz100.com/pc/course/courseInfo.do?courseId182320200226121405459。疫情期间,您在注意身体安全的同时,关注身体安全了吗?500元工作几天的薪酬,让你薪资翻几倍。顾翔老师的《软件测试技术实战设计、工具及管理》网上购买地址:ht
Stella981 Stella981
2年前
DevOps工具介绍连载(14)——裸金属服务器
顾翔老师近期推出一对一入职面试辅导。有兴趣者可加微信xianggu19720625与我联系。先要提供简历初选,合适者进一步洽谈。顾翔老师的《软件测试技术实战设计、工具及管理》网上购买地址:https://item.jd.com/34295655089.html《基于Django的电子商务网站》网上购买地址:https://item.j
Stella981 Stella981
2年前
DevOps工具介绍连载(6)——Capistrano
顾翔老师近期推出一对一入职面试辅导。有兴趣者可加微信xianggu19720625与我联系。先要提供简历初选,合适者进一步洽谈。顾翔老师的《软件测试技术实战设计、工具及管理》网上购买地址:https://item.jd.com/34295655089.html《基于Django的电子商务网站》网上购买地址:https://item.j
Stella981 Stella981
2年前
DevOps工具介绍连载(12)——VMware&AMI(亚马逊云机器镜像)&Docker
顾翔老师近期推出一对一入职面试辅导。有兴趣者可加微信xianggu19720625与我联系。先要提供简历初选,合适者进一步洽谈。顾翔老师的《软件测试技术实战设计、工具及管理》网上购买地址:https://item.jd.com/34295655089.html《基于Django的电子商务网站》网上购买地址:https://item.j