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

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

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

1: Сбор информации MySQL с помощью debconf-utils

Процесс создания состояний MySQL будет немного более сложным, чем в предыдущих примерах с Nginx и HAProxy. В отличие от этих двух приложений, установка MySQL обычно подразумевает ответы на ряд вопросов инсталлятора.

Прежде чем начать работу над файлом состояния, нужно выполнить тестовую установку MySQL на одном из миньонов. Затем вы можете использовать пакет debconf-utils для сбора информации о вопросах инсталлятора, которые нужно будет заполнить.

Если у вас до сих пор нет промежуточной среды, создайте ее:

sudo salt-cloud -P -m /etc/salt/cloud.maps.d/stage-environment.map

После того, как серверы баз данных будут доступны, выберите один из этих серверов и установите на него MySQL, чтобы затем собрать соответствующую информацию:

sudo salt stage-db1 pkg.install mysql-server

Чтобы легко запросить в базах данных debconf необходимую информацию, нужно установить пакет debconf-utils на миньон базы данных:

sudo salt stage-db1 pkg.install debconf-utils

Теперь в Salt будут доступны функции debconf. Можно использовать функцию модуля выполнения debconf.get_selections, чтобы собрать всю информацию для установки базы данных. эти данные нужно направить в less, потому что это вернет всю информацию из пакетов, установленных на этом хосте.

sudo salt stage-db1 debconf.get_selections | less

В выводе найдите раздел для MySQL.

. . .
mysql-server-5.5:
|_
- mysql-server/root_password
- password
|_
- mysql-server/root_password_again
- password
|_
- mysql-server-5.5/really_downgrade
- boolean
- false
|_
- mysql-server-5.5/start_on_boot
- boolean
- true
. . .

Две верхние записи содержат имена полей, которые вам нужны (mysql-server/root_password и mysql-server/root_password_again). Вторая строка в этих записях задает тип поля, который нужно указать в файле состояния.

Скопировав эту информацию из вывода debconf, вы должны извлечь файл /etc/mysql/my.cnf. Он понадобится позже при настройке MySQL.

sudo salt stage-db1 cp.push /etc/mysql/my.cnf

Переместив файл /etc/mysql/my.cnf на мастер Salt, удалите этот ресурс, чтобы создать свежий сервер для дальнейшей работы.

sudo salt-cloud -d stage-db1

Удалив сервер, вы можете воссоздать его в фоновом режиме с помощью этой команды (где sm – имя мастера Salt).

sudo salt --async sm cloud.profile stage-db stage-db1

Пока создается сервер БД, вы можете создать файл состояния для MySQL.

2: Файл состояния для MySQL

В каталоге /srv/salt создайте отдельный каталог для состояния БД.

sudo mkdir -p /srv/salt/mysql

Здесь нужно создать файл init.sls:

sudo nano /srv/salt/mysql/init.sls

Чтобы на миньонах устанавливался пакет debconf-utils, который поможет задавать требуемые значения, нужно добавить в файл состояния модуль pkg.installed.

debconf-utils:
pkg.installed

После установки пакета debconf-utils можно подготовить предварительные ответы на запросы инсталлятора БД с помощью модуля состояния debconf.set. Используйте атрибут name, чтобы указать имя пакета, для которого нужно установить ответы. Затем создайте структуру data, содержащую словарь информации, которую нужно использовать для заполнения запросов инсталлятора.

Структура data в основном содержит информацию для ответов на запросы, которые появились во время тестовой установки MySQL. Вы знаете имена полей и типы данных, которые нужно использовать. Чтобы указать пароль, извлеките его из pillar-системы Salt с помощью функции модуля pillar.get. Это позволит отделить учетные данные от кода. Указать пароль в pillar-системе можно немного позже.

Примечание: Обратите особое внимание на отступы словаря data. Весь блок имеет отступы в четыре пробела, а не в два пробела. Это типичный метод встраивания словаря в список YAML.

