Управление конфигурацией сервера с помощью ролей Chef

Published by Leave your thoughts

Чем больше становится инфраструктура, чем больше в ней компонентов, тем сложнее управлять и выполнять её оркестровку самостоятельно.

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

Читайте также предыдущие руководства:

Данное руководство научит вас использовать роли Chef для управления сервером и сервисами.

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

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

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

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

Роль в Chef – это категория, которая описывает действия и настройки относящихся к ней машин.

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

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

Что такое окружение?

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

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

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

К примеру, в окружении testing роли веб-сервера и БД может выполнять одна машина, а в окружении production эти роли можно распределить между несколькими машинами.

Использование ролей

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

Откройте каталог roles в каталоге chef-repo на рабочей станции.

cd ~/chef-repo/roles

В этом каталоге можно создавать различные файлы для ролей. Файлы роли можно писать в Ruby DSL или в JSON.

Создайте роль для веб-сервера:

nano web_server.rb

В этом файле укажите исходные данные роли:

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

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

Затем нужно указать run_list, список задач роли. Он может содержать кукбуки, рецепты и другие роли.

Примечание: Список задач всегда выполняется последовательно, поэтому зависимости нужно поместить перед другими компонентами.

name "web_server"
description "A role to configure our front-line web servers"
run_list "recipe[apt]", "recipe[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, а в окружении тестирования — 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 может автоматически создавать роли в этом формате. Попробуйте создать тестовую роль.

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 (эти ключи не нужно изменять).

Таким образом, можно очень быстро создать файл роли web_server (из предыдущего раздела) в формате 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 нужно подгружать на сервер самостоятельно. Для этого запустите:

knife role from file path/to/role/file

Эта команда загрузит файл роли с рабочей станции на сервер.

Примечание: Команда подходит как для формата Ruby DSL, так и для 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]"
]
}

К примеру, можно заменить рецепт ролью:

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

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

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

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

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

Использование окружений

Создание окружения

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

Создайте окружение для каждого этапа работы над продуктом (тестирования, производства и т.п.).

Окружения, как и роли, определяются в файлах Ruby DSL или JSON.

В каталоге chef-repo найдите каталог environments и откройте его:

cd ~/chef-repo/environments

Здесь хранятся все окружения. Создайте окружение для разработки и назовите его development.

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 может сгенерировать шаблон окружения:

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), которые нельзя изменять.

Перемещение файлов окружения

Файлы JSON сохраняются на сервер Chef автоматически. Файлы Ruby DSL нужно добавлять на сервер самостоятельно. Для перемещения файлов окружения можно использовать knife.

Чтобы подгрузить файл Ruby на сервер Chef, введите:

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

Чтобы переместить файл окружения JSON с сервера Chef на другой сервер, введите:

knife environment show development -Fjson > ~/chef-repo/environments/development.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 и как они работают. Используя категоризацию Chef, вы сможете создавать контексты для управления серверами.

Chef – производительный инструмент управления конфигурацией, который автоматизирует оркестровку и развёртывание с помощью Ruby. Chef позволяет использовать стандартные функции языка для достижения максимальной гибкости, а также предлагает DSL для некоторых ресурсов.

Tags:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *


*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>