Пользователь
0,0
рейтинг
25 декабря 2012 в 10:02

Разработка → Как стать кукловодом или Puppet для начинающих tutorial

Ruby*
Здравствуйте.
image
Этот топик открывает цикл статей по использованию системы управления конфигурацией Puppet.

Что такое система управления конфигурацией?


Предположим, что у вас есть парк серверов, выполняющих различные задачи. Пока серверов мало и вы не растёте, вы легко настраиваете каждый сервер вручную. Устанавливаете ОС (может быть, автоматизированно), добавляете пользователей, устанавливаете софт, вводя команды в консоль, настраиваете сервисы, правите конфиги ваших любимых текстовых редакторов (nanorc, vimrc), выставляете на них одинаковые настройки DNS-сервера, устанавливаете агент системы мониторинга, настраиваете syslog для централизованного сбора логов… Словом, работы довольно много и она не особенно интересна.

Я искренне верю, что хороший админ — ленивый админ. Он не любит делать что-то несколько раз. Первая мысль — написать пару скриптов, в котором будет что-то наподобие:

servers.sh
servers="server00 server01 server02 server03 server04"

for server in $servers ; do
  scp /path/to/job/file/job.sh $server:/tmp/job.sh
  ssh $server sh /tmp/job.sh
done


job.sh
#!/bin/bash
apt-get update
apt-get install nginx
service nginx start


Вроде всё стало легко и хорошо. Нужно что-то сделать — пишем новый скрипт, запускаем. Изменения приходят на все серверы последовательно. Если скрипт хорошо отлажен — всё станет хорошо. До поры.

Теперь представьте, что серверов стало больше. Например, сотня. А изменение долгое — например, сборка чего-нибудь большого и страшного (например, ядра) из исходников. Скрипт будет выполняться сто лет, но это полбеды.

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

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

Для сравнения: манифест puppet, выполняющий ту же работу, что и пара скриптов из начала топика:

nginx.pp
class nginx {
  package { 'nginx':
    ensure => latest
  }
  service { 'nginx':
    ensure => running,
    enable => true,
    require => Package['nginx']
  }
}
node /^server(\d+)$/ {
  include nginx
}

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

Что такое Puppet?


Puppet — система управления конфигурацией. Архитектура — клиент-серверная, на сервере хранятся конфиги (в терминах puppet они называются манифесты), клиенты обращаются к серверу, получают их и применяют. Puppet написан на языке Ruby, сами манифесты пишутся на особом DSL, очень похожем на сам Ruby.

Первые шаги


Давайте забудем о клиентах, серверах, их взаимодействии и т.п. Пусть у нас есть только один сервер, на котором установлена голая ОС (здесь и далее я работаю в Ubuntu 12.04, для других систем действия будут несколько отличаться).

Сначала установим puppet последней версии.

wget http://apt.puppetlabs.com/puppetlabs-release-precise.deb
dpkg -i puppetlabs-release-precise.deb
apt-get update
apt-get install puppet puppetmaster


Замечательно. Теперь у нас в системе установлен puppet и с ним можно играть.

Hello, world!

Создадим первый манифест:

/tmp/helloworld.pp
file { '/tmp/helloworld':
  ensure => present,
  content => 'Hello, world!',
  mode => 0644,
  owner => 'root',
  group => 'root'
}

И применим его:

$ puppet apply helloworld.pp 
/Stage[main]//File[/tmp/helloworld]/ensure: created
Finished catalog run in 0.06 seconds

Немного о запуске
Манифесты, приведённые в этом топике можно применять вручную с помощью puppet apply. Тем не менее, в последующих топиках для работы будет использоваться master-slave конфигурация (стандартная для Puppet).

Теперь посмотрите на содержимое файла /tmp/helloworld. В нём окажется (удивительно!) строка «Hello, world!», которую мы задали в манифесте.

Вы можете сказать, что можно было сделать echo "Hello, world!" > /tmp/helloworld, это было бы быстрее, проще, не пришлось бы думать, писать какие-то страшные манифесты и вообще это нафиг никому не нужно это как-то слишком сложно, но задумайтесь серьезнее. На самом деле, необходимо было бы написать touch /tmp/helloworld && echo "Hello, world!" > /tmp/helloworld && chmod 644 /tmp/helloworld && chown root /tmp/helloworld && chgrp root /tmp/helloworld, чтобы гарантированно добиться того же результата.