debconf-utils:
pkg.installed
mysql_setup:
debconf.set:
- name: mysql-server
- data:
'mysql-server/root_password': {'type': 'password', 'value': '{{ salt['pillar.get']('mysql:root_pw', '') }}' }
'mysql-server/root_password_again': {'type': 'password', 'value': '{{ salt['pillar.get']('mysql:root_pw', '') }}' }
- require:
- pkg: debconf-utils

Чтобы взаимодействовать с MySQL, на серверах баз данных должны быть доступны соответствующие библиотеки Python. Можно установить пакет ptyhon-mysqldb, чтобы обеспечить Salt доступ к возможностям MySQL. Затем можно безопасно установить программное обеспечение сервера MySQL. Используйте параметр require, чтобы указать зависимость сервера от debconf и библиотек Python.

После установки можно добавить состояние сервиса, чтобы сервис запускался автоматически. Это состояние будет следить за изменениями в пакете MySQL и в базовом конфигурационном файле MySQL и перезагружать сервис, если эти файлы изменились.

debconf-utils:
pkg.installed
mysql_setup:
debconf.set:
- name: mysql-server
- data:
'mysql-server/root_password': {'type': 'password', 'value': '{{ salt['pillar.get']('mysql:root_pw', '') }}' }
'mysql-server/root_password_again': {'type': 'password', 'value': '{{ salt['pillar.get']('mysql:root_pw', '') }}' }
- require:
- pkg: debconf-utils
python-mysqldb:
pkg.installed
mysql-server:
pkg.installed:
- require:
- debconf: mysql-server
- pkg: python-mysqldb
mysql:
service.running:
- watch:
- pkg: mysql-server
- file: /etc/mysql/my.cnf

Есть несколько файлов MySQL, которыми нужно управлять с помощью Salt. Наиболее очевидным является файл /etc/mysql/my.cnf, о котором мы говорили выше. Чтобы учитывать динамическую информацию, этот файл должен быть шаблоном Jinja.

Другие файлы связаны с управлением системой MySQL. Чтобы управлять базами данных, система Salt должна иметь информацию о том, как подключиться к РСУБД. Для этого можно создать простой файл в каталоге /etc/salt/minion.d и просто сослаться в нем на файл, в котором можно найти данные о соединении. Файл с данными о соединении с БД – еще один файл, который нужно добавить в состояние. Файл подключения к базе данных должен быть шаблоном.

. . .
mysql:
service.running:
- watch:
- pkg: mysql-server
- file: /etc/mysql/my.cnf
/etc/mysql/my.cnf:
file.managed:
- source: salt://mysql/files/etc/mysql/my.cnf.jinja
- template: jinja
- user: root
- group: root
- mode: 640
- require:
- pkg: mysql-server
/etc/salt/minion.d/mysql.conf:
file.managed:
- source: salt://mysql/files/etc/salt/minion.d/mysql.conf
- user: root
- group: root
- mode: 640
- require:
- service: mysql
/etc/mysql/salt.cnf:
file.managed:
- source: salt://mysql/files/etc/mysql/salt.cnf.jinja
- template: jinja
- user: root
- group: root
- mode: 640
- require:
- service: mysql

В завершение нужно добавить состояние service.restart, которое перезапустит процесс salt-minion. Это необходимо, чтобы миньон мог отслеживать и применять обновления файла /etc/salt/minion.d/mysql.conf. Процесс salt-minion нужно перезапускать только в том случае, если в файле /etc/salt/minion.d/mysql.conf есть изменения. Для этого добавьте реквизит watch.

. . .
/etc/mysql/salt.cnf:
file.managed:
- source: salt://mysql/files/etc/mysql/salt.cnf.jinja
- template: jinja
- user: root
- group: root
- mode: 640
- require:
- service: mysql
restart_minion_for_mysql:
service.running:
- name: salt-minion
- watch:
- file: /etc/salt/minion.d/mysql.conf

Сохраните и закройте файл.

3: Создание pillar-системы для MySQL

В состоянии MySQL для ввода root пароля MySQL значением из pillar-системы используется функция модуля pillar.get. Теперь нужно настроить эту систему так, чтобы состояние могло извлечь необходимые данные и собрать учетные данные БД.

