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

SaltStack — это целая экосистема, предназначенная для автоматизации сложных процессов и оркестрации множества систем. Сегодня мы рассмотрим, как SaltStack помогает решить задачи оркестрации.

Немного про сам SaltStack

SaltStack состоит из основных компонентов: Salt Master, Salt Minion.

Salt Master

Salt Master — это центральный сервер, который управляет миньонами (агентами) и распределяет команды. Основные функции:

  • Командное управление: отправка команд миньонам для выполнения различных задач.

  • Сбор данных: получение информации о состоянии миньонов.

  • Оркестрация: координация выполнения сложных задач, требующих взаимодействия нескольких систем.

Salt Minion

Salt Minion — это агент, установленный на управляемом узле (сервере, виртуальной машине и т.д.). Он выполняет функции:

  • Выполнение команд: принимает и исполняет команды от мастера.

  • Сбор данных: отправляет данные о состоянии системы мастеру.

  • Локальное управление: может выполнять задачи автономно без постоянного подключения к мастеру.

Подробнее с сам SaltStack можно прочитать здесь.

Оркестрация с помощью SaltStack

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

Salt Orchestrate Runner — это инструмент в SaltStack, который позволяет управлять и координировать выполнение задач на нескольких узлах. Он используется для написания и выполнения оркестрационных сценариев, которые могут включать выполнение команд, применение состояний и управление конфигурациями.

Простой сценарий оркестрации может включать выполнение команды на нескольких узлах:

# /srv/salt/orchestrate/simple_orchestrate.sls
execute_command:
  salt.function:
    - name: cmd.run
    - tgt: '*'
    - arg:
      - echo "Hello, world!"

Здесь сценарий /srv/salt/orchestrate/simple_orchestrate.sls определяет задачу execute_command, которая использует функцию cmd.run для выполнения команды echo "Hello, world!" на всех узлах (tgt: '*').

В сценарии посложней можно выполнить задачи последовательно:

# /srv/salt/orchestrate/complex_orchestrate.sls
prepare_servers:
  salt.state:
    - tgt: 'web*'
    - sls: webserver.setup

deploy_application:
  salt.state:
    - tgt: 'app*'
    - sls: app.deploy
    - require:
      - salt: prepare_servers

В этом примере сначала выполняется состояние webserver.setup на узлах с меткой web*, а затем состояние app.deploy на узлах с меткой app*, но только после успешного завершения первой задачи.

SLS файлы используются для определения состояний и задач, которые SaltStack должен выполнить. Эти файлы написаны в формате YAML и содержат описания состояния систем и действий, которые нужно выполнить.

Пример создания SLS файла:

# /srv/salt/webserver/setup.sls
install_nginx:
  pkg.installed:
    - name: nginx

start_nginx:
  service.running:
    - name: nginx
    - enable: True
    - require:
      - pkg: install_nginx

Здесь SLS файл /srv/salt/webserver/setup.sls определяет два состояния: установка пакета nginx и запуск сервиса nginx. Условие require гарантирует, что сервис будет запущен только после установки пакета.

Для выполнения SLS файла используется команда salt-run или salt:

salt 'web*' state.apply webserver.setup

Эта команда применяет состояния, определенные в webserver.setup, на всех узлах, соответствующих шаблону web*.

Как все это выглядит на практике

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

Настройка балансировщика нагрузки с Nginx

Создадим SLS файл для установки Nginx:

# /srv/salt/loadbalancer/install_nginx.sls
install_nginx:
  pkg.installed:
    - name: nginx

configure_nginx:
  file.managed:
    - name: /etc/nginx/nginx.conf
    - source: salt://loadbalancer/nginx.conf
    - user: root
    - group: root
    - mode: 644
    - require:
      - pkg: install_nginx

start_nginx:
  service.running:
    - name: nginx
    - enable: True
    - require:
      - file: configure_nginx

Пример конфигурационного файла Nginx:

# /srv/salt/loadbalancer/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    
    access_log /var/log/nginx/access.log main;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    upstream backend {
        server webserver1.example.com;
        server webserver2.example.com;
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}

Применение конфигурации:

salt 'loadbalancer*' state.apply loadbalancer.install_nginx

Последовательная конфигурация всех серверов кластера

Создадим SLS файл для установки и настройки веб-сервера:

# /srv/salt/webserver/setup.sls
install_nginx:
  pkg.installed:
    - name: nginx

configure_nginx:
  file.managed:
    - name: /etc/nginx/nginx.conf
    - source: salt://webserver/nginx.conf
    - user: root
    - group: root
    - mode: 644
    - require:
      - pkg: install_nginx

start_nginx:
  service.running:
    - name: nginx
    - enable: True
    - require:
      - file: configure_nginx

Пример конфигурационного файла для веб-сервера:

# /srv/salt/webserver/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    
    access_log /var/log/nginx/access.log main;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    server {
        listen 80;
        server_name webserver.example.com;

        location / {
            root /usr/share/nginx/html;
            index index.html index.htm;
        }
    }
}

Применение конфигурации на всех веб-серверах:

salt 'web*' state.apply webserver.setup

Автоматизация и мониторинг с помощью SaltStack

Настройка Salt Mine для сбора данных:

# /srv/salt/minion
mine_functions:
  network.ip_addrs: []

Настройка Beacons для мониторинга состояния сервера:

# /srv/salt/beacons.conf
beacons:
  service:
    - services:
        nginx: {}
    - interval: 10

Настройка Reactors для автоматического реагирования на события:

# /srv/salt/reactor/reactor.conf
reactor:
  - 'salt/beacon/*/service/':
    - /srv/salt/reactor/service_restart.sls

Пример Reactor SLS файла для перезапуска сервиса:

# /srv/salt/reactor/service_restart.sls
restart_service:
  local.cmd.run:
    - tgt: 'web*'
    - arg:
      - systemctl restart nginx
    - require:
      - beacon: salt/beacon/*/service/

Больше практических навыков по инфраструктуре вы можете получить в рамках практических онлайн-курсов от экспертов отрасли.

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


  1. petro_64
    04.07.2024 12:50

    Эх, Сальтстак, хорош ты был раньше, а сейчас вот думаем на Ansible переходить. С новыми версиями адовые баги.

    start_nginx:
      service.running:
        - name: nginx
        - enable: True
        - require:
          - file: configure_nginx

    Тут должна быть зависимость через watch - сам же наверное нужно релоадить nginx, если конфиг поменялся?

    - watch:
      - file: /etc/nginx/*

    В этом случае systemd unit будет перезапущен, если что-то попадающее по маске меняется.