Давайте по строкам разберём, что именно содержится в нашем манифесте:

/tmp/helloworld.pp
file { '/tmp/helloworld':
    ensure  => present,          # файл должен существовать
    content => 'Hello, world!',  # содержимым файла должна являться строка "Hello, world!"
    mode    => 0644,             # права на файл - 0644
    owner   => 'root',           # владелец файла - root
    group   => 'root'            # группа файла - root
}


В терминах Puppet здесь описан ресурс типа файл с названием (title) /tmp/helloworld.

Ресурсы

Ресурс — это самая мелкая единица абстракции в Puppet. Ресурсами могут быть:
  • файлы;
  • пакеты (Puppet поддерживает пакетные системы многих дистрибутивов);
  • сервисы;
  • пользователи;
  • группы;
  • задачи cron;
  • и т. д.

Синтаксис ресурсов вы можете невозбранно подсмотреть в документации.

В Puppet есть возможность добавлять свои ресурсы. Поэтому если хорошенько заморочиться, можно докатиться до манифестов наподобие:

webserver.pp
include webserver;
webserver::vhost { 'example.com':
    ensure => present,
    size   => '1G',
    php    => false,
    https  => true  
}

Puppet при этом будет создавать logical volume размером в 1 ГиБ на сервере, монтировать его куда положено (например в /var/www/example.com), добавлять нужные записи в fstab, создавать нужные виртуальные хосты в nginx и apache, рестартовать оба демона, добавлять в ftp и sftp пользователя example.com с паролем mySuperSecretPassWord с доступом на запись в этот виртуальный хост.

Вкусно? Не то слово!

Причем, самое вкусное, на мой взгляд — это не автоматизация рутины. Если вы например, идиот, и постоянно пересетапливаете ваши серверы в продакшне, Puppet позволит подхватить старый любовно созданный набор пакетов и конфигов с нуля в полностью автоматическом режиме. Вы просто устанавливаете Puppet-агент, подключаете его к вашему Puppet-мастеру и ждёте. Всё придёт само. На сервере волшебным (нет, правда волшебным!) образом появятся пакеты, разложатся ваши ssh-ключи, установится фаервол, придут индивидуальные настройки bash, сети, установится и настроится весь софт, который вы предусмотрительно ставили с помощью Puppet.
Кроме того, Puppet при старании позволяет получить самодокументируемую систему, ибо конфигурация (манифесты) сами же являются костяком документации. Они всегда актуальны (они же работают уже), в них нет ошибок (вы же проверяете свои настройки перед запуском), они минимально подробны (работает же).

Ещё немного магии


Немного о кроссдистрибутивности
В Puppet есть возможность использовать кроссдистрибутивные манифесты, это одна из целей, для которых он создавался. Я намеренно никогда не пользовался этим и вам не рекомендую. Парк серверов должен быть максимально гомогенным в плане системного ПО, это позволяет не думать в критические моменты «айблин, тут
rc.d, а не init.d» (реверанс в сторону ArchLinux) и вообще позволяет меньше думать на рутинных задачах.


Многие ресурсы зависят от других ресурсов. Например, для ресурса «сервис sshd» необходим ресурс «пакет sshd» и опционально «конфиг sshd»
Посмотрим, как это реализуется:
file { 'sshd_config':
    path    => '/etc/ssh/sshd_config',
    ensure  => file,
    content => "Port 22
    Protocol 2
    HostKey /etc/ssh/ssh_host_rsa_key
    HostKey /etc/ssh/ssh_host_dsa_key
    HostKey /etc/ssh/ssh_host_ecdsa_key
    UsePrivilegeSeparation yes
    KeyRegenerationInterval 3600
    ServerKeyBits 768
    SyslogFacility AUTH
    LogLevel INFO
    LoginGraceTime 120
    PermitRootLogin yes
    StrictModes yes
    RSAAuthentication yes
    PubkeyAuthentication yes
    IgnoreRhosts yes
    RhostsRSAAuthentication no
    HostbasedAuthentication no
    PermitEmptyPasswords no
    ChallengeResponseAuthentication no
    X11Forwarding yes
    X11DisplayOffset 10
    PrintMotd no
    PrintLastLog yes
    TCPKeepAlive yes
    AcceptEnv LANG LC_*
    Subsystem sftp /usr/lib/openssh/sftp-server
    UsePAM yes",
    mode    => 0644,
    owner   => root,
    group   => root,
    require => Package['sshd']
}

