读写锁厨师_配置管理101:编写厨师食谱

读写锁厨师

In a nutshell, server configuration management (also popularly referred to as IT Automation) is a solution for turning your infrastructure administration into a codebase, describing all processes necessary for deploying a server in a set of provisioning scripts that can be versioned and easily reused. It can greatly improve the integrity of any server infrastructure over time.

简而言之,服务器配置管理(通常也称为IT自动化)是一种将基础架构管理转换为代码库的解决方案,它以一组版本控制且易于重用的配置脚本描述了部署服务器所需的所有过程。 随着时间的推移,它可以大大提高任何服务器基础架构的完整性。

In a previous guide, we talked about the main benefits of implementing a configuration management strategy for your server infrastructure, how configuration management tools work, and what these tools typically have in common.

上一指南中 ,我们讨论了为服务器基础结构实施配置管理策略的主要好处,配置管理工具如何工作以及这些工具通常具有什么共同点。

This part of the series will walk you through the process of automating server provisioning using Chef, a powerful configuration management tool that leverages the Ruby programming language to automate infrastructure administration and provisioning. We will focus on the language terminology, syntax, and features necessary for creating a simplified example to fully automate the deployment of an Ubuntu 18.04 web server using Apache.

本系列的这一部分将引导您完成使用Chef的服务器配置自动化过程,Chef是一个功能强大的配置管理工具,利用Ruby编程语言来自动化基础结构管理和配置。 我们将重点介绍创建简化示例以使用Apache完全自动化Ubuntu 18.04 Web服务器的部署所必需的语言术语,语法和功能。

This is the list of steps we need to automate in order to reach our goal:

这是我们要实现目标需要自动化的步骤的列表:

  1. Update the apt cache

    更新apt缓存

  2. Install Apache

    安装Apache
  3. Create a custom document root directory

    创建一个自定义文档的根目录
  4. Place an index.html file in the custom document root

    index.html文件放在自定义文档的根目录中

  5. Apply a template to set up our custom virtual host

    应用模板来设置我们的自定义虚拟主机
  6. Restart Apache

    重新启动Apache

We will start by having a look at the terminology used by Chef, followed by an overview of the main language features that can be used to write recipes. At the end of this guide, we will share the complete example so you can try it by yourself.

我们将首先查看Chef所使用的术语,然后概述可用于编写食谱的主要语言功能。 在本指南的最后,我们将分享完整的示例,以便您可以自己尝试。

Note: this guide is intended to get you introduced to the Chef language and how to write recipes to automate your server provisioning. For a more introductory view of Chef, including the steps necessary for installing and getting started with this tool, please refer to Chef’s official documentation.

注意:本指南旨在向您介绍Chef语言以及如何编写配方以自动执行服务器配置。 有关Chef的更多介绍性视图,包括安装和使用此工具开始所必需的步骤,请参阅Chef的官方文档

入门 (Getting Started)

Before we can move to a more hands-on view of Chef, it is important that we get acquainted with important terminology and concepts introduced by this tool.

在我们进一步了解Chef之前,重要的一点是,我们熟悉此工具引入的重要术语和概念。

厨师条款 (Chef Terms)

  • Chef Server: a central server that stores information and manages provisioning of the nodes

    Chef Server :一个中央服务器,用于存储信息并管理节点的置备

  • Chef Node: an individual server that is managed by a Chef Server

    厨师节点 :由厨师服务器管理的单个服务器

  • Chef Workstation: a controller machine where the provisionings are created and uploaded to the Chef Server

    Chef Workstation :在其中创建配置并将其上载到Chef Server的控制器计算机

  • Recipe: a file that contains a set of instructions (resources) to be executed. A recipe must be contained inside a Cookbook

    配方 :包含一组要执行的指令(资源)的文件。 食谱必须包含在食谱中

  • Resource: a portion of code that declares an element of the system and what action should be executed. For instance, to install a package we declare a package resource with the action install

    资源 :代码的一部分,它声明系统的元素以及应执行的操作。 例如,要安装软件包,我们使用动作install声明软件包资源。

  • Cookbook: a collection of recipes and other related files organized in a pre-defined way to facilitate sharing and reusing parts of a provisioning

    食谱 :以预定义方式组织的食谱和其他相关文件的集合,以促进共享和重用部分配置

  • Attributes: details about a specific node. Attributes can be automatic (see next definition) and can also be defined inside recipes

    属性 :有关特定节点的详细信息。 属性可以是自动的(请参阅下一个定义),也可以在配方内定义

  • Automatic Attributes: global variables containing information about the system, like network interfaces and operating system (known as facts in other tools). These automatic attributes are collected by a tool called Ohai

    自动属性 :包含有关系统信息的全局变量,例如网络接口和操作系统(在其他工具中称为事实 )。 这些自动属性由称为Ohai的工具收集

  • Services: used to trigger service status changes, like restarting or stopping a service

    服务 :用于触发服务状态更改,例如重新启动或停止服务

