- Подписка на печатную версию:
- Подписка на электронную версию:
- Подшивки старых номеров журнала (печатные версии)
LXF128:DrBrown3
Материал из Linuxformat.
- Рецепты доктора Брауна
Содержание |
Дергая за нити
- Управляем гетерогенными сетями с сотнями машин.
Администраторы, обслуживающие много компьютеров, всегда ищут способы сэкономить время и усилия. Им нисколько не требуется, чтобы их загрузка линейно росла с ростом числа обслуживаемых систем. Подозреваю, что за годы тысячи администраторов написали десятки тысяч маленьких скриптов с ssh, scp, rdist или rsync в цикле for, для обновления и настройки своих подопечных компьютеров. Виртуализация отчасти все ухудшила, потому что теперь администраторы вынуждены прописывать изменения в количестве систем, до десяти раз превосходящем число компьютеров в стойке.
Самодельные скрипты работают прекрасно, но обычно решают сугубо конкретные задачи и не дают способа поделиться лучшими методиками с другими администраторами или экспортировать их на сайты. Эти проблемы и привели к появлению утилит управления конфигурацией, включая Puppet и Cfengine.
В Puppet [англ. «марионетка»], идее Люка Каньеса [Luke Kanies] из Reductive Labs, для описания конфигурации обслуживаемых компьютеров используется декларативный язык (см. «Декларативный vs императивный»). Основная идея архитектуры частично состоит в абстрактном представлении таких вещей, как сервис или учетная запись пользователя, без учета их конкретной реализации на целевом компьютере.
Настройки задаются в файле (или наборе файлов), называемом манифестом. Нырнем поглубже, на следующем примере:
user { chris: name => “chris”, uid => 503, home => “/home/chris”, password => ‘$1$GyE7uVtw$KCsWd.U2mcy05ZdGFiump/’, ensure => present,
Это пример использования ресурса для управления (в данном случае) учетными записями пользователей. Атрибуты данного ресурса (имя, идентификатор и т. д.) соответствуют полям /etc/passwd. Однако в определении ресурса нет никакой информации по поводу того, как реализуется эта конфигурация (например, создаются ли учетные записи командой useradd или же adduser): определение ресурса скрывает этот уровень детализации, упрощая создание конфигурации, применимой в гетерогенной смеси Unix-систем – Mac OS X, BSD, Solaris и всевозможных версий Linux.
У каждого обслуживаемого узла есть «клиентские провайдеры», знающие, как применить изменения в конфигурации на конкретной платформе. То же самое справедливо и для ресурсов других типов. Например, тип ресурса «пакет», используемый для установки (и удаления) пакетов, скрывает возможные реализации RPM, Yum, dpkg, apt-get, Fink, Portage, Rug … список можно продолжить. Чего он, к сожалению, не скрывает, так это различия между системами, в которых пакеты устанавливаются на самом деле. Поэтому мы можем увидеть такие конструкции:
$ssh = $operatingsystem ? { solaris => SMCossh, default => openssh } package { $ssh: ensure => installed, alias => openssh, require => Package[openssl], }
Обратите внимание на оператор выбора в первой строке, определяющий имя пакета по операционной системе обслуживаемого узла.
Просто дайте мне факты
На каждом обслуживаемом узле Puppet использует программу поддержки под названием Facter; ее задача – собирать в виде параметров данные об узле, включающие (среди прочего) название его операционной системы. Эти параметры доступны в виде переменных в манифесте Puppet и могут использоваться для подстройки конфигурации под платформу. Переменная operatingsystem в предыдущем примере показывает параметр Facter, используемый для этой цели.
Главный узел Puppet может выступать в роли файлового сервера. Это применяется, например, для передачи файлов с настройками конкретного сервиса на обслуживаемые узлы. Например, мы могли бы сохранить файл настройки ntpd в главном узле Puppet и сослаться на него в манифесте таким образом:
file { “/etc/ntp.conf ”: source => “puppet://puppetmaster/configs/ntp.conf ”, owner => ntp, mode => 644, backup => main, }
Атрибут source в этом примере показывает, где обслуживаемый узел должен получить файл конфигурации. Атрибут backup говорит, что оригинал ntp.conf нужно скопировать в файловую корзину main. Файловая корзина – репозиторий для резервных копий файлов; он может быть локальным (на обслуживаемом узле) или удаленным (на главном узле Puppet). Например, следующее определение ресурса задает удаленную файловую корзину:
filebucket { main: server => “puppetmaster.example.com” }
Путь к файлам, хранящимся в корзине, зависит от их MD5‑суммы. С точки зрения человека, это довольно странно и явно предназначено для того, чтобы предоставить средства для некоей поддержки транзакций и откатов внутри Puppet, которая, видимо, в разработке или по крайней мере в планах. На данный момент, восстанавливать файлы из файловой корзины нужно вручную.
Рассмотренные определения ресурсов соединяются с помощью классов и определений. И то, и другое – конструкции языка Puppet, задающие набор ресурсов; разница между ними в том, что классы можно создавать только один раз (на каждом обслуживаемом узле), а определения – многократно. Класс, например, можно было бы использовать для управления установленным пакетом или системным сервисом, а определение – для управления виртуальными хостами Apache или сетевыми интерфейсами, т. е. тем, что находится на компьютере в количестве больше одного. Существуют и другие типы ресурсов. Некоторые из них показаны в таблице.
Тип | Описание | Тип | Описание |
---|---|---|---|
cron | Управляет заданиями cron | notify | Отправляет сообщение в файл журнала |
exec | Выполняет внешние команды | package | Управляет пакетами |
file | Управляет файлами | schedule | Определяет расписание puppet |
filebucket | Репозиторий для резервных копий файлов | service | Управляет сервисами |
group | Управляет группами | tidy | Удаляет ненужные файлы |
host | Управляет узлами | user | Управляет пользователями |
mount | Управляет смонтированными файловыми системами | yumrepo | Управляет репозиториями Yum |
Определения узла внутри манифеста используются для связи заданных узлов с подходящими конфигурациями. Задать определение узла можно таким образом:
node /^www[0-9]+/ { include apache }
Здесь для имени узла используется регулярное выражение. К узлам с удовлетворяющими ему именами будет применен класс apache. В нем можно определить главным образом ресурсы (пакеты, сервисы, файлы настройки и т. д.), требуемые для запуска сервиса Apache. Для более тонкого контроля над тем, какая конфигурация применяется к каждому узлу, ресурсам можно назначить тэги (обычные текстовые строки), и разрешить узлу применять только те определения ресурсов, которые содержат заданный тэг. Например, для описания изменений конфигурации для набора тестируемых серверов определения ресурсов можно снабдить тэгом «experimental». Описанная в манифесте конфигурация передается на обслуживаемые узлы по архитектуре «ведущий–ведомый», показанной выше.
Один из компьютеров назван ведущим узлом Puppet, и на нем установлена программа puppetmaster. На каждом из обслуживаемых узлов, на рисунке – клиентов, установлен агент Puppet (управляемый им демон).
Манифест создается и хранится на ведущем узле Puppet. Каждые 30 минут ведомые узлы подключаются к ведущему, и он передает им конфигурацию. Для своей идентификации ведомые узлы передают ведущему сертификаты X.509. При первом подключении они создают запрос на подпись сертификата, и администратор может воспользоваться сертификационными полномочиями главного узла для самоподписи сертификатов и их возвращения клиентам. После этого для аутентификации узла и создания защищенного соединения используется SSH. Также можно запустить демоны Puppet на обслуживаемых узлах в режиме прослушивания, и ведущий узел подключится к ним и передаст конфигурацию. Это удобно для тестирования, и по-моему, было бы также удобно, если бы ведущий узел Puppet находился во внутренней сети, а обслуживаемые узлы – во внешней, со шлюзом NAT посередке, чтобы ведомые узлы не могли соединиться с ведущим.
На данный момент в Puppet не поддерживается управление версиями: например, нельзя откатиться к предыдущей конфигурации. Конечно, можно развернуть свое средство управления версиями, поместив манифесты на сервере, например, в Subversion.
Устанавливаем Puppet
Puppet написан на Ruby и распространяется по лицензии GPL2. Он доступен в репозиториях многих популярных дистрибутивов, включая Ubuntu и Fedora.
В Ubuntu для установки достаточно выполнить команду
$ sudo apt-get install ruby facter puppet
Если в вашем дистрибутиве нет пакетов Puppet или вам нужна самая свежая версия, загрузите архивы с Puppet и Facter с сайта Reductive Labs. Там содержится установочный скрипт на Ruby, и диалог установки будет выглядеть так:
# cd /root/downloads # wget http://reductivelabs.com/downloads/puppet/puppet-0.25.1.tar.gz # tar xzvf puppet-0.25.1.tar.gz # cd puppet-0 .25.1 # ruby install.rb
Естественно, сначала нужно установить Ruby!
Декларативный vs императивный
Декларативный язык определяет, какие операции нужно выполнить, а не то, как их выполнять. Императивный язык задает наборы действий – сделать то, потом се, потом это.
Например, если сказать «Возьми четыре ножа и вилки из ящика и положиих на стол», это будет императивный язык. А если сказать «Стол нужно накрыть на четверых», это декларативный язык.
Большинство обычных языков программи рования (включая PHP, C++ и Java) императивные. HTML декларативен: он задает внешний вид и расположение элементов web-страницы, а не последовательность команд, выполняемых браузером. Можно провести аналогию с файлом настройки вроде syslog.conf, где определяется, что делать с сообщения ми (декларативный), и кодом демона syslog (императивный).
Разница, должно быть, сугубо академична, но, просматривая манифесты Puppet, я был вынужден постоянно твердить себе: «Это описание, как нужно настроить компьютер, а не скрипт для его настройки».