- PVSM.RU - https://www.pvsm.ru -
[1]Puppet — довольно удобный инструмент для управления конфигурациями. По сути, это система, которая позволяет автоматизировать настройку и управление большим парком машин и сервисов.
Базовой информации о самой системе много, в том числе и на Хабре: здесь [2], здесь [3] и здесь [4]. Мы же постарались собрать в одной статье несколько «рецептов» использования Puppet под действительно большими нагрузками — в «боевых условиях» Badoo.
О чём пойдет речь:
Сразу оговоримся, что статья написана по следам доклада Антона Турецкого на конференции HighLoad++ 2012 [5]. За несколько дней наши «рецепты» обросли дополнительными подробностями и примерами.
Возвращаясь к нагрузкам, следует отметить, что в Badoo они действительно высокие:
Само по себе приложение Puppet является клиент-серверным. В случае с Puppet инициатором соединения выступает клиент; в данном случае это узел (англ. node), на котором нужно развернуть конфигурацию.
Клиент собирает факты о себе с помощью утилиты facter — неотъемлемой зависимости приложения Puppet, затем отправляет их обычным запросом HTTP POST на сервер и ждёт его ответа.
Cервер получает дамп с фактами от клиента и компилирует каталог. При этом он исходит из информации в имеющихся на сервере манифестах, но также учитывает полученые от клиента факты. Каталог отправляется клиенту.
Получив каталог с сервера, клиент производит изменения в системе. О результатах выполнения сообщает серверу с помощью запроса HTTP POST.
После выполнения клиентом всех правил, отчёт следует сохранить. Puppet предлагает использовать для этого как свои наработки, так и сторонние коллекторы. Пробуем!
Устанавливаем базовый пакет и получаем следующую картину:
На первый взгляд, всё замечательно — поставил и работай. Однако с течением времени картинка становится менее радостной. Количество клиентов увеличивается, системные администраторы пишут манифесты, вследствие которых растут временные затраты на компиляцию кода и обработку каждого клиента.
И в определённый момент картина становится совсем уж печальной.
Первое, что приходит в голову — увеличить количество процессов puppet master на сервере. Да, именно потому, что в базовой поставке Puppet этого не умеет, да и по ядрам он не «размазывается».
Есть ли варинаты решения, предложенные производителем? Безусловно, но по разным причинам они оказались неприменимы в наших условиях.
Почему не Apache + mod_passenger? По определённым причинам в нашей компании веб-сервер Apache вообще не используется.
Почему не nginx + passenger? Чтобы избежать необходимости дополнительного модуля в той сборке nginx, которую мы используем.
Тогда что?
Почему именно Unicorn [6]?
Вот, на наш взгляд, его плюсы:
Ещё одной причиной выбора в пользу Unicorn послужила простота его установки и настройки.
worker_processes 12
working_directory "/etc/puppet"
listen '0.0.0.0:3000', :backlog => 512
preload_app true
timeout 120
pid "/var/run/puppet/puppetmaster_unicorn.pid"
if GC.respond_to?(:copy_on_write_friendly=)
GC.copy_on_write_friendly = true
end
before_fork do |server, worker|
old_pid = "#{server.config[:pid]}.oldbin"
if File.exists?(old_pid) && server.pid != old_pid
begin
Process.kill("QUIT", File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
end
end
end
Итак, хорошая новость: у нас есть возможность запуска нескольких процессов. Но есть и плохая: управлять процессами стало гораздо сложнее. Не страшно — для этой ситуации существует свой «рецепт».
God представляет собой фреймворк для мониторинга процессов. Он прост в настройке и написан на Ruby, как и сам Puppet.
В нашем случае God управляет различными инстансами процессов puppet master:
C настройкой особых проблем тоже не возникает. Достаточно создать конфигурационный файл в директории /etc/god/ для обработки файлов *.god.
God.watch do |w|
w.name = "puppetmaster"
w.interval = 30.seconds
w.pid_file = "/var/run/puppet/puppetmaster_unicorn.pid"
w.start = "cd /etc/puppet && /usr/bin/unicorn -c /etc/puppet/unicorn.conf -D"
w.stop = "kill -QUIT `cat #{w.pid_file}`"
w.restart = "kill -USR2 `cat #{w.pid_file}`"
w.start_grace = 10.seconds
w.restart_grace = 10.seconds
w.uid = "puppet"
w.gid = "puppet"
w.behavior(:clean_pid_file)
w.start_if do |start|
start.condition(:process_running) do |c|
c.interval = 5.seconds
c.running = false
end
end
end
Обратите внимание, что мы выделили Puppet CA в отдельный инстанс. Сделано это специально, чтобы все клиенты использовали единый источник для проверки и получения своих сертификатов. Немного позже мы расскажем, как этого добиться.
Как уже говорилось, весь процесс обмена информацией между клиентом и сервером происходит по HTTP, значит, нам ничто не мешает настроить простую http-балансировку, прибегнув к помощи nginx.
upstream puppetmaster_unicorn {
server 127.0.0.1:3000 fail_timeout=0;
server server2:3000 fail_timeout=0;
}
# для основного процесса puppet master (к примеру, production-окружение)
upstream puppetca {
server 127.0.0.1:3000 fail_timeout=0;
}
# для Puppet CA
location ^~ /production/certificate/ca {
proxy_pass http://puppetca;
}
location ^~ /production/certificate {
proxy_pass http://puppetca;
}
location ^~ /production/certificate_revocation_list/ca {
proxy_pass http://puppetca;
}
location / {
proxy_pass http://puppetmaster_unicorn;
proxy_redirect off;
}
Подведем промежуточные итоги. Итак, вышеуказанные действия позволяют нам:
А масштабирование?
Технические возможности сервера puppet master не безграничны, и если нагрузки на него становятся предельно допустимыми, то встает вопрос масштабирования.
Эта проблема решается следующим образом:
Для запуска ещё одного сервера нам достаточно:
На этом наш «тюнинг» не заканчивается, поэтому снова вернёмся к теории.
Если клиент присылает нам отчёт и факты о себе, то почему бы не хранить эту информацию?
В этом нам поможет Storeconfigs — опция puppet-server, которая позволяет сохранять актуальную информацию о клиентах в базе данных. Система сравнивает последние данные от клиента с уже имеющимися. Storeconfigs поддерживает следующие хранилища: SQLite, MySQL, PostgreSQL. Мы используем MySQL.
В нашем случае множество клиентов забирают конфигурацию каждые три минуты, примерно столько же присылают отчёты. В итоге мы уже получаем большие очереди на запись в MySQL. А ведь нам предстоит ещё и забирать данные из БД.
Эта проблема получила следующее решение:
Использование Apache ActiveMQ позволило нам направлять сообщения от клиентов не сразу в БД, а пропускать их через очередь сообщений.
В результате мы имеем:
Для настройки puppet-server потребовалось дописать в конфигурацию следующие строки:
[main]
async_storeconfigs = true
queue_type = stomp
queue_source = stomp://ACTIVEMQ_address:61613
dbadapter = mysql
dbuser = secretuser
dbpassword = secretpassword
dbserver = mysql-server
И не забудем про запуск процесса puppet queue.
Благодаря описанным настройкам Puppet работает на сервере шустро и хорошо, но хорошо бы регулярно мониторить его активность. Настало время вспомнить о Puppet Reports.
Что нам предлагается по умолчанию:
Увы, целиком и полностью нас не устроил ни один из вариантов по одной-единственной причине — отсутствие качественной визуальной составляющей. К сожалению, а может и к счастью, стандартный Puppet Dashboard в тот момент показался нам слишком скучным.
Поэтому мы остановили свой выбор на Foreman [7], который порадовал нас симпатичными диаграммами с самым необходимым.
На картинке слева мы видим, какое количество времени уходит на применение каждого типа ресурсов. За 360 градусов берется полное время выполнения на клиенте.
Картинка справа отображает количество событий с указанием статуса. В данном примере запущен всего один сервис, более 10 событий пропущено по причине того, что их текущее состояние полностью соответствует эталонному.
И последняя рекомендация: обновиться до версии 3.0.0
График отчётливо показывает выигрыш во времени после обновления. Правда, производительность выросла не на 50%, как обещали разработчики, но прирост оказался вполне ощутимым. После правки манифестов (см. сообщение [8]) мы всё-таки добились обещанных 50%, поэтому наши усилия себя полностью оправдали.
В заключение можно сказать, что при должной настройке Puppet способен справиться с серьёзными нагрузками и управление конфигурацией на 2000 серверов ему вполне по плечу.
Антон [banuchka [9]] Турецкий, системный администратор
Badoo
Автор: Badoo
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/linux/18648
Ссылки в тексте:
[1] Image: http://habrahabr.ru/company/badoo/blog/157023/
[2] здесь: http://habrahabr.ru/post/67471/
[3] здесь: http://habrahabr.ru/post/68532/
[4] здесь: http://habrahabr.ru/post/126487/
[5] HighLoad++ 2012: http://highload.ru
[6] Unicorn: http://unicorn.bogomips.org/
[7] Foreman: http://theforeman.org/
[8] сообщение: http://projects.puppetlabs.com/issues/7285
[9] banuchka: http://habrahabr.ru/users/banuchka/
[10] Источник: http://habrahabr.ru/post/157023/
Нажмите здесь для печати.