Что такое Ansible и как его использовать


Оглавление (нажмите, чтобы открыть):

Краткое руководство: Как установить и настроить Ansible в Linux для автоматизации

Главное меню » Операционная система Linux » Краткое руководство: Как установить и настроить Ansible в Linux для автоматизации

Почему необходимо установить и настроить Ansible в Linux.

Есть много таких инструментов, доступных для автоматизации, таких как Chef или Puppet. Однако эти инструменты имеют сложности в настройке. У нас есть отличная альтернатива для этих вариантов, это Ansible. С помощью ее, вы можете очень легко установить и настроить Ansible в Linux.

Это руководство быстро расскажет вам о том, как установить и настроить Ansible в Linux.

Сколько Ansible работает!

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

Детали установки для установки Ansible.

Детали для сервера управления Ansible:

Детали машины клиента:

Шаг 1: Установка Ansible на сервере управления.

Для Linux Mint, Ubuntu и Debian
Для RHEL, CentOS и Fedora

Пожалуйста, обратите внимание, что нет никакого официального репозитория Ansible для RedHat, мы все еще можем установить Ansible, добавляя репозиторий Epel под RHEL или Centos.

После установки Ansible вы можете проверить версию с помощью следующей команды.

Шаг 2: Настройка SSH для настройки Ansible.

Для развертывания или управления на клиентской машине с нашего сервера управления «destroyer», нам нужно установить пароль на SSH между ними. В этой демонстрации мы настроили пользователя lradmin для пароля SSH.

Генерировать ключи SSH на сервере управления для пользователя lradmin.

Здесь мы сделали генерацию ключей, в следующем шаге нам необходимо скопировать содержимое «/root/.ssh/id_rsa.pub» на клиентскую систему для пользователя lradmin. Пожалуйста, следуйте инструкциям, приведенные в этом посте, так чтобы пароль имел связь между сервером управления и машиной клиента web1 и web2.

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

Шаг 3: Создание файла инвентаризации для Ansible.

На следующем этапе нам нужно создать файл инвентаризации для списка клиентов. В основном его список IP клиента или имя хоста для машин, которые используются для автоматизации.

Пожалуйста, добавьте ниже строки кода в файл “/etc/Ansible/hosts” на нашем сервере управления.

Приведенные выше строки кода описывают, как список клиентских машин подпадает под категорию веб-пользователя, имеющего Ansible как lradmin.

Шаг 4: Проверьте соединение.

Теперь пришло время, чтобы проверить, является ли наша конфигурация правильно установлена или нет. Для этого мы будем использовать пинг в Ansible.

В приведенной выше команде мы использовали пинг для нашего веб – сервера.

Система должна ответить сообщением ниже, если все Ok.

Шаг 4: Выполнение удаленных команд на клиентских машинах.

Теперь мы имеем возможность запускать произвольные команды на клиентских машинах, чтобы извлечь некоторую информацию о них. Таким образом, чтобы сделать это, необходимо использовать модуль «command» в пределах Ansiblensible.

  • В случае, если вы хотите использовать файловую систему на клиентской машине.
Проверка бесперебойной работы клиентских машин.

Вывод:

Необходимость автоматизации в ИТ-индустрии увеличивается с каждым днем для снижения стоимости, а также время для выполнения различных задач. Есть инструменты и приложения, доступные на рынке. Ansilble проста в установке и настройке. Кроме того, его агент запускает любой фоновый процесс на клиентах.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Использование роли и плейбука Ansible на примере установки и настройки NGINX


В статье разберем использование Ansible для установки веб-сервера NGINX. Мы попробуем продемонстрировать максимум возможностей системы управления — плейбуки (playbook), роли (role), переменные (vars), шаблоны (templates), обработчики (handlers). Также мы сделаем развертывание веб-сервера на 2 разных семейства операционных систем — на основе deb и RPM.

Группы хостов

Создадим тестовую группу хостов, на которой будем тестировать удаленную установку приложения.

Открываем файл хостов ansible:

Добавляем группу хостов или редактируем ее:

* в данном примере мы создаем 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:


— 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

  • — начало файла YAML. Данный формат имеет строгую структуру — важен каждый пробел;
  • hosts — группа хостов, к которым будут применяться правила плейбука (если мы хотим, чтобы правила применялись ко всем хостам, указываем hosts: all);
  • become — указывает на необходимость эскалации привилегий;
  • become_method — метод эскалации привилегий;
  • become_user — пользователь под которым мы заходим с помощью become_method;
  • remote_user — пользователь, под которым будем подключаться к удаленным серверам;
  • roles — список ролей, которые будут применяться для плейбука.

* В данном случае мы задействуем нашу группы хостов, которые создали в самом начале; повышаем привилегии методом su под пользователем root (su — root) для группы redhat-servers и методом sudo для debian-servers; подключение к серверам выполняется от пользователя ansible; используем созданную нами роль nginx (саму роль мы создадим позже). Для систем RPM сначала выполним роль epel — она будет отвечать за установку репозитория EPEL, так как в стандартном репозитории nginx нет.

Стоит отдельно уделить внимание вопросу повышения привилегий. IT-среды могут применять разные политики относительно безопасности. Например, на серверах CentOS, по умолчанию, нет sudo и повышать привилегии нужно с помощью su. В Ubuntu наоборот — по умолчанию есть sudo, а su не работает, так как пароль на root не устанавливается. В данном случае есть несколько путей при работе с Ansible:

  1. Как в нашем примере, разделить группы хостов на разные семейства операционных систем и применять к ним разные методы повышения привилегий. Чтобы данный плейбук корректно отработал, учетная запись, под которой идет удаленное подключение к серверу (в нашем примере ansible) должна иметь такой же пароль, как у пользователей root на серверах семейства Red Hat. Данный метод удобен с точки зрения отсутствия необходимости приводить к единому виду безопасность серверов разного семейства. Однако, с точки зрения безопасности лучше, чтобы пароли у root и ansible были разные.
  2. Использовать метод для создания плейбука, как описан выше, но запускать его с ключом —limit, например, ansible-playbook —limit=debian-servers . — таким образом, мы запустим отдельные задания для каждого семейства операционных систем и сможем ввести индивидуальные пароли для каждого случая.
  3. Мы можем на всех серверах deb установить пароль для пользователя root, таким образом, получив возможность для become_method: su.
  4. И наконец, можно для серверов Red Hat установить sudo и проходить become с помощью метода sudo.

