Chef中收敛与幂等的区别

dex*_*ren 17 theory configuration-management chef-infra

Chef中融合与幂等的基本区别是什么?

jti*_*man 40

融合和幂等不是特定于厨师的.它们通常归因于配置管理理论,但在其他领域也有用,尤其是数学.

让我们从更基本的,幂等的开始.我们将忽略幂等的数学用法,而是关注人们谈论它时的配置管理.那就是:"同一动作的多个应用程序对系统状态没有副作用." 幂等操作的一个简单示例是mkdir -p:

mkdir -p /var/lib/statedir/myapp
Run Code Online (Sandbox Code Playgroud)

无论我们运行此命令多少次,都会导致创建该树.另一种说明幂等操作的方法是,"一次又一次地运行工具不会在第一次之后改变系统".

现在将其与收敛进行对比.通常,汇聚意味着将[人或者]事物聚集在一起.在配置管理中,收敛意味着使系统状态符合已定义的策略.也就是说,只有在需要制作时才对系统进行更改.汇聚操作的一个简单示例是:

if [ ! -d /var/lib/statedir/myapp ]; then
  mkdir -p /var/lib/statedir/myapp
fi
Run Code Online (Sandbox Code Playgroud)

这是收敛的,因为如果所需的目录不存在,我们只执行mkdir命令.我们还将其称为"测试和修复"操作.也就是说,我们测试我们正在管理的特定事物的当前状态,然后使用特定命令或操作修复它,如果它不在该状态.这就是Chef在幕后用这样的资源做的事情:

directory '/var/lib/statedir/myapp' do
  recursive true
end
Run Code Online (Sandbox Code Playgroud)

我们(Chef)谈论这个问题的方式是,Chef采取幂等行动将系统融合到各种资源声明的状态.Chef中的每个资源都是声明性的,并对资源的当前状态执行测试,然后修复系统以匹配该资源.

为了深入了解关于Chef如何工作的杂草,它在Chef运行中有一个"编译"阶段和一个"融合"阶段.在"编译"阶段,它评估节点上的Ruby配方,并且它正在寻找它添加到"资源集合"的资源对象.一旦它评估了所有的配方,它就进入"融合"阶段,在那里迭代资源集合,采取适当的行动将资源置于所需的状态,从而创建用户,编写文件,安装包,等等.

  • -1. 我不认为这是一个特别清楚的解释。它使幂等性和收敛性听起来像是基本上相同的东西,因为您用作这两个概念的示例的命令在语义上是相同的。幂等但不收敛命令(或收敛但不幂等命令,如果这样的事情甚至有意义)的示例将增加清晰度。 (4认同)

Mar*_*ery 6

免责声明:我是配置管理社区的局外人,花了我很多小时才能弄清楚接下来的内容。我在此答案中批评配置管理社区,因此您应该意识到它们的世界不是我的世界,在我目前的工作中我什至不使用任何配置管理工具,而我只是根据我能找到的东西来判断它们在Google上。

定义

要说一个操作是收敛的,就意味着它会将其管理的系统任何部分置于指定状态。

当配置管理人员说某个操作是幂等时,通常意味着如果您在运行一次之后立即第二次运行该操作,则第二次运行将立即终止,而不进行任何多余的工作。

特别是当在Chef上下文中将资源描述为幂等时,这意味着在资源已进入所需状态之后后续Chef运行,请不要在x / y资源更新消息中将其视为“已更新” 运行结束。

请注意,大多数内置的资源满足幂等的最后,严格的定义默认情况下,你可以通过它实现在自己的食谱和自定义资源only_ifnot_if警卫和converge_if_changed

一些评论,以及关于其他定义的注释

令人困惑的是,您在互联网上找到的大多数“幂等”定义都与我刚才给出的任何定义都不匹配。我不是相信专家所说的定义,而是通过观察他们实际使用该术语的方式来推断它。令人不寒而栗的是,找到某人给出“幂等”的定义,然后以明显在随后的几段中与该定义不一致的方式使用该词。

