我在 AWS 部署中遇到了问题,因为对 AWS 和 Puppet 还不太熟悉。
所以回到我的疑问——您可以使用 AWS 机器标签或 CNAME 域来区分 puppet 节点吗?
关于该计划的一些背景:
- 有多个机器集群,一个 php 集群,一个旧版 php 集群,一个 java 集群,一个 perl 集群
- 使用 puppet 控制配置 - 对 puppet 来说仍然很新,但作为开发人员,我喜欢能够对服务器配置进行版本控制的想法
- 在这些集群上启用了自动缩放 - 显然这是云的主要优势,当涉及到任何合理的性能时,它会产生更高的成本(那些亚马逊机器比我的手机还慢......)
- 由 Capistrano 控制部署,这让事情变得简单很多
因此,在 AWS 中,您会得到那些超级讨厌的公有/私有机器 DNS……您无法识别这些机器。为了缓解这个问题,AWS 似乎希望您标记所有内容 - 所以我这样做了。借助 Route53 API,找到了一个脚本,该脚本为每台带有“ShortName”标签的机器创建 CNAME 记录。
每台机器都有一个 ShortName 标签作为其 CNAME,不幸的是 puppet 仍然解析私有 dns 名称。
我希望
node 'perl-cluster'{}
在 Puppet 中,有人知道如何实现这一点吗?
谢谢
答案1
我这样做的方法是为服务器编写一个自定义事实,以从用户数据中识别其角色,可以通过 169.254.169.254 访问,请参阅您自己的用户数据...
curl http://169.254.169.254/latest/
所以当我输入时,facter role
我会得到“dbserver”,“webserver”等等,然后用它来定义一个节点,重要的是不要让自动缩放组丝毫不关心服务器的名称是什么。
/etc/puppet/manifests/nodes.pp
node default{
include nodes::type
}
/etc/puppet/modules/nodes/manifests/init.pp
import “type.pp”
/etc/puppet/modules/nodes/manifests/type.pp
class nodes::type{
case $role {
“dbserver” : {
include mysql
}
}
case $role {
“webserver” : {
include httpd
}
}
}
/etc/puppet/manifests/modules.pp
import nodes
我不想告诉您在您的情况下具体该怎么做,但在这里我将向您展示如何创建自定义事实来报告 EC2 实例 ID。
Facter、curl 已安装。
mkdir -p /home/ec2-user/lib/ruby/facter
export FACTERLIB=/home/ec2-user/lib/ruby/facter
cat > /home/ec2-user/lib/ruby/facter/instance_id < EOF
# instance_id.rb
#
require 'facter'
Facter.add("instance_id") do
setcode "/usr/bin/curl -s http://169.254.169.254/latest/meta-data/instance-id"
end
EOF
瞧,一个自定义事实就被写下来了。
现在我可以用它来获取 ec2 实例 ID:
$ facter instance_id
i-a1c0ffee
我没有在这台机器上安装 puppet,但是如果我想让它可用于 puppet,我会把它放在 /var/lib/puppet/lib/facter 中,并将其分发给客户端,确保 puppet.conf 中的 pluginsync=true。
请记住,我所说的一切都非常主观,只是我做事的方式,如果有更好的方法,我会感兴趣。
答案2
从 facter 1.7(2013 年 4 月发布)开始,有内置事实可以报告您的 EC2 实例的各种详细信息。
参考:http://docs.puppetlabs.com/facter/1.7/core_facts.html#ec2ec2-instance-data
答案3
我同意 Sirch 的观点,目前看来,自定义事实似乎是可行的方法。AWS 描述了如何使用云形成事实:
https://s3.amazonaws.com/cloudformation-examples/IntegratingAWSCloudFormationWithPuppet.pdf
这篇文章很有趣,但读起来有些困难。其中的定制事实是:
# cfn.rb
require 'rubygems'
require 'json'
filename = "/var/lib/cfn-init/data/metadata.json"
if not File.exist?(filename)
return
end
parsed = JSON.load(File.new(filename))
parsed.default = Hash.new
parsed[\"Puppet\"].each do |key, value|
actual_value = value
if value.is_a? Array
actual_value = value.join(',')
end
Facter.add(\"cfn_\" + key) do
setcode do
actual_value
end
end
end
然后他们像这样配置他们的节点:
node basenode {
include cfn
}
node /^.*internal$/ inherits basenode {
case $cfn_roles {
...cloud formation include...
}
}
我更倾向于通过 hiera 来实现这一点,例如:
---
:backends:
- yaml
:yaml:
:datadir: /etc/puppet/hiera
:hierarchy:
- "roles/%{::cfn_roles}"
- common
然后有类似 common.yaml 的内容:
classes: cfn # or whatever your custom fact class is
角色/dbserver.yaml:
classes: mysql
角色/webserver.yaml:
classes: httpd
httpd::port: 8080
...
杰夫