Вступление

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

Это мое личное мнение основанное на десятке лет работы с различными системами конфигураций и двухлетнего периода миграции 200+ ролей с Ansible на SaltStack.

Сотни статей уже было написано про сравнение таких систем как Puppet, Chef, Ansible и SaltStack. У каждой из них есть своя ниша и серебряной пули не существует. Эта статья не ставит целью сделать очередное сравнение, которое устареет через ~6 месяцев. Мне скорее хочется показать вам несколько фундаментальных отличий между этими системами.

Статья рассчитана на людей уже знакомых с системами контроля версий и может быть сложна в понимании для тех кто с ними не работал.

Я буду стараться использовать английский язык в именах и названиях и русский язык для всего остального.

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

Я много работал с Puppet, Ansible и SaltStack, но сосредоточится я хочу на SaltStack как альтернативе для Ansible.

Главная причина для этого то что Ansible и SaltStack написаны на Python, когда Puppet и Chef написаны на Ruby. Язык инструмента казалось бы не должен иметь принципиального значения, но именно в этой сфере он очень важен.

Так же Ansible сейчас считается лидером рынка и на этот факт просто грустно смотреть.

Транспорт

Ключевым различием между Ansible и SaltStack является транспорт.

Ansible работает поверх протокола SSH и гордится этим.

Почему это важно?

Давайте посмотрим под капот коммуникации Ansible, для этого запустите ansible-playbook с аргументом -vvv в консоли вы увидите вот такие куски логики:

ssh -o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=600s -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/tmp/elasticsearch-salt-withmaster-current/ssh_key"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=centos -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null -o ControlMaster=auto -o ControlPersist=60s -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o ControlPath=/home/jenkins/.ansible/cp/%h-%p-%r 172.31.23.3 '/bin/sh -c '"'"'sudo -H -S -n -u root /bin/sh -c '"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-lpecwxhszeyfmvzzvfgbqaxgyctivtwe; PATH='"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:$PATH'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"' /usr/bin/env python'"'"'"'"'"'"'"'"' && sleep 0'"'"''
[CUT]
scp -o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=600s -o StrictHostKeyChecking=no -o Port=22 -o 'IdentityFile="/tmp/elasticsearch-salt-withmaster-current/ssh_key"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=behavox -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null -o ControlMaster=auto -o ControlPersist=60s -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o ControlPath=/home/jenkins/.ansible/cp/%h-%p-%r /ws/roles/common_user_env/files/screenrc '[172.31.18.215]:/opt/behavox/.ansible/tmp/ansible-tmp-1573069165.36-50102547946249/source'

"Во-первых это красиво!", точнее ужасно.

Во-вторых это очень медленно и неэффективно.

Ansible вынужден совершать множество операций на каждое действие, таких как:

  • Проверить ssh подключение и права

  • Собрать факты об удаленной системе, такие как информация об ОС, hardware, network и тд.

  • Скопировать Python модули и сопутствующие файлы

  • Выполнить Python модули и получить результат

  • Очистить временные файлы за собой

И так плюс-минус на каждую операцию. Маркетологи Ansible называют это "radically simple IT automation platform" так как он работает без специального транспорта и без удаленного агента, то есть готов к работе буквально сразу. И скорость работы - это цена за эту простоту.

Давайте теперь посмотрим на SaltStack.

Создатель SaltStack, Thomas S. Hatch, рассказывал что когда он решил написать свою систему для удаленного управления серверами он выбрал самое быстрое и эффективное что было на рынке для транспорта - ZeroMQ. Позже инженеры из Linkedin добавили возможность работы через raw tcp.

Скорость работы SaltStack была изначальной целью заложенной в дизайн приложения. Идея заключается в том что Salt Master общается с Salt Minions(далее Мастер и Миньены) через publish/subscribe модель, где мастер публикует задачу, а миньены принимают ее и асинхронно выполняют.

From Said van de Klundert blogpost
From Said van de Klundert blogpost

Это означает что Мастер отправляет одно сообщение в общую шину коммуникации вида "Миньены соответствующие определённым критериям - выполняйте вот такую-то логику". Например: "Миньены с именем начинающимся на fe-* - выполняйте formula.nginx"