为了对此进行探讨,让我们开始探讨配置管理领域之外存在的“幂等”定义。维基百科(https://en.wikipedia.org/wiki/Idempotence)上列出了许多此类定义。在配置管理上下文中最经常(错误地)给出幂等的含义如下:

  • 在数学中,函数˚F被说成是幂等的,如果F(F(X))= F(X)为的所有可能值X
  • 在数学中,如果满足其他某种形式的定义或其他形式的定义(通常具有“反复进行一次操作具有与一次相同的效果”的共同主题),则据说其他种类的数学对象也都是幂等的。
  • 在编程中,说一个函数或过程是幂等的,意味着两件事之一:
    1. 对于带有参数并返回值的函数,该值与数学含义完全相同。
    2. 对于具有副作用的函数,在调用该函数一次之后,后续调用将使系统状态保持不变。

大量混乱的源给出了这些定义之一,即在配置管理上下文中的“幂等”的含义,然后迅速以某种方式继续使用该术语,以明确表明这并不是他们真正在使用的定义。一些例子:

  • 佩斯对这个问题竞争性回答。他在那里宣称:

    如果在系统上多次执行该步骤(其基础状态未更改)后,结果与该步骤已执行一次相同,则该步骤是幂等的。

    但是接下来以不等幂的步骤为例:

    rm -rf /var/log/myapp
    mkdir -p /var/log/myapp
    
    Run Code Online (Sandbox Code Playgroud)

    显然,此步骤确实符合Pace对幂等的定义,因为连续运行多次可使我们进入与运行一次相同的最终状态(即/var/log/myapp存在且为空的状态)。但是,它在第​​二次运行时会做多余的工作,因此Pace将其描述为非等幂的。

  • Mischa Taylor和Seth Vargo的书《学习厨师:配置管理和自动化指南》。他们在那里声称:

    当Chef代码是幂等时,它可以在同一系统上运行多次,结果将始终相同,而不会产生意外的副作用。

    但随后,评论他们的示例食谱之一:

    我们的配方是否通过了幂等检验?可悲的是没有。... Chef错误地认为仍有需要做的事情-在第二次运行中更新了2/3资源。如果配方确实是幂等的,我们将看到0/3资源已更新。Chef将检查系统的状态,确认自上次运行以来没有任何更改(没有人触摸两次运行之间的节点),并且不执行任何资源更新

    再次,他们基于多次运行配方时系统状态不变的情况,对幂等性进行了定义,但是实际上使用该词来表示可以避免不必要的工作。

  • 本·福特(Ben Ford)的幂等性:不仅在Puppet博客上是个大而恐怖的词,他在博客中首先给出了幂等性的定义...

    幂等仅是一个词,它描述一次操作或运行10001次都会产生相同效果的操作。加一不是幂等的,因为结果一直在递增,但乘以一是幂等的,因为无论将其乘以多少,答案都是相同的!

    然后,他给出了这样的例子幂等,它们虽然它与上面给出的定义一致,是有点怀疑-因为它集中在后续执行没有做多余的工作,而不是在他们达到相同的结果

    想象一下,当您12岁时,您的妈妈要您取出垃圾桶。作为您的好孩子,您丢下了GameBoy,然后按照要求跳了起来,是吗?

    但是过了30分钟,当她回过客厅,看到你ed缩在沙发上玩“超级马里奥乐园”时,她再次告诉你取出垃圾。我强烈怀疑您没有跳起来去拿空的垃圾袋。相反,您说:“妈妈已经做到了!” 那就是幂等。被告知一次将垃圾取出的效果与被告知两次的效果相同。您没有再做一次,因为它已经完成了。

    最后,他将自己的定义抛诸脑后,并给出了一个示例,尽管重复执行该操作得到相同的结果,但他声称该操作不是幂等的:

    那么那时候您因编写非等幂执行程序而受到责难了吗?Puppet的新手通常会替换他们的Shell脚本,他们编写的代码看起来像这样:

    exec { '/usr/bin/curl http: //server.net/packages/package.tar.gz -o /tmp/package.tar.gz ': }
    
    -> exec { 'tar -xf /tmp/package.tar.gz -C /tmp/package': }
    
    -> exec { '/tmp/package/installer.sh': }
    
    file { '/tmp/package':
        ensure  => absent,
        force   => true,
        require => Exec[ '/tmp/package/installer.sh'],
    }
    
    file { '/tmp/package.tar.gz':
        ensure  => absent,
        force   => true,
        require => Exec[ '/tmp/package/installer.sh'],
    }
    
    Run Code Online (Sandbox Code Playgroud)

    那怎么了?可以,对吧?下载压缩包,解压缩,安装东西,然后自己清理。假设没有拼写错误或网络问题,它看起来应该可以完美运行。而且会的。但是,每次Puppet运行时,它将完美运行。换句话说,它将每三十分钟下载并运行一次安装程序脚本!

    但是结果将是一样的,本!之前,这是您告诉我们幂等性定义的细节!

    显然,本本尽管提出了自己的主张,但实际上是在运用“避免重复劳动”的幂等定义。

运算可以是幂等但不能收敛的吗?

是。这样的操作不会使系统进入指定的最终状态,但避免在连续运行中出现多余的工作。Pace的答案提供了这种操作的示例,而“ 像厨师一样思考”提供了另一个操作:

一个系统可以是幂等的,而不会收敛。例如,如果我们拥有伪if file X does not exist, write the current timestamp to file X幂等的伪代码,但实际上不能说它收敛于特定的最终状态。

我能想到的一个最佳实践示例是可以使用典型的软件包管理器install命令安装软件包,您可以将它描述为幂等但非收敛的:

  • 如果未安装软件包,则安装最新版本
  • 如果已经安装了旧版本,则不会更新。

状态(获得的软件包的版本)不是由配方决定的,因此可以说它不是收敛的,但是可以成功避免不必要的工作。

运算可以收敛但不是幂等吗?

是的,一点没错!一个简单的例子是上文已经引用的本·福特的例子,它无条件地将文件下载到某个本地路径。这是收敛的,因为最终状态始终相同(文件存在),但不是幂等的,因为它在每次运行时都会执行重新下载文件的不必要工作。


就其价值而言,我感到很沮丧的是,配置管理社区使用了在更广泛的编程世界中已经具有明确含义的术语,然后以相关但仍明显不同的方式使用了该术语,而从未提供以下方面的正式定义:在他们的世界中意味着什么。搜索Chef文档(https://www.google.co.uk/search?q=site%3Ahttps%3A%2F%2Fdocs.chef.io+idempotent)会产生该术语的许多用法,但没有定义。当术语“浮动”的大多数定义与用法不匹配时,此主题会使人们感到困惑,这并不奇怪。

我只能设法找到一个曾经给出过幂等定义的人,这些定义与该术语的使用方式一致,那就是编码专家(又名Noah Kantrowitz)。在我之前引用的《像厨师一样思考》中,他写道:

“同等”……是指演员为实现所需状态所做的尽可能少的动作。

2015的IRC对话中,他写道:

幂等意味着在不需要时不采取行动,收敛意味着它“定居”在特定的最终状态。

除了这个人以外,我从字面上找不到任何其他人提供过与整个配置管理社区使用它的方式相匹配的术语定义。

  • 多么好的答案啊!准确剖析“幂等”这个词在配置管理实践中如何被用来表示有点不同的东西,尽管人们用同样的词来定义“幂等”。这个答案也让我立即明白了为什么他们需要“收敛”这个词 - 因为一旦“幂等”最终意味着“不报告更改/不重做工作”,这使得“幂等”对于说“结果”毫无用处相同的最终状态”,突然间你必须找到另一个意思相同的词。 (2认同)
  • 我第一次尝到这一点是当有人告诉我我的 Ansible 剧本不是幂等的时,我想“什么!?它在重新运行时搞乱了所需的状态!?好吧,这是一个我需要修复的严重错误!” - 结果他们只是意味着某些步骤报告“已更改”而不是“未更改”。(公平地说,这仍然是一个错误,只是一个表面的错误 - 当结果状态未更改时报告更改会产生误导,并且用户必须能够相信报告的结果并不表明状态已更改,除非状态实际上以某种方式发生了更改很重要。) (2认同)