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

Ansible - введение

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

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

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

Поехали. Установка ansible для archlinux выглядит так:
sudo pacman -S ansible
Далее требуется указать кем мы хотим управлять. Обычно управляющий и управляемые узлы это разные машины, а каналом связи является чаще всего ssh. Список и способ подключения хранится в файле hosts (по умолчанию лежит в /etc/ansible/hosts). Но в данном случае предполагается, что управлять будем локальной машиной, а файл hosts (как в прочем и остальные настройки) хочется хранить в одном месте, что бы удобно потом положить их в git. Поэтому создадим новый файл "~/.config/ansible/hosts" с таким содержанием:
[local]
home ansible_connection=local ansible_python_interpreter=/usr/bin/python2
Тут создаётся группа "local", содержащая одну машину, с названием "home". Уточняем, что подключаться к ней нужно локально (без использования ssh), а так же, что python нужно брать отсюда: "/usr/bin/python2". Последнее важно, т.к. по умолчанию ansible будет пытаться запускать просто python, а в archlinux это третья версия, с которой ansible толи совсем не дружит, толи делает это плохо.

Теперь можно сделать что-то минимальное:
$ ansible -i ~/.config/ansible/hosts all -m ping
home | success >> {
    "changed": false, 
    "ping": "pong"
}
Что это значит? Для всех машин (параметр "all", впрочем, хост у нас всего один), которые хранятся в hosts выполнить модуль ping. В ответ было сообщено, что команда выполнилась для машины "home", причём выполнилась успешно и модуль ping рапортует нам, что в конфигурации машины, он ничего не поменял. При необходимости можно выполнять напрямую команды bash:
$ ansible -i ~/.config/ansible/hosts all -a "ls ~/.config/ansible"
home | success | rc=0 >>
hosts
library
Следующий уровень абстракции это так называемые playbooks. Фактически это конфигурационный файл на модном yaml, в котором последовательно вызываются необходимые модули. Готовых модулей, кстати, довольно много, не сказать, что есть на все случаи жизни, но список внушителен. В качестве примера поставим 2 первых попавшихся под руку python пакета, которых пока нет у меня в системе, составим playbook и сохраним его как "~/.config/ansible/test.yml":
- hosts: all

  tasks:
    - name: Refresh package list
      pacman: update_cache=yes

    - name: Install python packages
      pacman: name={{ item }} state=present
      with_items:
        - python2-idna
        - python2-notify
Тут думаю все очевидно. В начале описываем общие параметры - что выполнять нужно для всех машин из файла hosts, а потом в секции tasks описываем что собственно делать. Список заданий состоит из двух задач, первая с описанием "Refresh package list" вызывает модуль "pacman" с параметром "update_cache=yes". Вторая чуть интереснее: она так же вызывает модуль "pacman", в качестве параметров которому передаётся "name={{ item }} state=present", где вместо "{{ item }}" будут последовательно подставляться значения из секции "with_items", фактически это цикл со странным синтаксисом. Посмотреть что значат параметры модуля "pacman" можно тут, а почитать про циклы тут. Запускаем командой "ansible-playbook":
$ sudo ansible-playbook ~/.config/ansible/test.yml -i ~/.config/ansible/hosts

PLAY [all] ******************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [home]

TASK: [Refresh package list] ************************************************** 
changed: [home]

TASK: [Install python packages] *********************************************** 
changed: [home] => (item=python2-idna)
changed: [home] => (item=python2-notify)

PLAY RECAP ******************************************************************** 
home                       : ok=3    changed=2    unreachable=0    failed=0


$ sudo ansible-playbook ~/.config/ansible/test.yml -i ~/.config/ansible/hosts

PLAY [all] ******************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [home]

TASK: [Refresh package list] ************************************************** 
changed: [home]

TASK: [Install python packages] *********************************************** 
ok: [home] => (item=python2-idna)
ok: [home] => (item=python2-notify)

PLAY RECAP ******************************************************************** 
home                       : ok=3    changed=1    unreachable=0    failed=0
Я выполнил подготовленный playbook 2 раза подряд. Как видно в первый раз при выполнении обеих задач - ansible выдал, что обе они привели к изменениям на машине: "changed=2". Во второй раз реально выполнилась только первая задача - обновления кеша pacman, вторую задачу он пропустил, т.к. пакеты уже были установлены. Эту особенность - не выполнять задачу, если она уже выполнена, по возможности, поддерживают все модули ansible.

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

Посмотрим, что будет дальше.

Комментариев нет:

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