Поиск по сайту:

Как использовать роли и среды в Chef для управления конфигурациями сервера


Введение

По мере создания инфраструктуры управление многочисленными серверами, службами, пользователями и приложениями может очень быстро стать громоздким. Чтобы справиться с этой путаницей, можно использовать системы управления конфигурацией.

Chef — отличная система управления конфигурацией, которая позволяет очень легко настраивать различные компоненты всей системы. В предыдущих руководствах мы обсуждали, как создавать простые кулинарные книги для управления конфигурацией.

В этом руководстве мы продолжим изучение того, как вы можете управлять своей средой с помощью Chef. На этот раз мы поговорим о том, как использовать роли и среды, чтобы различать ваши серверы и службы в зависимости от того, какую функциональность они должны демонстрировать.

Мы предполагаем, что вы установили свой сервер, рабочую станцию и клиент и что у вас есть кулинарные книги, которые мы создали в нашем последнем руководстве.

Роли и окружение

Что такое роль?

В вашей организации, если ваша инфраструктура расширяется для удовлетворения требований более высокого трафика, скорее всего, будет несколько резервных серверов, выполняющих одни и те же основные задачи. Например, это могут быть веб-серверы, на которые балансировщик нагрузки передает запросы. Все они будут иметь одинаковую базовую конфигурацию и, можно сказать, будут выполнять одну и ту же «роль».

Взгляд шефа на роли почти полностью совпадает с обычным определением. Роль в Chef — это категория, описывающая, что конкретная машина должна делать. Какие обязанности у него есть и какой софт и настройки ему надо дать.

В разных ситуациях у вас могут быть определенные машины, выполняющие более одной роли. Например, если вы тестируете свое программное обеспечение, один сервер может включать компоненты базы данных и веб-сервера, в то время как в рабочей среде вы планируете разместить их на отдельных серверах.

С Chef это может быть так же просто, как назначить первый сервер обеим ролям, а затем назначить каждую роль отдельным компьютерам для ваших производственных машин. Каждая роль будет содержать сведения о конфигурации, необходимые для приведения машины в полностью рабочее состояние для выполнения своей конкретной роли. Это означает, что вы можете собирать кулинарные книги, которые будут обрабатывать установку пакетов, настройку службы, специальные атрибуты для этой роли и т. д.

Что такое среда?

С идеей роли связана концепция среды Chef. Среда — это просто обозначение, предназначенное для того, чтобы помочь администратору узнать, частью какого этапа производственного процесса является сервер. Каждый сервер может быть частью только одной среды.

По умолчанию создается среда с именем \_default. Каждый узел будет помещен в эту среду, если не указана другая среда. Среды могут быть созданы для пометки сервера как части группы процессов.

Например, одну среду можно назвать «тестирование», а другую — «производство». Поскольку вам не нужен код, который все еще тестируется на ваших рабочих машинах, каждая машина может находиться только в одной среде. Затем у вас может быть одна конфигурация для компьютеров в тестовой среде и совершенно другая конфигурация для рабочих компьютеров.

В приведенном выше примере, указанном в ролях, вы можете указать, что в вашей тестовой среде роли веб-сервера и сервера базы данных будут находиться на одном компьютере. В вашей производственной среде эти роли должны выполняться отдельными серверами.

Среды также помогают с самим процессом тестирования. Вы можете указать, что в продакшене поваренная книга должна быть стабильной версией. Однако вы можете указать, что если машина является частью тестовой среды, она может получать более новую версию поваренной книги.

Как использовать роли

Создайте роль с помощью Ruby DSL

Мы можем создавать роли, используя каталог roles в нашем каталоге chef-repo на нашей рабочей станции.

Войдите на свою рабочую станцию и перейдите в этот каталог:

cd ~/chef-repo/roles

В этом каталоге мы можем создавать различные файлы, которые определяют роли, которые мы хотим в нашей организации. Каждый файл роли может быть написан либо в Chef’s Ruby DSL, либо в JSON.

Давайте создадим роль для нашего веб-сервера:

nano web_server.rb

Внутри этого файла мы можем начать с указания некоторых основных данных о роли:

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

Они должны быть довольно прямолинейными. Имя, которое мы даем, не может содержать пробелы и в целом должно соответствовать имени файла, которое мы выбрали для этой роли, за вычетом расширения. Описание — это просто удобочитаемое сообщение о том, чем роль должна управлять.

Затем мы можем указать run_list, который мы хотим использовать для этой конкретной роли. Run_list роли может содержать поваренные книги (которые будут запускать рецепт по умолчанию), рецепты из поваренных книг (как указано с помощью синтаксиса cookbook::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», чтобы привести этот сервер в соответствие с требованиями рабочей политики. У вас также может быть рецепт в кулинарной книге nginx, предназначенный для настройки специальных изменений для тестовых серверов.

Предполагая, что эти два рецепта называются \config_prod и \config_test соответственно, мы могли бы создать несколько списков выполнения для конкретной среды, например:

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]"]

