如何使用角色和环境的Chef到控制服务器配置

Chef是一个配置管理工具,可以帮助您配置基础设施的自动化和可重复的方式。在本指南中,我们将探讨Chef生态系统中的角色和环境的概念。

介绍


当您构建您的基础架构时,管理您的许多服务器,服务,用户和应用程序可能会非常快速地笨重。 配置管理系统可以帮助您管理这种混乱。

Chef是一个优秀的配置管理系统,可以让你很轻松地配置整个系统的不同组件。 在以前的导游,我们讨论了Chef的术语 ,如何安装Chef服务器,工作站和节点(与Chef12Chef11 ),以及如何创建简单的Recipe来管理配置

在本指南中,我们将继续探讨如何使用Chef管理您的环境。 这一次,我们将讨论如何使用角色和环境来区分您的服务器和服务,基于它们应该展示什么样的功能。

我们假设您已经安装了服务器,工作站和客户端,并且我们在上一个指南中提供了我们创建的烹饪书。

角色和环境


什么是角色?


在您的组织中,如果您的基础架构增长以满足更高流量的需求,可能会有多个冗余服务器执行相同的基本任务。 例如,这些可能是负载均衡器将请求传递到的Web服务器。 它们将具有相同的基本配置,并且可以说每个都满足相同的“角色”。

角色的Chef的观点是几乎完全一样的常规定义。 在Chef角色是描述了一个特定的机器应该一个分类。 它有什么职责,应该给它什么软件和设置。

在不同的情况下,您可能有某些机器处理多个角色。 例如,如果您正在测试您的软件,一个服务器可能包括数据库和Web服务器组件,而在生产中,您计划在单独的服务器上使用这些组件。

使用Chef,这可以像将第一台服务器分配给两个角色一样简单,然后将每个角色分配给生产机器的单独计算机。 每个角色将包含使机器处于完全操作状态以满足其特定角色所需的配置详细信息。 这意味着您可以收集将处理包安装,服务配置,该角色的特殊属性等的Recipe。

什么是环境?


有关角色的想法是Chef环境的概念。 环境是一个简单的命名,旨在帮助管理员知道服务器是生产过程的一个阶段。 每个服务器可以是一个环境的一部分。

默认情况下,将创建一个名为“_default”的环境。 除非指定了另一个环境,否则每个节点都将放置到此环境中。 可以创建环境以将服务器标记为进程组的一部分。

例如,一个环境可以称为“测试”,另一个环境可以称为“生产”。 由于您不想要任何仍在测试生产机器上的代码,每台机器只能在一个环境中。 然后,您可以为测试环境中的机器配置一个配置,并为生产中的计算机配置完全不同的配置。

在角色中给出的上述示例中,您可以指定在测试环境中,Web和数据库服务器角色将位于单个计算机上。 在生产环境中,这些角色应由单个服务器处理。

环境也有助于测试过程本身。 您可以指定在生产中,cookbook应该是一个稳定的版本。 但是,您可以指定如果计算机是测试环境的一部分,则可以接收更新版本的Recipe。

如何使用角色


使用Ruby DSL创建角色


我们可以通过创建角色roles在我们的目录chef-repo目录我们的工作站上。

登录到您的工作站,现在移动到此目录:

cd ~/chef-repo/roles

在此目录中,我们可以创建不同的文件来定义我们在组织中所需的角色。 每个角色文件可以用Chef的Ruby DSL或JSON编写。

让我们为我们的网络服务器创建一个角色:

nano web_server.rb

在这个文件中,我们可以开始指定一些关于角色的基本数据:

name "web_server"
description "A role to configure our front-line web servers"

这些应该是相当简单的。 我们提供的名称不能包含空格,通常应该匹配我们为此角色选择的文件名,减去扩展名。 描述只是一个人类可读的消息,关于角色应该管理什么。

接下来,我们可以指定我们希望使用这一特定角色的运行列表。 角色的运行列表可以包含Recipe(将运行默认配方),从Recipe的Recipe,与其他角色(如使用Recipe::配方语法指定)。 记住,run_list总是按顺序执行,因此将依赖项项放在其他项之前。

如果我们想要指定run_list应该是我们在上一个指南中配置的,我们会有这样的东西:

name "web_server"
description "A role to configure our front-line web servers"
run_list "recipe[apt]", "recipe[nginx]"

我们还可以使用特定于环境的run_lists根据服务器所属的环境指定可变的配置更改。