package { 'sshd':
    ensure => latest,
    name   => 'openssh-server'
}

service { 'sshd':
    ensure    => running,
    enable    => true,
    name      => 'ssh'
    subscribe => File['sshd_config'],
    require   => Package['sshd']
}


Здесь используется инлайн-конфиг, который делает манифест некрасивым. На самом деле так почти никогда не делается, существует механизм шаблонов, основанный на ERB, и возможность просто использовать внешние файлы. Но нас не это интересует.

Самые вкусные строчки здесь — это строчки зависимостей — require и subscribe.

Puppet поддерживает много вариантов описания зависимостей. Подробно, как всегда, можно прочитать в документации.

  • Require означает ровно то, что ожидается. Если ресурс А зависит (require) от ресурса Б, то Puppet сначала обработает ресурс Б, а потом вернётся к ресурсу А.
  • Subscribe даёт чуть более хитрое поведение. Если ресурс А подписан (subscribe) на ресурс Б, то Puppet сначала обработает ресурс Б, а потом вернётся к ресурсу А (поведение как у require), и далее при изменениях Б, будет заново обрабатываться А. Это очень удобно для создания сервисов, зависящих от их конфигов (как в примере выше). Если конфиг изменяется, сервер перезапускается, не нужно самому об этом беспокоиться.


Существуют также notify, before, но мы их здесь касаться не будем. Интересующимся — в уже упопомянутую документацию.

Итог


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

Ссылки по теме


