Pull to refresh

Comments 66

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

И второй момент, как решить проблему dev-testing-stable версий с помощью puppet?
в ensure вы можете прописать конкретную версию пакета, если вы говорите об этом «dev-testing-stable версий»
Я в топике написал:
Здесь используется инлайн-конфиг, который делает манифест некрасивым. На самом деле так почти никогда не делается, существует механизм шаблонов, основанный на ERB, и возможность просто использовать внешние файлы. Но нас не это интересует.

Да, это грязно, да, так не делают. Здесь пример используется для показа работы зависимостей.
По моему опыту конфиги лучше описывать всё же в puppet, а не складывать их в пакеты по следующим причинам:
а) Апстрим всегда апстрим, а свои руки я считаю кривее рук мейнтейнеров. Если выйдет хот-секьюрити-фикс на openssh-server, puppet подтянет его сам (ensure => latest), а мне придётся прочитать об этом из рассылки, пересобрать пакет (руками! а я от этого избавиться пытаюсь), положить в репозиторий и только после этого ноды вытянут (опять же, через ensure => latest) новый пакет.
б) Один инструмент вместо нескольких. Я вдруг захочу изменить на всех серверах порт ssh с 22 на 45802. Мне надо разобрать пакет, заменить конфиг, собрать пакет, дёрнуть на всех нодах aptitude update && aptitude safe-upgrade (пусть и через puppet). Это работает для простого сервиса с несложным конфигом. Когда мне понадобится компилировать уникальный конфиг для каждой ноды на основании каких-либо их уникальных данных, полученных через facter или еще как-нибудь — я взвою и задумаюсь, что наверное puppet я использую как-то не так.

Всё верно, пакетный менеджер описывает состояние системы. Сделайте на любом своём сервере (на примере debian) dpkg -l | awk '{print $2}' > list, установите голую систему, запустите там for i in $(cat list); do apt-get install $i; done. Если после этого у вас серверы станут идентичными — жму руку. Я к тому, что пакетный менеджер описывает состояние системы, но не сервисов, которые эта система предоставляет (слово сервис здесь в широком смысле).

Dev-testing-stable я решаю с помощью лабораторий с отдельным окружением. В век виртуализации это не сложно. Гит помогает в плане упорядочивания изменений и хранения истории.
а. Так конфиг положить не в пакет openssh, а в mycompany-openssh-config конечно же! Сам сервер при этом будет из апстрима ставиться. А именно в конфигурационных пакетах уже писать postinstall скрипты, запускающие сервисы.
б. Кажется, создание уникальных конфигов — это изначально плохая идея, и мне в голову сходу не приходит, где это может быть нужно в гомогенной серверной среде.
а) Я вижу минус в множении сущностей. В вашем варианте необходим как свой репозиторий с пакетами mycompany*, так и puppet, который будет отслеживать эти самые апдейты. В моем варианте репозиторий не нужен, а конфиг можно легко править на мастере без необходимости сборки-разборки пакета. Я не спорю, вариант с пакетами имеет право на существование, но мне он не нравится потому что прозреваю там большее количество возни и большую вероятность ошибок.
б) Совсем не плохая. Тут описан хороший вариант динамической генерации манифестов и их применения. И знаете, банально менять конфиг одного виртуального хоста в nginx'e через пересборку пакета — это за гранью добра и зла.
Возни в принципе столько же — сначала поправить файлик-конфиг, потом закоммитить его, потом задеплоить. Если пару алиасов написать — то по количеству команд одинаково получится, разве что чуть дольше. Что хорошо в пакетах — есть зависимости, можно у совершенно разных сервисов использовать общие части. Я вижу в вашем примере, что в принципе зависимости есть. Но может ли один манифест зависеть от другого? Грубо говоря, есть какие-то базовые настройки нгинкса, которые вы записываете в /etc/nginx/nginx.conf (всякие там количества воркеров, логирование и т.д.), и есть конфиги для сервисов-сайтов, которые вы укладываете в /etc/nginx/sites-enabled/siteN.conf. Может ли манифест для siteN зависеть от манифеста, в котором создаётся конфиг nginx.conf?

