Тематические термины: Ansible, NGINX.
В статье разберем использование Ansible для установки веб-сервера NGINX. Мы попробуем продемонстрировать максимум возможностей системы управления — плейбуки (playbook), роли (role), переменные (vars), шаблоны (templates), обработчики (handlers). Также мы сделаем развертывание веб-сервера на 2 разных семейства операционных систем — на основе deb и RPM.
Создадим тестовую группу хостов, на которой будем тестировать удаленную установку приложения.
Открываем файл хостов 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: autoworker_connections: 2048client_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, которая будет определена в настройках плейбука, так как для каждого типа операционной системы она должна быть своя).
Теперь настраиваем нашу роль для использования шаблона:
Добавляем:
– name: Replace nginx.conf template: src=templates/nginx.conf dest=/etc/nginx/nginx.conf
* данная роль определяет, каким файлом на сервере ansible (src) необходимо заменить файл на удаленной системе (dest).
И последнее, открываем файл плейбука:
… вставляем:
– hosts: redhat-servers vars: nginx_user: nginx …
– hosts: debian-servers vars: nginx_user: www-data …
* в данном примере мы создаем переменную nginx_user. Так как для разных семейств операционных систем используются разные пользователя для nginx по умолчанию, мы также сделали переменную с разными значениями для RPM и deb.
Готово — запускаем плейбук:
… и вводим дважды пароли. На наших серверах должен появиться конфигурационной файл nginx.conf в соответствии с нашим шаблоном.
Создадим виртуальные домены при помощи ansible. Сначала создадим переменные — для каждого сервера должны быть свои домены — такие переменные можно задать в файле hosts, котором мы создавали хосты для ansible:
Добавляем к нашим строкам:
[redhat-servers]192.168.0.11 virtual_domain=domain1.admins24.com
[debian-servers]192.168.0.12 virtual_domain=domain2.admins24.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 задачи:
—…
– 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 задать в файле плейбука. Но мы так поступили намеренно, чтобы продемонстрировать возможность использования переменных при описании роли.
Открываем обработчик:
Дописываем:
– name: nginx restart service: name=nginx state=restarted
Запускаем плейбук:
В нашем примере нам не довелось использовать теги — еще одну удобную возможность управления запуском плейбука.
Теги позволяют отметить роль и при запуске плейбука запустить именно ее, проигнорировав другие роли. Например, есть такой плейбук:
… 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 — в нее поместит файлы с описанием роли.
Готовые библиотеки можно использовать для выполнения задач или просто как шпаргалки.
Продолжая использовать данный сайт вы принимаете политику конфиденциальности и cookies