Это очень легкое сообщение вида "одно-ко-многим". Миньены, которые постоянно слушают эту коммуникацию, забирают эту работу к себе, если они соответствуют указанным критериям, и начинают ее выполнять. Асинхронно. Мастер же зная что указанному критерию соответствовало например 100 миньенов переходит в режим ожидания ответа от этих 100 миньенов.

Даже если мастер в этот момент упадет - работа на миньенах все равно будет выполнена.

У асинхронной коммуникации есть свои плюсы и минусы, но в целом это архитектурное решение позволяет SaltStack масштабироваться до размеров Linkedin где на один мастер может обслуживать до 30000 миньенов.

DSL: Ansible

Ansible DSL прост и понятен. Его легко изучить за короткое время и достаточно просто читать.

Например здесь я создаю две директории используя встроенные возможности циклов и Jinja2 шаблонизации:

- name: 'Create directory {{ item }}'
  file:
    name: "/opt/behavox/{{ item }}"
    state: directory
    mode; "0755"
  loop:
    - myserviceA
    - myserviceB

DSL: SaltStack

SaltStack DSL это очень интересный зверь. Он целиком полагается на внешние способы шаблонизации.

У SaltStack есть такое понятие как Renders и по умолчанию SaltStack использует рендеры Jinja|Yaml - что это значит? Давайте рассмотрим вот этот пример:

{% for dir_name in ['myserviceA', 'myserviceB'] %}
formula.myservice.dir.{{ dir_name }}:
  file.directory:
    - name: /opt/behavox/{{ dir_name }}
    - mode: "0755"
    - makedirs: True
{% endfor %}

Вы можете видеть что у нас здесь Jinja2 шаблон под которым формируется yaml. SaltStack парсит этот файл используя указанные рендеры что бы получить рабочую структуру. В этом примере сначала отработает Jinja2 render и мы получили следующий yaml который и будет загружен.

  formula.myservice.dir.myserviceA:
    file.directory:
    - name: /opt/behavox/myserviceA
    - mode: '0755'
    - makedirs: true
  formula.myservice.dir.myserviceB:
    file.directory:
    - name: /opt/behavox/myserviceB
    - mode: '0755'
    - makedirs: true

Это пример стандартного подхода, который будет использоватся в 99% случаев по моему опыту. Но SaltStack позволяет делать гораздо больше. Если вы откроете ссылку на рендеры выше то вы заметите что SaltStack предлагает множество альтернативных вариантов.

Вы хотите хранить как DSL как GPG зашифрованные куски информации внутри которых лежат Mako шаблоны? Без проблем.

Если идти до конца то SaltStack предлагает py рендер и да это рендер на 100% Python.

Например вот как нем можно реализовать ту же логику создания двух директорий:

!#py

mkdir_common = {'file.directory': [
                  {'mode': '0755'},
                  {'makedirs': True}
                 ]
               }
def run(dir_name):
    config = {}
    for dir in ['myserviceA', 'myserviceB']:
        dirpath = '/opt/behavox/{}'.format(dir)
        config[dir] = mkdir_common
        config[dir]['file.directory'].append(dirpath)

return config

Это может показаться сверхусложнением и... это так и есть, но в одном случае из 1000 вы можете захотеть иметь под рукой всю силу ЯП что бы описать какую-нибудь сложную логику и SaltStack позволяет сделать это.

Оркестрация: Ansible

В большинстве случаев, работая с распределенными системами мы хотим выполнять операции в определенном порядке. Например поставить некие системные пакеты и запустить сервис на хостеА, дождаться пока сервис станет доступен и только потом запустить сервис на хостеБ, который зависит от сервиса на хостеА.

Это называется оркестрацией. Если вам это не нужно - вы счастливый человек.

Оркестрация это очень мощный инструмент и Ansible весьма хорошо ее поддерживает.

По умолчанию Ansible запускает каждую задачу последовательно(на одном или множестве хостов), ждет ее выполнения и только потом приступает к следующей.

Это очень медленно, но позволяет Ansible работать с данными полученными в реальном времени. Например:

  1. Запустить Mysql

  2. Загрузить в него некие данные

  3. Сделать в него запрос и сохранить ответ как переменную

  4. Использовать значение этой переменной в последующих задачах

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

Так же Ansible можно сказать выполнить определенную задачу только один раз даже если логика была нацелена на множество хостов.

Эти три возможности(сохранение данных в реальном времени, делегация исполнения и выполнение только один раз) позволяеют создавать очень сложные оркестрации способные покрыть множество сценариев.