Про пересборку пакета — вы не совсем правы, это ж не плитку таскать пешком на 12 этаж :) Пакет с конфигами за несколько секунд собирается, за 1 команду. Можно хоть в git hook добавить при желании.
Может ли манифест для siteN зависеть от манифеста, в котором создаётся конфиг nginx.conf?

Да, конечно. Без этого никакого смысла в puppet'е не было бы.
В Puppet что угодно может зависеть от чего угодно. Классы могут зависеть от ресурсов, ресурсы от классов, модули при желании могут быть зависимы от других модулей (сводится к зависимости между классами).
Пакеты, к сожалению, остаются императивным способом дистрибуции (часть логики остаётся в postinst и скриптах).
Я думаю, что оба способа имеют право на существование.
Емнип, по умолчанию dpkg ругается, когда пакет A пытается перезаписать файл из пакета B, что должно произойти при вашей схеме, если нужно поменять например /etc/nginx/nginx.conf. Неужели необходимо с -f устанавливать все подобные пакеты?
Как-то совсем не unix-way.
Ну и в конце концов, давайте посмотрим что делают большие дяди из больших компаний, например в викимедии: git. Что-то не похоже, что они пакеты с конфигами собирают.
dpkg ругается, если файл — не конфиг. А если конфиг — то не ругается.

Как дяди в большой компании раскатывают пакеты на сотни серверов и я так каждый день вижу. Исходя из этого опыта и говорю, что пакеты не так плохи и сложны, как многим кажется.
Яндекс — не единственная большая компания. Гугл не чурается puppet.
Так я ж не против Puppet как такового, мне просто странно видеть, что конфиги просто пишутся как файлы. Есть некоторое ощущение, что из этого может получиться каша в /etc серверов. Впрочем, т.к. я не администратор, и к тому же puppet не использовал, то это ощущение может оказаться и ложным. Я только dpkg -S умею делать, чтобы понять, откуда конфиг взялся и где его править :)

Вкратце, моя позиция такова: я настоятельно рекомендую всем админам использовать puppet/chef как только количество серверов, выполняющих одинаковые функции, станет больше одного. Пакеты не перпендикулярны puppet, эти два механизма отлично дополняют друг друга.
А не пробовали на /etc повесить VCS? В puppet, наверное как и в chef, можно делать коммиты с подробными комментариями изменений, а правящих конфиги ручками по этим рукам бить убедить после таких правок тоже коммиты делать.
На какой машине? На девелоперской? Или на тестинге? Весь /etc в один VCS положить? А если у меня на девелоперской машине 5 компонентов сервиса стоят вместе, а в продакшене это будут 5 разных групп машин, то как поступать?

В общем, так себе идея.
На продакшенах прежде всего. Конфиги разных сервисов и(или) виртхостов в отдельных репах, которые разворачиваются под отдельными юзерами, а на них симлинки из /etc. Общий VCS на /etc чисто как инкрементный бэкап и отслеживания что установка или обновление пакетов делает.

В общем мое дело предложить, может кому-то покажется заслуживающим внимание.
В итоге будет кучка разных реп. Как их потом деплоить? Для 1-2 серверов может и прокатит. Для десятков и сотен нужны уже другие тулзы, типа puppet/chef, и (я всё же рекомендую) пакетные менеджеры. Для тысяч и десятков тысяч серверов возникают совсем другие проблемы, типа физической невозможности разложить файл/пакет на все эти машины традиционными способами.

Эта статья про вторую категорию.

