简而言之,服务器配置管理(通常称为IT自动化)是一种将基础架构管理转变为代码库的解决方案,描述了在一组可以进行版本控制和轻松重用的配置脚本中部署服务器所需的所有过程。 它可以大大提高任何服务器基础架构的完整性。
在先前的指导 ,我们谈到了实施配置管理策略为您的服务器基础架构,配置管理工具是如何工作的,以及这些工具通常有什么共同之处的主要优势。
本系列的这一部分将引导您完成使用Chef的自动化服务器配置过程,Chef是一个强大的配置管理工具,利用Ruby编程语言自动化基础架构管理和配置。 我们将重点介绍创建一个简化示例所需的语言术语,语法和功能,以使用Apache完全自动化部署Ubuntu 14.04 Web服务器。
这是我们需要自动化以实现我们的目标的步骤列表:
- 更新
apt
缓存 - 安装Apache
- 创建自定义文档根目录
- 放置
index.html
文件中的自定义文档根目录 - 应用模板以设置我们的自定义虚拟主机
- 重新启动Apache
我们将首先看看Chef使用的术语,然后概述可用于编写Recipe的主要语言特性。 在本指南的最后,我们将共享完整的示例,以便您可以自己尝试。
注意:本指南旨在介绍Chef语言以及如何编写自动化服务器配置的配方。 对于Chef的更多介绍视图,包括必要的安装和开始使用此工具的步骤,请查看我们如何建立一个Chef12配置管理系统在Ubuntu 14.04服务器指南。
入门
在我们可以转到更实用的Chef视图之前,重要的是我们熟悉这个工具引入的重要术语和概念。
Chef条款
- Chef服务器 :存储信息和管理的节点的配置的中央服务器
- Chef节点 :由ChefServer管理的单个服务器
- Chef工作站 :在其中创建并上传到服务器Chef的provisionings控制机
- 配方 :包含的一组指令(资源)要执行的文件。 配方必须包含在里面Recipe
- 资源 :声明的系统的元件和应执行什么动作的代码的一部分。 例如,要安装一个软件包,我们宣布与行动的资源包 安装
- Recipe :在一个预先定义的方式组织的Recipe和其他相关文件的集合,以促进一个供应的共享和重用份
- 属性 :有关特定节点的详细信息。 属性可以是自动的(见下一个定义),也可以在Recipe中定义
- 自动属性 :包含有关系统的信息,例如网络接口和操作系统(称为事实在其他工具)的全局变量。 这些自动属性由一个称为Ohai工具收集
- 服务范围 :用于触发服务状态变化,比如重新启动或停止服务
配方格式
Chef Recipe是使用Ruby编写的。 配方基本上是资源定义的集合,其将创建将由节点执行的逐步指令集。 这些资源定义可以与Ruby代码混合,以实现更大的灵活性和模块化。
下面你可以找到将运行配方的一个简单的例子apt-get update
,并安装vim
算账:
execute "apt-get update" do
command "apt-get update"
end
apt_package "vim" do
action :install
end
写Recipe
使用变量
局部变量可以在recipe中定义为普通的Ruby局部变量。 下面的示例显示了如何创建一个稍后在资源定义中使用的局部变量:
package = "vim"
apt_package package do
action :install
end
但是,这些变量的作用域有限,仅在定义它们的文件中有效。 如果你想创建一个变量,并使其在全球范围,所以你可以从任何你的Recipe或配方的使用它,你需要定义一个自定义属性 。
使用属性
属性表示有关节点的详细信息。 Chef具有自动属性,这是由Ohai工具收集的属性,包含有关系统的信息(如平台,主机名和默认IP地址),但也可以定义自己的自定义属性。
属性有不同的优先等级,通过创建属性的类型定义的。 default
属性是最常见的选择,因为他们仍然可以通过其他的属性类型需要时覆盖。
下面的例子显示了之前例子如何看起来像一个default
节点属性,而不是一个局部变量:
node.default['main']['package'] = "vim"
apt_package node['main']['package'] do
action :install
end
在此示例中有两个细节要注意:
定义节点变量时的推荐做法是使用当前使用的Recipe作为键将它们组织为哈希。 在这种情况下,我们使用main
的,因为我们有相同名称的Recipe。 这避免了混淆,如果您使用可能具有类似命名属性的多个Recipe。
我们使用的通知node.default
定义属性的时候,但后来在访问它的价值的时候,我们使用node
直接。 该node.default
使用定义了我们正在创建类型默认的属性。 该属性可能其值覆盖由另一种类型的具有较高优先级,如正常或覆盖属性。
属性的优先级可以稍微有点混乱,但你会习惯于它的一些实践。 为了说明行为,请考虑以下示例:
node.normal['main']['package'] = "vim"
node.override['main']['package'] = "git"
node.default['main']['package'] = "curl"
apt_package node['main']['package'] do
action :install
end
你知道在这种情况下将安装哪个包吗? 如果你猜git
,你猜对了。 无论在其中的属性被定义,该类型的更高的优先级的顺序override
将使node['main']['package'] be evaluated to
git`。
使用循环
循环通常用于使用不同的输入值重复任务。 例如,您可以创建单个任务,并使用循环来重复任务,以便安装所有不同的软件包,而不是创建10个任务来安装10个不同的软件包。
Chef支持所有Ruby循环结构,用于在recipe中创建循环。 对于简单的使用, each
一个共同的选择:
['vim', 'git', 'curl'].each do |package|
apt_package package do
action :install
end
end
除了使用内联数组,还可以创建一个变量或属性来定义要在循环中使用的参数。 这将使事情更有条理,更容易阅读。 下面,同样的例子现在使用一个局部变量来定义应该安装的包:
packages = ['vim', 'git', 'curl']
packages.each do |package|
apt_package package do
action :install
end
end
使用条件
条件可以用于基于例如来自命令的变量或输出来动态地决定是否应当执行代码块。
Chef支持所有Ruby条件,用于在recipe中创建条件语句。 此外,所有资源类型支持两个特殊的属性,将任务是否应执行与否决定之前计算表达式: if_only
和not_if
。
下面的例子将检查是否存在php
尝试安装扩展之前php-pear
。 它将使用命令which
核查是否有一个php
目前此系统上安装可执行文件。 如果命令which php
返回false,这个任务将不会被执行:
apt_package "php-pear" do
action :install
only_if "which php"
end
如果我们想要做的对面,当条件为真,除了在任何时候都执行一个命令,我们使用not_if
来代替。 这个例子将安装php5
,除非该系统是CentOS的:
apt_package "php5" do
action :install
not_if { node['platform'] == 'centos' }
end
对于执行更复杂的评估,如果要在特定条件下执行多个任务,可以使用任何标准的Ruby条件。 下面的例子将只执行apt-get update
时,系统要么是Debian的或 Ubuntu:
if node['platform'] == 'debian' || node['platform'] == 'ubuntu'
execute "apt-get update" do
command "apt-get update"
end
end
属性node['platform']
是从Chef自动属性。 在最后一个例子是仅用于说明的更复杂的条件结构,但是它可以通过使用自动属性的简单测试来代替node['platform_family']
这将返回“Debian的”两个Debian和Ubuntu系统。
使用模板
模板通常用于设置配置文件,允许使用变量和其他旨在使这些文件更通用和可重用的功能。
Chef使用嵌入式Ruby(ERB)模板,这与Puppet使用的格式相同。 它们支持条件,循环和其他Ruby特性。
下面是用于设置Apache虚拟主机的ERB模板的示例,使用变量来定义此主机的文档根目录:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot <%= @doc_root %>
<Directory <%= @doc_root %>>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
为了应用模板,我们需要创建一个template
资源。 这是您将如何应用此模板来替换默认的Apache虚拟主机:
template "/etc/apache2/sites-available/000-default.conf" do
source "vhost.erb"
variables({ :doc_root => node['main']['doc_root'] })
action :create
end
Chef在处理本地文件时做了一些假设,以便实施组织和模块化。 在这种情况下,Chef会寻找一个vhost.erb
一个模板文件夹应该是在这个配方是位于同一菜谱里面模板文件。
与我们目前为止看到的其他配置管理工具不同,Chef对变量有更严格的范围。 这意味着你必须明确地为您提供计划模板,使用里面定义,当任何变量template
资源。 在这个例子中,我们使用了variables
的方法沿着传递doc_root
我们需要在虚拟主机模板属性。
定义和触发服务
服务资源用于确保服务被初始化和启用。 它们还用于触发服务重新启动。
在Chef中,服务资源需要在您尝试通知它们之前声明,否则您会收到错误。
让我们考虑我们以前的模板使用示例,其中我们设置一个Apache虚拟主机。 如果你想确保Apache是一个虚拟主机更改后重新启动时,您首先需要创建为Apache服务的服务资源。 这是如何在Chef中定义这样的资源:
service "apache2" do
action [ :enable, :start ]
end
现在,定义模板资源时,需要包括notify
,以便选择触发启动:
template "/etc/apache2/sites-available/000-default.conf" do
source "vhost.erb"
variables({ :doc_root => node['main']['doc_root'] })
action :create
notifies :restart, resources(:service => "apache2")
end
示例配方
现在让我们看看一个清单,它将在Ubuntu 14.04系统中自动安装Apache Web服务器,如本指南的介绍中所述。
完整的示例,包括设置Apache模板文件和一个HTML文件,由Web服务器提供服务,可以发现在Github上 。 该文件夹还包含一个Vagrantfile,可以让你在一个简化的安装测试清单,利用管理的虚拟机放浪 。
下面你可以找到完整的Recipe:
node.default['main']['doc_root'] = "/vagrant/web"
execute "apt-get update" do
command "apt-get update"
end
apt_package "apache2" do
action :install
end
service "apache2" do
action [ :enable, :start ]
end
directory node['main']['doc_root'] do
owner 'www-data'
group 'www-data'
mode '0644'
action :create
end
cookbook_file "#{node['main']['doc_root']}/index.html" do
source 'index.html'
owner 'www-data'
group 'www-data'
action :create
end
template "/etc/apache2/sites-available/000-default.conf" do
source "vhost.erb"
variables({ :doc_root => node['main']['doc_root'] })
action :create
notifies :restart, resources(:service => "apache2")
end
配方解释
行1
配方与属性定义,启动node['main']['doc_root']
我们可以在这里使用一个简单的局部变量,然而在大多数使用情况下,Recipe需要定义将从包括的Recipe或其他文件中使用的全局变量。 对于这些情况,有必要创建属性而不是局部变量,因为后者具有有限的范围。
行3-5
此执行资源运行的apt-get update
。
线7-10
这apt_package资源安装软件包apache2
。
第12-15行
该服务资源允许并启动服务apache2
。 稍后,我们将需要通知此资源以重新启动服务。 重要的是,服务定义在尝试通知服务的任何资源之前,否则您将收到错误。
17-22行
该目录资源使用的自定义属性定义的值node['main']['doc_root']
创建一个目录,将作为我们的文档根目录 。
第24-29行
一个cookbook_file资源用于本地文件复制到远程服务器。 这个资源会复制我们index.html
文件并将其放置在我们以前的任务中创建的文档根目录中。
第31-36行
最后,这个模板资源应用我们的Apache虚拟主机模板,并通知服务apache2
重启动。
结论
Chef是一个强大的配置管理工具,利用Ruby语言自动执行服务器配置和部署。 它允许您自由使用标准语言功能,以获得最大的灵活性,同时还为某些资源提供自定义DSL。