Привет, Хабр!

SaltStack позволяет администраторам и DevOps-специалистам взаимодействовать с различными уровнями своих инфраструктур, от индивидуальных серверов до центров обработки данных. Система использует модель Salt Minion.

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

Установим и настроим

Salt Master управляет Minions, отправляя им инструкции. Установка Salt Master обычно начинается с добавления репозитория SaltStack в список источников системы управления пакетами и выполнения установки через эту систему.

Для систем на базе Debian/Ubuntu юзаем манды:

wget -O - https://repo.saltstack.com/py3/ubuntu/20.04/amd64/latest/SALTSTACK-GPG-KEY.pub | sudo apt-key add -
echo "deb http://repo.saltstack.com/py3/ubuntu/20.04/amd64/latest focal main" | sudo tee /etc/apt/sources.list.d/saltstack.list
sudo apt-get update
sudo apt-get install salt-master

Для CentOS/RHEL:

sudo yum install https://repo.saltstack.com/py3/redhat/salt-py3-repo-latest.el7.noarch.rpm
sudo yum clean expire-cache
sudo yum install salt-master

Salt Minion устанавливается на управляемые узлы. Так же, как и для Master, можно начать с добавления репозитория:

На Debian/Ubuntu:

wget -O - https://repo.saltstack.com/py3/ubuntu/20.04/amd64/latest/SALTSTACK-GPG-KEY.pub | sudo apt-key add -
echo "deb http://repo.saltstack.com/py3/ubuntu/20.04/amd64/latest focal main" | sudo tee /etc/apt/sources.list.d/saltstack.list
sudo apt-get update
sudo apt-get install salt-minion

На CentOS/RHEL:

sudo yum install https://repo.saltstack.com/py3/redhat/salt-py3-repo-latest.el7.noarch.rpm
sudo yum clean expire-cache
sudo yum install salt-minion

После установки Minion нужно настроить его для связи с Master. Это делается путем изменения файла /etc/salt/minion, где необходимо указать адрес, ну или имя Salt Master:

master: ip_address_or_hostname_of_salt_master

После изменения файла конфигурации перезапускаем службу Minion:

sudo systemctl restart salt-minion

После установки и настройки на Master выполняем:

sudo salt-key -L

Это покажет список Minions, которые пытаются подключиться к Master. Для подтверждения ключа Minion юзаем:

sudo salt-key -A

Основы работы

Salt States позволяют определять желаемое состояние системы в форме декларативного кода. Эти определения хранятся в файлах с расширением .sls, обычно написанных на языке YAML для простоты чтения и поддержки.

Простой пример файла состояния, webserver.sls, может выглядеть так:

apache:
  pkg.installed: []

Здесь пакет apacheдолжен быть установлен на целевой системе.

Файл top.sls определяет какие state files применять к каким minions. Пример содержимого top.sls:

base:
  '*':
    - core

Состояние core применяется ко всем minions. Система позволяет использовать различные механизмы таргетинга, например, через glob-паттерны, регулярные выражения или данные grain.

Например, используем данные grains для таргетинга minions на основе их операционной системы. Состояние core.ubuntu применяется к minions с ОС Ubuntu, а core.centos - к minions на CentOS:

base:
  'os:Ubuntu':
    - match: grain
    - core.ubuntu
  'os:CentOS':
    - match: grain
    - core.centos

Рассмотрим, как может выглядеть core.sls для minions на Ubuntu:

# файл: core.ubuntu.sls
update_system:
  pkg.uptodate:
    - refresh: true

install_basic_packages:
  pkg.installed:
    - names:
      - curl
      - git
      - vim

Можно использовать регулярные выражения для таргетинга:

base:
  '^(web|db).*':
    - match: pcre
    - core.web_db_common

Здесь для таргетинга используются регулярные выражения и таким образом можно применять состояние core.web_db_common к minions, идентификаторы которых начинаются с web или db.

Состояния организуются в иерархическую структуру файлов, начиная от корня /srv/salt:

/srv/salt
├── core.sls
├── httpd
│   ├── files
│   │   ├── apache2.conf
│   │   └── httpd.conf
│   └── init.sls
└── top.sls

Salt позволяет определять различные среды, например, для разработки, тестирования и продакшна, с помощью отдельных file_roots для каждой среды и соответствующих разделов в файле top.sls:

base:
  '*':
    - core
dev:
  'webserver*dev*':
    - webserver
prod:
  'webserver*prod*':
    - webserver

Здесь для разных сред и соответствующих minions задаются различные наборы состояний.

К примеру необходимо убедиться, что редактор vim установлен, пакет Salt установлен и обновлен до последней версии, а службы salt-master и salt-minion запущены и конфигурационный файл minion находится на своем месте:

vim:
  pkg.installed: []

salt:
  pkg.latest:
    - name: salt
  service.running:
    - names:
      - salt-master
      - salt

-minion
    - require:
      - pkg: salt
    - watch:
      - file: /etc/salt/minion

/etc/salt/minion:
  file.managed:
    - source: salt://salt/minion
    - user: root
    - group: root
    - mode: 644
    - require:
      - pkg: salt

