Pull to refresh

Comments 32

Хороший пост. В работе на production используется Сhef (давний выбор, пока на нем и остаемся). Для личных целей рассматривал Ansible и Salt-ssh, остановился на первом варианте.
Интересно почитать мнения остальных, использует ли кто-нибудь salt-ssh или salt в masterless-mode на production. Будет круто, если расскажете про проблемы, с которыми сталкиваетесь.
Давно была мысль ознакомиться с Salt. Спасибо за статью!
Использую Ansible, как в личных целях, так и в production. Если есть опыт в других системах контроля конфигураций, будет интересно увидить сравнение сильных и слабых сторон.
P.S. На данный момент Ansible покрывает все мои задачи.

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


Если рассматривать configuration management с методом push over ssh, то здесь на текущий момент дефакто два лидера — Ansible и Saltstack.
Причем первенство с большим отрывом держит Ansible. У него вся документация, примеры и сценарии применения заточены под Push метод.


Фундаментальное отличие на мой взгляд одно. SaltStack использует Jinja и для шаблонов и для логики стейтов. Это значит что Jinja выполняется перед самим state. (Saltstack изначально ориентирован на Master-Slave режим работы, поэтому такое поведение рационально).
Эта особенность является одновременно и сильной и слабой стороной SaltStack.
Сильной, т.к. позволяет строить продвинутую логику.
Например, в цикле обработать несколько state и на их основе сгенерировать данные для другого state.
Допустим, у каждой роли есть свои настройки firewall. Jinja при запуске видит все эти роли и собирает итоговые переменные для роли фаервола. В результате получается довольно красиво и элегантно. Но, плата за сиё — избыточная сложность и, зачастую, меньшая прозрачность.
В ansible концептуально другой подход. "Только одни переменные, только в одном месте" ( variable-precedence-where-should-i-put-a-variable ).
Есть, конечно, хаки в духе hash_behaviour=merge, но они не рекомендуются к использованию.
С ansible проще начать. Больше сообщество и, как следствие, больше написанных ролей, которые можно повторно использовать.
Он лучше подходит для небольших энвайроментов. Мне очень нравится последовательное выполнение таска в сочетании с register.
Благодаря этому довольно просто реализуются развертывания в различных Cloud providers а также выкатавания апдейтов ПО: guide_rolling_upgrade.
Да и вообще это как старый добрый shell на стероидах.


Субьективно, нишевая область применения SaltStack это, всё таки, Master-Slave режим работы. А Salt-ssh — просто удобное дополнение к последнему, которое можно использовать и само по себе. Возможность же быстро переключаться между режимами работы — это тоже, однозначно, сильная сторона SaltStack.


Интересная, хоть и слегка устаревшая статья на эту тему: Moving away from Puppet: SaltStack or Ansible?


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

В отличие от Ansible, SaltStack использует Jinja2 как для обработки шаблонов, так и для построения логики.


Стоп-стоп.
Ansible в yml разметках тоже использует Jinja2. Я пишу все роли и шаблоны через него и работает же.

Он сначала собирает инфу о системе, потом генерит роли (или таски) и выполняет их. Или тут говорилось об этом в другом ключе?

Ansible в плейбуках использует свой собственный DSL (with\when\register\etc), а Jinja2 используется уже для templates.
Также, обработка циклов и условий осуществляется на уровне индивидуальных тасков.
Не сочтите за рекламу salt (в нем полно своих косяков), но эти различия довольно хорошо показаны по уже упомянутой ссылке.


SaltStack использует Jinja2 и для логики.
Причем, при желании там такого можно наворотить, что грустно становится....

Я использую salt достаточно давно на большом парке серверов (сейчас больше 6000 машин). Сперва использовался режим master-minion. Работало очень не надежно, подвисали и мастера и миньоны. Я перевел все на salt-ssh, стало работать лучше. Тем не менее у меня к salt много претензий:

1. У них явно есть проблемы с тестированием и сохранением обратной совместимости. Каждое обновление версии это боль. Сейчас мы используем 2015.8.7.
2. У нас salt в частности используется для конфигурирования pam. Недавно столкнулись с ситуацией, когда некоторые конфигурационные файлы pam на отдельных машинах оказались пустыми. Залогиниться невозможно, крон не работает. Повторяемо воспроизвести не получается. Начал диалог с ребятами из saltstack-а, но они ожидаемо помочь не смогли (потому что не смогли воспроизвести). Мое доверие к salt сильно подорвано.
3. Для работы salt на клиенте должен стоять python, у которого есть свои проблемы. В результате пришлось собирать python-2.7.10, ставить его в /opt вне всех путей, чтобы никому не мешал и хачить salt, чтобы использовал этот python.
4. Общее мнение людей, которые используют у нас salt — не удобно.