Кстати, Aecktann, предлагаю сегодня после ваших занятий обсудить третью категорию :)
Отчасти и её имел в виду, но в последнее время от неё практически отказался. Всё она в одну кучу мешает, и настройки серверов nginx, например, или пула php-fpm, и настройки mysql, и что изменяют apt-get install/upgrade. для меня это сейчас просто система резервного копирования по сути, когда нужно быстро откатиться на заведомо рабочий конфиг сервака в целом.
А вот тут хотелось бы сравнений и практического опыта. Все дело в том, что свои пакеты мы все равно собираем, так что не боимся и все такое, но вот для конфигов все же думаем в сторону puppet/chef и прочего. Не расскажете свой кейс? Может со статьей?
Я попробую призвать кого нибудь из админов:) Я то разработчик, тоже пакеты собираю, но не раскатываю. У нас есть штука, которую используют админы, работает примерно так: я запушил в гит новую версию своего софта, он на билдферме собрался. Я иду на сайт и делаю тикет на выкладку пакета (или нескольких) с указанием версий, пишу комментарий. Для каждого пакета в этой системе прописано, в каких проектах и на каких группах серверов он должен быть установлен. Админ получает нотификацию, что я сделал тикет, и, если ничего не мешает, запускает деплоймент. Для девелоперских кластеров иногда делают автовыкатывание, если разработчики и админы не против. У админов ещё есть спец. тулза, которая позволяет делать всякие операции на группах серверов.

Чем хороши конфиги в пакетах: в системе просто нету файлов, которые админ правил руками. Есть либо автосгенерённые в postinst (их стараемся избегать), либо файлы, установленные из пакета. Следовательно, dpkg -S на любой файл в системе с большой долей вероятности скажет, откуда он был установлен, какой версии пакет и можно ли его обновить. Если накосячили — легко и быстро можно откатиться. Для софта, который требует каких-то параметров машины в конфиге (скажем, адрес) пишем инит скрипты так, чтобы они по шаблону при старте эти конфиги генерировали. Шаблон, естественно, тоже в пакете.

А как вы раскатываете пакеты по машинам сейчас?
dsh`ем раскатываем.
в конфиге dsh`а прописаны группы серверов и в зависимости от группы делается
dsh -g Group_NAME sudo apt-get install packet_name
примерно так.
потому и хотелось бы почитать коллег.
А, тогда puppet обязательно попробуйте, вне зависимости от того, как конфиги будете хранить. Наша штука вроде бы не опенсорс и поэтому порекомендовать её не могу.
Да уже пару лет собираемся, вот уже дозрели :)
За краткий рассказ, что конфиги в пакетах используете в реальной жизни спасибо, хотя было бы интересно послушать админов.
В принципе dpkg не ругается и на обычные файлы если правильно использовать dpkg-divert.

Кстати — мне попался фееричный баг в ntpdate в дебиане/убунте — они просто игнорируют настройку dhcp для сервера времени
bugs.debian.org/cgi-bin/bugreport.cgi?bug=617965
решил только пакетом в котором скрипт переписывался
По поводу последующих статей
Мое имхо что сферический LAMP в вакууме вообще достаточно простой пример.
Особенно с замечательным разбиением по сайтам в deb-based, когда можно просто положить файлик в sites-enabled для апача или нгинкса.

Предлагаю рассмотреть что-то типа развертывания школьной сети — поверьте задача гораздо более интересная, особенно с учетом реалий школ :)
Оу, я тааак далёк от школ, их администрирования и в принципе от администрирования рабочих станций… Вообще не знаю, как там, чего, куда и зачем. Расскажете?
Ну тогда ладно, просто есть достаточно интересные моменты
1) как нормально работать в условиях рабочих станций, особенно когда рубанут все напрочь :)
2) как просто настроить с нуля puppet (на dns ресолвить хост puppet в сервер — пару раз встречал на хабре фиговый способ с прописыванием конфигов, но он подойдет только для тестов фактически)
3) хотелось бы чтобы рассказали про augeas — потому как в примере file { 'sshd_config': не очень гуд в случае обновления будет весело, у меня с ним были проблемы с нормальным добавлением секций, пришлось писать костыли, но очень помог когда нужно было
Кстати если пригодится — у меня была проблема на машинах со 128 метрами памяти, когда агент во время настройки скушал половину, но потом хочется еще что-то запустить и не засвопиться — писал класс, который перенастраивает его на одиночный запуск при загрузке

А вообще очень бы хотелось подробно услышать про отчеты и dashboard — статей не было, да и разобраться как-то самому не получилось
Рассказать попытаюсь, когда систематизирую информацию — все достаточно сумбурно к сожалению :)
Соглашусь, статья неплохая, но примеры достаточно скудные. Еще 1 момент. Увидел тег ruby, но кроме отсылки на принадлежность исходников к ruby и некоторый DSL(что уже не совсем и ruby), не увидел. Я бы предложил, например, сравнительную статью типа «puppet vs. chef». В последнем то как раз рецепты пишутся на ruby.
в манифестах можно писать полноценный код на ruby.