Главный минус этих возможностей - это все происходит очень медленно из-за необходимости постоянной синхронизации выполнения с Ansible контролером и из-за изначально медленного протокола коммуникации.

Оркестрация: SaltStack

SaltStack так же позволяет запускать определённую логику на определенных хостах, но как только выполнение было начато вы уже никак не можете на него повлиять.

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

SaltStack просчитывает все наперед что позволяет работать быстрее, но теряет в гибкости. Зато оператор может получить граф исполнения до исполнения и сверится с тем что это именно то что он бы ожидал.

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

Разработка и отладка: Ansible

В Ansible вы можете модифицировать следующее:

  1. Execution modules

  2. Callback plugins

  3. Strategy plugins

  4. Inventory plugins

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

Это приемлемый список, но важно понимать что каждый пункт идет с огромным количеством ограничений, например Callback plugins может поменять как результат исполнения будет выглядет в вашем терминале, но только в рамках самой логики исполнения. Например вы не сможете убрать таймстампы перед вызовом вашей логики и тд.

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

Отладка в Ansible... спорная. Ansible пытается скрыть от оператора всю поднаготную и каждый модуль может вернуть вам только одно сообщение. Вы не можете использовать такие привычные вещи как логирование. Только один ответ за раз и потом вы получаете что-то вида:

fatal: [demo-rm -> localhost]: FAILED! => {"changed": false, "msg": "Failed to connect to Zabbix server: urllib2.URLError - "}

Ок.

Для отладки таких проблем вам придется делать следующее:

  1. Запустить проблемную логику снова(в надежде что ошибка повторится) но с:

    1. Специальными аргументами которые сообщают Ansible не удалять временные файлы.

    2. С увеличенным логированием (-vvv) что бы увидеть в какую временную директорию эти файлы были помещены.

  2. Зайти на удаленную систему где происходит ошибка

  3. Распаковать Ansible модуль

  4. Поправить его что бы он печатал необходимую информацию

  5. Запустить и наконец понять в чем была проблема

Каждый раз когда мне приходилось проделывать эту процедуру - часть меня умирала.

Разработка и отладка: SaltStack

Вот список вещей которые можно модифицировать в SaltStack:

  1. beacons

  2. clouds

  3. engines

  4. grains

  5. log_handlers

  6. matchers

  7. modules

  8. output

  9. proxymodules

  10. renderers

  11. returners

  12. sdb

  13. serializers

  14. states

  15. thorium

  16. utils

  17. pillar

Это впечатляет. По сути все что не транспорт - поддается горячей модификации.

И да output модули SaltStack позволяют нам скрывать бесполезную информацию и раскрывать в подробностях изменения и ошибки.

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

[behavox@test-run-kproskurin-rm ~]$ salt-call state.apply formula.java -l debug
[DEBUG   ] Reading configuration from /opt/behavox/salt/minion
[DEBUG   ] Including configuration from '/opt/behavox/salt/minion.d/_schedule.conf'
[DEBUG   ] Reading configuration from /opt/behavox/salt/minion.d/_schedule.conf
[DEBUG   ] Including configuration from '/opt/behavox/salt/minion.d/proxy.conf'

...
[cut]

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

Imperative vs Declarative

Ansible утверждает что он декларативный инструмент для управления конфигурацией. Это лишь наполовину правда. В Ansible множество 100% декларативных модулей, но в нем так же огромное количество императивных модулей, например как uri.

Такие механизмы как register, when, changed_when, failed_when в Ansible поддерживают эти идею и позволяют делать идемпотентность и условную деларативность через императивные инструменты.

Это породило такое веяние как "Программирование на Ansible" aka "Башсибл".

Отчасти это очень мощный и гибкий инструментарий позволяющий делать плюс-минус все что угодно без навыков програмирования.

Я искренне убежден что минусы этого подхода перевешивают плюсы в долгом забеге.

Так же Ansible не гарантирует что все его модули идемпотентны и предлагает те же самые инструменты что бы обойти эту проблему. Это ведет к ухудшению читаемости и поддержки логики.

SaltStack явно разграничивает императивные и декларативные модули.

Execution modules(далее "модули исполнения") императивны и не идемпотентны. Они написаны как глаголы - скачай архив, удали файл и тд.

State modules(далее "модули состояния") декларативны и идемпотентны. Они приводят систему в определенное... состояние описывая финальный результат, а не как к нему прийти - убедись что пакет nginx установлен и он версии 1.21.3 и тп.

