Comments 38
Спасибо, Андрей. Такой подход действительно экономит кучу времени и сил.
+1
Теперь представьте, что вам нужно разделить эти сайты на две роли app_server и blog_server. Ну и как вы собираетесь это тестировать на dev окружении?
Применяю обе роли на ноду в dev окружении.
Можно рискнуть и надеяться, что все будет ОК или перезаписать атрибуты в Chef Environments (сначала на dev, потом на qa и т.д.) и не забыть почистить их после того, как они попадут на продакшн. Не самый лучший вариант.
А зачем чистить атрибуты environment, которые не касаются продакшена (а значит при правильном использовании никогда там не будут видны)? Как раз при тестировании нового функционала закидываете атрибуты в env, тестируете только на нем, и если все ок — выносите в роль.
Chef роли кажутся идеальнами для хранения списка запускаемых рецептов. Однако, этот подход страдает теми же недостатками, что и предыдущий антипаттерн. Если вы добавите или удалите рецепт из списка run_list в роли, то эти изменения применятся ко всем серверам с этой ролью, включая продакшн серверы.
Это никто не заставляет вас делать. Никто вам не помещает сделать:
knife ssh -E dev ‘role:webapp’ ‘sudo chef-client’
Который только затронет dev environment с ролью webapp.
+1
Теперь представьте, что вам нужно разделить эти сайты на две роли app_server и blog_server. Ну и как вы собираетесь это тестировать на dev окружении?
Применяю обе роли на ноду в dev окружении.
Если изменить роль, то она применится для всех энвов — об этом и речь в статье.
Можно рискнуть и надеяться, что все будет ОК или перезаписать атрибуты в Chef Environments (сначала на dev, потом на qa и т.д.) и не забыть почистить их после того, как они попадут на продакшн. Не самый лучший вариант.
А зачем чистить атрибуты environment, которые не касаются продакшена (а значит при правильном использовании никогда там не будут видны)? Как раз при тестировании нового функционала закидываете атрибуты в env, тестируете только на нем, и если все ок — выносите в роль.
Здесь речь о CI/CD — когда инфраструктурный код движется от дев к проду. И опять же, в роль нельзя, так как это глобальный конфиг и применится ко всем окружениям.
Chef роли кажутся идеальнами для хранения списка запускаемых рецептов. Однако, этот подход страдает теми же недостатками, что и предыдущий антипаттерн. Если вы добавите или удалите рецепт из списка run_list в роли, то эти изменения применятся ко всем серверам с этой ролью, включая продакшн серверы.
Это никто не заставляет вас делать. Никто вам не помещает сделать:
knife ssh -E dev ‘role:webapp’ ‘sudo chef-client’
Который только затронет dev environment с ролью webapp.
Никто не мешает вообще и по ssh зайти и ручками что-то поменять, но тогда зачем Chef?
0
Если изменить роль, то она применится для всех энвов — об этом и речь в статье.
Ну во первых применится — но не будет выполнена (chef-client сам не узнает про изменения). Вариатны решения без усугубления «Все в кукбуку»:
1) ничто не мешает нам создать отдельную роль (с атрибутами и ран листами) и тестировать на ней, а потом перенести в основную
2) никто не запрещал использовать специальные run_list для env:
{ "name": "webserver", "default_attributes": { }, "json_class": "Chef::Role", "env_run_lists": { "test": [ "role[base]", "recipe[apache]", "recipe[apache::copy_test_configs]" ], "dev": [ "role[base]", "recipe[apache]", "recipe[apache::copy_dev_configs]" ] }, "run_list": [ "role[base]", "recipe[apache]" ], "description": "The webserver role", "chef_type": "role", "override_attributes": { } }
Тоесть для dev и test я указал специфичные run_list, остальные будут использовать стандартный.
По поводу атрибутов — это очень гибкая вещь. можно тестовые запихать по неймспейсу env:
attribute_i_want = node[node.chef_environment]
Или просто ложим в env :)
Здесь речь о CI/CD — когда инфраструктурный код движется от дев к проду
Используя систему контроля версий создаете отдельную ветку в chef-repo, дальше тестируете в dev (который находится на вашей машине), используя chef-zero и vagrant, что бы не затрагивать основной сервер. По завершению — мерджим в мастер и заливаем на сервер. Вот так делаем движение от dev to prod.
Никто не мешает вообще и по ssh зайти и ручками что-то поменять, но тогда зачем Chef?
В моем примере все делается через knife, усугубления «руками» или работа без Chef в нем не присутствуют.
+1
Ну во первых применится — но не будет выполнена (chef-client сам не узнает про изменения).
Извини, но бред написал. Чисто для теста:
$ knife role edit ftp:
{
"name": "ftp",
"description": "",
"json_class": "Chef::Role",
"default_attributes": {
},
"override_attributes": {
},
"chef_type": "role",
"run_list": [
"recipe[test1]",
"recipe[test2]"
],
"env_run_lists": {
}
}
$ knife ssh "role:ftp" "tailf /var/log/chef/client.log" -x ec2-user -i /home/ec2-user/test.pem
ip-10-1-12-98.eu-west-1.compute.internal [2014-01-27T18:48:41+00:00] INFO: Running start handlers
ip-10-1-12-98.eu-west-1.compute.internal [2014-01-27T18:48:41+00:00] INFO: Start handlers complete.
ip-10-1-12-98.eu-west-1.compute.internal [2014-01-27T18:48:41+00:00] INFO: HTTP Request Returned 404 Object Not Found:
ip-10-1-12-98.eu-west-1.compute.internal [2014-01-27T18:48:41+00:00] INFO: HTTP Request Returned 412 Precondition Failed: {"message"=>"Run list contains invalid items: no such cookbooks test1, test2.", "non_existent_cookbooks"=>["test1", "test2"], "cookbooks_with_no_versions"=>[]}
ip-10-1-12-98.eu-west-1.compute.internal [2014-01-27T18:48:41+00:00] ERROR: Running exception handlers
ip-10-1-12-98.eu-west-1.compute.internal [2014-01-27T18:48:41+00:00] ERROR: Exception handlers complete
ip-10-1-12-98.eu-west-1.compute.internal [2014-01-27T18:48:41+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
ip-10-1-12-98.eu-west-1.compute.internal [2014-01-27T18:48:41+00:00] ERROR: 412 "Precondition Failed"
ip-10-1-12-98.eu-west-1.compute.internal [2014-01-27T18:48:41+00:00] ERROR: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
ip-10-1-12-98.eu-west-1.compute.internal [2014-01-27T18:48:41+00:00] ERROR: Sleeping for 300 seconds before trying again
0
Вот именно: «knife ssh» нужно, чтобы выполнить (как я писал после «knife role edit|load from file» ничего не изменится на нодах) или же ставить chef-client как демон (для тестирования мы эту возможность отключаем). А как я писал, никто не запрещает делать эту команду, ограничивая env для роли :)
+1
Не соглашусь с вами. Точнее даже не так: у вас конкретный подход, когда chef-client выключен.
Тогда всё просто: речь идёт о явном запуске и переконфигурации. В большинстве случаев chef-client постоянно крутится на сервере и следит за состоянием серверов. Особенно в клауде.
Добавились 3-4 бэканда — балансер уже «знает» об этом и перенастраивается (без явного вызова chef-client). Именно в таких случаях опасно менять глобальные роли/рецепты и т.д.
Если у вас по 10 серверов на окружение и вы толкнули роль, вероятно, через 3-5 минут 2-3 сервера уже будут перенастроены. Подход выше позволяет контролировать этот процесс и тестировать сначала на отдельных окружениях.
Такая же ситуация и с рецептами: обновил cookbook и везде, где его версия строго не была зафиксирована, он обновится (и что-нибудь сломает).
Кстати, в вашем же случае отключение chef-client как демон — не спасение! Это просто надежда, что «вот пока я буду разрабатывать/тетсить/исправлять баг» никто не додумается запустить chef-client на проде.
PS. В примере выше через knife ssh запускалась команда tail, а не chef-client. Сам по себе knife ssh не запускает реконфигурацию.
Тогда всё просто: речь идёт о явном запуске и переконфигурации. В большинстве случаев chef-client постоянно крутится на сервере и следит за состоянием серверов. Особенно в клауде.
Добавились 3-4 бэканда — балансер уже «знает» об этом и перенастраивается (без явного вызова chef-client). Именно в таких случаях опасно менять глобальные роли/рецепты и т.д.
Если у вас по 10 серверов на окружение и вы толкнули роль, вероятно, через 3-5 минут 2-3 сервера уже будут перенастроены. Подход выше позволяет контролировать этот процесс и тестировать сначала на отдельных окружениях.
Такая же ситуация и с рецептами: обновил cookbook и везде, где его версия строго не была зафиксирована, он обновится (и что-нибудь сломает).
Кстати, в вашем же случае отключение chef-client как демон — не спасение! Это просто надежда, что «вот пока я буду разрабатывать/тетсить/исправлять баг» никто не додумается запустить chef-client на проде.
PS. В примере выше через knife ssh запускалась команда tail, а не chef-client. Сам по себе knife ssh не запускает реконфигурацию.
+3
В данном коментарии я написал как вообще делается подход разработки или изменения кухни.
Укажите версии в env.
Поэтому сначала это и делается на dev (тоесть локальной машине). Я против тестирования вообще на живую на реальном сервере. На сервер заливается уже готовый результат.
B по логам той команды четко видно, что chef-client демонизирован на проверку каждые 5 минут :) и данная команда через knife ssh запускает (была указана в этом коментарии):
Такая же ситуация и с рецептами: обновил cookbook и везде, где его версия строго не была зафиксирована, он обновится (и что-нибудь сломает).
Укажите версии в env.
Кстати, в вашем же случае отключение chef-client как демон — не спасение! Это просто надежда, что «вот пока я буду разрабатывать/тетсить/исправлять баг» никто не додумается запустить chef-client на проде.
Поэтому сначала это и делается на dev (тоесть локальной машине). Я против тестирования вообще на живую на реальном сервере. На сервер заливается уже готовый результат.
PS. В примере выше через knife ssh запускалась команда tail, а не chef-client. Сам по себе knife ssh не запускает реконфигурацию.
B по логам той команды четко видно, что chef-client демонизирован на проверку каждые 5 минут :) и данная команда через knife ssh запускает (была указана в этом коментарии):
knife ssh -E dev ‘role:webapp’ ‘sudo chef-client'
+1
Локальное окружение и dev — обычно разные вещи. А если у вас не так, то значит у вас небольшое количество серверов и участников разработки кукбуков, поэтому вы можете себе позволить запускать клента руками и раскидывать конфигурацию по нескольким сущностям.
Если ещё berkshelf использовать, то указание версий в Chef Environments тоже не будет удобным.
Если ещё berkshelf использовать, то указание версий в Chef Environments тоже не будет удобным.
0
У нас до 100 машин на один Chef Server (у каждого проекта свой сервер, на самом большом проекте уже больше 100, но точное число глянуть не могу — нет доступа). На текущем пока только 24 машины. Не много, но есть и berkshelf, vagrant, chef-zero, fauxhai, chefspec, test-kitchen — развернуть одну ноду на основе кукбуков, ролей и прочего делается на локальной машине (что мы называем development environment) при разработке с покрытием тестами (например меняем ноду роли веб). Далее выкатываем на стейджинг — staging environment (через env и env_run_lists). Если вдруг сломался (риск минимизирован через тесты) — откатываем, чиним, и опять в бой. При успехе раскидывам как нужно по ролям и env, заливаем в мастер ветку и загружаем в сервер. Процес не быстрый, но пока ни одного сбоя (хоть за последнее время все работы сводятся к поддержки кукбуков и софта на нодах «up to date» ).
Указываем только особо важные кукбуки (или перед тестированием на staging, если просто обновляем вендорные кукбуки).
Вы правы. В моем понимании dev (development environment) — это там, где ведется разработка и первичное тестирование — его машина (ноутбук).
Если ещё berkshelf использовать, то указание версий в Chef Environments тоже не будет удобным.
Указываем только особо важные кукбуки (или перед тестированием на staging, если просто обновляем вендорные кукбуки).
Локальное окружение и dev — обычно разные вещи.
Вы правы. В моем понимании dev (development environment) — это там, где ведется разработка и первичное тестирование — его машина (ноутбук).
+1
Укажите версии в env.
Именно это и имел в виду, когда говорил:
где его версия строго не была зафиксирована
Поэтому сначала это и делается на dev (тоесть локальной машине)
Не всегда можно воспроизвести всё на локальной машине. Более того, может быть чёткое требование: на PROD1 делай так, а на PROD2 по-другому.
А так, да — сам пытаюсь всё локально проверять и тестить перед отправкой. И все версии зафиксированы строго. Сначала думал, что будет очень тяжело поддерживать все версии. На практике оказалось это очень редкое занятие и отнимает буквально пару минут. Зато не раз спало в сложных ситуациях.
Вот ещё никак руки не дойдут потыкать палочкой vagrant-lxc для поднятия более сложных вещей с меньшими ресурсами…
+1
> Если изменить роль, то она применится для всех энвов — об этом и речь в статье.
Не надо просто держать все энвы на одном шеф-сервере.
Не надо просто держать все энвы на одном шеф-сервере.
+2
Да, есть такой подход. Свои плюсы и минусы.
Минус: дополнительные расходы на содержание одного сервера.
Плюсы: всё достаточно изолировано, можно ограничивать права разработчиков и не пускать их на прод, оставляя полные права на dev/qa/staging.
Очень хорошо, что вы об этом упомянули.
Минус: дополнительные расходы на содержание одного сервера.
Плюсы: всё достаточно изолировано, можно ограничивать права разработчиков и не пускать их на прод, оставляя полные права на dev/qa/staging.
Очень хорошо, что вы об этом упомянули.
+1
Не нужно так категорично заявлять.
Вы деньги считать умеете? Заказчик — точно. И если окружение не очень большое, то будет использоваться один сервер. Также, возможен вариант, когда окружения не изолированны полностью и нужно, чтобы Chef сервер знал о них все.
Вы деньги считать умеете? Заказчик — точно. И если окружение не очень большое, то будет использоваться один сервер. Также, возможен вариант, когда окружения не изолированны полностью и нужно, чтобы Chef сервер знал о них все.
0
> Вы деньги считать умеете? Заказчик — точно. И если окружение не очень большое, то будет использоваться один сервер.
Отдельный шеф-сервер не то же самое, что отдельный физический сервер.
Отдельный шеф-сервер не то же самое, что отдельный физический сервер.
+1
А вы занете из каких (и из скольки) отдельных компонентов состоит Chef-server? И каждый из них потребляет реурсы. И не так-то просто их будет впихнуть в один сервер.
0
Разумеется, знаю. А также я знаю то, что можно настроить несколько шеф-серверов на использование одного и того же postgres-а, rabbitmq и bookshelf-а, а также подкрутить настройки jvm solr-ов, если окружения небольшие.
+1
Это реальный опыт или теоретические изыскания? Я понимаю, что это возможно, но сколько времени понадобится, чтобы заставить несколько Chef-серверов работать на одной ноде?
0
> сколько времени понадобится, чтобы заставить несколько Chef-серверов работать на одной ноде
Пара часов, если все впервые руками делать.
Пара часов, если все впервые руками делать.
0
Вы сами это делали?
Ещё один момент: каждая копия будет потреблять ресурсы, т.е. все равно нужны пропорциональные мощности. И я не думаю, что держать отдельный Chef-сервер для окружения из двух срверов — это правильно.
Ещё один момент: каждая копия будет потреблять ресурсы, т.е. все равно нужны пропорциональные мощности. И я не думаю, что держать отдельный Chef-сервер для окружения из двух срверов — это правильно.
0
>Вы сами это делали?
Да.
>Ещё один момент: каждая копия будет потреблять ресурсы, т.е. все равно нужны пропорциональные мощности.
Если вы беспокоитесь за ресурсы, которые могут потребить демоны, то на дополнительный шеф-сервер (erchef, webui, solr) уйдет 300 мегабайт (bookshelf, postgres, rabbitmq общие). И это если не урезать память jvm solr-а, которому для пары серверов dev окружения явно потребуется ее меньше, чем для продакшена.
>И я не думаю, что держать отдельный Chef-сервер для окружения из двух срверов — это правильно.
Почему, кроме экономии полугигабайта памяти?
Да.
>Ещё один момент: каждая копия будет потреблять ресурсы, т.е. все равно нужны пропорциональные мощности.
Если вы беспокоитесь за ресурсы, которые могут потребить демоны, то на дополнительный шеф-сервер (erchef, webui, solr) уйдет 300 мегабайт (bookshelf, postgres, rabbitmq общие). И это если не урезать память jvm solr-а, которому для пары серверов dev окружения явно потребуется ее меньше, чем для продакшена.
>И я не думаю, что держать отдельный Chef-сервер для окружения из двух срверов — это правильно.
Почему, кроме экономии полугигабайта памяти?
0
Дополнительные рецепты также могут быть включены, но тогда это правильнее называть application cookbook (прим. переводчика).
С моей точки зрения wrapper-cookbook не перестает быть wrapper'ом при расширении, например Jetty-cookbook не умеет ставить Jetty9 если мы в своей обертке добавим эту возможность, разве он станет при таком подходе App-cookbook'ом?
+2
Видел статьи epam о puppet, как считаете, где usecase для puppet а где для chef?
+1
Трудно разделить их объективно. Оба инструмента позволяют готовить инфраструктуру, автомтизировать любые задачи. Лично для меня, был путь Chef -> Puppet. После Chef-а Puppet кажется более бедным и не таким гибким по функционалу. Но это лишь мое личное мнение. Ещё Chef может предоставлятся как сервис (Enterprise Chef), так что начать его использовать легче.
0
Спасибо за ответ, интересно почитать Ваше мнение. Мое мнение, если хотите, что puppet не чуть не уступает chef, т.к. весь функционал написан на том же ruby, с дополнением приятного DSL для людей, которые не хотят вникать в то, что конкретно puppet делает для достижения цели, а хотят сфокусироваться на самой конфигурации и конечном состоянии инфраструктуры (ИМХО, конечно:). Проверено на .net девелоперах, которые уже сами создают свои манифесты и конфигурируют IIS хосты при помощи puppet — для них это как INI файл =)
+1
Лично пока с puppet не работал, но мой друг столкнулся с проблемой организации циклов, которые DSL не поддерживает (во всяком случае я такое от него услышал год назад). И ему пришлось сильно постараться.
Всё-таки puppet основан на DSL, который явно ограничен по сравнению с plain ruby. А сам по себе язык ruby имеет довольно приятный синтаксис.
Но, давайте не будем сравнивать тёплое с мягким, а остановимся на более конкретных вещах.
В последнее время, что в сообществе Chef, что в Puppet (да и других) очень часто тиражируют бесполезные «красивые» примеры применения в стиле «как поставить apache + wordpress» или «добавить юзера в mysql».
Очень не хватает реальных задач, который имеют свои особенности и не являются такими тривиальными. Вот тут-то и начинается самое интересное.
Вот, например, какую мне пришлось решить:
Установить и настроить mongodb cluster с возможностью объединения нод в реплики (replicaset) и добавлением этих реплик или просто нод как shard в общий кластер. При этом нужно уметь:
* держать на одном сервере несколько демонов: config db, mongo router и какой-нибудь mongod инстанс; или MongoDB Arbiter для ReplicaSet1 вместе с Mongod для ReplicaSet2
* Добавлять на лету ноды в реплику, реплики/шарды в кластер
* Иметь возможность дополнительно настраивать реплики (rs.conf())
Вот такая вот интересная задачка. Можно подумать как её решить с использованием Chef, а как с использованием Puppet.
Как только задачи перестаёт быть сферической в вакууме, сразу станет понятнее, что лучше использовать.
В интернете можно найти несколько cookbooks для MongoDB, но есть впечатление, что авторы не читали документацию вообще. И сколько бы там всего заявлено не было, хорошо, если этот cookbook сможет поднять примитивный кластер или реплику.
Всё-таки puppet основан на DSL, который явно ограничен по сравнению с plain ruby. А сам по себе язык ruby имеет довольно приятный синтаксис.
Но, давайте не будем сравнивать тёплое с мягким, а остановимся на более конкретных вещах.
В последнее время, что в сообществе Chef, что в Puppet (да и других) очень часто тиражируют бесполезные «красивые» примеры применения в стиле «как поставить apache + wordpress» или «добавить юзера в mysql».
Очень не хватает реальных задач, который имеют свои особенности и не являются такими тривиальными. Вот тут-то и начинается самое интересное.
Вот, например, какую мне пришлось решить:
Установить и настроить mongodb cluster с возможностью объединения нод в реплики (replicaset) и добавлением этих реплик или просто нод как shard в общий кластер. При этом нужно уметь:
* держать на одном сервере несколько демонов: config db, mongo router и какой-нибудь mongod инстанс; или MongoDB Arbiter для ReplicaSet1 вместе с Mongod для ReplicaSet2
* Добавлять на лету ноды в реплику, реплики/шарды в кластер
* Иметь возможность дополнительно настраивать реплики (rs.conf())
Вот такая вот интересная задачка. Можно подумать как её решить с использованием Chef, а как с использованием Puppet.
Как только задачи перестаёт быть сферической в вакууме, сразу станет понятнее, что лучше использовать.
В интернете можно найти несколько cookbooks для MongoDB, но есть впечатление, что авторы не читали документацию вообще. И сколько бы там всего заявлено не было, хорошо, если этот cookbook сможет поднять примитивный кластер или реплику.
+1
Оооочень разумный комментарий — Спасибо!
По поводу «красивых» примеров — да, Вы отчасти правы. Но все преимущество puppet в том, что весь heavy-lifting прячется в коде модуля, который написан на ruby, и очень часто конечными точками, с которыми работают девелоперы/админы являются манифесты на puppet DSL, где обычно задаются параметры ресурса. Поэтому такой ресурс вполне имеет смысл.
Вот идеальный вариант (mock code):
А сам модуль уже позаботится о том, чтобы все встало куда нужно (вот он и heavy-lifting) — как раз там будут все циклы и условия.
Сейчас я делаю всю конфигурацию вручную (не так часто поднимаются новые кластеры). Но каждый раз когда я читаю (свою же) документацию — это огромная головная боль не ошибиться в портах, так-как у меня на одном сервере 3 конфиг ноды от другого шарда, mongos, arbiter и 3 дата-ноды :)
Посмотрел на существующие решения и на мой первый взгляд установка всех компонентов на сервер при помощью puppet достаточно тривиальная задача (есть puppetlabs/mongodb и echocat/puppet-mongodb).
Основная сложность в синхронизации нод между собой, сейчас мы используем foreman, и для выполнения этой задачи, возможно, потребуется использовать node.pp (как в примере выше) с описанием всех нод разом — удобнее портировать в облако или на другой новый кластер, к примеру.
Также описание кластера в виде конфигурации puppet явно поможет улучшить понимание кластера другими разработчиками.
Как только появится задача по поднятия еще одного кластера (думаю достаточно скоро) — зафиксирую все в puppet, обещаю :)
По поводу «красивых» примеров — да, Вы отчасти правы. Но все преимущество puppet в том, что весь heavy-lifting прячется в коде модуля, который написан на ruby, и очень часто конечными точками, с которыми работают девелоперы/админы являются манифесты на puppet DSL, где обычно задаются параметры ресурса. Поэтому такой ресурс вполне имеет смысл.
Вот идеальный вариант (mock code):
node "mongo-1a" {
mongo_node {"data_27001":
type => "awesome_cluster_type" #Я - часть кластера awesome_cluster_type
shard => sh_1, #Я - часть шарда sh_1
rs => rs_1, #Я часть репликасет rs_1_sh1
}
mongo_node {"data_27002":
type => "awesome_cluster_type" #Я - часть кластера awesome_cluster_type
shard => sh_1, #Я - часть шарда sh_2
rs => rs_1, #Я часть репликасет rs_1_sh2
}
}
node "mongo-1b" {
mongo_node {"data_27001":
type => "awesome_cluster_type" #Я - часть кластера awesome_cluster_type
shard => sh_1, #Я - часть шарда sh_1
rs => rs_1, #Я часть репликасет rs_1_sh1
}
mongo_node {"data_27002":
type => "awesome_cluster_type" #Я - часть кластера awesome_cluster_type
shard => sh_1, #Я - часть шарда sh_2
rs => rs_1, #Я часть репликасет rs_1_sh2
}
}
node "mongo-2a" {
mongo_node {"data_27001":
type => "awesome_cluster_type" #Я - часть кластера awesome_cluster_type
shard => sh_1, #Я - часть шарда sh_1
rs => rs_1, #Я часть репликасет rs_2_sh1
}
mongo_node {"data_27002":
type => "awesome_cluster_type" #Я - часть кластера awesome_cluster_type
shard => sh_1, #Я - часть шарда sh_2
rs => rs_1, #Я часть репликасет rs_2_sh2
}
}
node "mongo-2b" {
mongo_node {"data_27001":
type => "awesome_cluster_type" #Я - часть кластера awesome_cluster_type
shard => sh_1, #Я - часть шарда sh_1
rs => rs_1, #Я часть репликасет rs_2_sh1
}
mongo_node {"data_27002":
type => "awesome_cluster_type" #Я - часть кластера awesome_cluster_type
shard => sh_1, #Я - часть шарда sh_2
rs => rs_1, #Я часть репликасет rs_2_sh2
}
}
А сам модуль уже позаботится о том, чтобы все встало куда нужно (вот он и heavy-lifting) — как раз там будут все циклы и условия.
Сейчас я делаю всю конфигурацию вручную (не так часто поднимаются новые кластеры). Но каждый раз когда я читаю (свою же) документацию — это огромная головная боль не ошибиться в портах, так-как у меня на одном сервере 3 конфиг ноды от другого шарда, mongos, arbiter и 3 дата-ноды :)
Посмотрел на существующие решения и на мой первый взгляд установка всех компонентов на сервер при помощью puppet достаточно тривиальная задача (есть puppetlabs/mongodb и echocat/puppet-mongodb).
Основная сложность в синхронизации нод между собой, сейчас мы используем foreman, и для выполнения этой задачи, возможно, потребуется использовать node.pp (как в примере выше) с описанием всех нод разом — удобнее портировать в облако или на другой новый кластер, к примеру.
Также описание кластера в виде конфигурации puppet явно поможет улучшить понимание кластера другими разработчиками.
Как только появится задача по поднятия еще одного кластера (думаю достаточно скоро) — зафиксирую все в puppet, обещаю :)
0
Допустил пару ошибок, вот что в идеале имелось в виду:
node "mongo-1a" {
mongo_node {"data_27001":
type => "awesome_cluster_type" #Я из awesome_cluster_type
shard => sh_1, #Я - часть шарда sh_1
rs => rs_1_sh1, #Я часть репликасет rs_1_sh1
}
mongo_node {"data_27002":
type => "awesome_cluster_type"
shard => sh_2,
rs => rs_1_sh2,
}
}
node "mongo-1b" {
mongo_node {"data_27001":
type => "awesome_cluster_type"
shard => sh_1,
rs => rs_1_sh1,
}
mongo_node {"data_27002":
type => "awesome_cluster_type"
shard => sh_2,
rs => rs_1_sh2,
}
}
node "mongo-2a" {
mongo_node {"data_27001":
type => "awesome_cluster_type"
shard => sh_1,
rs => rs_2_sh1,
}
mongo_node {"data_27002":
type => "awesome_cluster_type"
shard => sh_2,
rs => rs_2_sh2,
}
}
node "mongo-2b" {
mongo_node {"data_27001":
type => "awesome_cluster_type"
shard => sh_1,
rs => rs_2_sh1,
}
mongo_node {"data_27002":
type => "awesome_cluster_type"
shard => sh_2,
rs => rs_2_sh2,
}
}
0
А что будете делать, если в монго-реплике будет количество нод меняться, например при авто-масштабировании?
0
Количество нод в реплике есть смысл увеличивать только когда нужно много read либо redundancy, чаще проще масштабировать «в ширь» и добавлять шарды, что увеличит не только read но и write производительность, это если я правильно Вас понял.
Но основной вопрос не в этом, о каком способе авто-масштабировании идет речь? Из программного кода? На виртуальные инстансы? Если да, то это будет чуть сложнее, но не на много: нужно интегрироваться с foreman или puppet dashboard, используя их api проделывать тоже самое, устанавливая соответствующие параметры для ресурса mongo_node. Но когда есть настоящее авто-масштабирование, например на EC2, это не должно быть проблемой поднять ноду с нуля.
Я правильно понял вопрос?
Но основной вопрос не в этом, о каком способе авто-масштабировании идет речь? Из программного кода? На виртуальные инстансы? Если да, то это будет чуть сложнее, но не на много: нужно интегрироваться с foreman или puppet dashboard, используя их api проделывать тоже самое, устанавливая соответствующие параметры для ресурса mongo_node. Но когда есть настоящее авто-масштабирование, например на EC2, это не должно быть проблемой поднять ноду с нуля.
Я правильно понял вопрос?
+1
Да. Вы правильно поняли. Я как раз и ожидал примерно такого ответа. Если точнее, то речь не только о EC2 auto scaling, а о любом кластере и автоматическом добавлении/удалении нод. В Puppet приходится изобретать велосипед, в то время к в Chef есть унифицированное API. Это, на мой взгляд, главное отличие.
Вот пример из community cookbook
Таким простым способом получаем список нод, которые объединяются в кластер. При добавлении/удалении ноды изменится и результат поиска и кластер автоматически перенастраивается.
Вот пример из community cookbook
elasticsearch
:seeds = search(:node, "elasticsearch_cluster_name:#{node[:elasticsearch][:cluster_name]} AND elasticsearch_seed:true").sort_by { |n| n.name }.collect {|n| n["ipaddress"]}
node[:elasticsearch][:seeds] = seeds
Таким простым способом получаем список нод, которые объединяются в кластер. При добавлении/удалении ноды изменится и результат поиска и кластер автоматически перенастраивается.
0
Это явно проще, но в puppet, как оказалось такое можно сделать при помощи puppetdb и puppetdbquery.
Кстати, где chef хранит информацию о текущем состоянии той или иной конфигурации?
Кстати, где chef хранит информацию о текущем состоянии той или иной конфигурации?
+1
docs.opscode.com/chef_overview_server.html
Переделанная документация шефа сейчас ОЧЕНЬ качественная.
Огромное уважение разработчикам.
Переделанная документация шефа сейчас ОЧЕНЬ качественная.
Огромное уважение разработчикам.
+1
Тут вы по сути описали волшебную кнопку, которую надо нажать. А речь шла скорее про то, на сколько тяжело эту самую кнопку сделать. с таким же успехом я бы мог ответить на свой вопрос так:
Дополню этот вопрос:
Как вы добавите шард в кластер, даже если кол-во нод не будет меняться? Как вы настроите реплику?
node.set['mongodb']['install'] = true
node.set['mongodb']['build_me_really_cool_cluster'] = true
node.set['mongodb']['with'] = [ :shards, :replicas, :routers]
node.set['mongodb']['configure_it'] = :immediately
include_recipe "mongodb::fix_all_errors"
Дополню этот вопрос:
Как вы добавите шард в кластер, даже если кол-во нод не будет меняться? Как вы настроите реплику?
+1
Было бы здорово, если существовала такая волшебная кнопка! :) Сейчас у меня не существует решения, т.к. практически задачи не стоит, но если говорить на словах, то выходит следующее:
Ресурс mongo_node, который я описал — верхушка айсберга. За ним — стоит ruby code и другие классы puppet. Но это был всего лишь пример, глянул глубже, вот пример который лежит по второй ссылке, который я присылал в одном из комментариев выше:
Здесь создается базовый тип сервера монго при помощи inherits mongo_sharding_default наследуем эти параметры на нужные хосты, а далее дополнительно ставим на те же хосты конфиг ноды.
На 4й сервер ни mongos ни конфиги не ставятся.
Я это не проверял, но по мне вполне удовлетворительная конфигурация.
Как добавлять шард в кластер — добавляем в базовое описание:
Я ни разу не использовал chef, поэтому ни в коем случае не холиварю здесь. Знаю о нем только по-наслышке и из недостатков лично для меня вижу (если это не так, буду рад услышать опровержение):
— Puppet декларативный, мне проще думать о конечном состоянии сервера а не о пути к нему, когда я внедряю новый конфиг — девелоперы не запариваются о том, в каком состоянии сейчас находится сервер. Отсюда другой подход, в том числе на первый взгляд бедном DSL. Если рассматривать DSL как «умный» .ini или .conf файл, тогда все встает на свои места и heavy lifting делается в самом провайдере, а не в манифесте, что увеличивает читабельность кода.
Типичное сравнение:
— Уровень абстракции «ресурс» позволяет мыслить на этом уровне, забывая местами о типе операционной системы, что очень удобно и позволяет сильно унифицировать код для инфраструктуры-зооопарка (У меня Windows + CentOS + Ubuntu) — в chef это тоже поддерживается и тот же пример со службой сработает, но для меня концепт «продвинутого конфигурационного» выглядит удобнее чем «инструкции к применению», но опять же это все очень субъективно. На сайте puppet labs этот DSL называют «Человеческий интерфейс» :)
Так, вот, говоря о конфигурации mongo кластера — я буду уверен в результате, если скажу «Должно быть вот так», вместо «Нужно сделать последовательность действий» (а какой результат Вы хотели)?..
Все остальное очень схоже, и особенно сравнивать технологии смысла нет =)
Все это ИМХО человека, который почти 3 года пишет инфраструктуру на puppet и не пробовал, но слышал об особенностях chef.
Ресурс mongo_node, который я описал — верхушка айсберга. За ним — стоит ruby code и другие классы puppet. Но это был всего лишь пример, глянул глубже, вот пример который лежит по второй ссылке, который я присылал в одном из комментариев выше:
node mongo_sharding_default {
# Install MongoDB
include mongodb
# Install the MongoDB shard server
mongodb::mongod {'mongod_Shard1': mongod_instance => "Shard1", mongod_port => '27019', mongod_replSet => "Shard1", mongod_shardsvr => 'true' }
mongodb::mongod {'mongod_Shard2': mongod_instance => "Shard2", mongod_port => '27020', mongod_replSet => "Shard2", mongod_shardsvr => 'true' }
mongodb::mongod {'mongod_Shard3': mongod_instance => "Shard3", mongod_port => '27021', mongod_replSet => "Shard3", mongod_shardsvr => 'true' }
mongodb::mongod {'mongod_Shard4': mongod_instance => "Shard4", mongod_port => '27022', mongod_replSet => "Shard4", mongod_shardsvr => 'true' }
# Install the MongoDB Loadbalancer server
mongodb::mongos {
'mongos_profile':
mongos_instance => 'mongoproxy',
mongos_port => 27017,
mongos_configServers => 'mongo1.my.domain:27018,mongo2.my.domain:27018,mongo3.my.domain:27018'
}
}
node 'mongo1.my.domain',
'mongo2.my.domain',
'mongo3.my.domain' inherits mongo_sharding_default {
# Install the MongoDB config server
include mongodb
mongodb::mongod {
'mongod_config':
mongod_instance => 'profileConfig',
mongod_port => '27018',
mongod_replSet => '',
mongod_configsvr => 'true'
}
}
node 'mongo4.my.domain' inherits mongo_sharding_default { }
Здесь создается базовый тип сервера монго при помощи inherits mongo_sharding_default наследуем эти параметры на нужные хосты, а далее дополнительно ставим на те же хосты конфиг ноды.
На 4й сервер ни mongos ни конфиги не ставятся.
Я это не проверял, но по мне вполне удовлетворительная конфигурация.
Как вы добавите шард в кластер, даже если кол-во нод не будет меняться? Как вы настроите реплику?
Как добавлять шард в кластер — добавляем в базовое описание:
mongodb::mongod {'mongod_Shard5': mongod_instance => "Shard5", mongod_port => '27023', mongod_replSet => "Shard5", mongod_shardsvr => 'true' }
Я ни разу не использовал chef, поэтому ни в коем случае не холиварю здесь. Знаю о нем только по-наслышке и из недостатков лично для меня вижу (если это не так, буду рад услышать опровержение):
— Puppet декларативный, мне проще думать о конечном состоянии сервера а не о пути к нему, когда я внедряю новый конфиг — девелоперы не запариваются о том, в каком состоянии сейчас находится сервер. Отсюда другой подход, в том числе на первый взгляд бедном DSL. Если рассматривать DSL как «умный» .ini или .conf файл, тогда все встает на свои места и heavy lifting делается в самом провайдере, а не в манифесте, что увеличивает читабельность кода.
Типичное сравнение:
service "example_service" do
action :start
end
и
service {"example_service":
ensure => running,
}
— Уровень абстракции «ресурс» позволяет мыслить на этом уровне, забывая местами о типе операционной системы, что очень удобно и позволяет сильно унифицировать код для инфраструктуры-зооопарка (У меня Windows + CentOS + Ubuntu) — в chef это тоже поддерживается и тот же пример со службой сработает, но для меня концепт «продвинутого конфигурационного» выглядит удобнее чем «инструкции к применению», но опять же это все очень субъективно. На сайте puppet labs этот DSL называют «Человеческий интерфейс» :)
Так, вот, говоря о конфигурации mongo кластера — я буду уверен в результате, если скажу «Должно быть вот так», вместо «Нужно сделать последовательность действий» (а какой результат Вы хотели)?..
Все остальное очень схоже, и особенно сравнивать технологии смысла нет =)
Все это ИМХО человека, который почти 3 года пишет инфраструктуру на puppet и не пробовал, но слышал об особенностях chef.
+1
В примере выше — у вас хардкод, в частности — хардкод хостов, например, список где конфиг-сервера стоят.
+1
Недавно разговаривал с представителем opscode на конференции SCALE. Как Вы и указали ранее, из коробки все используют поиск, который решает проблему оркестрации (знать о текущем состоянии конфигурации кластера и действовать на основании этого).
Также узнал много нового из «первых уст», и как оказалось, в действительности в chef та же абстракция от уровня ос, и декларативная модель. А еще я узнал почему используется install («что сделать? — Установить.»), вместо puppetовского «installed» («как должно быть? — Установлено). Ходят слухи, что они такое сделали чтобы не казаться „слизанными“ с набирающего тогда обороты puppet.
В общем будет возможность — буду пробовать chef, а пока уже половина всей инфраструктуры описаны в puppet.
Кстати, chef теперь поддерживается в theforeman — рекомендую попробовать, хорошая штука.
Всем добра и ясных инфраструктур!
Также узнал много нового из «первых уст», и как оказалось, в действительности в chef та же абстракция от уровня ос, и декларативная модель. А еще я узнал почему используется install («что сделать? — Установить.»), вместо puppetовского «installed» («как должно быть? — Установлено). Ходят слухи, что они такое сделали чтобы не казаться „слизанными“ с набирающего тогда обороты puppet.
В общем будет возможность — буду пробовать chef, а пока уже половина всей инфраструктуры описаны в puppet.
Кстати, chef теперь поддерживается в theforeman — рекомендую попробовать, хорошая штука.
Всем добра и ясных инфраструктур!
0
Only those users with full accounts are able to leave comments. Log in, please.
Паттерны и антипаттерны Chef