например, в кусочке модуля, описывающего iptables, у меня встречается
    $default_open_ports = {
        'tcp' => [22],
        'udp' => []
    }

    if $open_ports == undef {
        $real_open_ports = $default_open_ports
    } else {
        $real_open_ports = $open_ports
    }

    if $custom_rules == undef {
        $real_custom_rules = []
    } else {
        $real_custom_rules = $custom_rules
    }

в принципе, можно использовать почти любой ruby-код. Правда, логику намного сложнее указанной, я не описывал.
Извините, но Ваш код больше смахивает на PHP, нежели на Ruby.
Раз он сам написан на ruby, может тогда не LAMP, а что-то типа nginx+unicorn+rails+mysql? (-:
К чему ваш комментарий, уважаемый?)
Ну и rvm тогда уж как минимум.
Конечно, с учётом различных версий, наложения патчей и т.п.

Потому и сказал, что это будет несколько интересней…
Ну… вот к этому: «В последующих топиках будет описано, как использовать более мощные возможности puppet при создании сферического LAMP-хостинга в вакууме»

Вот я и предложил своего сферического коня в вакууме. Вот. (-: Чуть более не тривиального.

P.S. Промахнулся
Puppet клиент висит и с какой-то периодичностью опрашивает мастер хост на наличие изменений? Не будет ли ситуации когда большое количество клиентов одновременно запросят изменения и положат сервер? Или, к примеру, если нужно обновить несколько серверов одновременно или в определенной последовательности, не дожидаясь пока клиенты сработают, есть подобный механизм управления?
Puppet-agent может работать в режиме демона (в этом случае он по умолчанию обращается к мастеру раз в полчаса), а можно сделать cronjob для обновления, тогда агент не будет висеть в памяти.
Касательно работы под нагрузкой, компания Badoo описала свой опыт на хабре.
Задача деплоя нового приложения — совсем другого рода, на мой взгляд.
Возможно, есть способы, с ходу ответить не могу. На заметку взял.
<< Или, к примеру, если нужно обновить несколько серверов одновременно или в определенной последовательности, не дожидаясь пока клиенты сработают, есть подобный механизм управления

puppetrun
А кто нибудь может кинуть ресурс, который бы управлял строками в текстовом файле, например в passwd? Очень хочется понять, как его реализовать.
Может неправильно понял вопрос, но, по-моему, имелся в виду контроль над конкретными строками. Не просто контент файла описывать, а «в файле должна быть такая-то строка (возможно в конкретном месте, что важно для xml/yaml/… конфигов)» или «строка, соответствующие маске такой-то, должна иметь конкретное содержание вариативной части маски»
1. Нет
2. Нет
3. Пример?

Нужен ресурс для управления строкой в файле. Желательно в виде примера на github
Как позиционировать строку? Двенадцатая строка в файле А должна содержать в себе строку S?
Задайте более реальный вопрос. А то получается сферический конь.
Куда уж реальнее? docs.puppetlabs.com/learning/ral.html

Я в терминах Puppet задаю вопрос. Мне нужно задавать виртуальные ресурсы и реализовывать их на хостах. Ресурс = одна строка в passwd файле. Не /etc/passwd а другой, для отдельного сервиса.

Я ищу готовую реализацию, что бы самому не выдумывать.
Модуль для ручной установки/запуска puppet`а на ноде github.com/garex/puppet-tools

Подходит для начала или если парк крайне маленький (masterless подход — без мастера). Более правильно делать через клиент/сервер (master).

IDE: Eclipse + Ruby development tools + Gepetto (это то и есть то самое, что надо).

Gepetto update site: download.cloudsmith.com/geppetto/updates
Категория: Gepetto
Имя: Gepetto

> На сервере волшебным (нет, правда волшебным!) образом

Только если руки не из жопы, т.к. зависимости никто не отменял и в случае чего мы не падаем, но в логи сыпется err: и в итоге у нас конечное состояние не то. Дебажить тоже трудновато, т.к. папет сам решение о порядке запуска принимает и каждый раз всё может быть по-другому, если мы делаем что-то довольно сложное или у нас не всё учтено.
WTF?
touch /tmp/helloworld && echo «Hello, world!» > /tmp/helloworld && chmod 644 /tmp/helloworld && chown root /tmp/helloworld && chgrp root /tmp/helloworld


Можно короче (и более, чем уверен, что можно ещё короче):
echo «Hello, world!» > /tmp/helloworld && chmod 644 /tmp/helloworld && chown root:root /tmp/helloworld
Откройте для себя мир GNU parallel. Накатывать сервера не обязательно последовательно.

Вопрос про накатывание набора/среза серверов Puppet'ом не раскрыт.

Сам пользуюсь babushka, обещаю написать про опыт использования, про все за и против после НГ.
А еще есть проект systemimager.
Когда все изменения достаточно сделать один раз на master'е, например нужной Вам группы серверов, после чего одной командой изменения улетят на все сервера группы.
И каков принцип работы? Оно просто смотрит на diff в файлах или там какая-то интеллектуальная оболочка, через которую нужно работать?
Как оно относится к изменениям типа sed -i «s/WORK/$HOSTNAME/» /etc/config/file?
Мне понтравился ansible.cc/
* push
* работает по ssh (не требует установки агента)
* умеет почти то же самое что и puppet

В реалиях ec2 удобен тем, что не нужно подписывать сертификаты и клиентов, а затем чистить их.
А я наоборот считаю работу по ssh минусом. Например, криво обновился ssh сервер -> залезть по ssh невозможно. Puppet в такой ситуации может спасти.
И часто у вас криво обновляется ssh?
К счастью нет, всего один раз было. Но отпечаток оставило.
легко. на сервере фаерволом закрыты все порты, кроме 22 и 80. тут умный молодой админ приходит и вопит: «АААА! держать ssh на 22-м порту опасно! перенесу на 23456-й порт!». ну и переносит. а потом «этаа… тут ммм...».
Ага, те еще деятели — на одном серваке порт 2222, на другом 2200 на третьем 22222 на четвертом 12345 на пятом еще какой. А потом блин еще и вспоминай после того как пол года на этот сервак не заходил :)
~/.ssh/config очень хорошо помнит за вас порты, если что.
вынужден этим пользоваться потому что часто за одним реальником прячется десяток виртуалок и их ssh DNAT`ится.
Chef в этом плане предлагает чуть другую метафору.

И да, так выглядит изначальныый рецепт:

include_recipe "apt"
include_recipe "nginx"


хотя можно и руками
bash "apt-get update" do
  code "apt-get update"
end

package "nginx" do
  action :upgrade
end

service "nginx" do
  action :start
end
вернее, чтобы разрешить в boot и запустить, последняя конструкция должна выглядеть так

service "nginx" do
  action [ :enable, :start ]
end


при этом подразумевается стиль запуска по умолчанию для целевой платформы.
А может всё же продолжение? :)
Sign up to leave a comment.

Articles