CFEngine

本文檔基于 CFEngine Core 3.9.1

Cfengine 是歷史最悠久的配置管理軟件. 雖然受到了來自眾多后起之秀(puppet, saltstack, Chef...)的挑戰(zhàn), 但是 CFE 還是成功的活了下來. 相對于其他配置管理軟件, CFE 最明顯的優(yōu)勢有:

  • 依賴少, 部署方便.

    當前版本只需要安裝一個包, 執(zhí)行一個命令即可完成部署.

  • 運行開銷小, 效率高

    CFE 使用 c/c++ 編寫, 運行效率毋庸置疑.

  • 架構(gòu)簡單

    最核心的組件只有 cf-agent 一個, 其他的組件其實都是可選的.

    cf-serverd 通常只是一個提供策略文件下載的文件服務(wù)器. 策略文件的解析是在 agent 端進行的. 所以, 相對于其他配置管理軟件, CFE 的 server 端能夠管理更多的 agent 端.

    cf-execd 也不過是個定時器.

    所以, 如果你用 rsync 同步策略文件, 用 crond 定期執(zhí)行 cf-agent, 完全可以不啟動 cf-agent 和 cf-serverd.

  • DSL不依賴于特定編程語言.

  • 安全

    外部只能觸發(fā) cf-agent 執(zhí)行, 以及類的定義. 無法利用 cf-agent 執(zhí)行策略文件之外的命令.

Install

參考官方文檔

軟件安裝完成后, 需要執(zhí)行/var/cfengine/bin/cf-agent --bootstrap <IP address of policy server>來進行初始化.

COMPONENT

cf-execd

周期性觸發(fā) cf-agent 執(zhí)行. 默認間隔 5 分鐘.

cf-runagent

cf-runagent 可以遠程批量觸發(fā) cf-agent 運行(通過 cf-serverd). 在這個過程中, 可以通過 --define-class, -D value 選項來定義 cf-agent 執(zhí)行時候的 class; 可以通過 --select-class, -s value 來篩選需要被觸發(fā)的 cf-agent. 實際使用的時候, 這些機制大概有兩方面的作用:

  1. 測試. 通過指定 class 可以在目標機器上應(yīng)用任意的策略.
  2. 可以遠程批量觸發(fā)命令執(zhí)行, 從而部分替代批量執(zhí)行工具, 例如: ansible. 但是通過這種方式觸發(fā)的命令需要在策略文件中預(yù)先定義, 而且無法傳遞參數(shù), 所以靈活性上稍有欠缺.

Modules

用法有兩種

  1. Set variables and classes based on command output

    • lines which begin with a ^ are protocol extensions
      • ^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 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.
  2. usemodule()

Promis

Command

Files

edit_line

雖然 edit_line 可以很靈活的控制文件內(nèi)容, 尤其是以"行"為單位的/簡單的配置文件. 但是對于復(fù)雜的, 結(jié)構(gòu)化的配置文件就顯得力不從心.

另一個問題是, 基于 edit_line 來控制文件內(nèi)容, 很難控制配置文件的完整內(nèi)容, 配置難以收斂. 所以強烈不推薦使用 edit_line.

edit template

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

edit_template 是多年來一直希望添加的功能. 但是即便是在不支持模板的 cfengine2 時代, 也不是實現(xiàn)不了, 只是稍微麻煩一點而已.

edit_xml

有了模板其實就不需要這個東西了, 和 edit_line 問題一樣, 無法控制配置的完整內(nèi)容, 配置難以收斂.

Q&A

如何確定 policy_server.

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

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

這些變量的值都是通過policy_server.dat的內(nèi)容決定的.

默認情況下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 執(zhí)行 cf_agent 都會先執(zhí)行sys.update_policy_path中的策略來更新策略文件. 那么sys.update_policy_path是誰呢? 我們可以通過下面的命令查看.

$ cf-promises --show-vars |grep update.cf

default:sys.update_policy_path           /var/cfengine/inputs/update.cf              source=agent

/var/cfengine/inputs/update.cf 引入了大量更新相關(guān)的策略文件

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 如果被設(shè)置, 那么無論服務(wù)器端的 cf_promises_validated 文件是否有變化, validated_updates_ready 這個類都會被設(shè)置, 也就是說: 會觸發(fā)客戶端進行更新.

  "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 默認情況下是不被設(shè)置的, 也就是說默認情況下需要通過 cf_promises_validated 文件的狀態(tài)來判斷是否更新.

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) 被設(shè)置為傳入的參數(shù), 但是沒有指定 policy_server 更新時的 servers. 實際上, copy_from 的默認 servers 是 localhost, policy_server 更新的時候是從本機同步文件, 所以無需指定.

Link

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,993評論 19 139
  • OSSIM架構(gòu)與組成綜述 一、背景 如果運維工程師手里沒有高效的管理工具支持,就很難快速處理故障。市面上有很多運維...
    OSSIMCN閱讀 1,453評論 0 1
  • https://nodejs.org/api/documentation.html 工具模塊 Assert 測試 ...
    KeKeMars閱讀 6,416評論 0 6
  • 一、基礎(chǔ)知識篇:Http Header之User-AgentUser Agent中文名為用戶代理,是Http協(xié)議中...
    iPhone閱讀 15,884評論 0 13
  • 今天是第46天,孕期軟件說郭小米現(xiàn)在有黑豆那么大了,什么鬼,瓜子變黑豆?那不是更小了嗎,莫非逆生長?看來程序員的語...
    little_R閱讀 316評論 0 0