0


如何创建简单的 Chef Cookbooks 来管理 Ubuntu 上的基础设施

简介


Chef 是一个配置管理系统,旨在让您能够以自动化、可靠和可扩展的方式自动化和控制大量计算机。

在之前的教程中,我们已经了解了一些常见的 Chef 术语,并讨论了如何安装 Chef 服务器、工作站和节点(使用 Chef 12 或 Chef 11)。在本指南中,我们将以这些指南为起点,开始讨论如何自动化您的环境。

在本文中,我们将讨论创建 Chef cookbook 的基础知识。Cookbooks 是配置单元,允许我们在远程节点上配置和执行特定任务。我们构建 cookbooks,然后告诉 Chef 我们要在哪些节点上运行 cookbooks 中概述的步骤。

在本指南中,我们假设您从上一课结束时拥有的三台机器开始。您应该有一个服务器、一个工作站,以及至少一个节点来推送配置更改。

基本 Cookbook 概念


Cookbooks 作为 Chef 用来将节点带入特定状态的配置和策略细节的基本单元。这意味着 Chef 使用 cookbooks 执行工作,并确保节点的状态符合预期。

Cookbooks 通常用于处理一个特定的服务、应用程序或功能。例如,可以创建一个 cookbook 来使用 NTP 与特定服务器设置和同步节点的时间。它可以安装和配置数据库应用程序。Cookbooks 基本上是基础设施选择的包。

Cookbooks 在工作站上创建,然后上传到 Chef 服务器。然后,cookbook 中描述的配方和策略可以作为节点的“运行列表”的一部分分配给节点。运行列表是 chef-client 按顺序在节点上运行的配方和角色的列表,以使节点符合您为其设置的策略。

通过这种方式,您在 cookbook 中编写的配置细节将应用于您希望遵循 cookbook 中描述场景的节点。

Cookbooks 组织在一个完全自包含的目录结构中。有许多不同的目录和文件用于不同的目的。现在让我们来看一些更重要的目录和文件。

配方


配方是 cookbook 的主要工作组件。一个 cookbook 可以包含多个配方,或依赖外部配方。配方用于声明不同资源的状态。

Chef 资源描述系统的一部分及其期望的状态。例如,一个资源可以说“应安装软件包 x”。另一个资源可能会说“服务 x 应该在运行”。

配方是一系列相关资源的列表,告诉 Chef 如果实现了该配方,系统应该如何看起来。当 Chef 运行配方时,它会检查每个资源是否符合声明的状态。如果系统匹配,则继续下一个资源,否则,它会尝试将资源移动到给定的状态。

资源可以是许多不同类型。您可以在这里了解有关不同资源类型的信息。一些常见的资源类型包括:

  • package:用于管理节点上的软件包
  • service:用于管理节点上的服务
  • user:管理节点上的用户
  • group:管理组
  • template:使用嵌入式 Ruby 模板管理文件
  • cookbook_file:将文件从 cookbook 中的文件子目录传输到节点上的位置
  • file:管理节点上文件的内容
  • directory:管理节点上的目录
  • execute:在节点上执行命令
  • cron:编辑节点上现有的 cron 文件

属性


Chef 中的属性基本上是设置。将它们视为您可能想在 cookbook 中使用的简单键值对。

可以应用几种不同类型的属性,每种属性对节点最终操作的设置具有不同的优先级。在 cookbook 级别上,我们通常定义我们正在配置的服务或系统的默认属性。稍后可以通过特定节点的更具体的值覆盖这些属性。

创建 cookbook 时,我们可以在 cookbook 的属性子目录中为我们的服务设置属性。然后我们可以在 cookbook 的其他部分引用这些值。

文件


cookbook 中的文件子目录包含我们将放置在使用 cookbook 的节点上的任何静态文件。

例如,可以将任何不太可能修改的简单配置文件完整地放在文件子目录中。然后,配方可以声明一个资源,将文件从该目录移动到节点上的最终位置。

模板


模板类似于文件,但它们不是静态的。模板文件以

.erb

扩展名结尾,这意味着它们包含嵌入的 Ruby。

这些主要用于将属性值替换到文件中,以创建将放置在节点上的最终文件版本。

例如,如果我们有一个定义服务默认端口的属性,模板文件可以调用插入属性的位置,文件中声明端口的位置。使用这种技术,您可以轻松创建配置文件,同时保持您希望在其他地方更改的实际变量。

Metadata.rb


metadata.rb 文件用于管理有关软件包的元数据。这包括软件包的名称、描述等信息。

它还包括依赖信息,您可以指定此 cookbook 需要哪些 cookbooks 来运行。这将允许 Chef 服务器正确构建节点的运行列表,并确保所有部分都被正确传输。

创建一个简单的 Cookbook


为了演示与 cookbook 工作相关的一些工作流程,我们将创建一个自己的 cookbook。这将是一个非常简单的 cookbook,它在我们的节点上安装和配置 Nginx web 服务器。

首先,我们需要进入工作站上的

~/chef-repo

目录:

cd ~/chef-repo

