Тематические термины: Ansible , NGINX .
В статье разберем использование Ansible для установки веб-сервера NGINX. Мы попробуем продемонстрировать максимум возможностей системы управления — плейбуки (playbook), роли (role), переменные (vars), шаблоны (templates), обработчики (handlers). Также мы сделаем развертывание веб-сервера на 2 разных семейства операционных систем — на основе deb и RPM.
Задаем группы хостов
Плейбук
Роль
Запуск плейбука
Создание конфигурационных файлов nginx
Использование переменных
Шаблон для nginx.conf
Шаблон для virtual hosts
Использование тегов
Ansible Galaxy
Создадим тестовую группу хостов, на которой будем тестировать удаленную установку приложения.
Открываем файл хостов ansible:
vi /etc/ansible/hosts
Добавляем группу хостов или редактируем ее:
[redhat-servers]
192.168.0.11
[debian-servers]
192.168.0.12
* в данном примере мы создаем 2 группы хостов — redhat-servers для серверов семейства Red Hat и debian-servers — для deb-серверов. В каждую группу входят по одному серверу — 192.168.0.11 и 192.168.0.12 .
Проверить доступность хостов для ansible можно командой:
ansible -m ping all -u ansible -k
* данной командой мы пропингуем все хосты из инвентаризационного файла hosts.
… мы должны получить, примерно, такой ответ:
192.168.0.11 | SUCCESS => {
«ansible_facts»: {
«discovered_interpreter_python»: «/usr/bin/python3»
},
«changed»: false,
«ping»: «pong»
}
192.168.0.12 | SUCCESS => {
«ansible_facts»: {
«discovered_interpreter_python»: «/usr/bin/python»
},
«changed»: false,
«ping»: «pong»
}
Создаем файл для playbook:
vi /etc/ansible/play.yml
—
— hosts: redhat-servers
become:
true
become_method:
su
become_user:
root
remote_user:
ansible
roles:
— epel
— nginx
— hosts: debian-servers
become:
true
become_method:
sudo
become_user:
root
remote_user:
ansible
roles:
— nginx
* где:
* В данном случае мы задействуем нашу группы хостов, которые создали в самом начале; повышаем привилегии методом su под пользователем root (su — root) для группы redhat-servers и методом sudo для debian-servers ; подключение к серверам выполняется от пользователя ansible ; используем созданную нами роль nginx (саму роль мы создадим позже). Для систем RPM сначала выполним роль epel — она будет отвечать за установку репозитория EPEL, так как в стандартном репозитории nginx нет.
Стоит отдельно уделить внимание вопросу повышения привилегий. IT-среды могут применять разные политики относительно безопасности. Например, на серверах CentOS, по умолчанию, нет sudo и повышать привилегии нужно с помощью su. В Ubuntu наоборот — по умолчанию есть sudo, а su не работает, так как пароль на root не устанавливается. В данном случае есть несколько путей при работе с Ansible:
Роли в Ansible используются для логического разделения плейбука. Они имеют строгий синтаксис и файловую структуру. Таким образом, конфигурация становится более упорядоченной и понятной для дальнейшей поддержки.
И так, для ролей должна быть четкая файловая структура — создаем каталоги:
mkdir -p /etc/ansible/roles/nginx/tasks
mkdir -p /etc/ansible/roles/epel/tasks
* в данном случае мы создали каталоги nginx , epel и tasks внутри каталога roles . В ansible это означает, что мы создали роли с названием nginx и epel , а файл main.yml , который мы поместим в каталоги tasks будет описывать задачи данных ролей.
Создаем файл с описанием задач для роли nginx:
vi /etc/ansible/roles/nginx/tasks/main.yml
—
— name: Install Nginx Web Server on RedHat Family
yum:
name=nginx
state=latest
when:
ansible_os_family == «RedHat»
notify:
— nginx systemd
— name: Install Nginx Web Server on Debian Family
apt:
name=nginx
state=latest
when:
ansible_os_family == «Debian»
notify:
— nginx systemd
* где
* В данном примере мы создали простую задачу для роли по развертыванию nginx . На системы RPM установка выполняется с помощью модуля yum , на deb — apt . Версия должна быть последней ( latest ); после установки пакета, необходимо разрешить автозапуск сервиса и запустить его.
* при установке пакетов также следует учитывать, что некоторые могут иметь разные названия в разных системах. Например, Apache в RMP-системах называется httpd , в deb — apache2 .
Создаем файл с описанием задач для роли epel:
vi /etc/ansible/roles/epel/tasks/main.yml
—
— name: Install EPEL Repo
yum:
name=epel-release
state=present
Обратите внимание, что в плейбуке выше мы задействовали notify, но не задали handlers — в качестве примера, мы вынесем его в отдельный файл:
mkdir /etc/ansible/roles/nginx/handlers
vi /etc/ansible/roles/nginx/handlers/main.yml
—
— name: nginx systemd
systemd:
name: nginx
enabled: yes
state: started
* handlers — описание обработчика, который может быть вызван с помощью notify; systemd — модуль для управления юнитами systemd; systemd enabled — разрешает или запрещает сервис; systemd state — состояние, которое должно быть у сервиса. В данном примере мы указываем, что у демона nginx должно быть состояние started и разрешен автозапуск ( enabled ).
Запускаем наш плейбук:
ansible-playbook /etc/ansible/play.yml -kK
После ввода данной команды система запросит первый пароль для учетной записи, от которой мы подключаемся к удаленным серверам (в нашем примере мы задали ее в самом плейбуке, опции remote_user):
SSH password:
После ввода пароля, будет запрошен второй пароль — для повышения привилегий на самой удаленной системе:
BECOME password[defaults to SSH password]:
… в итоге мы должны увидеть следующую картину:
192.168.0.11 : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
192.168.0.12 : ok=2 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
После установки веб-сервера nginx необходимо его настроить. Процесс настройки мы разделим на создание переменных и шаблонов конфигурационных файлов, а также настройки роли для формирования конфигурационных файлов на основе шаблона.
Переменные задаются в файле main.yml, который находится в каталоге vars, который, в свою очередь, находится в каталоге роли. И так, создаем каталог для переменных:
mkdir /etc/ansible/roles/nginx/vars
… и сам файл main.yml:
vi /etc/ansible/roles/nginx/vars/main.yml
worker_processes: auto
worker_connections: 2048
client_max_body_size: 512M
* где представлены некоторые опции настройки NGINX:
Создаем каталог для хранения шаблонов:
mkdir /etc/ansible/roles/nginx/templates
… и создаем первый шаблон для конфигурационного файла nginx.conf:
vi /etc/ansible/roles/nginx/templates/nginx.conf
user {{ nginx_user }};
worker_processes {{ worker_processes }};
worker_priority -1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections {{ worker_connections }};
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main ‘$remote_addr — $remote_user [$time_local] «$request» ‘
‘$status $body_bytes_sent «$http_referer» ‘
‘»$http_user_agent» «$http_x_forwarded_for»‘;
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
reset_timedout_connection on;
client_body_timeout 35;
send_timeout 30;
gzip on;
gzip_min_length 1000;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
gzip_disable «msie6»;
types_hash_max_size 2048;
client_max_body_size {{ client_max_body_size }};
proxy_buffer_size 64k;
proxy_buffers 4 64k;
proxy_busy_buffers_size 64k;
server_names_hash_bucket_size 64;
include /etc/nginx/modules-enabled/*.conf;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
* это пример рабочего конфигурационного файла. Переменных могло быть и больше, но для демонстрации их использования, вполне, достаточно. Сами переменные заключены в двойные фигурные скобки и были нами определены в файле выше (кроме переменной nginx_user , которая будет определена в настройках плейбука, так как для каждого типа операционной системы она должна быть своя).
Теперь настраиваем нашу роль для использования шаблона:
vi /etc/ansible/roles/nginx/tasks/main.yml
Добавляем:
— name: Replace nginx.conf
template:
src=templates/nginx.conf
dest=/etc/nginx/nginx.conf
* данная роль определяет, каким файлом на сервере ansible ( src ) необходимо заменить файл на удаленной системе ( dest ).
И последнее, открываем файл плейбука:
vi /etc/ansible/play.yml
… вставляем:
— hosts: redhat-servers
vars:
nginx_user: nginx
…
— hosts: debian-servers
vars:
nginx_user: www-data
…
* в данном примере мы создаем переменную nginx_user . Так как для разных семейств операционных систем используются разные пользователя для nginx по умолчанию, мы также сделали переменную с разными значениями для RPM и deb.
Готово — запускаем плейбук:
ansible-playbook /etc/ansible/play.yml -kK
… и вводим дважды пароли. На наших серверах должен появиться конфигурационной файл nginx.conf в соответствии с нашим шаблоном.
Создадим виртуальные домены при помощи ansible. Сначала создадим переменные — для каждого сервера должны быть свои домены — такие переменные можно задать в файле hosts, котором мы создавали хосты для ansible:
vi /etc/ansible/hosts
Добавляем к нашим строкам:
[redhat-servers]
192.168.0.11 virtual_domain=domain1.remontka.com
[debian-servers]
192.168.0.12 virtual_domain=domain2.remontka.com
* мы создали переменную virtual_domain , у которой будут свои значения для каждого хоста.
Создаем шаблон:
vi /etc/ansible/roles/nginx/templates/nginx_vhosts.conf
server {
listen 80;
server_name {{ virtual_domain }} www.{{ virtual_domain }};
root /var/www/{{ virtual_domain }};
access_log /var/log/nginx/{{ virtual_domain }}_access_log;
error_log /var/log/nginx/{{ virtual_domain }}_error_log;
location / {
fastcgi_pass unix:{{ fastcgi_pass_path }};
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~* ^.+.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|docx|xls|xlsx|exe|pdf|ppt|tar|wav|bmp|rtf|js)$ {
expires modified +1w;
}
}
* в данном примере мы создаем простой конфигурационный файл для создания виртуального домена. В качестве самого домена берется значение переменной virtual_domain , которую мы задали через файл hosts . Переменная fastcgi_pass_path будет создана для каждой группы систем своя и определяем путь до сокетного файла для взаимодействия nginx с fastcgi.
Настраиваем нашу роль — создаем 3 задачи:
vi /etc/ansible/roles/nginx/tasks/main.yml
Добавляем:
—
…
— name: Create home directory for www
file:
path: /var/www/{{ virtual_domain }}
state: directory
— name: Add virtual domain in NGINX for RPM
vars:
fastcgi_pass_path: /var/run/php-fpm/php5-fpm.sock
template:
src=templates/nginx_vhosts.conf
dest=/etc/nginx/conf.d/{{ virtual_domain }}.conf
when:
ansible_os_family == «RedHat»
notify:
— nginx restart
— name: Add virtual domain in NGINX for Deb
vars:
fastcgi_pass_path: /run/php/php7.2-fpm.sock
template:
src=templates/nginx_vhosts.conf
dest=/etc/nginx/sites-enabled/{{ virtual_domain }}.conf
when:
ansible_os_family == «Debian»
notify:
— nginx restart
* первая задача нужна для создания каталога, в котором будут находиться файлы сайта (без данного каталога наш конфигурационный сайт выдаст ошибку при попытке перезапустить сервис nginx). Вторая задача создаем конфигурационный файл для виртуального домена, который находится в каталоге /etc/nginx/conf.d ; источником данных служит созданный нами шаблон nginx_vhosts.conf ; также мы задаем переменную fastcgi_pass_path , которая будет указывать путь до сокетного файла. Третья задача также создает конфигурацию для виртуального домена на базе созданного шаблона; в отличие от второй задачи, третья создает конфигурационный файл в каталоге /etc/nginx/sites-enabled , а также имеет другое значение переменной fastcgi_pass_path . После успешного выполнения задачи, будет отправлен сигнал на перезапуск службы nginx для применения настроек (некоторые сервисы принимают более предпочтительный вариант — reloaded ).Также мы добавили условие — вторая задача будет применяться к система на базе Red Hat, третья — Debian.
* на самом деле, мы могли две последние задачи объединить в одну, а переменную fastcgi_pass_path задать в файле плейбука. Но мы так поступили намеренно, чтобы продемонстрировать возможность использования переменных при описании роли.
Открываем обработчик:
vi /etc/ansible/roles/nginx/handlers/main.yml
Дописываем:
—
…
— name: nginx restart
service:
name=nginx
state=restarted
Запускаем плейбук:
ansible-playbook /etc/ansible/play.yml -kK
В нашем примере нам не довелось использовать теги — еще одну удобную возможность управления запуском плейбука.
Теги позволяют отметить роль и при запуске плейбука запустить именно ее, проигнорировав другие роли. Например, есть такой плейбук:
…
roles:
— role: nginx
tags: web1
— role: apache
tags: web2
* в данном плейбуке есть две роли — одна называется nginx , вторая — apache ; для каждой роли мы задали свой тег.
Теперь, чтобы запустить плейбук, но выполнить в нем определенную роль, нам достаточно указать тег:
ansible-playbook —tags web2 /etc/ansible/play.yml -kK
* данная команда запустит плейбук с выполнением только роли с тегом web2 (в нашем примере, apache ).
На последок хочется сказать пару слов о Ansible Galaxy. Грубо говоря, это репозиторий готовых плейбуков и ролей. Найти файлы, соответствующую задаче, а также документацию можно на портале galaxy.ansible.com . Установка выполняется командой ansible-galaxy, например:
ansible-galaxy install geerlingguy.apache
* данная команда создаст в каталоге пользователя папку .ansible/roles/geerlingguy.apache — в нее поместит файлы с описанием роли.
Готовые библиотеки можно использовать для выполнения задач или просто как шпаргалки.
Если команда нам вернула предупреждение:
collection was NOT installed successfully: missing required ‘current_version’ from server response
… и не установила модуль, скорее всего, у нас низкая версия ansible. Проверить ее можно командой:
ansible —version
Начиная с версии 2.13.9, разработчик выпустил новый сервер Galaxy, а для версий ниже нужно использовать сервер old-galaxy.ansible.com.
Для решения проблемы открываем конфигурационный файл ansible:
vi /etc/ansible/ansible.cfg
Добавляем:
[galaxy]
server = https://old-galaxy.ansible.com/
Пробуем установку.
Zulip — программное обеспечение для реализации корпоративного чата. Разработан в 2012 году, в 2014 был…
Zookeeper — cервис-координатор, который позволяет обеспечить контроль синхронизации данных. Разработан на Java компанией Apache Software…
Zimbra — программное обеспечение для реализации почтового сервиса или, если сказать точнее, автоматизации совместной деятельности…
Zabbix — бесплатная система мониторинга. Позволяет отслеживать состояние сетевых узлов, компьютеров и серверов. Возможности: Поддержка…
YouTube — компания-владелец одноименного портала для просмотра и хранения видео. Чтобы пользоваться данным порталом достаточно…
Yota — провайдер, предоставляющий доступ к сети Интернет по беспроводной связи. Впервые, сервис начал работать…