В SaltStack почти невозможно сделать цепочку модулей исполнения что бы они притворились идемпотентными и декларативными. Вместо этого предлагает писать свои модули состояния.

По сути большинство модулей состояния это просто клей между модулями исполнения и дополнительными утилитами.

Например модуль состояния который создает директорию внутри себя вызывает модули исполнения вроде "проверь существует ли эта директория" и "создай директорию" и добавляет логический "клей" между этими операциями.

Если директории нет, то создай. Если есть, но с другими правами - поменяй. Если состояние уже верное - ничего не делай. И тд.

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

Выводы

В этой статье не покрыты сотни вещей которые может делать SaltStack и не может Ansible. Функциональность reactors и engines позволяют делать очень интересные решения вроде реакции на события на вашей системе или построения своего сервиса поверх SaltStack.

По моему мнению главное преимущество Ansible на сегодня это предельная простота и гибкость оркестрации. Этот инструмент хорошо подойдет командам с небольшим количеством обслуживаемых хостов(до сотни) и\или для команд без сильной инженерной экспертизы. Ansible как никто другой приблизился к идее о no-code configuration management.

Но как-только вы вырастаете из этой простоты Ansible становится сильно сложнее и менее удобным чем вы бы ожидали.

Отладка становится мучением, время выкаток увеличивается экспоненциально и вы начинаете регулярно наступать на различные мины вроде того что any_erros_fatal не остановится на падении первого элемента в цикле а доведет его до конца прежде чем вернуть ошибку и тп.

И большая часть примеров логики в интернете будет полна "Программирования на Ansible" которую вам придется поддерживать.

Спустя несколько лет использования SaltStack я пришел к выводу что Ansible это инструмент, а SaltStack это фреймворк.

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


