Веб разработчикам нужно настраивать сервера. Обычно под каждый проект. С тех пор как я научился делать это без помощи гугла, настройка перестала быть чем-то интересным, и хотелось её максимально автоматизировать.
Первой идеей было создание виртуальной машины и копирование её при необходимости. Схожие конфигурации настраивать стало проще, но каждый раз когда что-то в конфигурации менялось, приходилось заходить на сервер и настраивать его. Хотелось большего.
Путем проб и ошибок я пришел к связке
Формат пакета для разворачивания окружения в
Создать
Сервер будет работать на
Я использую приватную сеть, внутри которой каждая виртуальная машина получит свой
Настройки виртуальной машины:
Синхронизируем директории с настройками
Осталось настроить обеспечение хоста конфигурациями
Полностью
Описание конфигурации для
Я опишу возможности
Для начала найдем файл
Содержимое его крайне лаконично:
Полный мануал по состояниям есть на сайте проекта: http://docs.saltstack.com/en/latest/topics/tutorials/index.html#states.
Состояния хранятся в
Вызов одной функции можно сокращать:
Также, если
Обычно для работы с ФС используется функция
Если
По-умолчанию, файлы не являются шаблонами
В
Для хранения данных в
По умолчанию, любой
В примере выше, из
Значение
Он содержит список подключаемых файлов
Готовая конфигурация
При разворачивании нескольких образов одновременно нужно не забывать менять
Автоматизация позволяет сократить объем рутинной работы до небольших правок. Разворачивание обычных серверов сократилось до копипаста типовых настроек и запуска
Первой идеей было создание виртуальной машины и копирование её при необходимости. Схожие конфигурации настраивать стало проще, но каждый раз когда что-то в конфигурации менялось, приходилось заходить на сервер и настраивать его. Хотелось большего.
Путем проб и ошибок я пришел к связке
Vagrant
+ SaltStack
, где Vagrant
берет на себя изоляцию окружений, а SaltStack
– управление конфигурацией.Vagrant.
Vagrant
– это менеджер виртуальных машин с настройкой через Vagrantfile
, позволяющий в одной точке собрать конфигурацию машины готовую для запуска. Он умеет не только поднимать виртуальные машины, но и заниматься их "обеспечением". Обеспечение делегирует системам, которые для этого предназначены.Формат пакета для разворачивания окружения в
Vagrant
– .box
. Есть сервис для обмена боксами – https://vagrantcloud.com/. На данный момент он в бете, но, за исключением, "битых" ссылок на боксы, ошибок я не видел.Vagrantfile
Создать
Vagrantfile
не составляет труда. Подробности есть в документации, я же перечислю то, что понадобится в примере.Сервер будет работать на
debian
без предустановленых компонентов SaltStack
. На https://vagrantcloud.com/можно найти .box
.config.vm.box = "mokote/debian-7"
Я использую приватную сеть, внутри которой каждая виртуальная машина получит свой
IP
. Это позволяет запускать несколько машин одновременно и иметь к ним доступ.config.vm.network "private_network", ip: "192.168.56.107"
Настройки виртуальной машины:
config.vm.provider "virtualbox" do |v|
v.name = "demostand"
v.memory = 1024
v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
v.customize ["setextradata", :id, "--VBoxInternal2/SharedFoldersEnableSymlinksCreate/v-root", "1"]
end
Синхронизируем директории с настройками
SaltStack
и с проектом, который будет развернут на создаваемой машине. Для проекта я использовал nfs
в качестве метода синхронизации. Он работает быстрее, чем VirtualBox shared folders
, и настраивается всего одним параметром :nfs => true
, но требует root
доступ.config.vm.synced_folder "salt/roots/", "/srv/"
config.vm.synced_folder "~/Development/web/demostand", "/var/www/demostand", id: "vagrant-root", :nfs => true
Осталось настроить обеспечение хоста конфигурациями
SaltStack
. salt.minion_config
– файл, с которого начинается конфигурация сервера.salt.run_highstate = true
– запускать ли обеспечение при старте машины.salt.pillar
– данные pillar
-хранилища.config.vm.provision :salt do |salt|
salt.minion_config = 'salt/minion'
salt.run_highstate = true
salt.pillar({
"database" => {
"withUser" => true,
"name" => "demostand",
"password" => "fm2QTqimWUrk"
}
})
salt.pillar({"projectName" => "demostand"})
end
Полностью
Vagrantfile
можно посмотреть тут: https://github.com/ligser/salt-vagrant-demostand/blob/master/Vagrantfile.SaltStack
SaltStack
позволяет создавать связку master
–> minion
и инициировать мастером обеспечение minion
свежими конфигами. У меня не было такой необходимости, поэтому обеспечение будет выполняться без участия master
.Описание конфигурации для
SaltStack
– это набор утверждений (состояний, в терминологии SaltStack
), которые должны быть удовлетворены, чтобы minion
считался сконфигурированным успешно. Я опишу возможности
SaltStack
, которые мне пригодились.salt/minion
Для начала найдем файл
salt/minion
, который указан в Vagrantfile
. Это файл с которого начинается конфигурирование машины.Содержимое его крайне лаконично:
file_client: local
. Тут утверждается, что конфигурация хранится локально на minion
, по умолчанию, в директории /srv/salt
, в которую мы настроили синхронизацию.Состояния
Полный мануал по состояниям есть на сайте проекта: http://docs.saltstack.com/en/latest/topics/tutorials/index.html#states.
Состояния хранятся в
.sls
файлах. Обычно .sls
состоит из описания состояний в формате YAML
.apache: # ID
pkg: # состояние
- installed # функция
Вызов одной функции можно сокращать:
apache:
pkg.installed
Также, если
ID
не совпадает с именем объекта состояния – можно указать имя.apache_pkg:
pkg:
- name: apache
- installed
pkg
– это состояние пакетного менеджера. installed
– одна из самых часто используемых функций этого состояния, подразумевающая, что пакет с таким именем должен быть установлен в системе.service
– состояние сервисов. При помощи него можно запускать или останавливать сервисы. Состояние останавливающее apache2
:apache2:
service.dead
file
– состояние файловой системы. Обычно для работы с ФС используется функция
managed
. Если
ID
совпадает с именем файла, нам не нужно указывать параметр name
.source
– место, откуда берется содержимое файла. salt://
– указатель на /srv/salt
, или относительно Vagrantfile
: salt/roots/salt
.По-умолчанию, файлы не являются шаблонами
jinja
, поэтому использовать внутри них данные pillar
нельзя. Чтобы сделать файл шаблоном, нужно указать template: jinja
в параметрах. После этого, файл будет обработан шаблонизатором. jinja
используется и в самих .sls
файлах.В
SaltStack
поддерживаются зависимости между состояниями.watch_in
указывает, в каких сервисах используется файл, чтобы при его изменении перезапустить их. require
поддерживается состоянием pkg
и требует установки определенного пакета./etc/nginx/sites-available/default:
file.managed:
- source: salt://nginx/default
- template: jinja
- user: root
- group: root
- mode: 644
- watch_in:
- service: nginx
Данные
Для хранения данных в
SaltStack
сущестует две системы. pillar
– данные, которых не должно быть в файлах конфига. В Vagrantfile
я положил в pillar
2 ключа: database
– параметры БД и projectName
– имя проекта.grains
– статическая информация, которая будет загружена на minion
при его запуске.grains
я практически не использовал, поэтому не интересовался тонкостями этой системы, если нужно больше информации, она доступна на сайте SaltStack
: http://docs.saltstack.com/en/latest/topics/targeting/grains.html.По умолчанию, любой
.sls
файл обрабатывается шаблонизатором, поэтому в нем можно использовать конструкции:{{ }}
– вывод.{% %}
– условия, или циклы.{{ pillar['database']['name'] }}:
{% if (pillar['database']['withUser']) %}
mysql_user.present:
- host: localhost
- password: {{ pillar['database']['password'] }}
- require:
- service: mysql
- pkg: python-mysqldb
{% endif %}
В примере выше, из
pillar
берется значение [database][name]
, записанное в Vagrantfile
, и назначается в качестве ID
для состояния mysql_user.present
. Значение
['database']['password']
будет использовано в качестве пароля.Top.sls
top.sls
– файл, с которого SaltStack
начнет считывать состояния.Он содержит список подключаемых файлов
.sls
для данной конфигурации.Готовая конфигурация
Готовая конфигурация
Vagrant
и SaltStack
лежит на GitHub
. Она позволяет развернуть сервер с PHP
, nginx
и mysql
одной командой:vagrant up --provision
При разворачивании нескольких образов одновременно нужно не забывать менять
IP
в приватной сети.Вывод
Автоматизация позволяет сократить объем рутинной работы до небольших правок. Разворачивание обычных серверов сократилось до копипаста типовых настроек и запуска
vagrant up
. То, на что раньше могло уйти несколько часов, сейчас занимает минуты, большую часть которых сервер сам ставит пакеты.