Pillar-система идеально подходит в этой ситуации, поскольку она позволяет присваивать данные определенным хостам. Если хост не соответствует условиям, он не получит доступа к данным. На данном этапе состоянию нужен только root-пароль. Согласно файлу состояния, пароль в pillar-системе должен храниться в mysql:root_pw.

Создание файла top для pillar-системы

Прежде чем создавать файлы MySQL, нужно создать файл top. Этот файл используется для сравнения миньонов с данными pillar. Миньоны не смогут получить доступ к данным, если они не отвечают файлу top.

Ранее вы должны были создать каталог /srv/pillar. Теперь нужно создать файл top.sls в этом каталоге, чтобы начать работу:

cd /srv/pillar
sudo nano top.sls

Внутри нужно указать среду base. Используйте составное сравнение для поиска хостов. Файл будет оценивать роль сервера и серверную среду, чтобы определить, какой из pillar-файлов может использовать данный хост.

Pillar использует точечную нотацию для обозначения файлов в каталоге. Например, корневым каталогом системы pillar является /srv/pillar. Чтобы присвоить mysql.sls pillar, расположенный в каталоге dev, используйте dev.mysql.

Файл выглядит следующим образом:

base:
'G@env:dev and G@role:dbserver':
- match: compound
- dev.mysql
'G@env:stage and G@role:dbserver':
- match: compound
- stage.mysql
'G@env:prod and G@role:dbserver':
- match: compound
- prod.mysql

Сохраните и закройте его.

Создание pillar-файлов для сред

Только что вы создали общий pillar-файл для всех серверов.

Теперь нужно создать те каталоги, на которые ссылается вышеупомянутый файл:

sudo mkdir /srv/pillar/{prod,stage,dev}

Затем нужно создать файл mysql.sls в каждом из этих каталогов. Можно начать с файла /srv/salt/stage/mysql.sls, так как в настоящее время тестирование происходит в промежуточной среде:

sudo nano /srv/pillar/stage/mysql.sls

Файл состояния будет пытаться извлечь root-пароль MySQL из pillar-системы с помощью ключа mysql:root_pw. Это вложенный ключ, где root_pw является дочерним ключом mysql. Выберите пароль для root-пользователя MySQL и укажите его в файле:

mysql:
root_pw: staging_mysql_root_pass

Выберите любой пароль. Сохраните и закройте файл.

Создайте аналогичный файл для среды разработки:

sudo nano /srv/pillar/dev/mysql.sls
mysql:
root_pw: development_mysql_root_pass

Создайте еще один такой файл для среды производства:

sudo nano /srv/pillar/prod/mysql.sls
mysql:
root_pw: production_mysql_root_pass

Для каждой среды укажите индивидуальный пароль.

Мы еще вернемся к этим файлам, чтобы указать в них другие данные, которые нужно отделить от кода.

Пока что сохраните и закройте все эти файлы.

4: Создание шаблона /etc/mysql/my.cnf.jinja

Во время тестовой установки mysql-server на сервере stage-db1 вы переместили файл /etc/mysql/my.cnf на мастер-сервер. Он все равно должен быть доступен в кэш-файле Salt. Вы можете скопировать всю структуру каталога, ведущую к этому файлу кэша, в каталог /srv/salt/mysql:

sudo cp -r /var/cache/salt/master/minions/stage-db1/files /srv/salt/mysql

Перейдите в каталог, в котором хранится файл mycnf:

cd /srv/salt/mysql/files/etc/mysql

Создайте резервную копию исходного файла.

sudo cp my.cnf my.cnf.orig

Измените суффикс файла my.cnf на .jinja – это значит, что файл будет шаблоном.

sudo mv my.cnf my.cnf.jinja

Теперь нужно предоставить возможность удаленного подключения к MySQL. В сущности, MySQL привязывается к локальному интерфейсу loopback. Вместо этот БД должна прослушивать адрес хоста в частной сети.

