Журнал LinuxFormat - перейти на главную

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, я был вынужден постоянно твердить себе: «Это описание, как нужно настроить компьютер, а не скрипт для его настройки».

Персональные инструменты
купить
подписаться
Яндекс.Метрика