Автоматизируем настройку серверов с помощью CFEngine 2Евгений Зобнин (j1m@synack.ru) Администрируя сеть из множества машин, выполняющих однотипные функции, ты рано или поздно начнешь задумываться об автоматизации процесса их конфигурирования и управления ими. Программы вроде dssh и rsync в этом случае помогут только отчасти, вынуждая выполнять львиную долю работы вручную. Однако существует инструмент, способный автоматизировать большую часть функций администрирования и превратить сеть серверов в интеллектуальную самонастраиваемую инфраструктуру. CFEngine (ConFiguration Engine) – один из старейших и наиболее мощных инструментов администратора, который позволяет управлять сетью машин в автоматическом режиме с минимумом ручной работы. С помощью правил CFEngine администратор может описать состояние, в котором должна находиться та или иная машина или сеть машин в определенное время или при определенных обстоятельствах. Отклонение от этого состояния повлечет за собой принятие корректирующих мер. CFEngine позволяет контролировать многие аспекты состояния системы, включая редактирование файлов, запуск/останов сервисов, установку/удаление приложений, настройки сети и многое, многое другое. При должном уровне терпения и знаний особенностей работы контролируемых машин, ты вполне сможешь создать интеллектуальную сеть, где сбой какой-либо машины или появление аномалий будут автоматически исправлены без необходимости вмешательства со стороны человека. УстановкаНе так давно разработчики CFEngine объявили о выходе третьей версии своего ПО, которое включает множество дополнений, расширяющих функциональность и повышающих гибкость системы. Однако официальное англоязычное руководство и огромное множество другой документации, которую ты сможешь найти в Сети, до сих пор ссылается на версию номер два. Более того, во многих дистрибутивах третья версия вообще недоступна в репозиториях, поэтому мы не будем рассматривать ее в рамках статьи, а остановимся на стабильном и проверенном временем CFEngine 2. Итак, вторая версия CFEngine доступна почти во всех UNIX-подобных ОС и Linux-дистрибутивах, поэтому получить и установить его не составит труда. Например, для установки в Debian/Ubuntu достаточно выполнить всего одну команду: Пакет CFEngine состоит из трех ключевых компонентов:
Сервер cfservd – центральная часть комплекса, принимает запросы клиентов и отдает им файлы, содержащие инструкции по изменению конфигурации машин. Клиент cfagent, называемый в словаре CFEngine-агентом, устанавливается на все управляемые машины. Его задача – подключение к серверу, получение конфигурационных файлов и исполнение содержащихся в них инструкций (модификация системных файлов, установка ПО, запуск серверов и т. д.). Планировщик cfexecd ответственен за запуск агента на машине-клиенте. Его задача – запуск агента через определенные интервалы времени с возможным перенаправлением стандартных ввода/вывода и отсылка диагностических сообщений администратору. Кроме описанных выше компонент, CFEngine устанавливает в систему набор подсобных утилит, необходимых для выполнения специфических задач. Одна из них – cfrun, которая может быть использована для запроса экстренного подключения удаленных агентов к серверу (можно использовать для отладки). Утилита cfkey предназначена для создания пар "публичный/приватный ключ", используемых для взаимной аутентификации сервера и агентов. Демон cfenvd осуществляет мониторинг работоспособности системы, отслеживая информацию о процессах, сетевых соединениях, общей загруженности, свободной памяти и т.д. В дальнейшем эту информацию может использовать cfagent для обнаружения аномалий и принятия мер по устранению проблем, а утилита cfenvgraph способна визуализировать эту информацию в виде графа. Cfshow позволяет исследовать текущее состояние CFEngine с помощью интерфейса командной строки. После установки пакет создает собственный подкаталог в каталоге var (/var/lib/cfengine2), который содержит все компоненты системы: Каталоговая структура CFEngine 2
ПравилаУправление поведением агента CFEngine производится с помощью правил, описанных в конфигурационных файлах. Модифицируя их, администратор может изменять многие аспекты состояния системы, включая:
Конфигурационные файлы представляют собой своего рода скрипт на языке высокого уровня, читая который, агент получает информацию о том, какие действия ему необходимо выполнить для конфигурации целевой машины. Ключевая особенность этого скрипта заключается в том, что он ориентирован на получение одинаковых результатов на всех конфигурируемых машинах без необходимости составления отдельного скрипта для каждой из них. Чтобы добиться этого, язык конфигурационного файла требует задать набор действий, которые приведут целевую систему к желаемому состоянию. Все это похоже на управление группой администраторов-эникейщиков, за каждым из которых закреплена определенная машина. Вместо того, чтобы давать задание по установке и настройке apache каждому из них по отдельности, ты собираешь их всех и говоришь, что на подчиненных машинах необходимо выполнить команду «apt-get install apache2», а затем изменить определенные строки файла httpd.conf. Таким образом можно получить идентичные настройки индейца на всех машинах без лишней головной боли. Конфигурационные файлы CFEngine разделены на блоки, каждый из которых включает действие, условие и объявление. Описание этих блоков имеют следующую форму: Формат описания блоков конфигурационного файла Первая строка задает тип действия, который необходимо выполнить. CFEngine второй версии поддерживает более 20 различных типов действий, среди которых есть тип files, который позволяет проверять и исправлять права и владельцев файлов, editfiles для редактирования файлов, packages для установки пакетов и другие. Условие, как можно догадаться из названия, задает условие, при котором действие будет выполнено. Это может быть время на системных часах, тип операционной системы или что-то другое. Чтобы действие было выполнено в любом случае, условие можно опустить. Объявление представляет собой описание того, что необходимо проделать в рамках заданного действия. Для различных типов действий форма их описания будет отличаться, поэтому при задании неиспользуемых ранее действий тебе придется обращаться к документации. Кроме "обычных" действий, CFEngine позволяет задавать также мета-действия, которые предназначены не для модификации состояния системы, а для выполнения различных вспомогательных функций. Наиболее важным мета-действием является control, которое позволяет конфигурировать агента, скажем, задать список действий и их очередность в переменной actionsequence. Приведу пример:
С помощью этих правил мы указали агенту, что: 1. Он должен выполнить действие files (первый блок). 2. В рамках действия files он должен проверить права доступа и владельца файла /etc/shadow и исправить их, если они не совпадают с указанными (0640, root, shadow). Для проверки работоспособности правил сохрани их в файл (например, /tmp/sample.conf) и выполни следующую команду: Кроме прав доступа и владельца, в рамках правила files агент может выполнить проверку MD5-суммы файла, что можно использовать в качестве альтернативы системам контроля целостности системы (вроде tripwire). Список действий в порядке приоритета
Администрируя сеть из машин с различными операционными системами, ты столкнешься с проблемой отличий имен/прав/владельцев системных файлов. Ведь если в Linux файл теневых паролей носит имя /etc/shadow, а его владельцем является root:shadow, то, например, во FreeBSD ты получишь совсем иную картину: файл /etc/master.passwd и владелец root:wheel. Как быть в этом случае? Именно для этого и нужны условия (классы). Следующий набор правил одинаково хорошо отработает как на Linux-машинах, так и на машинах с FreeBSD:
В зависимости от используемой операционной системы, времени суток, нагрузки на систему, клиент CFEngine определяет множество классов, которые можно использовать для управления тем, какое действие будет выполнено в определенной ситуации. Ты можешь легко проверить, какие классы определены на машине, с помощью запуска следующей команды: Наиболее используемыми являются классы, определяющие операционную систему. CFEngine позволяет определить тип операционки вплоть до версии ядра и библиотеки libc, что может оказаться важным для обхода возможных проблем, связанных с этими компонентами. Также популярны классы, определяющие текущее время (например, Hr00 – полночь, Hr12 – полдень и т.д.), они могут быть использованы для выполнения действий по расписанию. CFEngine позволяет делать выбор между классами на основе логического "ИЛИ" или "И". Так, например, действие с условием freebsd|openbsd будет выполнено как на машине с ОС FreeBSD, так и на OpenBSD. Однако условие Hr00.OpenBSD будет выполнено только на опенке в полночь. Классы можно отрицать, указав перед ними знак восклицания. Это значит, что действие будет выполняться, пока класс не будет определен. Особую роль условия играют внутри действия control, позволяя устанавливать переменные в зависимости от параметров машины:
CFEngine позволяет создавать пользовательские классы, которые определяются в момент выполнения определенного условия. Например:
Мета-действие classes создает класс linux_sys, который будет определен только в том случае, если каталог /sys существует. В данном случае IsDir – это условие, при выполнении которого будет определен класс. В арсенале CFEngine имеется солидный багаж самых разнообразных условных выражений, среди которых: Некоторые популярные условные выражения действия classes
ИспользованиеЧтобы начать использовать CFEngine, тебе понадобятся:
Первые два пункта легко выполнить, следуя инструкциям, приведенным в разделе "Установка". Для составления правил ты можешь использовать приведенные ниже примеры, дополненные в соответствии с твоими требованиями. Важным шагом является настройка доверительной системы, которая включает в себя взаимный обмен публичными ключами между сервером и клиентами. Однако в большинстве случаев этот шаг излишен, потому как применение CFEngine для управления серверами глобальной сети – явление редкое, а во внутренней локальной сети можно обойтись и без аутентификации узлов. Мы сделаем так, чтобы все машины локальной сети изначально доверяли друг-другу и не требовали аутентификации с использованием ключей. Настройка сервераДля правильного функционирования сервера важно наличие трех конфигурационных файлов:
Начнем с файла правил агента. Его начальное содержимое может выглядеть следующим образом:
Обратившись к документации CFEngine, ты сможешь дополнить его любыми правилами, которые актуальны для твоих клиентских машин. Следующий файл cfservd.conf очень прост и прозрачен:
Единственное, что следует поменять в нем: имя домена и подсети. Наконец, cfrun.hosts содержит список обслуживаемых сервером хостов:
Закончив настройку, перезапусти CFEngine:
Настройка клиентовКлючевой конфигурационный файл агента носит имя update.conf. Он нужен для начальной настройки агента до того, как он сможет подключиться к серверу и забрать основной конфигурационный файл cfagent.conf. Следующего варианта будет вполне достаточно в большинстве ситуаций:
Чтобы сетевая инфраструктура, построенная на CFEngine, заработала, каждый клиент должен быть оснащен не только агентом, но и сервером. Вот конфигурационный файл сервера для клиентов:
Заставляем CFEngine перечитать свои конфиги: Теперь необходимо настроить клиентские машины так, чтобы агент CFEngine запускался в определенные промежутки времени. Каждые полчаса cron будет запускать cfexecd, который вызовет агента CFEngine, который в свою очередь получит последнюю версию cfagent.conf с сервера и выполнит описанные в ней правила. Таким образом ты сможешь динамически обновлять cfagent.conf на сервере, и в течение получаса внесенные тобой изменения отразятся на клиентах. Что дальшеCFEngine – сложный инструмент, и в этой статье ты открыл для себя лишь несколько процентов его возможностей. Файлы правил CFEngine серьезных контор насчитывают сотни и даже тысячи строк, благодаря чему контролируемые им машины могут находиться без присмотра в течение месяцев. В боковом выносе WWW перечислены ссылки на ресурсы, обратившись к которым, ты сможешь узнать о настоящей мощи CFEngine. Настройка аутентификацииЕсли ты решишь использовать CFEngine для конфигурирования географически распределенных узлов, то тебе не обойтись без настройки аутентификации. Для этого запусти команду cfkey на сервере и клиентах. Это приведет к созданию двух ключей в каталоге /var/lib/cfengine2/ppkeys: localhost.pub (публичный ключ) и localhost.priv (приватный ключ). После этого публичный ключ сервера необходимо скопировать на каждую машину-клиента под именем /var/lib/cfengine2/ppkeys/IP-сервера.pub. Публичные ключи клиентов также придется скопировать на сервер под именем /var/lib/cfengine2/ppkeys/root-IP-клиента.pub. WWW
INFOВызов агента по расписанию можно настроить и без использования cron. Для этого в правило control файла cfagent.conf достаточно добавить строку:
|