配方格式 (Recipe Format)

Chef recipes are written using Ruby. A recipe is basically a collection of resource definitions that will create a step-by-step set of instructions to be executed by the nodes. These resource definitions can be mixed with Ruby code for more flexibility and modularity.

厨师食谱是使用Ruby编写的。 配方基本上是资源定义的集合,将创建由节点执行的逐步指令集。 这些资源定义可以与Ruby代码混合使用,以实现更大的灵活性和模块化。

Below you can find a simple example of a recipe that will run apt-get update and install vim afterwards:

在下面,您可以找到一个食谱的简单示例,该食谱将运行apt-get update并随后安装vim

execute "apt-get update" do
 command "apt-get update"
end

apt_package "vim" do
 action :install
end

书写食谱 (Writing Recipes)

使用变量 (Working with Variables)

Local variables can be defined inside recipes as regular Ruby local variables. The example below shows how to create a local variable that is later used inside a resource definition:

可以在配方内部将局部变量定义为常规Ruby局部变量。 以下示例显示了如何创建局部变量,该局部变量随后在资源定义中使用:

package  = "vim"

apt_package package do
 action :install
end

These variables, however, have a limited scope, being valid only inside the file where they were defined. If you want to create a variable and make it globally available, so you can use it from any of your cookbooks or recipes, you need to define a custom attribute.

但是,这些变量的范围有限,仅在定义它们的文件内部有效。 如果您想创建一个变量并使它全局可用,那么您可以从任何食谱或食谱中使用它,则需要定义一个自定义属性

使用属性 (Using Attributes)

Attributes represent details about a node. Chef has automatic attributes, which are the attributes collected by a tool called Ohai and containing information about the system (such as platform, hostname and default IP address), but it also lets you define your own custom attributes.

属性表示有关节点的详细信息。 Chef具有自动属性,这些属性是由称为Ohai的工具收集的属性,并包含有关系统的信息(例如平台,主机名和默认IP地址),但是它还允许您定义自己的自定义属性。

Attributes have different precedence levels, defined by the type of attribute you create. default attributes are the most common choice, as they can still be overwritten by other attribute types when desired.

属性具有不同的优先级,由您创建的属性类型定义。 default属性是最常见的选择,因为在需要时它们仍可以被其他属性类型覆盖。

The following example shows how the previous example would look like with a default node attribute instead of a local variable:

以下示例显示了使用default节点属性而不是局部变量的上一示例的样子:

node.default['main']['package'] = "vim"

apt_package node['main']['package'] do
 action :install
end

There are two details to observe in this example:

在此示例中要注意两个细节:

The recommended practice when defining node variables is to organize them as hashes using the current cookbook in use as the key. In this case, we used main, because we have a cookbook with the same name. This avoids confusion if you are working with multiple cookbooks that might have similar named attributes. Notice that we used node.default when defining the attribute, but when accessing its value later, we used node directly. The node.default usage defines that we are creating an attribute of type default. This attribute could have its value overwritten by another type with higher precedence, such as normal or override attributes.

定义节点变量时,建议的做法是使用当前使用的食谱作为键将它们组织为哈希。 在这种情况下,我们使用main ,因为我们有一本同名的食谱。 如果您正在使用可能具有相似命名属性的多个食谱,则可以避免混淆。 请注意,定义属性时我们使用了node.default ,但是稍后访问它的值时,我们直接使用了nodenode.default用法定义我们正在创建类型为default的属性。 此属性的值可能会被其他具有较高优先级的类型所覆盖,例如普通覆盖属性。

