К основному контенту

Автоматизация задач по настройке ОС с помощью Ansible.

Ansible — система управления конфигурациями, написанная на Python, с использованием декларативного языка разметки для описания конфигураций.
Используется для автоматизации настройки и развертывания программного обеспечения. Обычно используется для управления Linux-узлами, но Windows также поддерживается. Поддерживает работу с сетевыми устройствами, на которых установлен Python версии 2.4 и выше по SSH или PowerShell соединению.

Слово «Ansible» означает вымышленную систему мгновенной гиперпространственной связи.

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

  • низкий порог входа;
  • декларативный язык описания конфигурации;
  • на управляемые узлы не нужно устанавливать никакого дополнительного ПО (агентов);

Простой пример

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

Пример настройки файла sudoers пользователя ansible  Развернуть исходный код

cat /etc/sudoers.d/ansible
ansible ALL=(ALL) NOPASSWD:ALL
Defaults:ansible !requiretty

Установка

Пример установки ПО ansible на Centos

sudo yum install epel-release
sudo yum install ansible

Файл инвентаря

Перед началом работы необходимо создать файл инвентаря с управляемыми машинами. Имена машин в инвентаре обычно совпадают с именами из файла /etc/hosts. Предполагается, что эти имена доступны для соединения по ssh.

Пример инвентаря  Развернуть исходный код

cat /home/ansible/playbooks/test
# одиночный сервер
test_srv
# группа серверов БД
[db]
db1
db2
# группа серверов приложений
[app]
app1
app2
# Группа групп
[test:children]
db
app

Помимо имен хостов в инвентаре можно хранить переменные, специфичные для данного инвентаря. Например глобальные настройки прокси сервера.
В рассматриваемом примере предполагается, что файл инвентаря расположен по адресу /home/ansible/playbooks/test

Выполнение произвольных команд на машинах из инвентаря

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

ansible -i test all -a "ls -la /home/ansible"
db1 | SUCCESS | rc=0 >>
total 16
drwx------. 4 ansible ansible 108 Nov 22 13:08 .
drwxr-xr-x. 3 root    root     21 Nov 22 12:55 ..
drwx------. 3 ansible ansible  17 Nov 22 12:58 .ansible
-rw-r--r--. 1 ansible ansible  18 Aug  2  2016 .bash_logout
-rw-r--r--. 1 ansible ansible 193 Aug  2  2016 .bash_profile
-rw-r--r--. 1 ansible ansible 231 Aug  2  2016 .bashrc
drwx------. 2 ansible ansible  29 Nov 22 12:55 .ssh
-rwx------. 1 ansible ansible  22 Nov 22 13:07 .tmux.conf
 
remsmed2 | SUCCESS | rc=0 >>
total 28
drwx------. 4 ansible ansible 4096 Nov 22 11:00 .
drwxr-xr-x. 4 root    root      35 Nov 22 10:34 ..
drwx------. 3 ansible ansible   17 Nov 20 13:58 .ansible
-rw-------. 1 ansible ansible   43 Nov 22 11:03 .bash_history
-rw-r--r--. 1 ansible ansible   18 May 26 21:49 .bash_logout
-rw-r--r--. 1 ansible ansible  193 May 26 21:49 .bash_profile
-rw-r--r--. 1 ansible ansible  231 May 26 21:49 .bashrc
drwx------. 2 ansible ansible   29 Nov 20 13:58 .ssh
-rwx------. 1 ansible ansible   22 Nov 20 14:01 .tmux.conf
-rw-------. 1 ansible ansible   54 Nov 22 11:00 .Xauthority

Синтаксис команды:
  • -i путь к файлу инвентаря, 
  • all - для всех машин в инвентаре (можно указывать по отдельности или группами, а также  использованием *),
  • -a команда, подлежащая выполнению.

Простой сценарий

Замечание: Ниже пойдет речь о ролях (roles) и сценариях (playbooks). В принципе можно не использовать роли, а описывать все задачи непосредственно в сценариях. Однако, такой подход противоречит рекомендациям разработчиков и не оптимален для повторного использования кода. Предполагается, что в примере книги сценариев лежат в /home/ansible/playbooks а роли в /home/ansible/playbooks/roles.

Сценарии (Playbooks)