@Aecktann
карма
29,1
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (64)

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

    И второй момент, как решить проблему dev-testing-stable версий с помощью puppet?
    • +1
      в ensure вы можете прописать конкретную версию пакета, если вы говорите об этом «dev-testing-stable версий»
    • +6
      Я в топике написал:
      Здесь используется инлайн-конфиг, который делает манифест некрасивым. На самом деле так почти никогда не делается, существует механизм шаблонов, основанный на 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 я решаю с помощью лабораторий с отдельным окружением. В век виртуализации это не сложно. Гит помогает в плане упорядочивания изменений и хранения истории.
      • +1
        а. Так конфиг положить не в пакет openssh, а в mycompany-openssh-config конечно же! Сам сервер при этом будет из апстрима ставиться. А именно в конфигурационных пакетах уже писать postinstall скрипты, запускающие сервисы.
        б. Кажется, создание уникальных конфигов — это изначально плохая идея, и мне в голову сходу не приходит, где это может быть нужно в гомогенной серверной среде.
        • +3
          а) Я вижу минус в множении сущностей. В вашем варианте необходим как свой репозиторий с пакетами mycompany*, так и puppet, который будет отслеживать эти самые апдейты. В моем варианте репозиторий не нужен, а конфиг можно легко править на мастере без необходимости сборки-разборки пакета. Я не спорю, вариант с пакетами имеет право на существование, но мне он не нравится потому что прозреваю там большее количество возни и большую вероятность ошибок.
          б) Совсем не плохая. Тут описан хороший вариант динамической генерации манифестов и их применения. И знаете, банально менять конфиг одного виртуального хоста в nginx'e через пересборку пакета — это за гранью добра и зла.
          • +1
            Возни в принципе столько же — сначала поправить файлик-конфиг, потом закоммитить его, потом задеплоить. Если пару алиасов написать — то по количеству команд одинаково получится, разве что чуть дольше. Что хорошо в пакетах — есть зависимости, можно у совершенно разных сервисов использовать общие части. Я вижу в вашем примере, что в принципе зависимости есть. Но может ли один манифест зависеть от другого? Грубо говоря, есть какие-то базовые настройки нгинкса, которые вы записываете в /etc/nginx/nginx.conf (всякие там количества воркеров, логирование и т.д.), и есть конфиги для сервисов-сайтов, которые вы укладываете в /etc/nginx/sites-enabled/siteN.conf. Может ли манифест для siteN зависеть от манифеста, в котором создаётся конфиг nginx.conf?

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

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

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

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

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

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

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

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

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

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

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

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

        А вообще очень бы хотелось подробно услышать про отчеты и dashboard — статей не было, да и разобраться как-то самому не получилось
      • 0
        Рассказать попытаюсь, когда систематизирую информацию — все достаточно сумбурно к сожалению :)
    • +3
      Соглашусь, статья неплохая, но примеры достаточно скудные. Еще 1 момент. Увидел тег ruby, но кроме отсылки на принадлежность исходников к ruby и некоторый DSL(что уже не совсем и ruby), не увидел. Я бы предложил, например, сравнительную статью типа «puppet vs. chef». В последнем то как раз рецепты пишутся на ruby.
      • 0
        в манифестах можно писать полноценный код на 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-код. Правда, логику намного сложнее указанной, я не описывал.
        • +2
          Извините, но Ваш код больше смахивает на PHP, нежели на Ruby.
          • 0
            Тяжёлое наследие.
            • 0
              Все-таки больше похоже на то, что вы привели кусок на внутреннем DSL, а не на Ruby.
              В точности, как в документации — docs.puppetlabs.com/puppet/2.7/reference/lang_conditional.html

              Ну и в Ruby этот код просто некорректен.
  • +2
    Раз он сам написан на ruby, может тогда не LAMP, а что-то типа nginx+unicorn+rails+mysql? (-:
    • –1
      К чему ваш комментарий, уважаемый?)
    • 0
      Ну и rvm тогда уж как минимум.
      • 0
        Конечно, с учётом различных версий, наложения патчей и т.п.

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

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

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

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

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

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

            Я ищу готовую реализацию, что бы самому не выдумывать.
  • 0
    Модуль для ручной установки/запуска 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: и в итоге у нас конечное состояние не то. Дебажить тоже трудновато, т.к. папет сам решение о порядке запуска принимает и каждый раз всё может быть по-другому, если мы делаем что-то довольно сложное или у нас не всё учтено.
  • 0
    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
  • +1
    Откройте для себя мир GNU parallel. Накатывать сервера не обязательно последовательно.

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

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

    В реалиях ec2 удобен тем, что не нужно подписывать сертификаты и клиентов, а затем чистить их.
    • 0
      А я наоборот считаю работу по ssh минусом. Например, криво обновился ssh сервер -> залезть по ssh невозможно. Puppet в такой ситуации может спасти.
      • 0
        И часто у вас криво обновляется ssh?
        • 0
          К счастью нет, всего один раз было. Но отпечаток оставило.
        • +2
          легко. на сервере фаерволом закрыты все порты, кроме 22 и 80. тут умный молодой админ приходит и вопит: «АААА! держать ssh на 22-м порту опасно! перенесу на 23456-й порт!». ну и переносит. а потом «этаа… тут ммм...».
          • 0
            Ага, те еще деятели — на одном серваке порт 2222, на другом 2200 на третьем 22222 на четвертом 12345 на пятом еще какой. А потом блин еще и вспоминай после того как пол года на этот сервак не заходил :)
            • 0
              ~/.ssh/config очень хорошо помнит за вас порты, если что.
              вынужден этим пользоваться потому что часто за одним реальником прячется десяток виртуалок и их ssh DNAT`ится.
              • –1
                Зачем DNAT? есть же ProxyCommand.
  • +1
    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
    
    • +1
      вернее, чтобы разрешить в boot и запустить, последняя конструкция должна выглядеть так

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


      при этом подразумевается стиль запуска по умолчанию для целевой платформы.
  • +1
    Продолжение будет?
    • +1
      Обязательно.
  • +1
    Спасибо, Aecktann!
    Если позволите, привнесу свою лепту в эту прекрасную тему:
    Управление правами доступа к WMI через Puppet
    Puppet + Opsview: автоматический мониторинг на основе шаблонов

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.