介绍
使用DigitalOcean元数据服务,管理员可以提供允许新服务器自动配置自身的说明。 虽然这很有用,但许多组织喜欢在配置管理工具(如Chef或Puppet)中处理所有基础架构配置。
在本指南中,我们将演示如何使用元数据服务和CloudInit引导DigitalOcean服务器以连接到现有的配置管理部署。 然后服务器的实际配置可以由配置管理服务处理。 我们将演示如何引导Chef和Puppet节点。
先决条件
为了完成本指南,您必须熟悉DigitalOcean元数据服务。 你可以找到更多关于如何将信息输入和检索的元数据服务信息本指南 。
该指南将利用一种脚本调用的cloud-config
是在第一次启动由CloudInit服务,以便执行首次运行配置消耗你Droplet。 你应该得到一些基本的了解cloud-config
脚本,它们的语法和行为,以更好地了解如何修改本指南中提供的脚本。 你可以找到介绍了云计算的配置脚本在这里 。 对于一个更实际的例子(与格式的限制一些讨论一起),您可以用执行云配置一些基本的任务阅读我们的指南这里 。
使用Cloud-Config脚本引导Chef节点
使用DigitalOcean元数据服务,您可以轻松地钩住你的新服务器与现有的Chef控制的基础架构cloud-config
脚本。
要将新服务器添加到此系统,您必须已配置Chef服务器,新服务器可以联系以接收配置说明。 如果您需要帮助部署Chef服务器和管理工作站,您可以按照本指南上手。
总体规划
当新服务器联机时,必须将其置于Chef服务器的控制下。 通常情况下,这可以通过连接到与新的服务器来实现knife
管理命令,并使用bootstrap
子命令。 这将连接到新服务器,安装Chef客户端和允许新节点连接到Chef服务器的验证凭证。 之后,Chef客户端连接到服务器,验证自身,接收新的客户端凭据,从服务器拉下其配置,并执行任何必要的操作,使其进入所需的状态。
在本指南中,我们将使用cloud-config
脚本来代替手工引导步骤,使得新节点自动连接到该服务器的Chef,验证本身,接收客户端证书,并执行初始Chef客户端运行。 服务器将在首次启动时自动执行此操作,而无需管理员的任何手动协助。
从刀配置文件收集必要的数据
为了让我们的cloud-config
脚本成功引导,这将需要访问通常提供给凭据knife
命令。 具体来说,我们需要以下信息:
- Chef验证名称
- 验证密钥
- 可以访问Chef服务器的URL
所有这些信息是可用的,以正确的格式,中knife
用于管理基础设施的Chef在工作站上的配置文件。 里面的Chef回购,应该有所谓的隐藏目录.chef
包含该文件。
假设你的Chef回购位于工作站上的主目录,被称为chef-repo
,可以输出的文件通过键入的内容:
cat ~/chef-repo/.chef/knife.rb
您需要的信息突出显示如下:
current_dir = File.dirname(__FILE__)
log_level :info
log_location STDOUT
node_name "jellingwood"
client_key "#{current_dir}/jellingwood.pem"
validation_client_name "digitalocean-validator"
validation_key "#{current_dir}/digitalocean-validator.pem"
chef_server_url "https://your_server.com/organizations/digitalocean"
syntax_check_cache_path "#{ENV['HOME']}/.chef/syntaxcache"
cookbook_path ["#{current_dir}/../cookbooks"]
验证名称和Chef服务器URL可以直接从文件中获取。 复制这些值,以便可以在使用它们cloud-config
文件。
该validation_key
点到实际的密钥保存的位置。 在上面的例子中,这表示它位于同一目录中knife.rb
文件,称为digitalocean-validator.pem
。 这可能会因您的配置而有所不同。
我们需要把这个文件的内容,所以使用cat
再次命令。 修改命令以将其指向为验证器键指定的位置:
cat ~/chef-repo/.chef/digitalocean-validator.pem
您将看到一个RSA私钥:
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA3O60HT5pwEo6xUwcZ8WtExBUhoL3bTjlsvHVXg1JVmBUES+f
V9jLu2N00uSZEDZneCIQyHLBXnqD/UNvWEPNvPzt1ecXzmw2BytB7lPDW4/F/8tJ
vAVrKqC7B04VFGmcFY2zC8gf8BWmX8CNRDQooM7UO5OWe/H6GDGPPRIITerO3GrU
. . .
sWyRAoGBAKNc/ZUM8ljRV0UJxQ9nbdozXRZjtUaNgXMNiw+oP2HYYdHrlkKnGHYJ
Js63rvjpq8pocjE8YI+2H0v4/4uWqW8GEBfrWbLMzGsYPnRyiHR5+hgjCUU50RB3
eFoNbURwLYcq2Z/IAQZpDpJWpofz3OVMpMXtei1cIflrAAd2wtWO
-----END RSA PRIVATE KEY-----
复制确认键的全部,让你可以在使用cloud-config
脚本瞬间。
基本Cloud-Config Chef客户端安装
一旦你有了上面的数据,你可以建立脚本。 Chef配置可以通过专用来实现cloud-config
称为模块chef
。 在cloud-config
必须包含有效YAML并且必须有#cloud-config
为脚本的第一行。
开始,你的脚本将如下所示:
#cloud-config
chef:
在cloud-config
文件声称能够从一个RubyGem包,或使用传统的“综合性”的安装方法安装客户端Chef要么。 然而,在实践中,gem和package方法都会失败,所以我们将使用“omnibus”方法。 虽然通常没有必要,但我们还会明确列出Omnibus安装程序的位置。
我们将设置force_install
为“假”。 这样,如果由于某种原因,Chef客户端已经安装在映像上(例如,如果您正在从快照部署),则不会重新安装客户端。 到目前为止,我们的脚本看起来像这样:
#cloud-config
chef:
install_type: "omnibus"
omnibus_url: "https://www.opscode.com/chef/install.sh"
force_install: false
接下来,我们使用的Chef基础设施中的新服务器选择一个名称的选项node_name
指令。 如果没有设置,Chef将使用服务器的主机名,因此这是可选的。 但是,这在您的Chef环境中必须是唯一的。
然后,我们可以添加我们从Chef工作站获取的所有连接信息。 我们将设置server_url
选项Chef服务器的位置,正是因为它是在knife.rb
文件。 这同样适用于在真validation_name
选项。
对于确认键时,我们将使用YAML管道符号( |
)进入我们的工作站上找到的全部确认键:
#cloud-config
chef:
install_type: "omnibus"
omnibus_url: "https://www.opscode.com/chef/install.sh"
force_install: false
node_name: "new_node"
server_url: "https://your_server.com/organizations/digitalocean"
validation_name: "digitalocean-validator"
validation_key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA3O60HT5pwEo6xUwcZ8WtExBUhoL3bTjlsvHVXg1JVmBUES+f
V9jLu2N00uSZEDZneCIQyHLBXnqD/UNvWEPNvPzt1ecXzmw2BytB7lPDW4/F/8tJ
vAVrKqC7B04VFGmcFY2zC8gf8BWmX8CNRDQooM7UO5OWe/H6GDGPPRIITerO3GrU
. . .
sWyRAoGBAKNc/ZUM8ljRV0UJxQ9nbdozXRZjtUaNgXMNiw+oP2HYYdHrlkKnGHYJ
Js63rvjpq8pocjE8YI+2H0v4/4uWqW8GEBfrWbLMzGsYPnRyiHR5+hgjCUU50RB3
eFoNbURwLYcq2Z/IAQZpDpJWpofz3OVMpMXtei1cIflrAAd2wtWO
-----END RSA PRIVATE KEY-----
此时,您的脚本具有连接到您的Chef服务器和创建客户端凭据所需的所有身份验证。
配置Chef Environment,run_list和Attributes
虽然上述详细信息为客户端连接到Chef服务器提供了足够的信息,但我们没有给节点提供有关如何实际配置自身的任何信息。 我们可以提供的信息cloud-config
脚本为好。
以指定新节点应被放置在环境中,使用environment
的选项。 如果不这样设定,在_default
环境将被设置,它是对于尚未被赋予另一个环境Chef节点的一般缺省。
chef:
environment: "staging"
我们run_list
可以被指定为客户端应以申请项目的简单列表。 这些可以是Recipe或角色。
chef:
run_list:
- "recipe[lamp]"
- "role[backend-web]"
您可以指定使用新节点的初始属性initial_attributes
层次。 这将设置会影响如何初始属性run_list
应用:
chef:
initial_attributes:
lamp:
apache:
port: 80
mysql:
username: webclient
pass: $#fjeaiop34S
当迷上了以前的cloud-config
脚本,它可能是这个样子:
#cloud-config
chef:
install_type: "omnibus"
omnibus_url: "https://www.opscode.com/chef/install.sh"
force_install: false
node_name: "new_node"
server_url: "https://your_server.com/organizations/digitalocean"
validation_name: "digitalocean-validator"
validation_key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA3O60HT5pwEo6xUwcZ8WtExBUhoL3bTjlsvHVXg1JVmBUES+f
V9jLu2N00uSZEDZneCIQyHLBXnqD/UNvWEPNvPzt1ecXzmw2BytB7lPDW4/F/8tJ
vAVrKqC7B04VFGmcFY2zC8gf8BWmX8CNRDQooM7UO5OWe/H6GDGPPRIITerO3GrU
. . .
sWyRAoGBAKNc/ZUM8ljRV0UJxQ9nbdozXRZjtUaNgXMNiw+oP2HYYdHrlkKnGHYJ
Js63rvjpq8pocjE8YI+2H0v4/4uWqW8GEBfrWbLMzGsYPnRyiHR5+hgjCUU50RB3
eFoNbURwLYcq2Z/IAQZpDpJWpofz3OVMpMXtei1cIflrAAd2wtWO
-----END RSA PRIVATE KEY-----
environment: "staging"
run_list:
- "recipe[lamp]"
- "role[backend-web]"
initial_attributes:
lamp:
apache:
port: 80
mysql:
username: webclient
pass: $#fjeaiop34S
重定向输出和配置Chef Client运行
上面的脚本包含了所有的下所需的信息chef:
部分。 不过,也有一些其他的东西,我们应该做使用一些其他cloud-config
模块。
首先,我们应该指定我们希望将每个命令和子命令的输出重定向到CloudInit进程的输出日志中。 这是位于/var/log/cloud-init-output.log
默认。 我们可以用做output
这样的模块:
output: {all: '| tee -a /var/log/cloud-init-output.log'}
我们要做的另一件事是将Chef客户端设置为在安装和配置后真正运行。 在撰写本文时,综合安装方法不会自动执行此操作。
我们可以等待,直到迫使这种行为chef-client
可执行文件安装在服务器上调用命令。 使用简单bash
循环中,我们将检查每五秒钟这个文件的存在。 当它被发现,我们将运行chef-client
,以实现我们所指定的初始配置。
该runcmd
模块可以用来发出任意命令。 这是我们的理想地点bash
循环:
runcmd:
- while [ ! -e /usr/bin/chef-client ]; do sleep 5; done; chef-client
此外,您还可以选择添加另一个cloud-config
第一次开机后指令,空航线的元数据终结点。 这是有用的,因为我们在我们的用户数据中放置一个私钥。 没有空路由元数据端点,服务器上的任何用户都可以访问。 通过添加:
disable_ec2_metadata: true
将这些与我们到目前为止构建的脚本结合起来,我们可以获得完整的脚本来引导我们的节点并将其连接到Chef基础设施:
#cloud-config
chef:
install_type: "omnibus"
omnibus_url: "https://www.opscode.com/chef/install.sh"
force_install: false
node_name: "new_node"
server_url: "https://your_server.com/organizations/digitalocean"
validation_name: "digitalocean-validator"
validation_key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA3O60HT5pwEo6xUwcZ8WtExBUhoL3bTjlsvHVXg1JVmBUES+f
V9jLu2N00uSZEDZneCIQyHLBXnqD/UNvWEPNvPzt1ecXzmw2BytB7lPDW4/F/8tJ
vAVrKqC7B04VFGmcFY2zC8gf8BWmX8CNRDQooM7UO5OWe/H6GDGPPRIITerO3GrU
. . .
sWyRAoGBAKNc/ZUM8ljRV0UJxQ9nbdozXRZjtUaNgXMNiw+oP2HYYdHrlkKnGHYJ
Js63rvjpq8pocjE8YI+2H0v4/4uWqW8GEBfrWbLMzGsYPnRyiHR5+hgjCUU50RB3
eFoNbURwLYcq2Z/IAQZpDpJWpofz3OVMpMXtei1cIflrAAd2wtWO
-----END RSA PRIVATE KEY-----
environment: "staging"
run_list:
- "recipe[lamp]"
- "role[backend-web]"
initial_attributes:
lamp:
apache:
port: 80
mysql:
username: webclient
pass: $#fjeaiop34S
output: {all: '| tee -a /var/log/cloud-init-output.log'}
runcmd:
- while [ ! -e /usr/bin/chef-client ]; do sleep 5; done; chef-client
disable_ec2_metadata: true
上述脚本可以根据您的基础架构中的每个新服务器进行调整。
使用Cloud-Config脚本引导Puppet节点
如果你的基础架构依赖于Puppet的配置管理,可以用puppet
模块来代替。 像Chef为例,自举一个Puppet节点包括使用cloud-config
附加新的服务器的现有配置管理基础设施。
在开始之前,您应该为您的基础架构配置一个Puppet主服务器。 如果您需要帮助得到一个Puppet服务器运行起来,看看这个指南 。
总体规划
当一个新的Puppet服务器联机时,安装一个Puppet代理,以便它可以与Puppet主服务器通信。 该代理负责接收和应用指示节点的期望状态的信息。 为此,代理程序与主机连接,上传有关其自身的数据,下拉描述其所需状态的当前目录,并执行达到该状态所需的操作。
在此之前,在第一次运行时,代理必须向主服务器注册自己。 它创建证书签名请求并将其发送给主服务器进行签名。 通常,代理将定期重新连接到主机,直到证书签名,但您可以配置您的Puppet自动签署具有某些特性的传入请求,如果这适合您的环境(我们将在后面讨论)。
使用我们的cloud-config
脚本,我们将配置我们的新服务器,它需要连接到主首次的信息。 此时,它可以以目录的形式从Puppet主服务器检索配置详细信息。
收集来自Puppet Master的必要数据
我们需要做的建立我们之前的第一件事cloud-config
文件是收集来自我们的Puppet主服务器,我们将需要连接的数据。 我们只需要几个信息。
首先,您需要获取Puppet主服务器的完全限定域名(FQDN)。 您可以输入以下命令:
hostname -f
在大多数情况下,它应该返回如下:
puppet.example.com
你也可以检查你的Puppet主配置文件,看是否dns_alt_names
选项设置:
cat /etc/puppet/puppet.conf
. . .
dns_alt_names = puppet,puppet.example.com
. . .
如果在设置这些选项后生成了Puppet master的SSL证书,它们也可以使用。
我们需要收集的另一个项目是Puppet master的证书颁发机构证书。 这可以在任一找到/var/lib/puppet/ssl/certs/ca.pem
或/var/lib/puppet/ssl/ca/ca_crt.pem
:
sudo cat /var/lib/puppet/ssl/certs/ca.pem
结果将如下所示:
-----BEGIN CERTIFICATE-----
MIIFXjCCA0agAwIBAgIBATANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFQdXBw
ZXQgQ0E6IHB1cHBldDAeFw8xNTAyMTkxOTA0MzVaFw0yMDAyMTkxOTA0MzVaMBwx
GjAYBgNVBAMMEVB1cHBldCBDQTogcHVwcGV0MIICIjANBgkqhkiG9w0BAQEFAAOC
. . .
arsjZT5/CtIhtP33Jl3mCp7U2F6bsk4/GDGRaAsFXjJHvBbL93NzgpkZ7elf0zUP
rOcSGrDrUuzuJk8lEAtrZr/IfAgfKKXPqbyYF95V1qN3OMY+aTcrK20XTydKVWSe
l5UfYGY3S9UJFrSn9aBsZzN+10HXPkaFKo7HxpztlYyJNI8UVSatcRF4aYYqt9KR
UClnR+2WxK5v7ix0CVd4/KpYH/6YivvyTwxrhjF2AksZKg==
-----END CERTIFICATE-----
复制证书的完整。 我们将包括本在我们的cloud-config
文件,这样我们的新的服务器可以验证它们连接到正确的Puppet Master。
一旦你有了这些信息,你就可以开始构建cloud-config
文件,以便在新的服务器本身可以插入现有的Puppet基础设施。
基本云配置Puppet节点安装
在cloud-config
新节点的Puppet配置相当简单。 所有具体的Puppet配置位于中puppet:
文件的部分。 正如所有cloud-config
文件中,第一行必须包含#cloud-config
上其自身的:
#cloud-config
puppet:
在此之下,只有两个子部分。 第一是ca_cert
键。 这将使用管道字符启动YAML文本块,以便可以将CA证书完整地作为缩进块提供:
#cloud-config
puppet:
ca_cert: |
-----BEGIN CERTIFICATE-----
MIIFXjCCA0agAwIBAgIBATANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFQdXBw
ZXQgQ0E6IHB1cHBldDAeFw8xNTAyMTkxOTA0MzVaFw0yMDAyMTkxOTA0MzVaMBwx
GjAYBgNVBAMMEVB1cHBldCBDQTogcHVwcGV0MIICIjANBgkqhkiG9w0BAQEFAAOC
. . .
arsjZT5/CtIhtP33Jl3mCp7U2F6bsk4/GDGRaAsFXjJHvBbL93NzgpkZ7elf0zUP
rOcSGrDrUuzuJk8lEAtrZr/IfAgfKKXPqbyYF95V1qN3OMY+aTcrK20XTydKVWSe
l5UfYGY3S9UJFrSn9aBsZzN+10HXPkaFKo7HxpztlYyJNI8UVSatcRF4aYYqt9KR
UClnR+2WxK5v7ix0CVd4/KpYH/6YivvyTwxrhjF2AksZKg==
-----END CERTIFICATE-----
确保包括整个证书以及开始和结束标记,并适当缩进。
根据第二部分puppet:
伞是conf:
部分。 这是用于指定将被附加到一个通用的键-值对puppet.conf
文件。 该键值应根据第头部放置,因为他们将在puppet.conf
文件。
例如,至少,新服务器将需要知道Puppet主服务器的地址。 在puppet.conf
文件,这下找到[agent]
部分,如下所示:
. . .
[agent]
server = puppet.example.com
. . .
要在指定此cloud-config
语法,你想补充一点什么,我们到目前为止有:
#cloud-config
puppet:
ca_cert: |
-----BEGIN CERTIFICATE-----
MIIFXjCCA0agAwIBAgIBATANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFQdXBw
ZXQgQ0E6IHB1cHBldDAeFw8xNTAyMTkxOTA0MzVaFw0yMDAyMTkxOTA0MzVaMBwx
GjAYBgNVBAMMEVB1cHBldCBDQTogcHVwcGV0MIICIjANBgkqhkiG9w0BAQEFAAOC
. . .
arsjZT5/CtIhtP33Jl3mCp7U2F6bsk4/GDGRaAsFXjJHvBbL93NzgpkZ7elf0zUP
rOcSGrDrUuzuJk8lEAtrZr/IfAgfKKXPqbyYF95V1qN3OMY+aTcrK20XTydKVWSe
l5UfYGY3S9UJFrSn9aBsZzN+10HXPkaFKo7HxpztlYyJNI8UVSatcRF4aYYqt9KR
UClnR+2WxK5v7ix0CVd4/KpYH/6YivvyTwxrhjF2AksZKg==
-----END CERTIFICATE-----
conf:
agent:
server: "puppet.example.com"
注意, conf:
部分是在符合ca_cert
部,而不是一个子元素。 这是连接到Puppet主服务器所需的最低限度。 在发现的任何额外的配置项puppet.conf
可以用类似的方法首先创建了段名的水平,然后定义键-值对添加。
在此之后,我们应该重定向将来的所有输出到cloud-init-output.log
文件,并添加runcmd
线相媲美,我们添加了Chefconfig中的之一。 这将等待,直到安装Puppet代理,然后启用并重新启动它。 我们也可以在第一次运行之后对元数据端点进行null路由,就像我们在Chef部分中做的那样。 这些行cloud-config
指令应该放在任何其它模块部分外:
. . .
conf:
agent:
server: "puppet.example.com"
output: {all: '| tee -a /var/log/cloud-init-output.log'}
runcmd:
- while [ ! -e /usr/bin/puppet ]; do sleep 5; done; puppet agent --enable; service puppet restart
disable_ec2_metadata: true
使用此信息,新服务器可以连接到Puppet主服务器,然后生成客户端证书签名请求以传输到主服务器。 默认情况下,客户端证书必须在Puppet主机上手动签名。 一旦完成,在下一个Puppet代理更新间隔(默认情况下每30分钟),节点将从Puppet主机下拉其配置。 我们稍后将演示如何实现相对安全的自动签名机制,以避免此延迟。
定义节点的证书名称
一个可以被放置到新服务器的值的puppet.conf
文件是一个独特的情况。 在cloud-config
文件中, certname
选项,如果某些变量给出从环境中替代值。 识别以下变量:
-
%i
:服务器的实例ID。 这将从采取http://169.254.169.254/metadata/v1/id
创建服务器时。 它对应于用于唯一标识Droplet的Droplet ID。 -
%f
:服务器的FQDN。
考虑到这一点,一个共同的certname
设置是这样的:
#cloud-config
puppet:
. . .
conf:
agent:
server: "puppet.example.com"
certname: "%i.%f"
这将产生一个certname
用类似这样的模式:
|-Droplet ID
|
| |-Fully Qualified Domain Name
| |
|-----||-------------------|
123456.testnode.example.com
有DropletID作为的一部分certname
可以为配置安全Puppet自动签名有用的,因为我们将在下一节中看到。
实现Puppet证书自动签名
如果您希望实施证书自动签名系统以避免管理员干预,则有几个选项。 您必须首先在您的Puppet主服务器上设置此。
在puppet.conf
Puppet主服务器上的文件,你可以设置autosign
下的选项[master]
文件的部分。 这可以采取几个不同的值:
-
true
:这将告诉Puppet主服务器签署来在每一个证书请求,没有做任何检查。 这在真实环境中非常危险,因为任何主机都可以获得签署的CSR并进入您的基础设施。 -
<whitelist_filename>
第二个选项是指定将作为主机的白名单或主机正则表达式的文件。 Puppet master将根据此列表检查证书签名请求,以查看证书是否应该被签名。 这也是不推荐的,因为证书名称可以容易地欺骗。 -
<policy_executable>
第三个选项是指定的脚本或可执行文件可以运行,以确定证书签名请求是否应该签署。 Puppet将传递certname作为参数,并通过标准输入传递整个CSR。 如果返回退出状态为0,则证书已签名。 如果另一个状态给出,该证书将不会被签署。
基于策略的自动签名是实现自动密钥签名的最安全的方法,因为它允许您在如何区分合法和非合法请求方面任意复杂。
为了演示基于策略的自动签名,您可以添加certname
变量您的cloud-config
包含%i
实例ID变量。 我们将使用%i.%f
因此,它也包括选择以及主机名:
#cloud-config
puppet:
conf:
agent:
server: "puppet.example.com"
certname: "%i.%f"
ca_cert: |
. . .
您完整的cloud-config
现在看起来是这样的:
#cloud-config
puppet:
conf:
agent:
server: "puppet.example.com"
certname: "%i.%f"
ca_cert: |
-----BEGIN CERTIFICATE-----
MIIFXjCCA0agAwIBAgIBATANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFQdXBw
ZXQgQ0E6IHB1cHBldDAeFw8xNTAyMTkxOTA0MzVaFw0yMDAyMTkxOTA0MzVaMBwx
GjAYBgNVBAMMEVB1cHBldCBDQTogcHVwcGV0MIICIjANBgkqhkiG9w0BAQEFAAOC
. . .
arsjZT5/CtIhtP33Jl3mCp7U2F6bsk4/GDGRaAsFXjJHvBbL93NzgpkZ7elf0zUP
rOcSGrDrUuzuJk8lEAtrZr/IfAgfKKXPqbyYF95V1qN3OMY+aTcrK20XTydKVWSe
l5UfYGY3S9UJFrSn9aBsZzN+10HXPkaFKo7HxpztlYyJNI8UVSatcRF4aYYqt9KR
UClnR+2WxK5v7ix0CVd4/KpYH/6YivvyTwxrhjF2AksZKg==
-----END CERTIFICATE-----
output: {all: '| tee -a /var/log/cloud-init-output.log'}
runcmd:
- while [ ! -e /usr/bin/puppet ]; do sleep 5; done; puppet agent --enable; service puppet restart
disable_ec2_metadata: true
在Puppet主服务器上,我们将必须设置一个验证脚本。 因为Puppet已经安装了Ruby,所以我们可以创建一个简单的Ruby脚本。
由于我们使用的是%i.%f
的格式certname
,我们可以检查的第一部分是否certname
(第一个点之前的部分),与我们的帐户的有效DropletID一致。 这只是一个简单的检查,在实践中做的不会比白名单文件多。 然而,如果你愿意,你可以适应这个想法要复杂得多。
为此,我们需要一个来自DigitalOcean控制面板“Apps&API”部分的个人访问令牌。 您还需要安装一个DigitalOcean Ruby库。 下面,我们将向您展示了使用一些简单的脚本驳船和DropletKit DigitalOceanRuby的客户。
如果您希望使用插入客户端,请通过键入以下命令在Puppet master上安装gem:
sudo gem install barge
下面的脚本可以用来检查的第一部分是否certname
在证书签名请求一个有效的DropletID对应:
#!/usr/bin/env ruby
require 'barge'
TOKEN = 'YOUR_DIGITALOCEAN_API_TOKEN'
droplet_ids = []
certname = ARGV[0]
id_string = certname.slice(0...(certname.index('.')))
id_to_check = id_string.to_i
client = Barge::Client.new(access_token: TOKEN)
droplets = client.droplet.all
droplets.droplets.each do |droplet|
droplet_ids << droplet.id
end
Kernel.exit(droplet_ids.include?(id_to_check))
如果您希望使用DropletKit,官方的DigitalOcean Ruby客户端,您可以通过键入以下命令来安装该gem:
sudo gem install droplet_kit
请注意,DropletKit gem仅对Ruby 2.0及更高版本有效,因此在使用Puppet附带的Ruby版本时可能不会出现这种情况。
DropletKit的脚本可以这样修改:
#!/usr/bin/env ruby
require 'droplet_kit'
TOKEN = 'YOUR_DIGITALOCEAN_API_TOKEN'
droplet_ids = []
certname = ARGV[0]
id_string = certname.slice(0...(certname.index('.')))
id_to_check = id_string.to_i
client = DropletKit::Client.new(access_token: TOKEN)
droplets = client.droplets.all
droplets.each do |droplet|
droplet_ids << droplet.id
end
Kernel.exit(droplet_ids.include?(id_to_check))
您可以将对应于您在一个名为安装Gem脚本/etc/puppet/validate.rb
并标记通过键入可执行:
sudo chmod +x /etc/puppet/validate.rb
然后,您可以以下添加到您的puppet.conf
文件(位于/etc/puppet/puppet.conf
如果使用开源Puppet):
. . .
[master]
autosign = /etc/puppet/validate.rb
. . .
重新启动Apache服务以实现新的签署策略:
sudo service apache2 restart
现在,当Puppet master接收到证书签名请求时,它将检查证书名称的第一部分是否与您帐户中的有效Droplet名称相对应。 这是一个大致的例子,说明如何使用可执行文件验证请求。
结论
通过利用cloud-config
脚本,您可以轻松地引导你的新服务器,并把他们关到现有的配置管理系统。 这允许您在管理解决方案范围之外进行重要更改之前,通过现有工具立即控制您的基础架构。