Ansible与仅在Vagrant中运行Provisioning Bash Shell有何不同?


38

一群熟练使用Shell脚本解决问题的IT系统管理员正在考虑开始使用Ansible。

开始使用Ansible与继续编写Shell脚本是否有实质性的区别和充分的理由?

Answers:


29

我从没使用过Ansible,但是从几周以来,我试图弄清楚与壳牌相比,Ansible有什么好处-至少在我的情况下,这证明了它们运行的​​困扰很大的广告系列是有效的!经过多次不成功的尝试(证明他们的文档如何未能回答最明显的问题之一),我想我终于明白了:

现在,让我们观看介绍视频,并以潜在的新用户随机浏览Ansible ans的介绍材料,让我们将其与熟练的Shell程序员可以立即生产的内容进行比较。

我的结论是,通过外壳脚本编写,Ansible本质上提供了1.检查系统是否符合期望状态的可能性,2.与Ansible Tower集成的能力,Ansible Tower是一个付费系统,似乎包含监视功能。在某些重要情况下,例如在实现不可变服务器模式时,点1可能不是很有用,因此列表很薄。

我的结论是,正如文档所介绍的那样,Ansible通过shell脚本提供的好处在少数几个可用模块很好涵盖的乐观情况下是明智的,但在一般情况下很小甚至是假设的。对于熟练的Shell程序员来说,这些好处很可能会被其他折衷方案所抵消。

但这也许只能证明介绍材料有多糟糕!

快速入门视频:

有一个快速入门视频。它始于一个页面,声称……好吧,这些并不是真正的声明,而是项目符号列表,这是一种人工制品,通常用于暂停演示文稿中的批判性判断(因为未显示逻辑,因此不能批评!)

1. Ansible很简单:

1.1人工可读的自动化–规范是技术文档,如何

  name: upgrade all packages
  yum:
    name: '*'
    state: latest

比在shell脚本中找到相应的yum调用更容易阅读?此外,任何与AppleScript接触过的人在阅读“人类可读的自动化”时都会死于笑声。

1.2不需要特殊的编码技能–如果不编写正式规范,编码是什么?它们具有条件和变量,那么如何不编码呢?为什么我需要我无法编程的东西,从那以后就变得僵硬了?声明很不正确!

1.3按顺序执行任务–好吧,也许某些代码高尔夫爱好者意识到可以无序执行任务的语言,但是按顺序执行任务看起来并不例外。

1.4快速提高生产力–熟练的shell程序员现在可以高效地工作。这种反论点与最初的论点一样严重。

2. Ansible强大

销售艺术品的流行推销员技巧是欺骗人们,使他们相信他们将获得这些艺术品的“力量”。汽车或等渗饮料的广告历史应提供令人信服的示例清单。

在这里Ansible可以进行“应用程序部署” –但是shell脚本肯定可以进行“配置管理”,但这仅是对工具用途的说明,而不是功能,以及“工作流程编排”的描述虽然有点自命不凡,但没有例子超越了GNU Parallel的能力。

3. Ansible无代理

为了填充该列,他们以三种不同的方式写道,这仅需要ssh,众所周知,ssh是一个守护程序,与遍布世界配置管理的这些代理无关!

视频的其余部分

视频的其余部分介绍了清单,清单是资源(例如服务器)的静态列表,并演示了如何在三台服务器上同时部署Apache。这确实与我的工作方式不匹配,在我的工作方式中资源是高度动态的,并且可以由我的云提供程序提供的命令行工具枚举,并由我使用管道|运算符的shell函数使用。另外,我不会同时在三台服务器上部署Apache,而是构建一个主实例映像,然后使用该映像启动三个实例,它们是另一个实例的精确副本。因此,论证的“编排”部分看起来并不十分相关。

随机文档步骤1:与EC2集成

EC2是Amazon的计算服务,与之交互是受Ansible模块支持的。(还提供了其他流行的云计算提供商):

# demo_setup.yml

- hosts: localhost
  connection: local
  gather_facts: False

  tasks:

    - name: Provision a set of instances
      ec2:
         key_name: my_key
         group: test
         instance_type: t2.micro
         image: "{{ ami_id }}"
         wait: true
         exact_count: 5
         count_tag:
            Name: Demo
         instance_tags:
            Name: Demo
      register: ec2