Для этого найдите строку bind-address в разделе [mysqld]. Используйте модуль выполнения network.interface_ip, чтобы извлечь адрес, присвоенный интерфейсу eth1 миньона.

. . .
[mysqld]
. . .
bind-address            = {{ salt['network.interface_ip']('eth1') }}

Также нужно отключить разрешение имен DNS. Благодаря параметру skip-name-resolve MySQL не будет выдавать ошибку, если не сможет разрешить имя.

. . .
[mysqld]
. . .
bind-address            = {{ salt['network.interface_ip']('eth1') }}
skip-name-resolve

Сохраните и закройте файл.

5: Создание файла /etc/salt/minion.d/mysql.conf

Затем нужно создать файл, который используется для добавления в конфигурации миньона информации о том, как подключиться к базе данных MySQL. Вместо того чтобы хранить конфигурации в файле /etc/salt/minion, вы можете поместить новый файл в каталог /etc/salt/minion.d, в котором миньон узнает, где найти информацию о соединении.

Создайте необходимую структуру каталогов в /srv/salt/mysql/files:

sudo mkdir -p /srv/salt/mysql/files/etc/salt/minion.d

Создайте в этом каталоге файл mysql.conf:

sudo nano /srv/salt/mysql/files/etc/salt/minion.d/mysql.conf

В файле должна быть только одна опция – расположение файла информации о соединении. В данном случае это будет файл /etc/mysql/salt.cnf:

mysql.default_file: '/etc/mysql/salt.cnf'

Сохраните и закройте файл.

6: Создание шаблона /etc/mysql/salt.cnf

Теперь нужно создать файл, на который ссылается конфигурация миньона. Это будет шаблон, так как он будет динамически собирать данные из pillar-системы. Поместите этот файл в каталог /srv/salt/mysql/files/etc/mysql:

sudo nano /srv/salt/mysql/files/etc/mysql/salt.cnf.jinja

Внутри нужно открыть раздел [client] и указать тип информации. Далее можно указать клиента для подключения к локальной машине с пользователем root по сокету Unix, расположенному в /var/run/mysqld/mysqld.sock. Это все значения MySQL по умолчанию.

[client]
host                = localhost
user                = root
socket              = /var/run/mysqld/mysqld.sock

Теперь нужно добавить пароль. Пароль будет извлекаться прямо из системы pillar так же, как и в разделе debconf файла состояния MySQL.

[client]
host                = localhost
user                = root
socket              = /var/run/mysqld/mysqld.sock
password            = {{ salt['pillar.get']('mysql:root_pw', '') }}

Сохраните и закройте файл.

7: Проверка состояния

Теперь базовое состояние БД готово.

Чтобы протестировать его, используйте функцию модуля state.show_sls.

sudo salt stage-db1 state.show_sls mysql

Просмотрите результаты, убедитесь, что у Salt нет проблем с анализом файла /srv/salt/mysql/init.sls.

Затем выполните пробный прогон состояния, добавив test=True в конец функции state.apply:

sudo salt stage-db1 state.apply mysql test=True

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

Все комментарии об ошибке будут содержать фразу «one or more requisite failed» (кроме состояния mysql_setup – оно не сработает ввиду отсутствия debconf.set). Убедитесь, что в выводе нет других ошибок.

После теста можно применить состояние:

sudo salt stage-db1 state.apply mysql

Также нужно проверить, что Salt может подключаться к базе данных MySQL и запрашивать данные. Убедитесь, что вы можете запросить список баз данных по умолчанию:

sudo salt stage-db1 mysql.db_list
stage-db1:
- information_schema
- mysql
- performance_schema

Это значит, что система Salt смогла подключиться к БД MySQL с помощью информации из файла /etc/mysql/salt.cnf.

После тестирования можно удалить сервер stage-db1:

sudo salt-cloud -d stage-db1

Его можно восстановить в фоновом режиме с помощью этой команды (где sm – это имя мастера Salt).

sudo salt --async sm cloud.profile stage-db stage-db1

Tags: , ,