Создание роли

Роли в 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:


— 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

  • — начало файла YAML;
  • name — название для роли (может быть любым);
  • yum/apt — используемый модуль для установки приложения;
  • yum/aptname — название пакета, которое мы устанавливаем;
  • yum/aptstate — состояние пакета, которое должно контролироваться ролью;
  • when — условие, при котором данная роль будет выполняться;
  • notify — обработчик, который будет вызван в случае успешного выполнения задачи. При необходимости, можно задать несколько обработчиков;

* В данном примере мы создали простую задачу для роли по развертыванию nginx. На системы RPM установка выполняется с помощью модуля yum, на deb — apt. Версия должна быть последней (latest); после установки пакета, необходимо разрешить автозапуск сервиса и запустить его.
* при установке пакетов также следует учитывать, что некоторые могут иметь разные названия в разных системах. Например, Apache в RMP-системах называется httpd, в deb — apache2.

Создаем файл с описанием задач для роли epel:


— name: Install EPEL Repo
yum:
name=epel-release
state=present

Обратите внимание, что в плейбуке выше мы задействовали notify, но не задали handlers — в качестве примера, мы вынесем его в отдельный файл:


— 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):

После ввода пароля, будет запрошен второй пароль — для повышения привилегий на самой удаленной системе:

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 с помощью шаблона ansible

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

Создаем общие переменные

Переменные задаются в файле main.yml, который находится в каталоге vars, который, в свою очередь, находится в каталоге роли. И так, создаем каталог для переменных:

. и сам файл main.yml:

worker_processes: auto
worker_connections: 2048
client_max_body_size: 512M

* где представлены некоторые опции настройки NGINX:

  • worker_processes — определяет количество рабочих процессов. Чаще всего, оптимальнее выставлять автоматическое конфигурирование.
  • worker_connections — максимальное количество соединений одного рабочего процесса.
  • client_max_body_size — максимальный размер загружаемых данных.

Шаблон для nginx.conf

Создаем каталог для хранения шаблонов:

. и создаем первый шаблон для конфигурационного файла nginx.conf:

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

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.

Готово — запускаем плейбук:

ansible-playbook /etc/ansible/play.yml -kK

. и вводим дважды пароли. На наших серверах должен появиться конфигурационной файл nginx.conf в соответствии с нашим шаблоном.


Шаблон для создания виртуальных доменов в NGINX

Создадим виртуальные домены при помощи ansible. Сначала создадим переменные — для каждого сервера должны быть свои домены — такие переменные можно задать в файле hosts, котором мы создавали хосты для ansible:

Добавляем к нашим строкам:

[redhat-servers]
192.168.0.11 virtual_domain=domain1.dmosk.ru

[debian-servers]
192.168.0.12 virtual_domain=domain2.dmosk.ru

* мы создали переменную 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;
>