相应的shell脚本与由JSON替换的YAML本质上是相同的:

provision_a_set_of_instances()
{
  aws --output=text ec2 run-instances --image-id …   
}

或JSON版本

provision_a_set_of_instances()
{
  aws --output=text ec2 run-instances --cli-input-json "$(provision_a_set_of_instances__json)"  
}

provision_a_set_of_instances__json()
{
  cat <<EOF
{
    "ImageId": … 
}
EOF
}

两种版本本质上是相同的,有效负载的大部分是YAML或JSON结构中的初始化值的枚举。

随机文档步骤2:持续交付和滚动升级

本指南的最大部分没有显示任何真正有趣的功能:它引入了变量(IIRC,shell脚本也具有变量)!,并且Ansible模块处理mysql,因此,如果不是在搜索“我如何创建mysql用户”之后进行搜索,拥有XY权限”并以类似

# Create Application DB User
mysql --host "${mysql_host}" --user "${mysql_user}" --password "${mysql_password}" "${mysql_table}" <<EOF
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';
EOF

您在“如何在ansible中创建具有XY特权的mysql用户”之后搜索,最后得到

- name: Create Application DB User
  mysql_user: name={{ dbuser }} password={{ upassword }}
              priv=*.*:ALL host='%' state=present

区别可能仍然不是很有意义。在该页面上,我们还发现Ansible具有模板元编程语言

{% for host in groups['monitoring'] %}
-A INPUT -p tcp -s {{ hostvars[host].ansible_default_ipv4.address }} --dport 5666 -j ACCEPT
{% endfor %}

当我看到这个时,我碰巧真的在我的舒适区。这种用于声明性语言的简单元编程与BSD Makefile完全一样,是一种理论范例!我碰巧广泛的编程本文节选说明一个YAML文件的工作的承诺被打破(这样我就可以不通过YAML分析器,运行我的剧本)。它也向我们表明,Ansible必须讨论评估顺序的微妙技巧:我们必须确定变量是在语言的“声明部分”还是在语言的“命令性”元部分扩展的。在这里,shell编程更简单,除了显式 eval或外部脚本采购之外,没有元编程。假设的等效外壳摘录为

enumerate_group 'monitoring' | {
  while read host; do
    …
  done
}

与Ansible变体相比,它的复杂性是可以忍受的:它仅使用该语言的普通,常规,无聊的构造。

随机记录步骤3:测试策略

最后,我们遇到了 Ansible 的第一个真正有趣的功能:“ Ansible资源是期望状态的模型。这样,就不必测试服务是否已启动,软件包是否已安装或其他类似的东西。Ansible是将确保这些事情在声明上是正确的系统。而是在您的剧本中声明这些内容。”现在开始有点有趣,但是:

  1. 除了可用模块容易实现的少数标准情况外,我还必须自己提供实现测试的位,这很可能涉及一些shell命令。

  2. 在实现不可变服务器模式的情况下,检查安装的一致性可能不是很重要:通常所有运行的系统都是从主映像(例如,实例映像或docker映像)生成的,并且从不更新-而是由替换新的代替。

未解决的问题:可维护性

Ansible的入门资料忽略了可维护性的问题。在基本没有类型系统的情况下,shell脚本可以轻松实现JavaScript,Lisp或Python的可维护性:只有在广泛的自动化测试套件的帮助下才能成功实现广泛的重构,或者至少需要允许简单的交互式测试的设计。就是说,尽管shell脚本是系统配置和维护的通用语言,但几乎每种编程语言都具有与shell的接口。因此,通过使用高级语言将外壳配置位的各个位粘合在一起来利用高级语言的可维护性优势是完全可行的。对于OCaml,我写了Rashell 基本上为子流程提供了常见的交互模式,这使得配置脚本到OCaml的翻译非常简单。

从Ansible的角度来看,剧本的结构非常薄弱,并且存在元编程功能,这使得情况基本上和shell脚本一样糟糕,但要点是,如何为Ansible编写单元测试并不明显,并且不能模仿引入临时高级语言的论点。

配置步骤的幂等性

