Что здесь интересного?
Статья поможет разобраться с тем, как управлять произвольным количеством конфигурационных файлов некоего сервиса в SaltStack.
SaltStack (underfloor): что это и как с ним быть?
Многие уже имели опыт работы с системами автоматизированного управления конфигурациями, к которым относится Salt, и рассказывать подробно о том как его готовить и что он может я не стану, тут можно прочесть что это, а тут почитать как его быстро и легко приготовить.
SaltStack (lobby): типичное применение на простом примере
Итак, предположим, у Вас есть задача автоматизировать установку, внедрение конфигурационных файлов и мониторинг их изменений, перезагрузку в случае необходимости такого популярного сервиса как nginx. Для упрощения системы, сделаем предположение что обслуживаемые сервера построены на базе Debian Wheezy. (Для всех остальных, — читаем про grains систему, — она поможет определить на какой системе мы применяем стейт и соответствующим образом поменять его поведение).
Итак:
nginx-repo-key-install:
cmd.run:
- name: 'apt-key adv --keyserver keys.gnupg.net --recv-keys ABF5BD827BD9BF62'
- unless: 'apt-key list | grep -q 7BD9BF62'
nginx-repo:
pkgrepo.managed:
- humanname: nginx-repo
- name: deb http://nginx.org/packages/mainline/debian/ wheezy nginx
- require_in:
- pkg: nginx-pkg
- required:
- cmd: nginx-repo-key-install
nginx-pkg:
pkg.installed:
- name: nginx
- refresh: True
- require:
- pkgrepo: nginx-repo
nginx-service:
service.running:
- name: nginx
- full_restart: True
- require:
- pkg: nginx-pkg
- watch:
- file: nginx-config-vhost
nginx-config-vhost:
file.managed:
- name: /etc/nginx/conf.d/vhost.conf
- source: salt://__CONFIGS/vhost.conf
- user: root
- group: root
- mode: 644
Тут все, как «книжка пишет», но рассмотрим подробнее (очень важно как бэкграунд для последующих выкладок):
- nginx-repo-key-install: импортируем в систему ключ официального репозитория
- nginx-repo: вносим в apt официальный репозиторий
- nginx-pkg: ставим свеженький пакет
- nginx-service: берем под контроль сервис и заставляем следить за изменениями конфигурационного файла
- nginx-config-vhost: собственно — конфигурационный файл и место откуда его брать
Для пытливых умов, невооруженным взглядом, видны упущения (к примеру, — не описан контроль над nginx.conf) но все они сделаны для того, чтобы уменьшить не связанную с проблемной областью информационную нагрузку.
SaltStack (second floor): Много конфигурационных файлов
В первом примере был показан сервис в котором есть один файл где описан какой-то виртуальный сервер nginx. При его изменении на Salt мастере (salt://__CONFIGS/vhost.conf) и перезапуске стейта, файл будет обновлен на машине и сервис nginx будет перезапущен (full_restart: True) автоматически.
Зачастую виртуальных хостов на машине с nginx будет несколько. Рассмотрим как организовать управление ими.
Допустим, что есть файлы vhost{1,2,3,4,5}.conf. В таком случае нижняя часть стейта будет выглядеть так:
......
nginx-service:
service.running:
- name: nginx
- full_restart: True
- require:
- pkg: nginx-pkg
- watch:
{% for cnf in ['vhost1.conf', 'vhost2.conf', 'vhost3.conf', 'vhost4.conf', 'vhost5.conf'] %}
- file: nginx-config-{{ cnf }}
{% endfor %}
{% for cnf in ['vhost1.conf', 'vhost2.conf', 'vhost3.conf', 'vhost4.conf', 'vhost5.conf'] %}
nginx-config-{{ cnf }}:
file.managed:
- name: /etc/nginx/conf.d/{{ cnf }}
- source: salt://__CONFIGS/{{ cnf }}
- user: root
- group: root
- mode: 644
{% endfor %}
Тут начинается немного магии Salt, а именно: Jinja — шаблонизатор для Python (на котором и написан SaltStack). В стейте все очевидно, — делаем много объектов file с разными названиями и подвязываем все их к службе, чтобы при изменениях проводился её перезапуск. Для оптимизации можно использовать систему pillar-ов чтобы хранить имена файлов с конфигурациями. Но это — домашнее задание.
SaltStack (one floor upper): Много конфигурационных файлов — но сколько и каких — неизвестно.
Итак то, зачем и задумывалась эта статья, — ситуация достаточно обыденная для большинства рабочих систем с виртуальным хостингом: большое, заранее неизвестное и постоянно меняющееся количество конфигурационных файлов. Как же в таком случае поступить с разворачиванием инфраструктуры через Salt? Решение есть! К сожалению недостаточно очевидное (пришлось даже к разработчикам за разъяснениями обращаться), но работающее.
Итак:
......
nginx-service:
service.running:
- name: nginx
- full_restart: True
- require:
- pkg: nginx-pkg
- watch:
{% for cnf in salt['cp.list_master'](prefix='__CONFIGS/') %}
- file: nginx-config-{{ cnf }}
{% endfor %}
{% for cnf in salt['cp.list_master'](prefix='__CONFIGS/') %}
{% set items = cnf.split('/') %}
nginx-config-{{ cnf }}:
file.managed:
- name: /etc/nginx/conf.d/{{ items|last }}
- source: salt://{{ cnf }}
- user: root
- group: root
- mode: 644
{% endfor %}
Собственно теперь о самых интересных местах:
{% for cnf in salt['cp.list_master'](prefix='__CONFIGS/') %}
вызываем ф-цию list_master из модуля cp с префиксом '__CONFIGS/' (имя папки на Salt мастере где лежат все конфигурационные файлы для этого сервиса) которая с выдает список файлов в этом каталоге и итерируем по списку циклом for.
{% set items = cnf.split('/') %}
Проблема cp.list_master заключается в том, что она выдает полный путь к файлу (вместе с префиксом), а нам нужно лишь имя файла для того, чтобы указать его в директиве "- name:". В связи с этим мы сплиттим полный путь по слешам и используем только последний элемент списка — т.е. имя файла:
- name: /etc/nginx/conf.d/{{ items|last }}
В итоге получаем пересмотренный каталог, включенные в оборот файлы конфигураций имеющиеся в этом каталоге и сразу же подвязываем к автоматическому перезапуску сервиса в случае правок в файлах.
Заключение
Очень кратенько, но надеюсь поможет тем читателям Хабра, которые только начинают внедрять SaltStack и хотят пойти немного дальше чем книжные примеры с простым менеджментом пакетов. Успехов!