Спасибо что дочитали до конца. Если вам хочется обсудить SaltStack на русском языке, то приглашаем вас в русскоязычный Telegram канал: https://t.me/saltstack

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


  1. amarao
    20.09.2021 12:49
    +1

    Транспорт ансибла - blessing & a curse. Каждый раз, когда "медленно", к нему прикручивают "быстро" (hello, mitogen). Каждый раз, когда прикручивают быстро, возникает желание вернуться на ванильный ансибл, потому что "точно работает".

    Все создатели всех систем конфигурации ради удобства архитектуры сделали неудобно в эксплуатации. Точнее, не неудобно, а "шероховато". Условный ансибл способен прорваться через любую бездну. ssl proxy с терминацией на jump хост? Без проблем, только чуть медленее. У каждого сервера свой номер порта, и IP'шник, который плавает? Без проблем, динамическое инвентори твой друг. Можно даже и на уровне плейбуки подвигать ansible_host/port.

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

    Сейчас сага со вторым питоном ещё не закончена, но когда закончится, исчезнут все следы старья, и будет просто: есть ssh и питон - ансибл работает. Есть ssh - ансибл работает, но не так удобно. Нет ssh, но есть хоть что-то для cli? Чуть-чуть подфигачить молотком и ансибл работает.

    Ни одна система управления даже близко не подошла к этому уровню универсальности.


    1. gecube
      20.09.2021 12:56

      Ансибл - это не система управления конфигурацией.

      Это тул для автоматизации. Да, он может быть использован как SCM. В частности - если речь про установку пакетов на одиночную машину. Но оркестрация на нем - это мрак. Посмотрите хотя бы на kubespray. Нет, никогда в жизни, увольте.

      SCM - это папет и Солт, простите. Причем у папета еще относительно вменяемая объектная модель есть. Объектна модель и ансибл? Не смешите мои тапочки...


      1. amarao
        20.09.2021 14:57
        +1

        Я плохо видел солт и паппет, но наблюдал chef в самом кровавом режиме (когда на нём пытались описывать всё, включая квантовую физику на коммутаторах), и там я понял, что ни одна из систем этого поколения, на самом деле, не подходит, в основном из-за слабой типизации данных.

        Есть тайная мечта узрить хороший язык конфигурации с фашизмом уровня rust (ownership, traits, generics), но пока я вижу jinja в момент принятия решения - на этом нельзя писать надёжный код. Можно более-менее делать сайд-эффекты, да, но не решения, особенно, с трансляцией в уровень исполнения.

        В этом смысле Ансибл, который и не пытается (в отличие от ряда его пользователей) - разумный компромисс.

        И нет, у меня нет в ассортименте хорошего инструмента для оркестрации. Ни одного. Я страдаю.


        1. Oloremo Автор
          20.09.2021 15:00

          Я согласен про строгую типизацию и прочее и хочу заметить что Соль идет в эту сторону в проекте под названием Idem. Нам нем сейчас переписывают небольшой кусок, но в перспективе это позволит писать значительно более надежную логику.

          Пока что мы живем за счет сильного CI с проверками каждого куска логики


        1. AnthonyMikh
          21.09.2021 12:25

          Есть тайная мечта узрить хороший язык конфигурации с фашизмом уровня rust (ownership, traits, generics)

          Посмотрите Dhall.


          1. amarao
            21.09.2021 12:46

            Посмотрел. На этом невозможно писать в продакшене. Даже если в компании образуется админ-хаскелист, то он будет писать это в гордом одиночестве и оно сдохнет.

            Кроме того, проблема же не столько в типах данных для шаблонов, сколько в описании конфигурации, т.е. возможность введения разумных сущностей DSL'ного порядка. Выделываться с map/fold, кстати, можно и на jinja, с меньшим успехом, правда, но можно. И оно никогда не решает проблемы конфигурации.

            Главного, что не хватает, это хорошего DAG-подобного языка с ясным описанием ввода/вывода стейджей, зависимостей между ними и т.д. Есть consourse, который почти хорош, но без фашизма и без нормального single mode (только серверный). Есть миллион клонов make, которые все хотят файлы, а не абстрактные сущности.

            Мне бы хотелось что-то такое:

            impl VM for guest<libvirt<kvm>>{
               ...
            }
            
            impl VM for guest<openstack<mytype>>{
              ...
            }

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

            "Can't construct VM for openstack<mytype>, trait AccessIP not implemented for openstack<mytype>" вместо runtime сообщения от опенстека, что FIP не завезено.


        1. ALexhha
          21.09.2021 13:23

          Есть тайная мечта узрить хороший язык конфигурации с фашизмом уровня rust (ownership, traits, generics)

          cfengine не оно ?


          1. amarao
            21.09.2021 13:30

            Точно не cfengine. У меня есть живой пример проекта, который с cfengine уходил на анисбл, и люди были счастливы, всё время.


    1. Oloremo Автор
      20.09.2021 13:06
      +2

       к нему прикручивают "быстро" (hello, mitogen)

      Мы очень хотели что бы эта штука взлетела и решила все наши проблемы, но это pet project который не поддерживается RedHat и ломает половину логики.

      В остальном я в целом согласен, но ssh транспорт не такой простой как о нем часто думают.
      C условной Солью у вас либо есть подключение либо нет и если оно есть то все будет работать. Открыть надо два порта в одну сторону. Работает за натами и прочим.

      У нас было много проблем с ssh timeouts, sudo escalation timeouts и тд при работе с Ансиблом.


      1. gecube
        20.09.2021 13:13

        У нас было много проблем с ssh timeouts, sudo escalation timeouts и тд при работе с Ансиблом.

        поддержу. Просто модель у солта совершенно другая. Хочешь ssh - не вопроc, salt-ssh, нелюбимый ребенок SaltStack'а. В целом даже работает.

        А вот ZMQ позволяет управлять узлами из-за Ната. Что может быть важно для рестриктед окружений. А ансибл - приходится костылять всякие ssh proxy jump etc.


      1. amarao
        20.09.2021 13:37

        И большинство из них уже исправлены. Сейчас, обычно, таймаут - признак сломанного коннективити.


  1. gecube
    20.09.2021 13:35
    +2

    Вот что интересно - Кубер активно сжирает сейчас весь рынок SCM... По крайней мере для новых проектов - он прекрасно заменяет ансибл (описание конфигурации + деплой + что-то еще)


    1. amarao
      20.09.2021 14:41

      Не совсем так. Куб решает другого рода задачи. Он "ест" проблему сверху, заменяя парадигму эксплуатации. Если приложение ложится на кубовую архитектуру и компания готова терпеть вытекающие из него расходы, то ок, ура, ура. Но куб - это архитектура, это не инструмент. Я бы, даже, сказал, это идеология в первую очередь.

      А ансибл, наоборот, никакой архитектуры с собой не приносит - это просто инструмент, как молоток или паяльник.


      1. gecube
        20.09.2021 15:21

        Согласен. Но дело в том, что куб уже много где есть. И возникает вполне логичное желание - унифицироваться на нем... Что в случае монолитов порождает достаточно странных гомункулов.


        1. amarao
          20.09.2021 16:22
          +1

          куб - это решение.

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

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


          1. gecube
            20.09.2021 23:20

            Квартира точно так же может быть инструментом. Например, инструментом сохранения и инвестирования денег :-)


            1. P6i
              21.09.2021 16:38

              Пока не придет землетрясение в 8-9 баллов)


  1. kt97679
    21.09.2021 06:30

    Disclaimer: я очень много работал с salt вплоть до конца 2018 года. С тех пор что-то могло измениться и улучшиться.

    SaltStack без особых усилий может обслуживать тысячи нод. При желании он может обслуживать десятки тысяч нод.

    Мне удалось заставить salt работать на 10к+ машин. Для этого пришлось переключиться на salt-ssh. Использование мастеров-миньонов было бесконечной болью с крэшами как мастеров так и миньонов. Заставить это работать надежно не удалось. С другой стороны salt-ssh с грехом пополам тянул всю инфрастуктуру.

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

    Не могли бы вы раскрыть это утверждение?

    В плане отладки SaltStack ведет себя так как бы вы ожидали от обычного приложения на Python.

    В случае salt-ssh отладка выглядела так:

    1. меняем стейт
    2. применяем
    3. стейт не работает как надо
    4. запускаем salt-ssh с расширенным логированием
    5. вычленяем команду, которая запускается на удаленном хосте
    6. логинимся на удаленный хост
    7. запускаем там отредактированную команду, вычлененную ранее из логов (чтобы вывод не шел в /dev/null)
    8. из вывода пытаемся понять, в чем проблема
    9. переходим на 1


    1. gecube
      21.09.2021 07:03

      Не могли бы вы раскрыть это утверждение?

      Я думаю, что это важно по двум причинам. Первая - python есть почти везде, что гарантирует хотя бы возможность бутстрапа salt. С другой стороны, в каком-то смысле это же и является проблемой, т.к. фиксация на версии системного python может приводить к несовместимостям, невозможности использовать определённые модули и прочие приключения, которые случаются ещё и с ансиблом. Второе - доработать или разобраться в том, как работает salt, может средней руки админ. У нас был кейс, когда очень долго отрабатывал кейс для создания юзеров. Т.к. код на python и написан адекватно - мы смогли быстро разобраться. Оказалось, что достаточно было доустановить определённый системный пакет и все поехало. Был бы salt на erlang - я даже не знаю, получилось бы решить проблему


    1. Oloremo Автор
      21.09.2021 12:42

      Не могли бы вы раскрыть это утверждение?

      Да я плоховато его раскрыл.

      Я вел к тому что одно из главных преимуществ Ансибла на мой взгляд что его могут подхватить вчерашние сисадмины знающие только Баш. И в целом успешно им пользоватся.

      Что бы успешно пользоватся Солью, Папетом и особенно Шефом - надо уметь програмировать на Питоне или Рубях. Хотя бы чуть-чуть.

      И то что Ансибл и Соль написаны на Питоне дает им преимущество перед остальными в 2021 году когда Питон давно стал вторым Башем для нового поколения Ops\SRE.

      В случае salt-ssh отладка выглядела так:

      Мы не пользуемся salt-ssh - не могу прокоментировать. Жаль если так. Вроде бы ребята из Lyft тоже не пользуеются мастером но они делают masterless деплой просто через salt-call -local


      1. gecube
        21.09.2021 16:34

        Мы не пользуемся salt-ssh - не могу прокоментировать. Жаль если так. Вроде бы ребята из Lyft тоже не пользуеются мастером но они делают masterless деплой просто через salt-call -local

        я бы разделил этап разработки и прода. В проде salt-ssh на уже известной инфре прекрасно работал. А вот в момент отладки - я активно не его гонял, а salt-call -local.


      1. kt97679
        21.09.2021 22:22

        И то что Ансибл и Соль написаны на Питоне дает им преимущество перед остальными в 2021 году когда Питон давно стал вторым Башем для нового поколения Ops\SRE.

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


        1. gecube
          21.09.2021 23:42

          Смотря как устанавливать... venv реально решает...


    1. cbx
      19.10.2021 05:45
      +1

      Да, дебаг salt-ssh иногда весёлый бывает. Но во многих случаях можно отлаживать просто через salt-call локально, а если прям нужно понять что сломалось именно в salt-ssh, то есть способ включить нормальное логгирование и забыть о вычленении команд из логов:

      Взято тут https://twitter.com/SaltTips/status/1146306964026253312
      Взято тут https://twitter.com/SaltTips/status/1146306964026253312


  1. kt97679
    21.09.2021 08:09

    Т.к. код на python и написан адекватно

    К сожалению это не так. Salt использует очень много питоновской магии. Говорю не голословно, мне пришлось ловить очень неприятные race conditions в salt и это было ох как не просто. У меня есть знакомый гуру питона, который посмотрев на код salt сказал, что хуже он не видел.


    1. gecube
      21.09.2021 08:45

      У вас опыт негативный - у меня позитивный. 1:1?

      Касательно race condition - к сожалению, они возможны в любом коде. Даже на таких «надёжных» языках как Java, rust и golang. Но я представляю себе систему управления сотнями узлов на голанге… с необходимостью перекомпиляции всех бинарников, если понадобится подключить новую архитектуру или плагин. Не, нужно использовать подходящие инструменты.

      От вас (не ради стеба, а ради самообразования и возможно Вы кого-то отвадите от ошибок) я очень хотел бы услышать две вещи:

      1. Конкретные примеры проблем (кроме того, что Вы уже написали в сообщении выше про salt-ssh)

      2. Какие альтернативы Вы видите для управления конфигурацией сотен или тысяч узлов? Тот же ансибл с головной машины на 1000 узлов без лимитов и разбивки на батчи точно так же прекрасно выедает всю доступную память и падать. Или работает как маленький слоупочек


      1. kt97679
        21.09.2021 22:16

        Конкретные примеры проблем (кроме того, что Вы уже написали в сообщении выше про salt-ssh)

        Вот то, что было самым болезненным: github.com/saltstack/salt/issues/33223
        А вот все isues, которые я зафайлил: github.com/saltstack/salt/issues?q=is%3Aissue+author%3Akt97679

        У вас опыт негативный — у меня позитивный. 1:1?

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

        Какие альтернативы Вы видите для управления конфигурацией сотен или тысяч узлов?

        На сегодняшний день я, к сожалению, не вижу безпроблемного решения. У меня есть опыт работы с chef, salt и puppet. Ни от одного из них я не в восторге.


    1. Oloremo Автор
      21.09.2021 12:47
      +2

      Соль в целом очень сложный проект с историей.

      Там много магии, вендер пинов(не могут смигрировать с Tornado 4.5x уже года три) и большая и грустная история с тем что до 2019 года они принимали плюс-минус любые PR без регрессионых тестов.

      Мы тоже активные контрибьюторы и все патчи пытаемся вернуть в апстрим.

      Но надо заметить что в Ансибле мы нашли не меньше багов и проблем и до сих пор чешем голову когда вызов крупного template на 50 машинах может отесть до 10Гб ОЗУ на Ансибл контролере.

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


  1. besonu
    26.09.2021 16:18

    Ansible -- единственное решение для интерпрайза.

    В договорах на поддержку "аппаратно-программных" комплексов IBM и Oracle (про других не знаю) напрямую говорится, что заказчик несет ответственность за неисправности, вызванные установкой 3rd-party software.

    И да, если ваш менеждер поверил вам, что вы легко докажете поддержке, что "этот маленький агент точно не мог вызвать kernel panic", то бегите из этой конторы немедленно.


    1. gecube
      26.09.2021 18:05

      Ansible -- единственное решение для интерпрайза.

      какой-то очень голословный тезис. Salt и Puppet тоже вполне себе энтерпрайз. Напомню, что за первым стоит Vmware, а второй сам по себе разрабатывается одноименной компанией. Я уж не говорю о том, что если рассуждать так - ансибл - это редхат. Значит, редхат несет какие-то гарантии, то нет, это ошибочно и так это не работает (((

      вызванные установкой 3rd-party software.

      установкой, а не запуском? Точно так же IBM/Oracle могут доказать, что ваш сканер безопасности, который запускается по ссш или просто сканирует порты на IBM/Oracle решениях, лишает вас гарантии?