* ^.+\.(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 задачи:

Мастер Йода рекомендует:  Особенности реализации классов в PHP

— 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

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

На последок хочется сказать пару слов о Ansible Galaxy. Грубо говоря, это репозиторий готовых плейбуков и ролей. Найти файлы, соответствующую задаче, а также документацию можно на портале galaxy.ansible.com. Установка выполняется командой ansible-galaxy, например:

ansible-galaxy install geerlingguy.apache

* данная команда создаст в каталоге пользователя папку .ansible/roles/geerlingguy.apache — в нее поместит файлы с описанием роли.

Готовые библиотеки можно использовать для выполнения задач или просто как шпаргалки.

Ansible знакомимся с системой на примерах.

К вопросу управления серверами можно подходить по разному. Можно управлять ими в ручную, можно делать это при помощи самописных скриптов, а можно при помощи системы управления. Мне кажется, что когда количество серверов под вашем контролем переваливает за десяток, а работать с ними приходится часто, то система управления это больше необходимость, чем каприз. Кто то может работать и со скриптами, кому то достаточно и однострочников в консоли, конечно все эти решения работают, но не все они красивы и универсальны. Я лично к этому шёл очень долго, и не так давно понял что «пора». Уже даже поставил к себе в лаборатории Puppet, но тут на новой работе оказалось что пришли к использованию Ansible. Беглый поиск показал одно, крайне интересное преимущество над другими системами — отсутствие необходимости устанавливать клиент на управляемые серверы. Сам Ansible написан на Python, так же на Python пишутся и модули для него. Сам проект достаточно молод, его разработка началась 2012 году. Ну а сегодня, на примерах, я постараюсь показать на сколько удобно и быстро можно управлять огромным парком серверов.

Для начала нам нужно установить Ansible на «управляющий» сервер. В общем то это может быть любая машина, но у меня есть возможность выделить под неё отдельную.
Ansible есть в репозитории EPEL и нам понадобится для нормальной работы ещё sshpass

Первое что нам нужно сделать после установки, настроить файл hosts для Ansible. Он у него собственный и находится в /etc/ansible/hosts. Туда мы должны занести все наши машинки, которыми мы будем управлять. Можно добавлять в кучу, но я предпочитаю их группировать:

А в начале файла мы ещё определим рутовый пароль, для тех случаев, когда нужно будет из под обычного пользователя подниматься до рута, что бы выполнить необходимые действия. Вы можете и вводить пароль каждый раз руками, но для меня это не так удобно. Такая реализация мне нравится, тк на все своих серверах я сразу же запрещаю рутовый логин по ssh. На мой взгляд это достаточно усиливает безопасность системы, но у вас может быть и другое мнение на этот счёт.

И так, давайте проверим что всё работает и немного поиграем в Ansible из консоли, прежде чем приступим к написанию playbook`а.

Здесь мы просто говорим Ansible выполнить комманду uname -a для серверов группы webservers. Вы можете подставить своё название группы или all для всех серверов в файле hosts.

А вот и ещё кое что интересное

Вывод этой команды я положил на pastebin, ибо он слишком длинный. Здесь мы при помощи модуля setup получаем кучу информации о наших серверах в формате JSON.
Но, помимо большой портянки, мы можем и отфильтровать полученный результат

Но, как указано в справке к модулю, Ansible фильтрует только по первому уровню дерева, так же как и не получится использовать одновременно несколько фильтров.


Но работа из консоли это не так интересно, ввиду ограничения возможностей. Можно конечно лепить команды в кучу, но это уже не так эстетично, по этому пора приступить к написанию нашего первого playbook`а. Пожалуй первое, что хочется сделать со всеми своими серверами — обновление.
тк я использую CentOS я буду пользоваться модулем yum, но в комплекте есть всё необходимое для различных платформ, и apt и pkgng и portage.

Расскажу немного подробнее, построчно:
Для хостов группы webservers мы говорим залогиниться под пользователем korp, а потом при помощи sudo выполнить команды yum update и shutdown -r 1. Тут сразу стоит сказать — почему shutdown -r 1, а не now. Дело в том, что при shutdown -r now или reboot происходит ошибка, в баги её уже записали, писали о ней так же не однократно и пока приходится довольствоваться обходным решением.

Перейдём к следующему этапу. У нас есть сервер установки ПО и его настройки и возникает ситуация — в нашей сети появляется новый сервер. Пока не важно — какую задачу он будет выполнять, пока перед нами стоит задача его первоначальной настройки — подключить нужные репозитории, создать пользователей, поставить необходимый минимум ПО, в общем привести сервер к некому стандартно-базавому состоянию. Пишем ещё один playbook:

Пожалуй сразу оговорюсь о шаблонах, раз уж в этом скрипте я его использовал. Модуль template. Дело в том, что модуль lineinfile не умеет создавать файл, соответственно что бы создать файл и занести в него данные, нам нужно пользоваться шаблонами. Шаблоны пишутся в формате Jinja2 и он в общем то совсем не сложен. Я создал простой файл ntpdate.j2, но в данном случае, мне нужно внести всего одну запись и нет смысла городить целый шаблон, по этому я просто захордкоил в нём строку server ntp1.stratum2.ru.

Следующим этапом мы заносим новый сервер в /etc/ansible/hosts, как мы это делали уже с нашими серверами, а запускать развёртывание мы будем следующей командой:

ключ l говорит о том, что мы «ограничиваемся» хостом/группой с именем client3, ну и тк пока у нас нет пользователя в новой системе, мы логинимся туда в качестве пользователя root, а ключ k говорит о том, что бы ansible запросил у нас пароль от учётной записи root в интерактивном режиме.
После успешного завершения, нам нужно новую систему тоже обновить, по этому натравим на неё наш playbook update.yml

Но очень часто бывает так, что у нас в сети живут клиенты в различными ОС. по этому этот факт нам так же нужно учесть, ввиду того, что этот скрипт подходит только для CentOS 7, а со всеми другими системами, соответственно будут различные ошибки. Теперь попробуем переписать наш playbook таким образом, что бы он работал как с CentOS 7, так и с 6 версией, но так же поддерживал ещё и работу с Gentoo.
В случае, когда нам нужно установить ПО на разные системы, у нас есть 2 пути:
1. Когда имена пакетов совпадают, тогда можно обойтись достаточно просто:

2. Когда имена пакетов не совпадают, тогда для каждой системы нужно будет заводить отдельную секцию:

Ну а целиком наш новый файл будет иметь вот такой вид:

Посмотреть какие значения могут быть у переменных ansible_distribution, ansible_distribution_major_version, ansible_pkg_mgr можно при помощи модуля setup, возможно вы найдёте для себя иные методы определения принадлежности системы к чему-либо и у вас будут собственные условия.

Пожалуй этого количества примеров, хватит для того, что бы начать писать первые playbook`и в качестве старта. Остался ешё один момент, о котором я не успел рассказать — поддержка Windows.
Поддержка Windows появилась, начиная с версии 1.7 и в качестве средства управления используется powershell remoting, но так же для работы, на Linux-сервере Ansible понадобиться Python-модуль — winrm, а на Windows -сервере необходимо будет включить удалённую поддержку Powershell. Но на сервере версия Powershell должна быть не ниже 3.0. В документации размещены скрипты, для автоматической настройки Windows-сервера для работы с Ansible. На Windows-серверах поддерживает работа почти всех встроенных модулей Ansible (какие именно не работают, к сожалению, не указано), а так же имеется ряд специфичных модулей для Windows.

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

Добавить комментарий Отменить ответ

Для отправки комментария вам необходимо авторизоваться.

KAZARIN OnLine

Blog about IT, Me, My travels, vacations, etc…

По дирижируем оркестром. Ansible. Часть 1 — введение.

Итак, решил я по изучать системы оркестровки и управления конфигурацией и деплоем серверов. начинать надо с чего-то по проще, да по свежей. Поэтому я решил, что монстры типа Cheif и Puppet останутся на второе, а начну я с Ansible. Кому слово не знакомо прям совсем — вас ждет гостеприимный гугл, википедия и не менее гостепримный хабр.

А мы займемся сразу «мясом» — учить такие вещи надо на реальных юз-кейсах. Погнали — до этого мы осваивали Vagrant, его и задействуем в полную силу. Для начала- нам понадобится стенд из 3 виртуальных машин — Ansible server, с которого мы и будем дирижировать и пара подопытных — web сервер и сервер СУБД. Конфиг Vagranfile прост:

Скрипты провиженинга у всех имею одинаковое содержимое, т.к. далее эту задачу мы будем решать не Vagrant-ом. Вот пример:

Даем команду up, ждем пока взлетят все виртуалки, после чего заходим по ssh на ту, которая будет выполнять роль сервера ansible. Если поискать версию пакета ansible в репозитории (apt-cashe show ansble или aptitude show ansible) увидим, что там лежит версия 2.1.1, в то время как свежая-стабильная версия 2.3. Это не проблема — ставим ansible из их ppa репозитория:

sudo apt-add-repository ppa:ansible/ansible
sudo apt-get update
sudo apt-get install ansible

Что у нас появилось новенького? Давайте заглянем в /etc… О, да ладно, каталог «ansible». Вот это поворот)) Наверное внутри мы найдем какие-то конфигурационные файлы. Действительно — внутри 2 файла и каталог (который пуст кстати) — cfg самого ansible и каталог с списком хостов. Хорошо, заберем его себе в домашнюю папку и поиграемся:

Итак, файл hosts довольно простой по структуре. Комментарии в нем подсказывают, что пустые строки игнорируются, строки начинающиеся с # это комментарии, строки в [скобках] воспринимаются как названия групп узлов а все прочее- как имена/адреса узлов. То есть либо имена, либо ip адреса. DNS сервер мы поднимать тут не будем, поэтому подопрем все костыльком-эмуляцией в виде записи в файле /etc/hosts — добавим записи с именами и адресами хостов. Пусть они будут web-server и db-server.

Отлично! Теперь идем в файл hosts, который принадлежит ansible. Добавляем записи ( давайте сразу используем функционал групп)

Осталось только в cfg файле указать что мы используем файл из нашего домашнего каталога — меняем строку «#inventory = /etc/ansible/hosts» на «inventory = hosts» ( не забываем убрать комментарий). Ок, теперь подготовим наши машинки. Для доступа на другие хосты, Ansible использует ssh. Самый удобный вариант это ssh — ключи. Команда ssh-keygen поможет сгенерировать Вам простой ключ, а ssh-copy-id *имя сервера* — доставить его на нужный сервер ( под доставить я понимаю еще и настроить Ваш вход по нему).

Однако тут есть «мааааааленькая» загвоздка. Малюсенькая. Для первого входа с одной машины на другую, нам понадобится установить пользователю «ubuntu» пароль. Команда «passwd ubuntu», запущенная от рута поможет Вам ( почему от рута, ведь мы меняем свой пароль — попробуйте сами))) Должно же Вам быть немного интересно). После чего, копируем ключ на веб и дб сервер и проверяем вход на них по ssh — команда «ssh web-server» должна отработать без каких либо сообщений и пустить Вас на машину веб-сервера. Все, мы готовы продолжать!

И вот, казалось бы все готово к нашему триумфу как… что такое? Даем команду «ansible -m ping all » (для этого кстати надо зайти в наш каталог с конфигом ansible.cfg и исправленным файлом hosts, иначе утилита потянется к стандартному конфигу в /etc) и видим, что нам дают результат:

Не найден файл python по ожидаемому пути… Хм. В мою душу закрались смутные подозрения… Которые при проверке на наших целевых машинах полностью оправдались (если что, это сервер субд):

В ubuntu 16.04, в стандартной поставке идет только python3, а старого, доброго пайтона 2 версии нет( Ничего, apt-get install -y python-minimal спасет ситуацию. Кстати, стоит добавить эту команду в провижен скрипты Vagrant. Отлично, после этого у нас все идет как надо — проверка работоспособности Ansible пройдена

Мастер Йода рекомендует:  Пользуемся AJAX-объектом

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

Посмотрим — пусть он вернет нам локальный хостнейм всех узлов, время аптайма и некоторую информацию о системе.

Поиграйтесь сами- посмотрите, под кем Вы залогинены, попросив выполнить команду whoami, сколько осталось места на сервере, выполнив команду «df -h» и т.д. Это все хорошо, но может мы уже что-то по конфигурируем, спросите Вы? Скучно просто вытаскивать те данные, которые мы и так получим с помощью мониторинга. Ок, сказано- сделано. Давайте дадим простую команду — создадим пользователя. Только сделаем это изящно, средствами Ansible.

Создание пользователя потребует от нас повышения привелегий. Другими словами- запуск sudo и введение пароля. Все это делается очень легко:

Мы добавили пользователя на обе машины с помощью Ansible и с его же помощью убедились, что он появился в локальных списках пользователей. Теперь немного о тех мантрах, что я тут вбивал с клавиатуры (ansible -h нам в помощь):

  • -m MODULE_NAME, —module-name=MODULE_NAME — имя модуля, который я собираюсь использовать. Как видно, мы попробовали два модуля — это shell ( отдавать команды) и user ( управлять пользователями)
  • -K, —ask-become-pass — запросить пароль на случай, если потребуется эскалация привилегий.
  • -a MODULE_ARGS, —args=MODULE_ARGS — аргументы модуля. У каждого они свои.

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


Поиск статей в блоге

Kirill Kazarin

IT инженер, Системный администратор (Senior),
начинающий DevOps.
Специализируюсь в области локальных сетей, Linux систем, виртуализации и ИБ. Люблю Рок музыку, пеший туризм и собак!

Национальная библиотека им. Н. Э. Баумана
Bauman National Library

Персональные инструменты

Ansible

Ansible

Создатели: Michael DeHaan
Разработчики: Red Hat
Выпущена: 20 February 2012 года ; 7 years ago ( 2012-02-20 )
Постоянный выпуск: 2.0.2.0 / 19 April 2020 года ; 3 years ago ( 2020-04-19 )
Написана на: Python
Операционная система: GNU/Linux, UNIX, Microsoft Windows
Тип ПО: Configuration management, Infrastructure as Code, Orchestration engine
Лицензия: GNU General Public License
Веб-сайт www .ansible .com

Ansible — это программное обеспечение , написанное на python, которое занимается автоматизацией рутиных и повторяющихся задач, таких как управление и настройка серверов. Большой плюс Ansible в том, что вам не требуется устанавливать какое либо дополнительное программное обеспечение на серверах. [1]

Ansible берет на себя всю работу по приведению удаленных серверов в необходимое состояние. Администратору необходимо лишь описать, как достичь этого состояния с помощью так называемых сценариев (playbooks; это аналог рецептов в Chef). Такая технология позволяет очень быстро осуществлять переконфигурирование системы: достаточно всего лишь добавить несколько новых строк в сценарий.

Содержание

Преимущества

Преимущества Ansible по сравнению с другими аналогичными решениями (здесь в первую очередь следует назвать такие продукты, как Puppet, Chef и Salt) заключаются в следующем:

  • на управляемые узлы не нужно устанавливать никакого дополнительного ПО, всё работает через SSH (в случае необходимости дополнительные модули можно взять из официального репозитория);
  • код программы, написанный на Python, очень прост; при необходимости написание дополнительных модулей не составляет особого труда;
  • язык, на котором пишутся сценарии, также предельно прост;
  • низкий порог вхождения: обучиться работе с Ansible можно за очень короткое время;
  • документация к продукту написана очень подробно и вместе с тем — просто и понятно; она регулярно обновляется;
  • Ansible работает не только в режиме push, но и pull, как это делают большинство систем управления (Puppet, Chef);
  • имеется возможность последовательного обновления состояния узлов (rolling update). [2]

Недостатки

  • Отсутствие менеджера зависимостей. Сейчас все роли можно хранить в репозитарии, но как работать с зависимостями и обновлять роли — внятного ответа нет. Большинство пользуются этим подходом (аналогично с Chef, например, 3 года назад), но при разрастании проекта очевидны недостатки такого подхода.
  • Неполная документация. .
  • Режим ansible-pull для больших инсталляций потребует серьезной доработки.
  • Неудобный дебаг. [3]

Установка

Требования для установки Ansible минимальны. На машине с которой производится управление должен быть установлен Python 2.6 или выше. На управляемых узлах должен быть установлен только Python версии не ниже 2.4, но он, как правило, по умолчанию включен в состав большинства дистрибутивов linux-систем. MS Windows не поддерживается. Вам также могут потребоваться следующие модули Python, устанавливаемые через pip или пакетный менеджер вашей операционной системы:

В Ubuntu установка самого Ansible и зависимостей осуществляется добавлением репозитория и установкой пакета:

Информация об узлах

Перед внесением изменений Ansible подключается к управляемым узлам и собирает информацию о них: о сетевых интерфейсах и их состоянии, об установленной операционной системе и т.п. Он может делать это как с помощью собственного модуля, так и с помощью инструментов ohai и facter, если они установлены (такая возможность специально предусмотрена для пользователей, уже имеющих опыт работы с системами удаленного управления конфигурациями: ohai и facter являются библиотеками фактов для Chef и Puppet).

Во время деплоя, как правило, требуется не только установить какое-либо приложение, но и настроить его в соответствии с определенными параметрами на основании принадлежности к группе серверов или индивидуально (например, ip-адрес BGP-соседа и номер его AS или параметры для базы данных). Как уже было сказано, загромождать файл hosts будет не очень красиво, поэтому разработчики Ansible пошли следующим путём:

  • файлы с переменными групп хранятся в директории “group_vars/имя_группы”;
  • файлы с переменными хостов в директории “hosts_vars/имя_хоста”;
  • файлы с переменными роли (о них речь пойдет ниже) в директории “имя_роли/vars/имя_задачи.yml”;

Помимо пользовательских переменных можно (и даже нужно) использовать факты, собранные ansible перед выполнением сценариев и отдельных задач.

Модули Ansible

В состав Ansible входит огромное количество модулей для развёртывания, контроля и управления различными компонентами, которые можно условно разделить на следующие группы (в скобках приведены названия некоторых продуктов и сервисов):

  • облачные ресурсы и виртуализация (Openstack, libvirt);
  • базы данных (MySQL, Postgresql, Redis, Riak);
  • файлы (шаблонизация, регулярные выражения, права доступа);
  • мониторинг (Nagios, monit);
  • оповещения о ходе выполнения сценария (Jabber, Irc, почта, MQTT, Hipchat);
  • сеть и сетевая инфраструктура (Openstack, Arista);
  • управление пакетами (apt, yum, rhn-channel, npm, pacman, pip, gem);
  • система (LVM, Selinux, ZFS, cron, файловые системы, сервисы, модули ядра);
  • работа с различными утилитами (git, hg).

Ansible позволяет не только выполнять единичные задачи, но и писать сценарии, которые необходимо выполнить на управляемых узлах.

Cценарии (playbooks)

Все сценарии в Ansible пишутся на YAML. Это — человекочитаемый формат сериализованных данных, гораздо более простой, чем XML или JSON.

В начале сценария обязательно должна присутствовать последовательность символов «–––» (так в YAML обозначается начало документа). Перед каждым новым разделом списка ставится дефис ( — ):


Основными параметрами/группами простого сценария являются:

hosts — в нем указываются управляемые узлы или группы узлов, к которым нужно применить изменения; tasks — здесь описывается состояние, в которое необходимо привести управляемый узел, альтернативой этому могут служить роли;

Также в сценарии перед непосредственным описанием задач могут быть указаны следующие параметры или группы параметров:

  • gather_facts — собирать или нет информацию о хостах перед выполнением задач, по умолчанию — да;
  • vars — в нем указываются различные переменные, которые будут использованы при выполнении сценария;
  • connection — можно указать метод соединения с хостами: pure ssh, paramiko, fireball, chroot, jail, local, accelerate (применимо также для выполнения отдельного модуля);
  • sudo — после установления соединения выполнять задачу с привилегиями другого пользователя, по умолчанию другой пользователь — root;
  • sudo_user — в сочетании с предыдущим параметром можно указать с привилегиями какого именно пользователя будет выполнена задача;
  • vars_prompt — перед выполением плэйбука Ansible в интерактивном режиме может уточнить указанные в этом разделе параметры;
  • remote_user (в предыдущих версиях — просто user) — имя пользователя для авторизации на удалённом хосте.

Сценарии могут выполняться не только от имени пользователя, под именем которого установлено соедиение, но и любого другого. В следующем примере авторизация на хосте будет произведена с именем yourname, но задачи будут выполняться от имени пользователя root. [4]

Использование Ansible Playbooks

В инструкции описано применение и работа с Ansible Playbook, а также кратко рассмотрена их структура.

Что такое Ansible Playbooks?

Playbook в Ansible определяет серию некоторых действий для выполнения и адресованы определенным наборам серверов. В отличие от некоторых других инструментов для выполнения настроек, Playbook не описывает состояние машины, а Ansible самостоятельно определяет все изменения, которые необходимо внести. Тем не менее, плейбуки должны быть разработаны как идемпотенты, а это значит, что они могут запускаться более одного раза без негативных последствий.

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

Playbook — это YAML-файл, который обычно имеет следующую структуру:

Например, следующий playbook будет входить на все серверы группы marketingservers и обеспечивать запуск веб-сервера Apache:

В плейбуке выше приведен пример задания (task):

Каждое задание должно иметь имя, которое впоследствии регистрируется и может помочь отслеживать прогресс. После строки имени (name) находится модуль, который будет запущен, в данном случае это служебный модуль. Другие атрибуты разрешают больше опций, в примере Ansible разрешается использовать привилегии sudo.

Запуск Ansible Playbook

Запустить готовый плейбук можно используя следующую команду:

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

ansible-playbook -l host_subset playbook.yml

ansible-playbook -l host3 nginx.yml

Регистрация результатов

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

Для каждой задачи при желании возможно зарегистрировать ее результат (сбой или успех) в переменной, которую можно проверить позже. При использовании этой функциональности рекомендуется указывать Ansible игнорировать ошибки для такой задачи, так как обычно выполнение playbook прерывается в случае возникновения каких-либо проблем.

Таким образом, если необходимо проверить, выполнилась ли задача или нет и принять решение о последующих шагах, необходимо использовать функциональность регистрации.

Введение в Ansible

Ansible — это отличная штука для того чтобы работать с серверами. Если вы иногда заходите по ssh на сервер чтобы там что-нибудь выполнить, то вам стоит посмотреть на Ansible и, возможно, начать его использовать.

Сначала нужно поставить Ansible. Если вы работаете на маке, то он устанавливается с помощью стандартного:

После того как Ansible установлен, можно начинать его использовать. Специально для написания этой статьи я поднял 2 тестовые машинки. Я не хочу показывать свои настоящие сервера, поэтому я запустил несколько docker контейнеров (можно было бы взять какой-нибудь VirtualBox и поднять несколько виртуалок, но докер для меня удобнее). В реальной жизни я управляю серверами, которые живут на digitalocean.com. Я настроил эти тестовые докер контейнеры так что я могу зайти на них с помощью команд:

Т.е. обе эти машинки живут на одном и том же айпишнике (айпишник докера), но на разных портах.

Ansible начинается с inventory файла. Это файл в котором записаны все сервера, которыми нужно управлять через Ansible. Обычно этот файл называется hosts. Чаще всего hosts файл — это просто перечисление hostname серверов:

Но в моем экспериментальном примере у моих машинок нет хостнеймов, плюс ssh работает не на стандартном 22 порту, и подключаюсь я не под своим пользователем, а под root. Так что мой inventory файл получает дополнительные параметры:

В данном случае имена server_a и server_b — это просто алиасы для Ansible, ничто больше в системе не знает про эти алиасы, но Ansible когда их видит понимает что нужно зайти по ssh на ip/порт и использовать указанное имя пользователя.

Все =) Ansible установлен, inventory файл написан, теперь можно начать использовать Ansible.

Самое простое что можно сделать — это проверить что все машины доступны

Вот что означают параметры, которые мы указали для программы ansible:

При запуске этой команды, Ansible прочитал inventory файл, создал список хостов, которые попадают под указанный паттерн и для каждого хоста выполнил следующие действия:

  • зашел по ssh на этот хост и создал временную папку
  • скопировал на этот хост по ssh скрипт в котором находится указанный модуль ping
  • запустил на удаленной машине этот скрипт
  • получил ответ от скрипта, распарсил его и показал на экране


Несмотря на название модуль ping никак не связан с командой ping — этот модуль ничего не пингует — он просто проверят что на указанные машинки можно зайти по ssh и что на этой машинке можно запустить этот python скрипт ping.

Модуль ping вполне может выдать ошибки. Например, если на машинке нет python, то мы получим:

А если машинка не доступна по сети, или не пускает по ssh, то ошибка будет:

Ansible прекрасен тем что для его работы на машинки не нужно ставить никаких специальных агентов — если можно зайти на машинку по ssh и если там есть python, то Ansible будет отлично работать.

Давайте попробуем что-нибудь более интересное чем модуль ping.

Вот как запустить на всех машинках из inventory файла команду:

Тут мы использовали модуль shell и передали ему аргумент — строку которую нужно выполнить в консоли. Ansible выполнил эту команду на обоих машинках, и показал их вывод. Вот так с помощью запуска одной команду на локальной машине мы получили информацию про версию ubuntu на двух серверах.

Команда ansible — это очень удобная штука для одноразового запуска команд на удаленных серверах. Даже если сервер один, иногда удобнее использовать команду ansible для того чтобы быстро что-нибудь сделать с этим сервером (ansible особенно помогает, когда до сервера плохая связь — тогда на удаленный машине неудобно работать — из-за сети все тормозит, поэтому набрать команду на локальном ноутбуке быстрее и приятнее).

Но самая мощь Ansible — это команда ansible-playbook — с ее помощью можно накатывать определенный набор команд для полной настройки серверов. С помощью плейбуков получается хранить изменения инфраструктуры в репозитории — и это волшебно прекрасно: есть вся история изменений, всегда можно откатиться на прошлую версию настроек, видно кто и когда что сделал с серверами. Но про ansible-playbook — в следующий раз.

Начинаем с Ansible в стиле best-practice

На просторах сети есть много гайдов на русском вроде «Учим Ansible с нуля». Но ни в одном из них я не видел, чтобы человека сразу же погружали в best-practice. Хотя бы в плане построение древа директорий для ролей. Считаю, что сделать это надо хотя бы потому, что переезд на best-practice может оказаться болезненным для новичков. Сейчас я попытаюсь исправить этот недочёт. Используемая в примерах ОС – Centos 7.5.

Мастер Йода рекомендует:  Надписи на графике выгрузки Роскомнадзора оказались посвящены Дню радио

Разберёмся немного, что за best-practice такой

Идём по ссылке и читаем:

These may not use all of the features in the latest release, but are still an excellent reference!

Мораль такова: всё аккуратно разложено по директориям для вашего же удобства в дальнейшем использовании. Сам Ansible понимает, для чего нужна каждая директория. Например, из rolename/vars он по умолчанию берёт переменные для роли, а из rolename/tasks он берёт основные задачи. Что такое роли можно прочитать, например, ТУТ >>

Установим Ansbile и GIT

Всё есть в стандартных репозиториях:

Далее скопируем раскладку директорий из репозитория, чтобы не создавать руками:

Хотя первый раз, конечно, советую пройти это всё вручную – для закрепления материала. Обязательно зайдите в директорию и изучите её содержимое.

Далее пропишем хост в тестовый инвентаризационный файл:

Протестируем соединение с тестовым хостом:

У нас почти всё настроено

Осталось только попробовать на реальном примере:

Перед запуском зайдите в site.yml и поменяйте role: common на role: nginx. Прелесть ролей как раз в том, что вам нужно просто указать имя директории и Ansible всё поймёт сам.

Ну и запускаем нашу роль:

В итоге на тестовом сервере успешно установлен и настроен nginx.

Есть вопрос? Напишите в комментариях!

тут блог

Общественные обязательства интроверта.
Сообщения на ИТ тематику, но не обязательно.

Об Ansible

Начнём новый год с буквы «A». Ansible.

Кстати, Анзи́бль — это такая фантастическая фиговина для мгновенной связи на межгалактических расстояниях.

А Ansible — это программка для удалённого запуска команд и совершения прочих нужных действий на куче серверов. Мы её используем для настройки серверов и деплоя наших сервисов уже на нескольких проектах.

Ансибл — чертовски гибкая штука. Настолько гибкая, что без определённых соглашений все эти таски и плейбуки легко превращаются в нечитабельную немодифицируемую глючную лапшу. Чего только стоит, что переменные в Ансибле можно определять индивидуально для каждого хоста, для группы хостов, умолчательные значения для роли, просто переменные для роли, переопределять в плейбуке, из командной строки, конкретно для данной задачи. А ещё переменные могут создаваться в результате выполнения задач, и использоваться в последующих задачах. А ещё есть факты, то есть переменные, автоматически собранные при инспектировании хостов, типа объема памяти, размера дисков и набора сетевых интерфейсов. Ужос.

Эмпирическим путём у нас сложились правила использования Ансибла. В основном вдохновлённые и следующие статье Миши Бланка «Laying out roles, inventories and playbooks».

Все ансибловые файлы у нас валяются в подкаталоге ansible самого проекта. Вообще, идеология Ансибла подразумевает, что должны быть универсальные переиспользуемые роли, выкладываемые в Ansible Galaxy, единый конфиг в /etc , единый набор Inventory на все окружения, с которым работает данный юзер, и лишь плейбуки, специфичные для данного проекта.

Но на практике с универсальностью ролей всё плохо. Во-первых, страшно запускать фиг знает кем написанную роль от рута на десятках серверов. Во-вторых, написать действительно универсальную роль весьма сложно, поэтому роли из Galaxy всё равно приходится подпиливать по свои нужды. Проще написать неуниверсальную роль для данного проекта. В-третьих, роли очень быстро устаревают, ибо версии софта, который они устанавливают, стремительно меняются. А мейнтейнить проще простые специфичные роли.

Вот поэтому у нас не сложился общий репозиторий ролей. Некоторые роли просто копируются из другого проекта. А остальные 90% пишутся под этот проект. Всё лежит под системой контроля версий проекта, и всё хорошо.


Начинается всё с файла ansible/ansible.cfg :

Далее Inventory. Инвентарь. Это ваши хосты. По группам. Инвентарей будет много. Потому что окружений будет много: ну это всё тестовое, продакшен и т.п. На каждое окружение — свой Inventory.

В hostfile стоит прописать значащие имена хостов. Лучше доменные имена, но если доменных имён нет, стоит что-нибудь внятное вместо них придумать, а правильный IP указать как ansible_host . Ну и юзера, и ssh порт, и прочие параметры подключения для каждого хоста указать.

В группу должны входить абсолютно одинаковые хосты. Ну которые нужно одинаково настроить. Потому что переменные удобнее и правильнее назначать на группы, и в плейбуках правильнее вызвать роли на всю группу. Разве что первый (нулевой) хост в группе может быть особенным (для хостов из других групп), на него можно ссылаться как << groups['etl-server'][0] >> .

Кроме перечисления собственно хостов и групп в Inventory можно поместить шаблоны и файлы. Вообще-то, это не Ansible-way. В Ансибле подразумевается, что шаблон должен быть один, где-нибудь в роли. А все нюансы и хитрости под конкретное окружение должны задаваться переменными, а также условиями и циклами в шаблоне. Это ж Jinja2, там всё можно.

Вот только сопровождать сложный универсальный шаблон, как правило, сложно. Ну и юзерам ещё и шаблонизацию Ансибла объяснять? Ты тут только-только устаканил набор всех возможных переменных в application.yml , более-менее описал их все в Вики. А теперь ещё и шаблон родить, и переменные Ансибла придумать, и снова это всё задокументировать?

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

Чтобы так делать, нужно использовать каталог (а не файл, который hostfile) Inventory, и определять inventory_ignore_extensions в ansible.cfg . Использовать такой шаблон, заданный в Inventory, можно так:

Нужно быть осторожным, если Inventory содержит ключи да пароли. Ведь оно лежит в репозитории. Для публичных проектов нужно будет использовать Ansible Vault.

Roles. Роли. Тут самое мясо. Тут команды, которые, собственно, что-то делают.

Начинается всё с подкаталога roles , а дальше идут каталоги, чьи имена соответствуют названиям ролей.

В роли мы объединяем таски, которые выполняют какой-то связанный набор настроек, на определённой группе хостов, в определённый момент жизненного цикла продукта, который можно переиспользовать для разных групп хостов. Получается какая-то роль common для настройки локалей, NTP, включения файервола. По роли на установку и настройку нужного софта: Java, Spark, MongoDB, всё, что душе угодно. В простейшем случае эти роли просто ставят нужные пакеты. В более сложных случаях нужна ещё хитрая подгонка по месту.

И роли на установку наших сервисов. Тут важен момент, когда роль нужна. Поэтому на каждый сервис получается, как правило, две роли. Одна делает provision: создаёт юзеров, каталоги, юнит systemd. Её для данного хоста достаточно запустить один раз, более ничего из этого на данном хосте меняться не будет. Другая роль делает deploy: копирует jarник/бинарник сервиса, настраивает конфиг по шаблону, перезапускает сервис. Её нужно запускать при каждом деплое, когда код сервиса у нас изменился. Раз делать разные вещи нужно в разное время и с разной периодичностью, это должны быть разные роли.

Внутри роли у нас есть дефолтные значения переменных, в defaults/main.yml . Это можно рассматривать как документацию к роли. Тут перечислены все переменные, которые роль использует. Ну и заданы дефолтные значения, чтобы роль работала. Более правильные конкретные значения следует переопределять в Inventory.

Так как переменные задаются в Yaml, есть соблазн развешать иерархию имён в виде вложенных объектов с именованными свойствами. Но в Ансибле так не принято. Потому что в Ансибл не завезли нормального наследования/переопределения объектов. Поведение по умолчанию: объявление объекта уровнем выше полностью затирает все вложенные определения, и все многочисленные свойства нужно определять заново. Можно сделать, чтобы наоборот, все свойства всех объектов всегда мержились. Но тогда нельзя убрать свойство, определённое где-то ранее. В общем, лучше с этим не связываться, и задавать переменные как независимые примитивные значения, в худшем случае — списки. А для разделения пространств имён использовать префиксы через подчёркивание.

Далее в роли есть шаблоны, в templates , и файлы, в files . Разница в том, что файлы пересылаются на удалённый хост как есть, например, таском copy , а шаблоны сначала прогоняются через Jinja2, таском template . Соответственно, эти таски и ищут по умолчанию файлы и шаблоны своей роли в этих самых каталогах.

В tasks/main.yml у нас определяются таски. Но товарищ Бланка рекомендует в main.yml сами таски не писать, а инклудить другие файлы с тасками, проставляя при этом теги.

Правда, в Ansible 2.4 простой как пробка include задепрекейтили в пользу статических и динамических инклудов. Похоже, теперь нужно использовать import_tasks .

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

Допустим, известно, что нужно поправить конфиг грешной Монги. Но точно неизвестно, как именно. Приходится пользоваться методом научного тыка, и совершать несколько итераций, экспериментируя на одном хосте. Можно делать всё руками, а потом не забыть перенести изменения в Ансибл. Можно делать всё в Ансибле, но тогда, чтобы пропустить этапы установки MongoDB, а выполнить только замену конфига на конкретном хосте, можно задать теги и хост:

Ещё в ролях есть handlers . Это такие таски, которые запускаются только один раз после успешного выполнения других тасков, если эти таски что-то изменили. Жизненно необходимая вещь для перезапуска сервисов, если менялись бинарники или конфиги. И неперезапуска, если не менялись.

Полезно, кстати, последним таском в роли добавить команду валидации этих самых конфигов. Например, для nginx это может выглядеть так:

Тогда этот хэндлер перезапустит nginx, только если конфигурация изменилась, и она правильная:

Playbooks. Плейбуки. Игровые книжки. Это Yaml файл, который объединяет Inventory, точнее группы хостов, где это должно играться, с ролями, то есть тем, что должно играться.

Получается, на каждый независимый шаг развёртывания всей системы создаётся свой плейбук. Их получается довольно много, но меньше, чем ролей. На каждую группу серверов, которую можно (или нужно) настраивать отдельно — свой плейбук. На каждый наш сервис: пара плейбуков — для provision и deploy. Собственно, разработчикам нужны только deploy плейбуки, чтобы запускать их, когда меняется код. А остальное запускается лишь один раз, либо когда появляется новый сервер.

Сам плейбук прост: это просто связь групп и ролей. Если у вас одно единственное Inventory, можно даже сделать файл исполняемым и снабдить shebangом.

Можно поместить плейбуки в подкаталог playbooks , но нам пока хватало их россыпи прямо в каталоге ansible . Чтобы не запутаться мы делаем Makefile с самыми частыми вариантами запуска ansible-playbook .

Если плейбук завалился с ошибкой, Ансибл создаёт .retry файл рядом с файлом плейбука, куда записывает те хосты, где выполнение завершилось с ошибкой. Чтобы можно было сделать ansible-playbook playbook.yml —limit @playbook.retry . Не забудьте добавить *.retry в .gitignore .

Вот так и живём с Ansible. Успешно.

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

Сейчас придётся делать микросервисы, запускаемые в облаке. Чувствую, что придётся изрядно переосмыслить роль Ansible во всём этом. Возможно, понадобится универсальная роль для деплоя любого сервиса. Возможно, эту роль нужно будет запускать не на каком-то удалённом хосте, а локально, чтобы управлять облаками через их API. Есть у Ансибла модули и для этого.

Программист — это звучит гордо

Знаниями нужно делиться, иначе они протухают.

Страницы

суббота, 11 июля 2015 г.

Ansible — введение

Есть такой класс инструментов, как системы управления конфигурациями. Они сейчас довольно многочисленны: chef, puppet, salt и другие. Отличия в них не принципиальные — одна проще в настройке, другая стабильнее и чуть больше умеет, но в целом выбрав одну из них, вы так или иначе сможете добиться поставленных целей. Я к сожалению не обладаю достаточной компетенцией, что бы их сравнивать, поскольку со всеми знаком только на уровне статей\документации. Лично для себя, что бы познакомиться с этим классом инструментов я выбрал ansible. Судя по отзывам он наиболее логичен, прост в освоении, активно развивается и написан на python. Последнее важно, т.к. я более или менее знаком с этим языком, в отличии от часто используемого для таких инструментов ruby.

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

У меня дома большого парка машин нет, но парочка все же найдётся. Вообще считается, что для таких объёмов применять такие инструменты — излишне, проще руками настроить. Но все же хочется автоматически их синхронизировать и иметь возможность в случае сбоя быстро восстановить все пакеты и конфиги. Плюс — учиться на примерах приближенных к реальным гораздо эффективнее, чем по документации.

Поехали. Установка ansible для archlinux выглядит так:

/.config/ansible/hosts» с таким содержанием:

Тут создаётся группа «local», содержащая одну машину, с названием «home». Уточняем, что подключаться к ней нужно локально (без использования ssh), а так же, что python нужно брать отсюда: «/usr/bin/python2». Последнее важно, т.к. по умолчанию ansible будет пытаться запускать просто python, а в archlinux это третья версия, с которой ansible толи совсем не дружит, толи делает это плохо.

Теперь можно сделать что-то минимальное:

Я выполнил подготовленный playbook 2 раза подряд. Как видно в первый раз при выполнении обеих задач — ansible выдал, что обе они привели к изменениям на машине: «changed=2». Во второй раз реально выполнилась только первая задача — обновления кеша pacman, вторую задачу он пропустил, т.к. пакеты уже были установлены. Эту особенность — не выполнять задачу, если она уже выполнена, по возможности, поддерживают все модули ansible.

Итак: полученных знаний вполне хватит, что бы написать playbook, который установит все необходимые пакеты и раскидает конфиги по нужным директориям. Правда пока ещё много не хватает, н-р установки через yaourt, но дальше попытаюсь исправить это. Базовое изучение ansible, как и обещали занимает совсем мало времени, благодаря хорошей документации, так же удивляет обилие русских статей на тему. Пока создаётся впечатление, что такой же результат мог быть получен, при помощи bash скриптов гораздо быстрее и нагляднее.

Добавить комментарий