Все свои проекты и деплою через пакеты. Это позволяет и откатить быстро если что не так (в salt откат мягко говоря не прост, версионирования стейтов нет, chef в этом смысле много удобнее), и сделать dpkg-divert чтобы обновление другого пакета не испортило кастомный конфиг.

Когда будет время буду смотреть на ansible.
Немного могу сказать про ansible

3. Для его работы в большинстве случаев должен тоже стоять python. Без него работает только несколько команд, которые можно использовать для его установки.

Так же, можно попробовать pypy. Его не обязательно собирать, оно почти везде из под коробки работает.

Пример роли для ansible для установки pypy можно найти тут.
Еще к недостаткам salt-ssh можно отнести сложность отладки. Для того, чтобы понять, что пошло не так на клиенте надо прогнать salt-ssh с высоким уровнем логирования, вычленить команду для запуска salt на клиенте, залогиниться на клиента, выполнить команду предварительно отредактировав ее и добавив логирования.

У нас на порядок меньше хостов, но я с вами солидарен. Есть впечатление, что ребята из saltstack занимаются созданием фич, при этом обратная совместимость прихрамывает. Баги касательно salt-ssh у них также в очень низком приоритете.
Трудно сказать как дела обстоят с ansible, но есть предположение что получше. т.к. последний изначально проектировался под push метод работы и находится под крылом RedHat.
С python у меня лично не было проблем, кроме одного случая с багом в file.rescue, когда требовался python-msgpack. Но это довольно быстро починили.

я год ждал фикса касательно salt-ssh и mercurial, после чего пришлось разобраться самому и отправить пулреквесты)
в целом salt-ssh реализованы не все фишки (например с таргетингом по grains не все так просто) и основная часть работ ведётся по работе над фиксами в режиме minion

касательно недостатков: за 2 года часто что-то ломали после выхода новых патчей и стабильность отставляла желать лучшего, но в последних версиях этого года все вроде более-менее гладко
Насчет chef — здесь тоже не все хорошо. У нас он используется в виде solo, запускается по получению события после сборки пакета с приложением. То есть имитируется push (через serf). Беда в том, что исторически было принято использовать только один run_list для ноды — один конечный state, который настраивается путем переписи атрибутов в нескольких ролях. Все издержки атомарного деплоя приходится учитывать в конечном cookbook. Кстати в плане отката версии пакета мы сталкиваемся с той же проблемой что и вы. Я это обходил так: в data_bag указываю конкретную версию комита (в описании пакета хранится commit), chef поставит этот пакет и создаст правильные symlink'и. Ту же логику я мог бы реализовать на Ansible намного быстрее.

В конечном итоге поддерживать это становится также неудобно, и я все больше оглядываюсь в сторону Ansible. Того же мнения и некоторые коллеги.
похоже автор ещё не открыл для себя Saltfile =) использовать /etc/salt и /srv/salt не обязательно + это очень неудобно если у вас куча проектов, на много удобней хранить состояния в репозитории и просто настроить Saltfile
что-то вроде:
cat Saltfile 
salt-ssh:
  config_dir: ./salt/

Благодарствую, как-то пропустил его мимо и не пользовался! Пока мне хватло разных ростеров + разные pillar roots, file roots для разных проектов. Но Saltfile выглядит, действительно, удобнее.

вы наверно один на проекте, с Saltfile команде не обязательно знать что такое salt, достаточно их salt-ssh ключи добавить на сервер и рассказать что команду надо запускать из каталога где лежит Saltfile

я вот выкинул fabric и перешёл на такой подход

Есть определенные нюансы. Что сальт, что ансибл очень специфически работают с sudo, предполагая что пользователь не имеет ограничений (ака NOPASSWD: ALL) и в audit\securе логе начинает происходить эдакая вахканалия.
Для деплоймент-задачь в jenkins еще можно придумать обходов, но на счет доступа команде(админов) — пришлось отказаться от судо и добавить ssh ключи к root.
Благо, ключи логируются. Да и вообще проблема не нова.


К чему я веду — как бы считаю не совсем правильным давать доступ к системе управления конфигурациями тем, кто не понимает как оно работает, иначе таки очень просто отстрелить себе ногу:
salt-ssh host -r 'echo "rm -rf /"'


Про Saltfile — это, безусловно, удобно, но ведь всех проблем не решает. Есть же еще и пиллар данные… в которых чувствительную информацию хочется хранить безопасно.


И вы под командой кого имеете в виду? разработчиков в том числе?