Книга сценария содержит:
  • hosts - группу машин инвентаря, на для которых будет выполняться эта книга. Например, если в hosts записать db - то книга будет выполняться только на машинах, входящих в группу db, для остальных машин команды книги будут проигнорированы.
  • user - пользователь который будет выполнять книгу. В данном примере - это специально для этих целей созданный пользователь "ansible".
  • become - требуется ли эскалация привилегий, для выполнения задач описанных в книге. Поскольку установка ПО требует прав суперпользователя параметр устанавливается  "yes".
  • roles - список ролей которые будут применены к машинам в ходе работы книги. Поиск ролей будет осуществляться программой по пути ./roles/role_name/tasks/main.yml
Пример playbook  Развернуть исходный код

cat /home/ansible/playbooks/new_machine.yml
- hosts: all
  user: ansible
  become: yes
 
  roles:
    - essentials

В более сложных реализациях может содержать много чего еще: выполнение команд, объявление переменных и т.д.

Роли

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

Простая роль "Essentilas"  Развернуть исходный код

cat /home/ansible/playbooks/roles/essentials/tasks/main.yml
- name: Installing packages.
  yum: name={{ item }}
  with_items:
      - vim
      - tmux
      - atop
Все что делает роль - установка нескольких пакетов пакетов, с помощmю вызова модуля yum. В данном примере в составе роли присутствует только один файл с командами.

Выполнение книги

ansible-playbook -i test -l db1 new_machine.yml
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [db1]
TASK: [Installing packages.] *********************************************
changed: [db1] => (item=[u'vim', u'tmux', u'atop'])
PLAY RECAP ********************************************************************
db1 : ok=3 changed=1 unreachable=0 failed=0

Синтаксис:
  • -i путь к файлу инвентаря
  • -l от limit. Книга будет применена только к указанному хосту/группе хостов. Допускается использование шаблонов (например: "*")
  • new_machine.yml - название книги которая будет выполнена.
Разъяснение результатов выполнения:
·         GATHERING FACTS - на этом этапе ansible собирает полезную информацию об обрабатываемой системе: ip адрес, версию ОС, аппаратную составляющую и многое другое. Все эти параметры записываются в переменные, к которым можно обращаться в ходе выполнения роли. 
·         TASK - отчет о выполнении каждого шага. В данном примере он один.
·         PLAY RECAP - общая сводка о выполнении - количество выполненных команда для всех машин, к которым была применена книга.

Повторное выполнение книги

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

ansible-playbook -i test -l db1 new_machine.yml
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [db1]
TASK: [Installing packages.] *********************************************
ok: [db1] => (item=[u'vim', u'tmux', u'atop'])
PLAY RECAP ********************************************************************
db1 : ok=4 changed=0 unreachable=0 failed=0

Видно, что TASK уже не changed а ок. И в сводке также changed=0

Пример посложнее

Запуск сервиса и правка конфигурационного файла

В примере будет усложнена предыдущая роль, путем добавления и правки конфигурации для tmux и atop.
Справка: программа atop, помимо стандартного atop функционирования top-like может работать как сервис и вести историю загрузки системы, как sar - только лучше. Для этого требуется запустить atop в качестве демона. Одновременно изменим с 10 минут на минуту интервал, по которому он будет собирать данные.

Новый файл роли будет выглядеть так:  Развернуть исходный код

cat /home/ansible/playbooks/roles/essentials/tasks/main.yml
- name: Installing packages.
  yum: name={{ item }}
  with_items:
      - vim
      - tmux
      - atop
 
- name: Start atop service.
  service: 
      name: atop
      state: started
      enabled: yes
 
- name: Minutely schedule.
  lineinfile:
      dest: /etc/sysconfig/atop
      regexp: '^INTERVAL='
      line: 'INTERVAL=60'
# Тут не помешает перезапуск сервиса с помощью handler, но как-нибудь в другой раз.

В первом добавленном блоке сервис atop переводится в состояние started и enabled (запуск при старте системы).
Во втором блоке редактируется конфигурационный файл atop. С помощью регулярного выражения идет поиск строки начинающейся со слова INTERVAL, при нахождении строка заменяется на INTERVAL=60.

Использование шаблонов конфигураций и переменных Ansible.

В примере будет создан конфигурационный файл терминального мультиплексора tmux на основе заранее созданного шаблона и переменных ansible.