Установка нескольких пакетов выглядит просто:

common_packages:
  pkg.installed:
    - pkgs:
      - git
      - htop
      - vim

Управление состояние службами реализуется также достаточно просто. Например, гарантировать, что служба Apache запущена:

apache_service:
  service.running:
    - name: apache2
    - enable: True
    - reload: True
    - require:
      - pkg: apache2

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

Чтобы управлять содержимым файла на целевой системе, можно использовать следующий пример, который гарантит наличие определённого текста в файле:

motd_custom_message:
  file.managed:
    - name: /etc/motd
    - source: salt://files/motd.txt
    - user: root
    - group: root
    - mode: 644

Файл /etc/motd на целевом узле будет иметь содержимое, соответствующее файлу motd.txt, хранящемуся на master в директории salt://files/.

А перезаписать файл конфигурации, можно юзая шаблон Jinja2, и обновить службу, если файл был изменён:

nginx_config:
  file.managed:
    - name: /etc/nginx/nginx.conf
    - source: salt://nginx/nginx.conf.jinja
    - template: jinja
    - user: root
    - group: root
    - mode: 644
    - require:
      - pkg: nginx

nginx_service:
  service.running:
    - name: nginx
    - watch:
      - file: nginx_config

Файл /etc/nginx/nginx.conf генерируется из шаблона Jinja2 и, если он изменяется, служба nginx будет перезапущена.

SaltStack для автоматизации задач и оркестровки

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

Пример Reactor SLS файла:

remove_key:
  wheel.key.delete:
    - match: {{ data['id'] }}

Здесь будет удаление ключа minion при определенном событии. Можно также юзать Reactor для запуска задач на уровне minion:

touch_file:
  caller.file.touch:
    - args:
      - name: /tmp/foo

При написании файлов Reactor SLS стоит помнить, что реакции следует держать простыми! Исключать сложные вычисления и Jinja шаблоны, которые могут замедлить обработку. Для более сложных задач лучше использовать систему оркестровки Salt.

Система оркестровки Salt предоставляет framework для координирования и выполнения задач на множестве узлов. Используя Runner state.orchestrate можно определить состояния, которые управляют выполнением модулей, состояний и других Runner на master и minion.

Пример оркестровки:

# /srv/salt/orch/deploy.sls
create_instance:
  salt.runner:
    - name: cloud.profile
    - prof: cloud-centos
    - provider: cloud
    - instances:
      - server1
    - opts:
        minion:
          master: master1

Также можно использовать Jinja для динамической передачи данных через Pillar при выполнении оркестрации.

С помощью оркестровки можно определить сложные последовательности задач с учетом зависимостей между ними, используя полный набор requisites, доступных в Salt States. Например:

bootstrap_servers:
  salt.function:
    - name: cmd.run
    - tgt: 10.0.0.0/24
    - tgt_type: ipcidr
    - arg:
      - bootstrap

Команда bootstrap выполняется на всех узлах в подсети 10.0.0.0/24. Затем можно запустить highstate на определенных группах minion, применить настройки хранилища и так далее, используя зависимости и другие функции Salt для управления порядком выполнения задач.


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

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


  1. zo0Mx
    20.04.2024 07:29

    Спасибо за интересный материал! Будет продолжение?


    1. jackcrane
      20.04.2024 07:29
      +1

      Будет продолжение?

      внизу написано "на курсах в OTUS" .


  1. kt97679
    20.04.2024 07:29

    странно, что ничего не написано про salt-ssh


    1. 13werwolf13
      20.04.2024 07:29
      +1

      сторонники солта стараются умалчивать что нужен salt-ssh чтобы развернуть сам salt..


  1. skeletor
    20.04.2024 07:29

    sudo salt-key -L

    Это покажет список Minions, которые пытаются подключиться к Master. Для подтверждения ключа Minion юзаем:

    sudo salt-key -A

    На самом деле это не совсем так. ключ "-L" покажет список всех ключей, которые разбиты на несколько категорий: одобреные (Accepted), ожидающие (Unaccepted), заблокированные (там 2 вида: Rejected/Denied). Так вот, только ожидающие будут соответствовать "которые пытаются подключиться к Master".

    Теперь про сам ключ "-A". Я бы не рекомендовал его использовать, так как он автоматически принимает все ключи. Лучше для этого использовать конструкцию " salt-key -a '*' " и salt покажет какие ключи будут добавлены и спросит "добавить?". Иногда бывает, что кто-то хочет добавить какой-то тестовый однодневный docker-контейнер. Не нужно забывать еще о некоторой особенности salt-stack: не активные ключи нужно время от времени удалять, так как они влияют на выполнение batch'евый заданий (когда применяется к группе). К примеру, у вас задание salt -G roles:DNS state.sls dns_prod и, если у вас хотя бы один мертвый ключ с ролью DNS, вы будете ожидать возврата терминала 60 секунд (by default), не смотря на то, что все minion'ы уже вернули статус выполнения stat'a. Поэтому, я за то, что бы не слепо "принимать" все ключи, а еще раз перепроверять, что принимать. Хотя, кому как удобнее.