Ок, у каждого свои потребности)
Да, имел в виду разрабов.

А с этого момента можно поподробней )
Как вы решаете проблему защиты от отстрела ноги? А также проблему чувствительных данных? Девелоперы к ним тоже имеют доступ и могут вносить изменения?
Еще интересно, у вас получается и стейты и пиллар хранятся в одном репозитории + Saltfile?
Также, реализовано ли как-то reuse стейтов между разными проектами?
Используются ли мульти-окружения (dev\stg\etc\prod) и к ним девелоперы имеют доступ?


Со своей стороны могу сказать, что для деплоймента применяю дженкинс. Т.е. при коммите в гит или при запуске job в jenkins, эта самая джоба собирает пакет(rpm\deb) и\или идет на нужный сервер(а) и деплоит его.
Но как и любая другая схема, всё это тоже имеет свои ограничения.

Да, самый корректный вариант — CI и деплой с него, но увы на последних проектах этого нет) посему все вручную и ничего интересного, по поводу доступа тоже особо не парюсь. но если очень захотеть. то можно salt.renderers.gpg использовать.

Еще интересно, у вас получается и стейты и пиллар хранятся в одном репозитории + Saltfile?
Используются ли мульти-окружения (dev\stg\etc\prod) и к ним девелоперы имеют доступ?

получается
tree salt/
salt/
├── master
├── roots
│   ├── pillar
│   │   ├── base.sls
│   │   ├── client-staging.sls
│   │   ├── git.sls
│   │   ├── nginx.sls
│   │   ├── packages.sls
│   │   ├── python.sls
│   │   ├── services.sls
│   │   ├── staging.sls
│   │   └── top.sls
│   └── salt
│   ├── backup.sls
│   ├── cron.sls
│   ├── django.sls
│   ├── files
│   │   ├── backup
│   │   │   └── aws_config
│   │   ├── crontab
│   │   ├── django
│   │   │   └── settings_production.py
│   │   ├── nginx
│   │   │   ├── htpasswd
│   │   │   └── nginx.conf
│   │   └── uwsgi
│   │   └── vassal.ini
│   ├── git.sls
│   ├── nginx.sls
│   ├── packages.sls
│   ├── postgresql.sls
│   ├── python.sls
│   ├── top.sls
│   └── uwsgi.sls
└── roster
➤ cat salt/master
file_roots:
base:
- ./salt/roots/salt

pillar_roots:
base:
- ./salt/roots/pillar

➤ cat Saltfile
salt-ssh:
config_dir: ./salt/

#roster
staging:
host: xxxxx
user: ubuntu
sudo: True
priv: ~/.ssh/id_rsa
minion_opts:
grains:
role: staging


С кастомными grains в salt-ssh не всё так просто, приходится ухищряться, grains: в ростере работает только в версиях 2016+:
➤ cat salt/roots/pillar/top.sls
base:
'*':
- base
- packages
- services
- python
- git
- nginx

'staging': # G@ не работает, хотя в свежих версиях не тестил
- match: list
- staging
...
➤ cat salt/roots/pillar/staging.sls
postgres: # например пеереопределяем не весь pillar, а только нужные поля, остальное все `наследуется` из базовых
version: 9.5



после чего в стейте добавляю в context `role` (это хак, но я не уверен что кастомный грейин исправвили в последних версиях salt-ssh, надо проверить):
{{ pillar.project.project_path }}/settings/local.py:
file.managed:
- source: salt://files/django/settings_production.py
- template: jinja
- user: ubuntu
- context:
role: {{ grains.role }}

ну и далее просто `{% if role=='staging' %}` в шаблонах или grains.role в стейтах
рекомендую глянуть http://www.saltstat.es/posts/meta/intermediate.html

Благодарю за развернутые детали. Тут наиболее интересно на мой взгляд это тесное взаимодействие с разработчиками, что они тоже применяют сальт и имеют к нему доступ. Однако, неясно как происходит повторное использование кода для другого проекта. Получается что стейты начинают жить в разных местах....


Касательно ролей, таргетинга и мульти-окружений, меня интересовало применительно к вашей структуре развертывания. Лично я же использую таргетинг по пиллар:


  'I@roles:sphinx_server or I@sphinx_server_role:true':
    - match: compound
    - sphinx

и мульти окружения, которые просто напросто имеют разные пиллар данные, которые назначаются через систему рендеринга pillar/top.sls, впрочем как и роли:


example_env:
  'example_hosts':
    - _roles/sphinx_server

_roles/sphinx_server.sls:


sphinx_server_role: true
include:
  - sphinx

Вообщемто по этому делу я собирался написать отдельную статью.