一旦进入,我们可以使用 knife 创建一个 cookbook。正如我们在之前的指南中提到的,knife 是一个用于配置与 Chef 系统的大多数交互的工具。我们可以使用它在我们的工作站上执行工作,也可以连接到 Chef 服务器或单个节点。

创建 cookbook 的一般语法是:

knife cookbook create cookbook_name

由于我们的 cookbook 将处理安装和配置 Nginx,我们将适当地命名我们的 cookbook:

knife cookbook create nginx

** 创建 cookbook nginx
** 为 cookbook nginx 创建 README
** 为 cookbook nginx 创建 CHANGELOG
** 为 cookbook nginx 创建 metadata

knife 在这里做的是在我们的 cookbooks 目录中为我们的新 cookbook 构建一个简单的结构。我们可以通过导航到 cookbooks 目录,然后进入 cookbook 名称的目录来查看我们的 cookbook 结构。

cd cookbooks/nginx
ls

attributes  CHANGELOG.md  definitions  files  libraries  metadata.rb  providers  README.md  recipes  resources    templates

正如您所见,这创建了一个文件夹和文件结构,我们可以用来构建我们的 cookbook。让我们从配置的最大块开始,即 recipe。

创建一个简单的 Recipe


如果我们进入

recipes

子目录,我们会看到里面已经有一个名为

default.rb

的文件:

cd recipes
ls

default.rb

这是在引用 “nginx” recipe 时将运行的 recipe。这是我们将要添加代码的地方。

用您的文本编辑器打开文件:

nano default.rb

#
# Cookbook Name:: nginx
# Recipe:: default
#
# Copyright 2014, YOUR_COMPANY_NAME
#
# All rights reserved - Do Not Redistribute
#

目前这个文件中唯一的内容是一个注释头。

我们可以开始规划我们的 Nginx web 服务器需要完成的事情。我们通过配置 “资源” 来做到这一点。资源不描述 如何 做某事;它们只描述系统的一部分在完成时应该是什么样子。

首先,显然我们需要确保软件已安装。我们可以通过首先创建一个 “package” 资源来实现这一点。

package 'nginx' do
  action :install
end

这段小代码定义了一个 Nginx 的 package 资源。第一行以资源类型(package)和资源名称(‘nginx’)开始。其余部分是一组操作和参数,声明了我们希望资源发生的事情。

在这个资源中,我们看到

action :install

。这一行告诉 Chef,我们正在描述的资源应该被安装。运行此 recipe 的节点将检查 Nginx 是否已安装。如果已安装,它将在任务列表中将其标记为已完成。如果没有安装,它将使用客户端系统上可用的方法安装程序,然后将其标记为已完成。

安装服务后,我们可能希望调整节点上的当前状态。默认情况下,Ubuntu 在安装后不会启动 Nginx,因此我们需要更改这一点:

service 'nginx' do
  action [ :enable, :start ]
end

在这里,我们看到了一个 “service” 类型的资源。这声明了对于 Nginx 服务组件(允许我们使用 init 或 upstart 管理服务器的部分),我们希望立即启动服务,并且在机器重新启动时也启用自动启动。

我们将要声明的最后一个资源是我们将要提供的实际文件。由于这只是一个我们不会修改的简单文件,我们可以简单地声明我们希望文件的位置,并告诉它在 cookbook 中的位置:

cookbook_file "/usr/share/nginx/www/index.html" do
  source "index.html"
  mode "0644"
end

我们使用 “cookbook_file” 资源类型告诉 Chef,这个文件在 cookbook 本身中是可用的,并且可以按原样传输到该位置。在我们的示例中,我们正在将一个文件传输到 Nginx 的文档根目录。

在我们的情况下,我们在第一行指定了我们要创建的文件名。在 “source” 行中,我们告诉它在 cookbook 的 “files/default” 子目录中查找文件的名称。Chef 在 cookbook 的 “files/default” 子目录中查找此文件。

“mode” 行设置了我们正在创建的文件的权限。在这种情况下,我们允许 root 用户读写权限,其他用户只有读权限。

完成后保存并关闭此文件。

创建索引文件


正如你在上面看到的,我们定义了一个 “cookbook_file” 资源,它应该将一个名为 “index.html” 的文件移动到节点上的文档根目录。我们需要创建这个文件。

我们应该将这个文件放在我们的 cookbook 的 “files/default” 子目录中。现在输入以下命令进入该目录:

cd ~/chef-repo/cookbooks/nginx/files/default

在这个目录中,我们将创建我们引用的文件:

nano index.html

当你完成后,保存并关闭文件。

创建辅助 Cookbook


在我们继续之前,让我们预先解决一个小问题。当我们的节点尝试运行我们现在创建的 cookbook 时,很可能会失败。

这是因为它将尝试从 Ubuntu 仓库安装 Nginx,而我们节点上的软件包数据库很可能已经过时。通常,我们在运行软件包命令之前会运行 “sudo apt-get update”。

为了解决这个问题,我们可以创建一个简单的 cookbook,其唯一目的是确保软件包数据库已更新。

我们可以使用之前使用的 knife 语法来做到这一点。让我们将这个 cookbook 命名为 “apt”:

knife cookbook create apt

这将创建与我们最初使用 Nginx cookbook 时相同类型的目录结构。

让我们直截了当地编辑我们新 cookbook 的默认 recipe。

nano ~/chef-repo/cookbooks/apt/recipes/default.rb

在这个文件中,我们将声明一个 “execute” 资源。这只是一种定义我们想要在节点上运行的命令的方式。

我们的资源看起来像这样:

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

第一行为我们的资源命名。在我们的情况下,出于简单起见,我们称资源为这个。如果定义了 “command” 属性(正如我们所做的),那么这就是实际执行的命令。

由于这些是完全相同的,所以这一点并不重要。

保存并关闭文件。

现在我们有了新的 cookbook,有许多方法可以确保我们在运行 Nginx cookbook 之前执行它。我们可以将其添加到节点的运行列表中,也可以将其与 Nginx cookbook 本身联系起来。

这可能是更好的选择,因为我们不必记住在每个要为 Nginx 配置的节点上都在 “nginx” cookbook 之前添加 “apt” cookbook。

我们需要调整 Nginx cookbook 中的一些内容以实现这一点。首先,让我们再次打开 Nginx recipe 文件:

nano ~/chef-repo/cookbooks/nginx/recipes/default.rb

在这个 cookbook 的顶部,在我们定义的其他资源之前,我们可以通过输入以下内容引入 “apt” 默认 recipe:

include_recipe "apt"

package 'nginx'do
  action :installend

service 'nginx'do
  action [:enable,:start]end

cookbook_file "/usr/share/nginx/www/index.html"do
  source "index.html"
  mode "0644"end

保存并关闭文件。

我们需要编辑的另一个文件是

metadata.rb

文件。当 Chef 服务器将运行列表发送到节点时,会检查此文件,以查看应该添加到运行列表的其他 recipe。

现在打开文件:

nano ~/chef-repo/cookbooks/nginx/metadata.rb

在文件底部,你可以添加以下行:

depends "apt"

完成后,我们的 Nginx cookbook 现在依赖于我们的 apt cookbook 来处理软件包数据库更新。

将 Cookbook 添加到你的节点


现在我们的基本 cookbook 已经完成,我们可以将它们上传到我们的 chef 服务器。

我们可以通过输入以下命令来单独执行:

knife cookbook upload apt
knife cookbook upload nginx

或者,我们可以通过输入以下命令来上传所有内容:

knife cookbook upload -a

无论哪种方式,我们的 recipes 都将被上传到 Chef 服务器。

现在,我们可以修改我们节点的运行列表。我们可以通过输入以下命令轻松完成:

knife node edit <name_of_node>

如果需要找到可用节点的名称,可以输入以下命令:

knife node list

对于我们的目的,当我们输入这个命令时,我们会得到一个看起来像这样的文件:

{"name":"client1","chef_environment":"_default","normal":{"tags":[]},"run_list":[]}

在此之前,你可能需要设置你的 EDITOR 环境变量。你可以通过输入以下命令来完成:

exportEDITOR=<name_of_editor>

正如你所看到的,这是一个简单的 JSON 文档,描述了我们节点的一些方面。我们可以看到一个 “run_list” 数组,目前为空。

我们可以使用以下格式将我们的 Nginx cookbook 添加到该数组中:

"recipe[<name_of_recipe>]"

完成后,我们的文件应该如下所示:

{"name":"client1","chef_environment":"_default","normal":{"tags":[]},"run_list":["recipe[nginx]"]}

保存并关闭文件以实施新的设置。

现在,我们可以 SSH 进入我们的节点并运行 Chef 客户端软件。这将导致客户端检查 Chef 服务器。一旦这样做,它将看到已为其分配的新运行列表。

SSH 进入你的节点,然后运行以下命令:

sudo chef-client

正如你所看到的,我们的 apt cookbook 也被发送并运行了,即使它不在我们创建的运行列表中。这是因为 Chef 聪明地解决了依赖关系,并在执行之前修改了实际的运行列表。

注意:确保一个 cookbook 或 recipe 在另一个之前运行的方法有各种各样。添加依赖关系只是其中一种选择,可能会有其他更好的方法。

我们可以通过访问我们节点的 IP 地址或域名来验证这一点:

http://<node_domain_or_IP>

你应该会看到类似于这样的内容:

!Chef node Nginx

恭喜,你已经使用 Chef cookbooks 配置了你的第一个节点!

结论


虽然这只是一个非常简单的例子,可能并没有比手动配置服务器节省多少时间,但希望你能开始看到使用这种基础设施构建方法的可能性。

它不仅可以实现快速部署和配置不同类型的服务器,还确保您了解所有机器的确切配置。这使您能够验证和测试您的基础设施,并为您提供了在需要时快速重新部署基础设施的框架。


本文转载自: https://blog.csdn.net/rubys007/article/details/138678826
版权归原作者 白如意i 所有, 如有侵权,请联系我们删除。

“如何创建简单的 Chef Cookbooks 来管理 Ubuntu 上的基础设施”的评论:

还没有评论