The attributes’ precedence can be slightly confusing at first, but you will get used to it after some practice. To illustrate the behavior, consider the following example:

首先,属性的优先级可能会有些混乱,但是经过一些练习后,您会习惯它。 为了说明此行为,请考虑以下示例:

node.normal['main']['package']  = "vim"

node.override['main']['package'] = "git"

node.default['main']['package'] = "curl"

apt_package node['main']['package'] do
 action :install
end

Do you know which package will be installed in this case? If you guessed git, you guessed correctly. Regardless of the order in which the attributes were defined, the higher precedence of the type override will make the node['main']['package'] be evaluated togit`.

您知道在这种情况下将安装哪个软件包吗? 如果您猜到了git ,那么您猜对了。 无论定义属性的顺序如何,类型override的较高优先级都会使node['main']['package'] be evaluated to git`。

使用循环 (Using Loops)

Loops are typically used to repeat a task using different input values. For instance, instead of creating 10 tasks for installing 10 different packages, you can create a single task and use a loop to repeat the task with all the different packages you want to install.

循环通常用于使用不同的输入值重复执行任务。 例如,您不必创建10个任务来安装10个不同的软件包,而是可以创建一个任务并使用循环对要安装的所有不同软件包重复执行该任务。

Chef supports all Ruby loop structures for creating loops inside recipes. For simple usage, each is a common choice:

Chef支持所有Ruby循环结构,用于在配方内部创建循环。 为了简单使用, each都是常见的选择:

['vim', 'git', 'curl'].each do |package|
 apt_package package do
   action :install
 end
end

Instead of using an inline array, you can also create a variable or attribute for defining the parameters you want to use inside the loop. This will keep things more organized and easier to read. Below, the same example now using a local variable to define the packages that should be installed:

除了使用内联数组,您还可以创建变量或属性来定义要在循环内使用的参数。 这将使事情更有条理,更易于阅读。 在下面的示例中,现在使用局部变量定义应安装的软件包:

packages = ['vim', 'git', 'curl']

packages.each do |package|
 apt_package package do
   action :install
 end
end

使用条件 (Using Conditionals)

Conditionals can be used to dynamically decide whether or not a block of code should be executed, based on a variable or an output from a command, for instance.

例如,条件变量可用于基于变量或命令的输出来动态决定是否应执行代码块。

Chef supports all Ruby conditionals for creating conditional statements inside recipes. Additionally, all resource types support two special properties that will evaluate an expression before deciding if the task should be executed or not: if_only and not_if.

Chef支持所有Ruby条件语句,用于在配方内创建条件语句。 此外,所有资源类型都支持两个特殊属性,这些属性将在决定是否执行任务之前先评估表达式: if_onlynot_if

The example below will check for the existence of php before trying to install the extension php-pear. It will use the command which for verifying if there is a php executable currently installed on this system. If the command which php returns false, this task won’t be executed:

下面的示例将在尝试安装扩展php-pear之前检查php是否存在。 它将使用命令which核查是否有一个php目前安装在此系统上执行。 如果which php命令返回false,则此任务将不会执行:

apt_package "php-pear" do
 action :install
 only_if "which php"
end

If we want to do the opposite, executing a command at all times except when a condition is evaluated as true, we use not_if instead. This example will install php5 unless the system is CentOS:

如果我们想做相反的事情, 除非条件被评估为真, 否则始终执行命令,我们改用not_if 。 除非系统是CentOS,否则此示例将安装php5

apt_package "php5" do
 action :install
 not_if { node['platform'] == 'centos' }
end

For performing more complex evaluations, of if you want to execute several tasks under a specific condition, you may use any of the standard Ruby conditionals. The following example will only execute apt-get update when the system is either Debian or Ubuntu:

为了执行更复杂的评估,例如要在特定条件下执行多个任务,可以使用任何标准Ruby条件。 以下示例仅在系统为Debian Ubuntu时执行apt-get update

if node['platform'] == 'debian' || node['platform'] == 'ubuntu'
 execute "apt-get update" do
   command "apt-get update"
 end
end