Сальт на мой взгляд вообще такой сумаcшедший конструктор, что я порой перестаю считать это достоинством. Функционала навернуто ооочень много.

я сам подумываю о переходе на ansible тк 90% ф-ционала мне не нужны) ну и всякие стейты например для django — устаревшие
по поводу реюза, можно всякие gitfs использовать для каких-то общих вещей, но пока с этим не игрался, а вот всякие https://github.com/saltstack-formulas меня не всегда устраивают
за таргетинг спс, проверю, я просто уже не помню где у меня костыль, а где корректное использование) к-во issue на гитхабе уже начинает пугать

можем продолжить дискуссию в jabber'e slav0nic@jabber.ru или на почте slav0nic0@gm…
я сам подумываю о переходе на ansible тк 90% ф-ционала мне не нужны) ну и всякие стейты например для django — устаревшие

как будто в ansible есть нормальные роли… Проблема в том, что сторонние роли либо некачественные, либо неполные. А сами вендоры каких-либо решений не очень хорошо знают ansible.
Плюсы salt-ssh:
1. быстрее, чем ansible
2. удобнее дорабатывать, чем chef/puppet (т.к. на python)
3. вывод более вербозный по умолчанию, чем ansible
4. работает стабильнее, чем ansible
5. не нужно переделывать state при миграции с server-minion на salt-ssh и наоборот (есть нюансы).
Можно попросить вас дать больше деталей по каждому пункту? Опыта работы с ansible у меня нет, но от людей вокруг слышал хорошие отзывы. Сейчас стал работать с puppet и не вижу особых сложностей с разработкой кастомных модулей но может у меня задачи простые?
1. blog.ryandlane.com/2014/08/04/moving-away-from-puppet-saltstack-or-ansible Детали по ссылке. Вообще ansible можно разогнать через pipelining и mitogen, но это такое себе решение.
2. chef и puppet на Ruby. Это уже является некоторым порогом для входа. К тому же, когда инфраструктура разрастается, то puppet поддерживать становится сложно. Именно из-за того, что он ориентирован на состояние, а зачастую нужно строить императивные цепочки действий. И тут начинается магия со stage. Есть еще косячки, связанные с ресурсами, которые могут изменяться разными манифестами (например, нужно менять sysctl под разные программы — clickhouse, elasticsearch, mysql и пр. — и все в рамках одного узла, возможно, конечно, стоит договориться, что один узел (одна ВМ) == одна функция, но не всегда это реализуемо). Также можете оценить сложность ролей/манифестов/формул для всех 4 SCM, например, по установке Prometheus: prometheus.io/docs/prometheus/latest/installation/#using-configuration-management-systems
3. без комментариев. Просто нужно смотреть глазами.
4. Если речь про ssh, то плюс/минус одинаково. Но в режиме master-minion обмен у salt идет по 0MQ, что весьма надежно и хорошо масштабируется. Дополнительно у меня были странности с ансибл. Вроде того, что он виснет на машине администратора. По каким-то неведомым причинам. Странно, но неприятно. С salt'ом таких неожиданностей не было, что в режиме master-minion, что salt-ssh (хотя допускаю, что может ломаться из-за кривого python на машине админа).
5. ansible работает только в одном режиме — push через ssh на удаленный сервер. Есть теоретически ansible-pull, но он делает то же самое, но в рамках локальной машины. И есть еще AWX/Tower, но это решение больше про централизацию запуска плейбуков и их объединение в цепочки, чем именно централизация по типу puppet/salt.

Если есть вопросы — задавайте, с радостью отвечу.
Дополнительно замечу, что очень обидно, что очень мало информации по SCM в целом на русском, и по Salt — в особенности. Хотя я знаю несколько крупных именно российских компаний, которые эту технологию используют весьма активно.
salt стал более стабильным, миграция на 2108.3.1 прошла практически безболезненно. Но с учетом всех предыдущих проблем в конфигурации мастер-миньон будем и дальше использовать salt-ssh. Благо удалось побороть все критичные для нас проблемы и добиться надежной работы.
У меня строгие сомнения в необходимости делать единого мастера на всю инфраструктуру. Выглядят разумными три варианта:
1. masterless от слова совсем. git'ы по проектам. Каждый сервер принадлежит какому-то проекту. Идет туда и забирает свою частичку конфигурации и применяет к себе
2. salt-ssh — централизованно разливаем изменения через процесс CI/CD. Каждый репозиторий привязывается к определенному множеству серверов.
3. каждый проект — отдельно. У каждого проекта свой репозиторий. И свой master. Если нужно объединить все вместе — используем syndic.

