我用了 Puppet 有一年多. 也是在 Vagrant 里面搭环境用. Puppet 代码 + 配置模板大概上千行. 是从自己对 Puppet 一无所知开始写起. 所以借题扯个蛋吧.
需要强调的是 Chef 我一点都没用过... 所以下面出现的 Chef 信息可能有误.
最开始接触 Puppet 和 Chef 的时候感觉一下子要学好多陌生的概念, 好讨厌. 当时 Puppet 的文档比 Chef 亲切得多, 陌生概念也比 Chef 看上去要少一点, "快使用 Vagrant" 的欲望又十分强烈, 就先从 Puppet 用起来了. 虽然 Puppet 和 Chef 默认的设计都是 Master-Agent 的架构, 但也都可以在单机内使用. 我的使用方式就是 Vagrant 提供的 puppet provisioner, 由 Vagrant 替我 ssh 进虚拟机然后跑 puppet apply
. Chef 的等价物是 chef-solo
.
用到现在, 对 Puppet 比较恼火的有以下两点
执行顺序不确定(non-deterministic). 虽然说正确的做法是开发者应该显式声明依赖关系, 但 Puppet 的问题是当我犯了错误没能正确声明依赖关系的时候, 不一定会在测试中出错... Chef 就不存在这个问题. 以及, 当我需要在一个 puppet class (Chef 方面的等价物好像是叫 recipe?)里序列化地部署几个资源时, 本来是一目了然的自上而下的顺序, 却还要手动声明这几项之间的依赖关系. 另一个小问题是后来我需要在部署完成时打印一条成功提示, 由于 Puppet 没有执行顺序这回事, 所以需要用某种不整洁的 hack 才行. 甚至 Puppet 后来又引入 Stages 机制用来解决此类问题......
Puppet 自己的语法始终觉得不习惯. 而 Chef 完全是 Ruby 语法. 似乎也存在有 Ruby 语法版的 Puppet, 这个没有仔细深究.
如果现在给我再选择一次的话, 估计会坚持把 Chef 啃下来. 不过现在这样说实在是这山望着那山高...
至于说"能在 Vagrant 中使用"这件事, 一方面要看 basebox 里是否预先安装了 Chef / Puppet. 另一方面要看 Vagrant 是否安装了 provisioner 整合支持. 官方文档里列出 Ansible, Chef, Puppet 这几个意味着内置支持. 以及 vagrant-omnibus 这个插件会帮你在虚拟机里安装 / 更新虚拟机里的 Chef. 我用的 basebox 里的 Puppet 至今还没更新过.