Ansible的文档提请注意编写幂等配置步骤的必要性。更准确地说,应该编写配置步骤,以便可以将步骤序列aba简化为ab,即,我们不需要重复配置步骤。这比幂等要强。由于Ansible允许剧本使用任意的shell命令,因此Ansible本身无法保证会遵守此更严格的条件。这仅取决于程序员的纪律。


这似乎是一本手册...令人印象深刻!
Pierre.Vriens

4
我完全同意。我们使用Ansible已有一年多了,现在使用的是Docker容器,该容器使用良好的普通bash脚本构建。到目前为止,在我看来,定义状态也是最有趣的功能,但是正如您已经提到的那样-有很多服务没有相应的Ansible模块,因此无论如何您总是必须退回到bash命令。是的,我们也只将不可变的容器部署到服务器,因此在这种情况下定义状态实际上并没有任何优势。
Andreas

1
彻底使用ansible后,我可以确认我提出的所有要点。幂等是可能的,但不是由ansible强制执行的(请参见模块vmware_guest中的不良公民),使用其宏系统确实是一个痛苦,即使对结构化数据执行最基本的处理也越来越困难,一些基本的事情做错了(如果没有疗法,剧本格式就不能吃掉Unix文件模式),唯一真正的好处是为ansible编写了有用的功能。因此,如果不是Red Hat推出该产品,我将无法理解其广泛采用。
Michael Le BarbierGrünewald,

1
@Andreas我同意您仍然有很多情况需要退回到shell或命令模块,这并不意味着您的烦恼不能是幂等的。核心模块本身仅通过检查是否应执行操作来保持幂等性。您可以使用shell或命令模块自己做同样的事情,方法是先运行一个检查是否应该执行的任务并注册其输出,然后根据第一个任务的输出对第二个任务执行条件。
利维

1
@MichaelLeBarbierGrünewald,总体而言,我必须达成共识,当我与Ansible合作时,运行起来确实很痛苦,其工作需要花费数周的时间才能将一本剧本连接到我以前的基于云的公司的基础架构上,以配置Linux发行版,安装LAMP / LEMP或其他。一旦完成,它为我们节省了时间,但是仅仅花了一个月的时间就使它开始运行。我们谁都不是bash熟练的脚本编写者,因此这不是替代方案。
丹尼尔

22

当您这样说时,即使Ansible具有某些固有的优势,使用其熟悉的工具(在本例中为Shell脚本)的好处也必须被抵消。我认为对此没有明确的答案。

如果团队可以使用Shell实现Ansible提供的功能:

  1. 声明式,幂等配置管理
  2. 访问可重复使用的摘录(即剧本)以获取行业流行的服务。
  3. 通过重试,滚动逻辑等对远程执行进行可靠的管理

那么他们可能会坚持自己所知道的。

毕竟,您可以在BASH中实施“守卫”。您可以在那里找到许多BASH现有工作来解决各种服务器配置任务(实际上,任何Dockerfile都有90%bash安装代码)。您可以非常接近Ansible / Salt / Chef-Zero提供的功能,而无需实际将整个现有解决方案移植到这些工具。

这是NIH(此处未发明)趋势与抛出好的,已建立的脚本以支持更健壮的解决方案之间的一种平衡行为。

需要牢记的最后一个考虑因素:当您尝试向团队招募更多人员时,您的技术堆栈如何衡量。寻找具有Ansible经验的人比寻找具有您自己的特定脚本CM工具经验的人要容易得多。严格来说,这不是技术上的考虑,而是文化上的考虑。您想成为发明自己的Ansible的怪异组织,还是想成为找到合适工作工具的合理组织?这些决定会影响您吸引人才的能力。


4
喜欢你的答案;我还要提到的是,如果bash团队要追求幂等,执行管理和重用,基本上是编写自己的配置管理框架,那么这将涉及成本,而且我们都知道对于内部项目而言,这真的很讨厌。
ᴳᵁᴵᴰᴼ

我也赞成您的回答,尤其是将现有的经验放在最重要的位置。我有两个小批评家:首先是幂等性 这当然是配置系统的重要方面,但是由于可以在可使用的剧本中使用任何可能的shell命令,因此系统最多可以激发使用幂等性。(实际上,我们希望功能更强大,即等幂aba = ab。)其次,在某些重要情况下,例如,当使用实例映像实现不可变服务器模式时,远程执行的可靠管理可能完全不相关。
Michael Le BarbierGrünewald17年

