Блог Слёрм

Инсталляция LEMP-стека с помощью Ansible

Обсудим, как установить LEMP-стек с помощью Ansible. Разберемся с тем, как автоматизировать рутинные задачи, что такое Ansible и как он работает.

Чем Ansible полезен в работе


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

  • Обеспечение повторяемости решений задач в удобной форме. Например, вы решили задачу, потратили время, разобрались в софте и хотите сохранить решение, чтобы затем его повторить, а не вспоминать каждый раз заново. Для этого есть Ansible, который в этом как раз и поможет.

  • Установка и конфигурирование софта на сколь угодно много удаленных машин с одной главной машины. Вы решили задачу, обеспечили повторяемость ее решения и хотите раскатать его на сто серверов, но не делать каждый раз перезапись скрипта. За вас это сделает Ansible. Нужно только запустить решение задачи на те сервера, которые вам нужны, и все, вы великолепны :)

Почему Ansible?


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

Во-первых, простота. Она стоит во главе угла, что доказывает их слоган “Simple IT automation”, что переводится как «Простая IT-автоматизация». Вы прикладываете минимум усилий для получения хорошего результата. 

Во-вторых, отсутствие необходимости устанавливать софт на удаленные серверы. Нужна только контрольная машина, на которую установлен Ansible. 

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

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

Как работает Ansible?


В экосистеме Ansible существует всего два понятия: control node, машина, с которой производятся изменения и на которой установлен сам Ansible, и host, ноды, на которые мы устанавливаем софт и которые нам нужно сконфигурировать. 

Ansible подключается по SSH как стандарт сетевого администрирования к удаленным нодам, загружает туда модули, написанные на Python, и выполняет их на удаленных машинах. Проще говоря, контрольная нода управляет, а хосты подчиняются.

Как устроен Ansible?


Концепция Ansible заключается в том, что его кто-то должен вызвать: либо пользователь, либо public/private cloud. Затем Ansible обрабатывает запрос при помощи inventory, модулей, API и плагинов. Модули обеспечивают установку или настройку софта внутри хостов, а плагины расширяют функциональность самого Ansible. И то, и другое может быть написано на Python. Все это предназначено для того, чтобы конфигурировать удаленные хосты или сетевые устройства.

Установка Ansible


На контрольной машине должен быть установлен Python, т. к. Ansible написан на нем. Необходимо будет немного поработать в консоли, и все.

Нам нужно создать несколько виртуальных машин для vagrant: контрольную ноду и какой-нибудь хост. Я пользуюсь классной фичей vagrant – объявление нескольких машин. 

Vagrant.configure("2") do | config |
config.vm.define "controlnode" do |controlnode|
controlnode.vm.box = "ubuntu/focal64"
controlnode.vm.hostname = "controlnode"
controlnode.vm.network "private_network", ip: "192.168.50.4"
controlnode.vm.provision "shell", inline: <<-SHELL
sed -i 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/#g' /etc/ssh/sshd_config
service ssh restart
SHELL
end

Вторая машина, управляемая vagrant, – это наша нода. Здесь нет никакой смонтированной папки, поскольку это удаленная машина. У нее тот же самый SHELL, чтобы мы могли зайти в нее по SSH.

config.vm.define "server" do |server|
server.vm.box = "ubuntu/focal64"
server.vm.hostname = "server"
controlnode.vm.network "private_network", ip: "192.168.50.5"
controlnode.vm.provision "shell", inline: <<-SHELL
sed -i 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/#g' /etc/ssh/sshd_config
service ssh restart
SHELL
end

Мы видим вывод команды ‘vagrant status’: контрольная нода и сервер запущены. Команда ‘vagrant ssh’ работает, ей нужно указать название виртуальной машины. Vagrant создает виртуальную машину vagrant, пароль vagrant, если иное вы не указали в файлике. Должна работать следующая SSH-команда: vagrant@192.168.50.4. Такой IP мы указали выше. 

На SSH нам предлагается провалидировать хост, добавить его в список доверенных и ввести пароль. Так мы попадаем внутрь машины. Теперь можно выйти и зайти через vagrant SSH, чтобы не путаться и получить тот же самый результат без запроса пароля, т. к. vagrant все проделывает за нас. 

Теперь займемся установкой Ansible. Важно понимать, что Ansible поделен на две части: ansible-core и ansible-community. Первый – это «голый» Ansible без плагинов и модулей, второй же содержит в себе предустановленные плагины и модули. Мы будем использовать второй Ansible. 

