Инфраструктура SaltStack: создание состояний Salt для Nginx  

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 работает правильно.

Заключение

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

Tags: , ,