Дополнения файла роли  Развернуть исходный код

tail -n 7 /home/ansible/playbooks/roles/essentials/tasks/main.yml
- name: Setup tmux.conf as template.
  template:
    src: tmux.conf.j2
    dest: "/home/ansible/.tmux.conf"
    owner: "ansible"
    group: "ansible"
    mode: 0700

Файл шаблона ansible будет искать по адресу ./roles/essentials/templates/tmux.conf.j2

Шаблон конфигурации  Развернуть исходный код

cat ./roles/essentials/templates/tmux.conf.j2
set -g status-bg {{ tmux_status_bar_colour_bg }}

Конфигурационный файл меняет цвет статусной панели tmux на цвет, указанный в переменной.
Для передачи переменных в задание существует несколько способов несколько. Самый простой - добавить опцию extra-vars к команде запуска книги.


ansible-playbook -i test -l db1 new_machine.yml --extra-vars "tmux_status_bar_colour_bg=red"

Полезные ссылки

Статья на Habrahabr. Очень хороший материал для начала. Данная заметка написана с оглядкой на нее. Best practices из официальной документации. Рекомендуется к прочтению перед написанием собственных сценариев.Документация от разработчиков.

Комментарии

Популярные сообщения из этого блога

Установка и настройка pgAgent(планировщика заданий PostgreSQL)

Установка pgAgent Последняя версия скрипта для установки агента  тут . Перенести инструкцию по агенту в отдельную тему. 1. Создать пользователя ОС, и сделать ему домашний каталог: useradd -s /bin/false -r -M pgagent mkdir /home/pgagent 2. Установить и настроить демон: yum install pgagent_94 При наличии ошибок вида (была на Oracle Linux 6.8) Error: Package: pgagent_94-3.4.0-1.rhel6.x86_64 (pgdg94)            Requires: libwx_baseu-2.8.so.0(WXU_2.8)(64bit) Нужно установить EPEL systemctl enable pgagent_94 chown pgagent:pgagent /var/log/pgagent_94.log 3. Установить схему агента в базе: sudo -u postgres psql -f /usr/share/pgagent_94-3.4.0/pgagent.sql postgres 4. Создать файл паролей для подключения агента к базе. vi /home/pgagent/.pgpass localhost:5432:*:postgres:postgres chown pgagent.pgagent /home/pgagent -R chmod 600 /home/pagent/.pgpass 5. Запустить и проверить работу агента systemctl start pgagent_94.service systemctl status pga

Включение логирования для Haproxy

Изначально логирование в syslog в HaProxy отключено. Ниже пример настройки логирования для ОС Centos 7. Настройка: Добавить строку  log 127.0.0.1 local2 в секцию global файла /etc/haproxy/haproxy.cfg Раскомментировать $ModLoad imudp и $UDPServerRun 514 в файле  /etc/rsyslog.conf Создать файл  /etc/rsyslog.d/haproxy.conf со следующим содержимым:  local2.* /var/log/haproxy.log Перезапустить rsyslog и haproxy.

Использование oraenv для установки окружения.

Для настройки окружения в Linux можно все параметры базы указать в .bash_profile: ORACLE_HOME=/app/oracle/product/11.2.0.4/dbhome_1 export ORACLE_HOME ORACLE_BASE=/app/oracle export ORACLE_BASE ORACLE_SID=orcl export ORACLE_SID PATH=$PATH:$HOME/bin:$ORACLE_HOME/bin export PATH Но лучше использовать для этих целей утилиту oraenv. oraenv берет данные из файла /etc/oratab orcl:/app/oracle/product/12.1.0/dbhome_1:N И на ее основе задает параметры окружения: ORACLE_SID, ORACLE_BASE,ORACLE_HOME и PATH Использовать можно в интерактивном режиме: . oraenv ORACLE_SID = [orcl] ? orcl The Oracle base has been set to /app/oracle И в неинтерактивном режиме. Добавить в  .bash_profile: ORACLE_SID=orcl ORAENV_ASK=NO . oraenv Для ASM ситуация аналогичная. . oraenv ORACLE_SID = [orcl] ? +ASM1 The Oracle base has been set to /u01/app/oracle echo $ORACLE_HOME /app/11.2.0/grid