Сила salt'а именно в возможности оркестрации, т.е. выполнении каких-то определенных команд на множестве серверов (хотя бы, например, пропинговать их).

Теоретически в облачной среде тренд заключается в том, что нужно подготавливать базовые образы операционных систем со всем необходимым для запуска ВМ (тулинг есть — packer от HashiCorp). И версионировать их тоже. Но, к сожалению, у нас, во-первых, не настоящая облачная среда. А, во-вторых, это не снимает вопрос что же делать со stateful приложениями вроде баз данных — нужно как-то реализовывать вопрос вывода обновляемых нод из кластеров и сохранения данных в момент обновления ВМ из нового базового образа.
У меня было по 2 мастера (production и staging) на каждый датацентр. 2 гит репозитория: в одном конфигурация базовой инфраструктуры (днс, смтп, лдап итд), в другом разработчики держали конфигурации своих сервисов. Каждая ветка общего репозитория на мастере предсталена environment-ом. Базовый репозиторий — base environment. На каждом клиенте работал cron job, который утром дергал ближайший мастер, чтобы тот прогнал на этом клиенте базовые стейты. При этом все мастера равноправны, каждый может работать с любым клиентом. Но staging мастера работали из staging ветки базового репозитория, а production мастера соответственно из мастера. Изменения базового репозитория можно было обкатать на не production машинах и в случае каких-то проблем поправить их без обрушения production. Нагрузка распределялась по нескольким мастерам и в случае если какой-то мастер был недоступен клиент обращался к следующему из списка (в соседнем датацентре). К слову, проблем с перегрузкой мастеров я не видел. Физического сервера с 24 ядрами и 48Гб памяти было достаточно, чтобы накатить обновления на 5000 серверов за примерно 30 минут при условии что базовые стейты выполнялись примерно 2 минуты. Можно было увеличить параллелизм и ускорить процесс еще сильнее, но я решил не выжимать из мастеров все соки. Для разработчиков на мастерах был установлен самописный ограниченный шелл, который позволял им запускать только salt.

На мой взгляд оркестрация у salt весьма слабая, хотя может что-то изменилось в последних версиях, а я это пропустил.
Большое спасибо за развернутый ответ. Я с salt работал достаточно много, вот основные мои претензии:
habr.com/ru/post/303418/#comment_9659790
habr.com/ru/post/315012/#comment_9905944
В ближайшее время буду работать с puppet, но возможно предложу переключиться на что-то другое, если критическая масса недовольства у людей вокруг достигнет нужного уровня. Мой опыт работы с salt-ssh показывает, что очень удобно, когда на клиенте не надо устанавливать агента и все взаимодействие идет через ssh. В частности это сильно облегчает миграцию на следующие версии SCM. Насколько я знаю подобным требованиям на сегодняшний день удовлетворяют только ansible и salt-ssh. С учетом предыдущего не самого позитивного опыта работы с salt-ssh единственным кандидатом вижу ansible, но допускаю, что при более близком знакомстве столкнусь с сюрпризами.
В ближайшее время буду работать с puppet

Не рекомендую. Мне не понравилось. Жить можно… Но все прям очень не круто. Опять же повторюсь:
Также можете оценить сложность ролей/манифестов/формул для всех 4 SCM, например, по установке Prometheus: prometheus.io/docs/prometheus/latest/installation/#using-configuration-management-systems

Еще накину.
2. Нет версионности для стейтов. Внес изменения, выкатил их, захотел откатить — и вот тут начинаются танцы с саблями, штатных средств нет.

У паппета ЯКОБЫ версионность есть. Но фишка в том, что если Вы возьмете готовый модуль, который ставит софт XXX, а потом перекатитесь на версию модуля +1. Она Вам, например, не понравится, а потом Вы откатитесь на исходную версию модуля, то изменения модуля версии+1 не откатятся автоматически. Боль и унижение. Та же история с ансиблом.
Что еще хуже — если версия модуля из puppet forge Вам не очень подходит и требует кастомизации, то Вам придется ее вендорить к себе с вполне понятными последствиями для дальнейшей поддержки.

Ну, и если хотите более предметно поговорить про паппет — welcome в телеграм или скайп.
Переход на puppet связан со сменой работы. Так что особого выбора у меня нет, по крайней мере сейчас.

Огромное спасибо за предложение помощи, прямо сейчас вопросов у меня нет, но если что-то возникнет — безусловно спрошу совета. Как бы я хотел, чтобы кто-то мог мне помочь пока я разбирался с salt. Страшно подумать, сколько времени мне бы это сэкономило.
Sign up to leave a comment.

Articles

Change theme settings