Ansible не входит в список стандартных пакетов apt. Для установки Ansible нам нужно воспользоваться командой apt от repository: apt-add-repository ppa: ansible/ansible. Если вы работаете с CentOS, то архив Ansible уже существует на вашей машине, а если вы работаете с Ubuntu, вам придется его добавить, но в этом нет ничего сложного. 

Настройка плейбука для установки LEMP


Плейбук – это список сценариев для запуска Ansible. Плейбуки пишутся в формате .yml. Начинаются они с трех дешей «---» и заканчиваются тремя точками «...». Плейбуки позволяют оставлять комментарии. Плеи в плейбуке задаются с помощью массива. Каждый плей должен содержать host. Для запуска плейбука используем консольную команду ansible-playbook.

vagrant@controlnode:~/ansible$ 1s
hosts.ini playbook.yml
vagrant@controlnode:~/ansible$ ansible-playbook

Каждый плей в плейбуке характеризуется целью и набором задач, тасками. Каждый таск содержит имя. Имя, как и хост, – это строка. Строки задаются через кавычки. Наша первая таска – установка nginx на удаленной машине.

hosts: "all"
become: true
tasks:
name: "Install nginx via apt"
ansible.builtin.apt:
  name: "nginx"
  state: "latest"
  update_cache: true

Теперь удалим папку var/www/html, чтобы скопировать нашу папку. Для этого воспользуемся модулем ansible.builtin.file. 

name: "Delete /var/www/html folder"
ansible.builtin.file:
path: "/var/www/html"
state: "absent"

Мы скопировали наш лендинг в папку var/www/html. Я скопировал наш лендинг в папке files в директории Ansible, давайте ее загрузим.

name: "Copy our lending to /var/www/html folder"
ansible.builtin.copy:
  src: "files/html"
  dest: "/var/www/"
  owner: "vagrant"
  group: "vagrant"
  mode: "0644"

Запускаем плейбук на controlnode.

ansible-playbook playbook.yml -i hosts.ini

Если плейбук отыграл успешно, то заходим сюда и любуемся – http://192.168.50.5/

Рефакторим с помощью ролей


Ansible предоставляет очень грамотный механизм для разделения тасок по смысловым частям, т. е. он предоставляет роли. Роли – это некий набор тасок, объединенных общим смыслом.

Посмотрим, как эти роли работают. У нас есть плейбук с тасками, разделенными по смыслу и являющимися базовыми строительными блоками для ролей. Ansible позволяет создать папку roles, из которой он будет по умолчанию читать роли. Внутри роли установлен порядок: все таски этой роли лежат в папке tasks в файле main.yml. Копируем таски как массив.

В плейбуке роли включаются при помощи директивы roles, где прописываются их имена. Роли выполняются и указываются перед тасками. Отрефакторенная структура плейбука будет выглядеть следующим образом:

#################
# LEMP PLAYBOOK #
#################
---
- hosts: "all"
  become: true
  roles:
  - nginx # все таски файла main.yml по пути %директория ansible%/roles/nginx/tasks/
  - mysql # все таски файла main.yml по пути %директория ansible%/roles/mysql/tasks/
  - php # все таски файла main.yml по пути %директория ansible%/roles/php/tasks/
  tasks:
  - name: "Reload nginx" # этот таск не относится к ролям напрямую, поэтому вынесен после выполнения всех ролей
    ansible.builtin.service:
      name: "nginx"
      state: "reloaded"

Ansible Galaxy


Следующий вопрос, который возникает после того, как мы сделали плейбук и отделили роли: можно ли тратить еще меньше сил? Можно. Ansible Galaxy содержит типовые решения многих проблем и типовые модули. Через Ansible Galaxy можно устанавливать готовые роли и использовать их в плейбуках. Рекомендую делать это программистам. Сисадминам и сеньорам я рекомендую залазить в роли, которые есть на GitHub. Это важно для понимания того, что и о чем там написано. 


Изучение и погружение в Ansible позволяет понять основы автоматической конфигурации и в разы уменьшить ручную работу. Курс «Ansible: Infrastructure as Code» от Слёрма обучает работе с переменными, плейбуками, содержит подробные лекции о том, как писать сложные хендбуки, а главное – дает понимание о том, как можно переиспользовать свою работу в различных системах и автоматизировать рутинные задачи.  

Узнать больше о курсе



Ansible