13

上面的答案涵盖了其中的一部分,但是却忽略了其中一个重要要素:收敛设计。我前一阵子在https://coderanger.net/thinking/在Chef的上下文中写了一些关于这个的单词,但是简短的版本是bash脚本是一组指令,而Ansible剧本(或Chef的食谱,Salt)状态等)是对所需状态的描述。通过记录所需的状态而不是要达到的状态,您可以应对更多的起始状态。这是很久以前在CFEngine中概述的Promise Theory的核心,并且我们(配置管理工具)此后一直在复制设计。

tl; dr Ansible代码说明了您想要的东西,bash代码说明了如何做某事。


2
您是否还可以添加一些对“承诺理论”的参考,例如书籍或文章,以及其他任何有价值的材料(如果有人想学习的话)?
Evgeny

1
当我说您可以编写幂等的bash代码时(即可以在任何时候开始,多次运行并收敛到所需的状态),实际上就是我提到的内容。但是,您的回答更加清楚了。
阿萨夫·拉维

是的,幂等性是收敛系统的重要属性,但两者并不总是直接相连的。)关于承诺理论的资料,马克·伯吉斯(Mark Engines)(CFEngine的创建者)有几本书,当我回到图书馆时,我可以找到链接。笔记本电脑。
coderanger


3

值得一提的是,在远程主机上运行ansible剧本的问题也会减少。因为这是运行ansible的主要原因。当您使用Shell脚本编写时,您仍然需要一种将scp's脚本编写到远程主机的方法。


从这个意义上来说,Ansible不仅仅是ssh的包装吗?
叶夫根尼

从本质上讲,是的。它执行ssh,远程复制python脚本并运行它们。顺便说一句,这意味着,如果您的ansible模块依赖于某些python库,则在某些情况下,该库应位于远程计算机上。
阿萨夫·拉维

1
而且,如果您搞砸了ssh配置,则您将被锁定在计算机之外,这是push vs pull的通常缺点。
Tensibai

0

现在是2019年,我在ansible学习曲线上花了几天时间,这是绝对的事实:Ansible不值得为此烦恼。

它尚未完成,无法在Windows上运行,并且YAML配置和误导性错误消息的组合会使您流血。这似乎是故意的,我是认真的。显然,这是redhat sysadmins沮丧的开发人员端项目的产物。可能是一个时髦。

如果您不需要除配置之外的任何其他功能,而您仅在一个特定的操作系统上进行配置。为了可惜,写一个像样的shell.script。

截至目前,整个项目使我想起了早期的Linux论坛,那里的菜鸟被告知RTFM,并被嘲笑为什么有人不能编写用于配置图形设置的GUI。你就是不明白吗?你应该坚持窗户...也许我会交配..快乐的VI-ing。

使用Docker。优先于任何事物。Docker非常简单而强大。

但是,如果您绝对必须提供预先存在的锡该怎么办?真正的替代品是什么?

好吧...还没有。但我会向您保证,除非ansible变得更好,否则很快就会出现。因为不管狂热者多么努力地推销它,并原谅它的失败……努力中的十分之五。

SCP制作了一个bash脚本,并避免了麻烦。


首先,它确实可以通过Win_RM或SSH在Windows上运行。其次,yaml语法非常好,可以通过编程生成,并且某些错误可能会误导其,与Java或Python在异常期间戳破它的胆量没有什么不同。第三,仅将脚本SCPing到服务器的概念不适用于高度动态的云环境。哪个服务器?服务器可能每天更换。Ansible允许轻松配置的清单插件,并通过简单的方法对服务器进行分组并为其分配变量。我认为Ansible不值得。我认为这对您的环境而言是过大的。
利维

@Levi是的。我所有的过错是ansible无法在Windows上运行,没有模式的配置,并且比完成任何任务的任何定制方法具有更长的学习曲线和更高的维护成本。
理查德

对于云环境,对于大型企业而言,还有其他方法可以证明学习曲线的合理性。我知道ansible会做什么。我只是看不到它的利基。
理查德·

利基市场是易于使用的多台机器自动化框架。对于Windows来说,它不如对Linux那样好。对于msdos和网络软件也不是很好。在2019年,Windows服务器如今已成为无用的小型利基市场。
dyasny
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.