В приведенном выше примере мы указали, что если узел является частью производственной среды, он должен запускать рецепт \config_prod в кулинарной книге \nginx. Однако, если узел находится в среде тестирования, он запустит рецепт \config_test. Если узел находится в другой среде, будет применен список выполнения по умолчанию.

Точно так же мы можем указать атрибуты по умолчанию и переопределить атрибуты. К этому моменту вы должны быть знакомы с атрибутами по умолчанию. В нашей роли мы можем установить атрибуты по умолчанию, которые могут переопределить любые атрибуты по умолчанию, установленные где-либо еще.

Мы также можем установить атрибуты переопределения, которые имеют более высокий приоритет, чем объявления многих других атрибутов. Мы можем использовать это, чтобы попытаться заставить узлы, которым назначена эта роль, вести себя определенным образом.

В нашем файле их можно добавить так:

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 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_class и chef_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 выше.

Перенос ролей между рабочей станцией и сервером

Когда мы сохраняем файл JSON, созданный с помощью команды knife, роль создается на сервере Chef. Напротив, наш файл Ruby, который мы создали локально, не загружается на сервер.

Мы можем загрузить файл ruby на сервер, выполнив команду, которая выглядит так:

<пред>

Это загрузит информацию о нашей роли, указанную в нашем файле, на сервер. Это будет работать либо с файлом в формате Ruby DSL, либо с файлом JSON.

В том же ключе, если мы хотим получить наш JSON-файл с сервера, мы можем сказать команде ножа показать этот файл роли в JSON, а затем передать его в файл, подобный этому:

<пред>

Назначение ролей узлам

Так что теперь, независимо от используемого нами формата, у нас есть роль на сервере Chef. Как мы назначаем узлу определенную роль?

Мы назначаем роль узлу так же, как и рецепту, в run_list узла.

Таким образом, чтобы добавить нашу роль к узлу, мы должны найти узел, выполнив:

knife node list

И тогда мы дали бы команду вроде:

<пред>

Это откроет файл определения узла, что позволит нам добавить роль в его run_list:

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

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

Например, мы можем заменить наш рецепт нашей ролью в этом файле:

<пред>

]

},

Это будет выполнять те же шаги, что и наши предыдущие рецепты, но вместо этого просто говорит о роли, которую должен иметь сервер.

Это позволяет вам получить доступ ко всем серверам в определенной роли с помощью поиска. Например, вы можете найти все серверы баз данных в вашей производственной среде, выполнив поиск роли и среды:

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

Это даст вам список узлов, которые настроены как сервер базы данных. Вы можете использовать это внутри своих кулинарных книг, чтобы настроить веб-сервер для автоматического добавления всех серверов производственной базы данных в свой пул для выполнения запросов на чтение.

Как использовать среды

Создание среды

В некотором смысле окружение довольно похоже на роли. Они также используются для дифференциации разных серверов, но вместо дифференциации по функции сервера среды различаются по фазе разработки, к которой принадлежит машина.

Мы обсуждали некоторые из них ранее, когда говорили о ролях. Среды, которые совпадают с вашим реальным жизненным циклом продукта, имеют наибольший смысл. Если вы запускаете свой код через тестирование, подготовку и производство, у вас должны быть соответствующие среды.

Как и в случае с ролями, мы можем настроить файлы определений либо в 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"
    }
})

Как видите, одно из основных преимуществ включения сред в вашу систему заключается в том, что вы можете указать ограничения версий для поваренных книг и развертываемых рецептов.

Мы также могли бы использовать формат JSON. Инструмент ножа может создать шаблон файла среды, набрав:

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_class и chef_type), которые следует оставить в покое.

Перемещение файлов среды на сервер и с сервера

На данный момент, если вы использовали Ruby DSL, ваш файл находится на рабочей станции, а если вы использовали JSON, ваш файл находится только на сервере. Мы можем легко перемещать файлы вперед и назад с помощью ножа.

Мы могли бы загрузить наш файл Ruby на сервер Chef, набрав следующее:

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

Для нашего файла JSON мы можем получить файл среды с сервера, набрав что-то вроде:

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

Это отобразит файл JSON с сервера и направит результаты в локальный файл в подкаталоге среды.

Настройка сред в узлах

Каждый узел может находиться ровно в одной среде. Мы можем указать среду, к которой принадлежит узел, отредактировав информацию об узле.

Например, чтобы отредактировать узел с именем client1, мы могли бы ввести следующее:

knife node edit client1

Это откроет файл в формате JSON с текущими параметрами узла:

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

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

Как видите, для chef_environment изначально задано значение _default. Мы можем просто изменить это значение, чтобы поместить узел в новую среду.

Когда вы закончите, сохраните и закройте файл. При следующем запуске chef-client на узле он примет новые атрибуты и ограничения версии и изменит себя, чтобы соответствовать новой политике.

Заключение

К настоящему времени вы должны хорошо понимать различные способы работы с ролями и средами, чтобы закрепить состояние, в котором должны находиться ваши машины. Используя эти стратегии категоризации, вы можете начать управлять тем, как Chef обрабатывает серверы в различных контекстах.

Джастин Эллингвуд