The attribute node['platform'] is an automatic attribute from Chef. The last example was only to demonstrate a more complex conditional construction, however it could be replaced by a simple test using the automatic attribute node['platform_family'], which would return “debian” for both Debian and Ubuntu systems.

属性node['platform']是Chef的自动属性。 最后一个示例只是为了演示更复杂的条件构造,但是可以使用自动属性node['platform_family']进行简单的测试来代替它,对于Debian和Ubuntu系统,该属性都将返回“ debian”。

使用模板 (Working with Templates)

Templates are typically used to set up configuration files, allowing for the use of variables and other features intended to make these files more versatile and reusable.

模板通常用于设置配置文件,从而允许使用变量和其他功能,以使这些文件更加通用和可重复使用。

Chef uses Embedded Ruby (ERB) templates, which is the same format used by Puppet. They support conditionals, loops and other Ruby features.

Chef使用嵌入式Ruby(ERB)模板,该模板与Puppet使用的格式相同。 它们支持条件,循环和其他Ruby功能。

Below is an example of an ERB template for setting up an Apache virtual host, using a variable to define the document root for this host:

以下是用于设置Apache虚拟主机的ERB模板的示例,使用变量来定义该主机的文档根目录:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot <%= @doc_root %>

    <Directory <%= @doc_root %>>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

In order to apply the template, we need to create a template resource. This is how you would apply this template to replace the default Apache virtual host:

为了应用模板,我们需要创建一个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 makes a few assumptions when dealing with local files, in order to enforce organization and modularity. In this case, Chef would look for a vhost.erb template file inside a templates folder that should be in the same cookbook where this recipe is located.

Chef在处理本地文件时会做一些假设,以加强组织和模块化。 在这种情况下,Chef将在template文件夹内寻找vhost.erb模板文件,该文件夹应与该配方所在的食谱相同。

Unlike the other configuration management tools we’ve seen so far, Chef has a more strict scope for variables. This means you will have to explicitly provide any variables you plan to use inside a template, when defining the template resource. In this example, we used the variables method to pass along the doc_root attribute we need at the virtual host template.

与到目前为止我们看到的其他配置管理工具不同,Chef对变量的范围更严格。 这意味着在定义template资源时,您将必须明确提供计划在模板内部使用的所有变量。 在此示例中,我们使用了variables方法来传递虚拟主机模板上所需的doc_root属性。

定义和触发服务 (Defining and Triggering Services)

Service resources are used to make sure services are initialized and enabled. They are also used to trigger service restarts.

服务资源用于确保服务已初始化并启用。 它们还用于触发服务重启。

In Chef, service resources need to be declared before you try to notify them, otherwise you will get an error.

在Chef中,在尝试通知服务资源之前需要声明它们,否则您将收到错误消息。

Let’s take into consideration our previous template usage example, where we set up an Apache virtual host. If you want to make sure Apache is restarted after a virtual host change, you first need to create a service resource for the Apache service. This is how such resource is defined in Chef:

让我们考虑之前的模板用法示例,在该示例中,我们设置了Apache虚拟主机。 如果要确保在更改虚拟主机后重新启动Apache,则首先需要为Apache服务创建服务资源。 这是在Chef中定义此类资源的方式:

service "apache2" do
  action [ :enable, :start ]
end

Now, when defining the template resource, you need to include a notify option in order to trigger a restart:

现在,在定义模板资源时,您需要包括一个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

配方示例 (Example Recipe)

Now let’s have a look at a recipe that will automate the installation of an Apache web server within an Ubuntu 14.04 system, as discussed in this guide’s introduction.

现在,让我们看一下将在Ubuntu 14.04系统中自动安装Apache Web服务器的方法,如本指南的简介中所述。

The complete example, including the template file for setting up Apache and an HTML file to be served by the web server, can be found on Github. The folder also contains a Vagrantfile that lets you test the recipe in a simplified setup, using a virtual machine managed by Vagrant.

可以在Github上找到完整的示例,包括用于设置Apache的模板文件和由Web服务器提供服务HTML文件。 该文件夹还包含一个Vagrant文​​件,可让您使用Vagrant管理的虚拟机以简化的设置测试配方。

Below you can find the complete recipe:

您可以在下面找到完整的食谱:

  • node.default['main']['doc_root'] = "/vagrant/web"

    node.default ['main'] ['doc_root'] =“ / vagrant / web”
  • execute "apt-get update" do

    执行“ apt-get更新”
  • command "apt-get update"

    命令“ apt-get更新”
  • end

    结束
  • apt_package "apache2" do

    apt_package“ apache2”做
  • action :install

    动作:安装
  • end

    结束
  • service "apache2" do

    服务“ apache2”做
  • action [ :enable, :start ]

    动作[:enable,:start]
  • end

    结束
  • directory node['main']['doc_root'] do

    目录节点['main'] ['doc_root']做
  • owner 'www-data'

    所有者“ www-data”
  • group 'www-data'

    组“ www-data”
  • mode '0644'

    模式'0644'
  • action :create

    动作:创建
  • end

    结束
  • cookbook_file "#{node['main']['doc_root']}/index.html" do

    cookbook_file“#{node ['main'] ['doc_root']} / index.html”执行
  • source 'index.html'

    来源'index.html'
  • owner 'www-data'

    所有者“ www-data”
  • group 'www-data'

    组“ www-data”
  • action :create

    动作:创建
  • end

    结束
  • template "/etc/apache2/sites-available/000-default.conf" do

    模板“ /etc/apache2/sites-available/000-default.conf”
  • source "vhost.erb"

    来源“ vhost.erb”
  • variables({ :doc_root => node['main']['doc_root'] })

    变量({:doc_root => node ['main'] ['doc_root']})
  • action :create

    动作:创建
  • notifies :restart, resources(:service => "apache2")

    通知:restart,resources(:service =>“ apache2”)
  • end

    结束

食谱解释 (Recipe Explained)

1行 (line 1)

The recipe starts with an attribute definition, node['main']['doc_root']. We could have used a simple local variable here, however in most use case scenarios, recipes need to define global variables that will be used from included recipes or other files. For these situations, it is necessary to create an attribute instead of a local variable, as the later has a limited scope.

配方以属性定义node['main']['doc_root'] 。 我们可以在这里使用一个简单的局部变量,但是在大多数用例场景中,配方需要定义将从包含的配方或其他文件中使用的全局变量。 对于这些情况,有必要创建一个属性而不是局部变量,因为后者的作用域有限。

3-5行 (lines 3-5)

This execute resource runs an apt-get update.

执行资源运行apt-get update

7-10行 (lines 7-10)

This apt_package resource installs the package apache2.

apt_package资源将安装软件包apache2

12-15行 (lines 12-15)

This service resource enables and starts the service apache2. Later on, we will need to notify this resource for a service restart. It is important that the service definition comes before any resource that attempts to notify a service, otherwise you will get an error.

服务资源启用并启动服务apache2 。 稍后,我们将需要通知此资源以重新启动服务。 重要的是,服务定义必须先于任何试图通知服务的资源,否则您将得到一个错误。

17-22行 (lines 17-22)

This directory resource uses the value defined by the custom attribute node['main']['doc_root'] to create a directory that will serve as our document root.

目录资源使用自定义属性node['main']['doc_root']定义的值来创建将用作文档根目录的目录

24-29行 (lines 24-29)

A cookbook_file resource is used to copy a local file to a remote server. This resource will copy our index.html file and place it inside the document root we created in a previous task.

cookbook_file资源用于将本地文件复制到远程服务器。 此资源将复制我们的index.html文件,并将其放置在上一个任务中创建的文档根目录下。

31-36行 (lines 31-36)

Finally, this template resource applies our Apache virtual host template and notifies the service apache2 for a restart.

最后,此模板资源将应用我们的Apache虚拟主机模板,并通知服务apache2重新启动。

结论 (Conclusion)

Chef is a powerful configuration management tool that leverages the Ruby language to automate server provisioning and deployment. It gives you freedom to use the standard language features for maximum flexibility, while also offering custom DSLs for some resources.

Chef是一个功能强大的配置管理工具,它利用Ruby语言来自动进行服务器配置和部署。 它使您可以自由使用标准语言功能以实现最大的灵活性,同时还为某些资源提供自定义DSL。

翻译自: https://www.digitalocean.com/community/tutorials/configuration-management-101-writing-chef-recipes

读写锁厨师

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值