SaltStack, или просто Salt – это мощная система удаленного выполнения и управления конфигурацией, которая позволяет управлять инфраструктурой структурированным и воспроизводимым способом. В этой серии руководств вы научитесь использовать систему состояний Salt для записи и применения повторяемых конфигураций. Это значит, что вы сможете легко создавать новые ноды, которые будут иметь идентичную конфигурацию.
В предыдущем руководстве вы узнали, как настроить salt-cloud для развертывания ресурсов. В данном мануале вы научитесь создавать состояния Salt для управления конфигурацией Nginx. Веб-сервер Nginx будет использоваться для обработки запросов во всех трех средах данной инфраструктуры.
1: Создание главного файла состояния Nginx
Salt обрабатывает управление конфигурацией через систему состояний. В простейшем случае конфигурации контролируются файлами, расположенными в корневом каталоге сервера Salt (в данном случае это /srv/salt). Чтобы начать настройку Nginx, создайте каталог в этом месте.
sudo mkdir /srv/salt/nginx
Файлы состояний имеют суффикс .sls. Файл init.sls в каталоге работает как главный конфигурационный файл определенного состояния или формулы Salt. Для выполнения функций, содержащихся в соответствующем файле init.sls, нужно сослаться на имя родительского каталога.
Создайте и откройте файл init.sls в этом каталоге, чтобы начать:
sudo nano /srv/salt/nginx/init.sls
Состояния пакетов и сервиса Nginx
Для начала нужно создать состояние с помощью идентификатора nginx. Это будет уникальным названием для данного состояния в системе состояний Salt. Поскольку модули состояния включать атрибут name, идентификатор также будет использоваться в качестве цели для установки (в функции pkg.installed) и сервиса, который нужно запустить (в функции service.running).
Nginx должен автоматически перезагружаться при определенных условиях: после обновления пакета, изменения основного конфигурационного файла или виртуального хоста по умолчанию. Salt может перезапускать Nginx при возникновении этих условий с помощью параметра watch:
nginx:
pkg:
- installed
service.running:
- watch:
- pkg: nginx
- file: /etc/nginx/nginx.conf
- file: /etc/nginx/sites-available/default
Ключи pkg: и file: после watch: представляют модули состояний, связанные с отслеживаемыми ресурсами. Ресурс pkg определяется в первой части файла. Затем нужно создать состояния для ресурсов file.
Состояние конфигурационного файла Nginx
Начать можно с файла /etc/nginx/nginx.conf. Этот файл нужно добавить в систему управления конфигурацией. В терминологии Salt это значит, что вы определите содержимое файла на мастер-сервере и выгрузите его на каждый миньон, который в нем нуждается. Установите обычные права доступа и собственности на файл. Строка source ссылается на файл на сервере Salt (текущий файл также находится в этой структуре). Этот путь будет создан позже.
nginx:
pkg:
- installed
service.running:
- watch:
- pkg: nginx
- file: /etc/nginx/nginx.conf
- file: /etc/nginx/sites-available/default
/etc/nginx/nginx.conf:
file.managed:
- source: salt://nginx/files/etc/nginx/nginx.conf
- user: root
- group: root
- mode: 640
Также нужно контролировать содержимое файла /etc/nginx/sites-available/default. Это виртуальный хост по умолчанию, который определяет, как будет обслуживаться контент. Этот блок состояния будет похож на предыдущий. Основное различие между ними заключается в том, что этот файл будет шаблоном Jinja.
Шаблоны Jinja позволяют Salt добавлять в файл индивидуальные параметры для каждого из миньонов. Это позволяет извлекать информацию с каждого хоста и создавать соответствующую версию файла для каждого из веб-серверов. Чтобы указать, что этот файл будет использовать Jinja, добавьте параметр template. Также нужно использовать суффикс .jinja в исходном файле.
. . .
/etc/nginx/nginx.conf:
file.managed:
- source: salt://nginx/files/etc/nginx/nginx.conf
- user: root
- group: root
- mode: 640
/etc/nginx/sites-available/default:
file.managed:
- source: salt://nginx/files/etc/nginx/sites-available/default.jinja
- template: jinja
- user: root
- group: root
- mode: 640
Теперь виртуальный хост по умолчанию будет размещен в каталоге sites-available на хостах-миньонах. Однако его все равно нужно связать с каталогом sites-enabled, чтобы активировать его. Это можно сделать с помощью функции file.symlink. Здесь просто нужно указать исходное местоположение файла в качестве target. Также необходимо добавить параметр require, чтобы это состояние выполнялось только после успешного выполнения предыдущего состояния:
. . .
/etc/nginx/sites-available/default:
file.managed:
- source: salt://nginx/files/etc/nginx/sites-available/default.jinja
- template: jinja
- user: root
- group: root
- mode: 640
/etc/nginx/sites-enabled/default:
file.symlink:
- target: /etc/nginx/sites-available/default
- require:
- file: /etc/nginx/sites-available/default
Состояние для контента сайта
Теперь в файле есть записи для установки и настройки Nginx. После этого нужно создать состояние для файла index.html, который будет содержать контент сайта.
Это состояние использует тот же формат, что и предыдущее состояние шаблона. Отличаются только идентификатор, источник и права доступа:
. . .
/etc/nginx/sites-enabled/default:
file.symlink:
- target: /etc/nginx/sites-available/default
- require:
- file: /etc/nginx/sites-available/default
/usr/share/nginx/html/index.html:
file.managed:
- source: salt://nginx/files/usr/share/nginx/html/index.html.jinja
- template: jinja
- user: root
- group: root
- mode: 644
Сохраните и закройте файл.
2: Установка Nginx и перемещение исходных файлов на мастер Salt
Теперь у вас есть основной файл состояния Nginx. Однако некоторые состояния ссылаются на файлы мастера Salt, которые еще не существуют.
Поскольку это в основном файлы по умолчанию, установленные с пакетом Nginx в Ubuntu, можно начать с файлов этого пакета. Веб-серверы одной сред – идеальное место для установки Nginx, с помощью которой вы сможете получить необходимые файлы.
Если вы еще не развернули ни одной среды, выберите map-файл одной из сред и разверните его. Здесь мы используем промежуточную среду, поскольку она требует мало ресурсов.
sudo salt-cloud -P -m /etc/salt/cloud.maps.d/stage-environment.map
Когда серверы будут запущены, выберите один из веб-серверов и установите на него Nginx. Для этого можно использовать модуль выполнения pkg, так как пока что состояния еще не полностью рабочие.
sudo salt stage-www1 pkg.install nginx
Получив конфигурацию для мастера Salt, включите опцию file_recv. Она позволяет запрашивать у миньонов отправку определенных файлов на мастер-сервер. С ее помощью можно получить стандартные конфигурационные файлы.
sudo salt stage-www1 cp.push /etc/nginx/nginx.conf
sudo salt stage-www1 cp.push /etc/nginx/sites-available/default
sudo salt stage-www1 cp.push /usr/share/nginx/html/index.html
Теперь эти файлы доступны на мастере. Путь к файлам создан в каталоге /var/cache/salt/master/minions/minion_id/files (в данном случае ID миньона – stage-www1). Скопируйте каталоги в каталог state:
sudo cp -r /var/cache/salt/master/minions/stage-www1/files /srv/salt/nginx
Если вы посмотрите на содержимое своего каталога state, вы увидите новый каталог под названием files. В этом каталоге доступны соответствующие каталоги в файловой системе minion и три скопированных файла:
find /srv/salt/nginx -printf "%P\n"
files
files/usr
files/usr/share
files/usr/share/nginx
files/usr/share/nginx/html
files/usr/share/nginx/html/index.html
files/etc
files/etc/nginx
files/etc/nginx/sites-available
files/etc/nginx/sites-available/default
files/etc/nginx/nginx.conf
init.sls
Здесь будут поддерживаться все управляемые файлы. Это соответствует пути в параметре source, который вы установили в файле состояния Nginx.
Поскольку теперь есть все нужные файлы, можно уничтожить миньон, на котором был установлен Nginx, и пересобрать его. Благодаря этому в дальнейшем вы сможете протестировать файлы состояния на чистом сервере. Уничтожьте миньон Nginx:
sudo salt-cloud -d stage-www1
Затем можно пересобрать его.
Для этого обычно используется map-файл. Но для сборки одного сервера лучше использовать непосредственно профиль stage-web. Затем вместо salt-cloud можно использовать расширение Salt cloud.profile, что позволяет добавить флаг –async. Он может пересобрать сервер stage-www1 в фоновом режиме, пока вы продолжите работать. Также нужно настроить таргетинг на мастер Salt, так как этот сервер обладает всеми необходимыми профилями:
sudo salt --async sm cloud.profile stage-web stage-www1
Пока нода stage-www1 собирается в фоновом режиме, вы можете продолжать работу.
3: Настройка /etc/nginx/nginx.conf
Теперь нужно поработать над главным конфигурационным файлом Nginx, который будет размещен в /etc/nginx/nginx.conf на миньонах. Найти этот путь можно в каталоге files:
cd /srv/salt/nginx/files/etc/nginx
Этот файл не нужно редактировать на данном этапе, но сейчас вы можете создать его резервную копию:
sudo cp nginx.conf nginx.conf.orig
На этот файл вы сможете ссылаться при пользовательской настройке. Быстро просмотреть любые изменения можно с помощью команды:
diff nginx.conf nginx.conf.orig
Если в будущем у вас возникнет необходимость создать пользовательскую конфигурацию Nginx в различных средах, вы сможете использовать этот файл как шаблон. В данный момент в этом нет необходимости.
4: Настройка шаблона /etc/nginx/sites-available/default
Теперь найдите исходный файл виртуального хоста:
cd /srv/salt/nginx/files/etc/nginx/sites-available
Скопируйте его на всякий случай:
sudo cp default default.orig
Затем можно изменить расширение файла на .jinja (это напомнит вам о том, что этот файл используется как шаблон).
sudo mv default default.jinja
Откройте этот шаблон:
sudo nano default.jinja
В самом начале файла нужно определить функции шаблонов Jinja. Стандартный виртуальный хост обрабатывает разные файлы в зависимости от того, включен ли балансировщик.
Когда соединения принимаются через балансировщик нагрузки, веб-сервер должен ограничивать свой трафик частным интерфейсом. Однако в среде разработки нет балансировки нагрузки, поэтому веб-сервер должен обслуживать открытый интерфейс. Мы можем настроить это различие с помощью Jinja.
Создайте переменную interface, которая определит интерфейс, который используется веб-сервером. Если миньон использует среду de», переменная будет иметь значение eth0. В противном случае она использует eth1, частный интерфейс сервера. Затем добавьте функцию grains.get для получения адреса, связанного с выбранным интерфейсом, и присвойте переменной addr. Это нужно поместить в начало файла:
{%- set interface = 'eth0' if salt['grains.get']('env') == 'dev' else 'eth1' -%}
{%- set addr = salt['network.interface_ip'](interface) -%}
# You may add here your
# server {
# ...
# }
. . .
Теперь нужно отредактировать блок server. Установите переменную addr в директивах listen и server_name. Удалите IPv6 и стандартные параметры server.
{%- set interface = 'eth0' if salt['grains.get']('env') == 'dev' else 'eth1' -%}
{%- set addr = salt['network.interface_ip'](interface) -%}
. . .
server {
listen {{ addr }}:80;
root /usr/share/nginx/html;
index index.html index.htm;
server_name {{ addr }};
location / {
try_files $uri $uri/ =404;
}
}
Сохраните и закройте файл.
5: Настройка шаблона /usr/share/nginx/html/index.html
Теперь можно перейти к файлу index.html. Перейдите в каталог на мастере Salt:
cd /srv/salt/nginx/files/usr/share/nginx/html
Начать нужно так же, как в прошлый раз. Создайте резервную копию исходного файла для дальнейшей работы. Затем нужно переименовать файл, чтобы указать, что это будет шаблон:
sudo cp index.html index.html.orig
sudo mv index.html index.html.jinja
Откройте файл шаблона, чтобы внести необходимые изменения:
sudo nano index.html.jinja
В начало файла добавьте другую переменную с помощью Jinja. Используйте функцию grains.get для получения имени хоста миньона. Сохраните это значение в переменной host.
{% set host = salt['grains.get']('host') -%}
<!DOCTYPE html>
<html>
. . .
Затем нужно использовать это значение, чтобы легко определить, какой веб-сервер обслуживает запросы. Сначала измените значение <title>:
{% set host = salt['grains.get']('host') -%}
<!DOCTYPE html>
<html>
<head>
<title>Welcome from {{ host }}</title>
. . .
Затем измените текст в body:
<body>
<h1>Welcome to nginx!</h1>
<p>Hello! This is being served from:</p>
<h2>{{ host }}</h2>
</body>
</html>
Сохраните и закройте файл.
6: Тестирование настройки
Настройка Nginx завершена. Теперь нужно протестировать состояния.
Используйте модуль выполнения state.show_sls, чтобы увидеть, как Salt интерпретирует файл Nginx. Используйте сервер stage-www1 в качестве цели.
sudo salt stage-www1 state.show_sls nginx
Вы увидите такой результат:
stage-www1:
----------
/etc/nginx/nginx.conf:
----------
__env__:
base
__sls__:
nginx
file:
|_
----------
source:
salt://nginx/files/etc/nginx/nginx.conf
|_
----------
user:
root
|_
----------
group:
root
|_
----------
mode:
640
- managed
|_
----------
order:
10002
. . .
Он в основном отображает информацию из файла /srv/salt/nginx/init.sls с некоторыми интересными дополнениями. Убедитесь, что Salt не допускает ошибок интерпретации и знает, как читать команды. Строка order – еще один важный аспект проверки. Она определяет, когда будет выполняться каждое из отдельных состояний в файле. Первое состояние будет иметь значение order 10000. Оттуда подсчитывается каждое дополнительное состояние. Обратите внимание, что __env__ отличается от env.
Затем запустите пробный прогон файла состояния. Это можно сделать с помощью функции state.apply с параметром test=True. Команда выглядит так:
sudo salt stage-www1 state.apply nginx test=True
Эта команда покажет изменения, если удалить опцию test=True. Просмотрите все изменения и убедитесь, что Salt может правильно интерпретировать все файлы. Поле Comment особенно важно, так как оно может выявлять проблемы даже в тех случаях, когда Salt отмечает состояние как успешное.
Если пробный прогон не выявил ошибок, вы можете попробовать применить состояние ко всем доступным в инфраструктуре веб-серверам.
sudo salt -G 'role:webserver' state.apply nginx
Используя состояние Nginx в промежуточной или производственной среде, вам понадобится внутренний IP-адрес веб-серверов. Эти страницы не доступны по открытому интерфейсу.
sudo salt-call mine.get 'role:webserver' internal_ip expr_form=grain
local:
----------
stage-www1:
ip_address
stage-www2:
ip_address
Если вы применили состояние Nginx в среде разработки, вам понадобится внешний адрес серверов:
- sudo salt-call mine.get ‘role:webserver’ external_ip expr_form=grain
- Протестируйте серверы с помощью curl:
- curl ip_address
Вы получите страницу index.html:
<!DOCTYPE html>
<html>
<head>
<title>Welcome from stage-www1</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>Hello! This is being served from:</p>
<h2>stage-www1</h2>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Как видите, при отображении Jinja на страницу было добавлено имя хоста миньона.
Состояние Nginx работает правильно.
Заключение
В следующем мануале этой серии вы научитесь создавать состояния для балансировщиков нагрузки. Для этого применяются некоторые из методов, которые вы выучили в этом руководстве.