例如,如果节点处于“生产”环境中,您可能需要在“nginx”Recipe中运行特殊配方,以使该服务器满足生产策略要求。 你也可以在nginxRecipe中有一个Recipe,意味着为测试服务器配置特殊的更改。

假设这两个Recipe被称为“配置刺”及“配置测试”,我们可以创建这样一些环境特定的运行列表:

name "web_server"
description "A role to configure our front-line web servers"
run_list "recipe[apt]", "recipe[nginx]"
env_run_lists "production" => ["recipe[nginx::config_prod]"], "testing" => ["recipe[nginx::config_test]"]

在上面的例子中,我们已指定,如果节点是生产环境的一部分,它应该运行“的nginx”菜谱内的“config 刺”配方。 但是,如果该节点是在测试环境中,将运行“配置测试”的配方。 如果节点在不同的环境中,则将应用默认run_list。

类似地,我们可以指定默认和覆盖属性。 此时,您应该熟悉默认属性。 在我们的角色中,我们可以设置默认属性,它可以覆盖任何其他地方设置的任何默认属性。

我们还可以设置override属性,它的优先级高于许多其他属性声明。 我们可以使用它来尝试强制分配此角色的节点以某种方式运行。

在我们的文件中,可以这样添加:

name "web_server"
description "A role to configure our front-line web servers"
run_list "recipe[apt]", "recipe[nginx]"
env_run_lists "production" => ["recipe[nginx::config_prod]"], "testing" => ["recipe[nginx::config_test]"]
default_attributes "nginx" => { "log_location" => "/var/log/nginx.log" }
override_attributes "nginx" => { "gzip" => "on" }

这里我们为节点中的任何服务器设置默认日志位置。 我们还指定,尽管其他属性声明在其他位置声明,该角色中的节点应将gzip属性设置为“on”。 这可以在几个地方覆盖,但通常是高优先级声明。

使用JSON创建角色


可用于配置角色的其他格式是JSON。 事实上,我们可以通过使用Knife自动创建这种格式的角色来探索这种格式。 让我们创建一个测试角色:

knife role create test

您的文本编辑器将打开并预先装入模板角色文件。 它应该看起来像这样:

{
  "name": "test",
  "description": "",
  "json_class": "Chef::Role",
  "default_attributes": {
  },
  "override_attributes": {
  },
  "chef_type": "role",
  "run_list": [

  ],
  "env_run_lists": {
  }
}

这基本上是我们输入到Ruby DSL格式文件中的相同信息。 唯一的区别是格式和增加了两个所谓的新钥匙json_classchef_type 这些在内部使用,不应该修改。

除此之外,我们可以很容易地用JSON重新创建我们的其他文件:

{
  "name": "web_server",
  "description": "A role to configure our front-line web servers",
  "json_class": "Chef::Role",
  "default_attributes": {
    "nginx": {
      "log_location": "/var/log/nginx.log"
    }
  },
  "override_attributes": {
    "nginx": {
      "gzip": "on"
    }
  },
  "chef_type": "role",
  "run_list": [
    "recipe[apt]",
    "recipe[nginx]"
  ],
  "env_run_lists": {
    "production": [
      "recipe[nginx::config_prod]"
    ],
    "testing": [
      "recipe[nginx::config_test]"
    ]
  }
}

这应该有与上面的Ruby版本几乎相同的功能。

在工作站和服务器之间传输角色


当我们保存使用knife命令创建的JSON文件时,将在Chef服务器上创建角色。 相反,我们在本地创建的Ruby文件不会上传到服务器。

我们可以通过运行以下命令将ruby文件上传到服务器:

knife role from file path/to/role/file

这将上传我们的文件中指定的角色信息到服务器。 这将使用Ruby DSL格式的文件或JSON文件。

同样,如果我们想从服务器获取我们的JSON文件,我们可以告诉knife命令在JSON中显示该角色文件,然后将其转换为如下所示的文件:

knife role show web_server -Fjson > path/to/save/to

分配角色到节点


所以现在,不管我们使用的格式,我们在Chef服务器上都有我们的角色。 我们如何为节点分配一定的角色?

在节点的run_list中,我们像一个配方一样向节点分配一个角色。

所以要将我们的角色添加到一个节点,我们可以通过发出以下命令找到该节点

knife node list

然后我们会给出一个命令:

knife node edit node_name

这将启动节点的定义文件,这将允许我们向其run_list添加一个角色:

{
  "name": "client1",
  "chef_environment": "_default",
  "normal": {
    "tags": [

    ]
  },
  "run_list": [
    "recipe[nginx]"
  ]
}

例如,我们可以用我们在这个文件中的角色来替换我们的Recipe:

{
  "name": "client1",
  "chef_environment": "_default",
  "normal": {
    "tags": [

    ]
  },
  "run_list": [
    "role[web_server]"
  ]
}

这将执行与我们以前的Recipe相同的步骤,但它只是说服务器应该具有的角色。

这允许您通过搜索访问特定角色中的所有服务器。 例如,您可以通过搜索角色和环境来搜索生产环境中的所有数据库服务器:

knife search "role:database_server AND chef_environment:prod" -a name

这将为您提供配置为数据库服务器的节点的列表。 您可以在烹饪书中内部使用它来配置Web服务器,以自动将所有生产数据库服务器添加到其池中,以发出读取请求。

如何使用环境


创建环境


在某些方面,环境与角色非常相似。 它们还用于区分不同的服务器,而不是通过服务器的功能区分,环境区别于机器所属的开发阶段。

我们在谈论角色时讨论了一些这样的问题。 与您的实际产品生命周期一致的环境是最有意义的。 如果您通过测试,暂存和生产来运行代码,则应该具有匹配的环境。

与角色一样,我们可以在Ruby DSL或JSON中设置定义文件。

在我们工作站上的“chef-repo”目录中,我们应该有一个环境目录。 这是我们应该放置我们的环境文件。

cd ~/chef-repo/environments

在这个目录中,如果我们要定义一个开发环境,我们可以创建一个这样的文件:

nano development.rb

name "development"
description "The master development branch"
cookbook_versions({
    "nginx" => "<= 1.1.0",
    "apt" => "= 0.0.1"
})
override_attributes ({
    "nginx" => {
        "listen" => [ "80", "443" ]
    },
    "mysql" => {
        "root_pass" => "root"
    }
})

如您所见,将环境并入系统的主要优点之一是您可以为烹饪书和部署的Recipe指定版本约束。

我们也可以使用JSON格式。 Knife工具可以通过键入以下内容生成环境文件的模板:

knife environment create development

这将打开我们的编辑器(同样,你可以设置你的编辑器export EDITOR=nano )与填充在名称中预装的环境文件。

我们可以通过输入以下内容创建相同的文件:

{
  "name": "development",
  "description": "The master development branch",
  "cookbook_versions": {
    "nginx": "<= 1.1.0",
    "apt": "= 0.0.1"
  },
  "json_class": "Cheff:Environment",
  "chef_type": "environment",
  "default_attributes": {
  },
  "override_attributes": {
    "nginx": {
      "listen": [
        "80",
        "443"
      ]
    },
    "mysql": {
      "root_pass": "root"
    }
  }
}

这个文件应该在功能上与我们上面演示的Ruby文件相同。 由于与JSON文件的作用,环境JSON文件的信息(两个额外碎片json_classchef_type )应该被单独留在家中。

将环境文件移入和移出服务器


此时,如果您使用Ruby DSL,您的文件在工作站上,如果您使用JSON,您的文件只在服务器上。 我们可以轻松地通过Knife来回移动文件。

我们可以通过键入以下内容将我们的Ruby文件上传到Chef服务器:

knife environment from file ~/chef-repo/environments/development.rb

对于我们的JSON文件,我们可以通过键入以下内容来获取服务器上的环境文件:

knife environment show development -Fjson > ~/chef-repo/environments/development.json

这将显示来自服务器的JSON文件,并将结果传递到environments子目录中的本地文件。

在节点中设置环境


每个节点可以在一个环境中。 我们可以通过编辑节点信息来指定节点所属的环境。

例如,为了编辑节点称为client1 ,我们可以输入:

knife node edit client1

这将打开一个带有当前节点参数的JSON格式的文件:

{
  "name": "client1",
  "chef_environment": "_default",
  "normal": {
    "tags": [

    ]
  },
  "run_list": [
    "role[web_server]"
  ]
}

正如你所看到的, chef_environment设置为_default最初。 我们可以简单地修改该值以将节点放入新环境中。

完成后,保存并关闭文件。 在节点上的下一个Chef-client运行时,它将拾取新的属性和版本约束,并修改其自身以与新策略一致。

结论


到目前为止,您应该很好地了解可以使用角色和环境的不同方式来巩固您的计算机应该处于的状态。使用这些分类策略,您可以开始管理Chef在不同上下文中处理服务器的方式。

作者:Justin Ellingwood