65. Ansible Playbooks - Часть 1
Содержание
Ansible Playbooks
В этом разделе мы рассмотрим основную причину, которую я вижу, по крайней мере, для Ansible. Я имею в виду, что это здорово - взять одну команду и обратиться ко многим различным серверам для выполнения простых команд, таких как перезагрузка длинного списка серверов и избавление от необходимости подключаться к каждому из них по отдельности.
Но как насчет того, чтобы взять голую операционную систему, объявить программное обеспечение и службы, которые мы хотим запустить на этой системе, и убедиться, что все они работают в нужном состоянии.
Здесь на помощь приходят учебники Ansible. Плейбук позволяет нам взять группу серверов и выполнить задачи конфигурации и установки для этой группы.
Формат плейбука
Плейбук > Игры > Задачи
Если вы занимаетесь спортом, вы, возможно, сталкивались с термином “плейбук”. Плейбук рассказывает команде о том, как вы будете играть, состоящий из различных пьес и задач. Если мы считаем пьесы декорациями в спорте или игре, а задачи связаны с каждой пьесой, у вас может быть несколько задач, составляющих пьесу, а в плейбуке может быть несколько различных пьес.
Эти плейбуки написаны на YAML (YAML - это не язык разметки), вы найдете много разделов, которые мы уже рассмотрели, особенно контейнеры и Kubernetes, в которых используются файлы конфигурации в формате YAML.
Давайте рассмотрим простой плейбук под названием playbook.yml.
- name: Simple Play
hosts: localhost
connection: local
tasks:
- name: Ping me
ping:
- name: print os
debug:
msg: "{{ ansible_os_family }}"
Вы найдете вышеуказанный файл simple_play. Если мы затем используем команду ansible-playbook simple_play.yml
, то пройдем следующие шаги.
Вы видите, что первая задача “сбор шагов” произошла, но мы не вызывали или не просили об этом? Этот модуль автоматически вызывается плейбуками для сбора полезных переменных об удаленных хостах. ansible.builtin.setup
Нашей второй задачей было установить ping, это не ICMP ping, а python скрипт, который сообщает pong
об успешном соединении с удаленным или локальным хостом. ansible.builtin.ping
Затем наша третья или на самом деле вторая определенная задача, так как первая будет выполняться, если вы не отключите печать сообщения, сообщающего нам о нашей ОС. В этой задаче мы используем условия, мы можем запустить этот плейбук на всех различных типах операционных систем, и это вернет нам имя ОС. Мы просто передаем этот вывод для удобства, но мы могли бы добавить задачу, чтобы сказать что-то вроде:
tasks:
- name: "shut down Debian flavoured systems"
command: /sbin/shutdown -t now
when: ansible_os_family == "Debian"
Vagrant для настройки нашего окружения
Мы будем использовать Vagrant для настройки нашего узлового окружения, я собираюсь оставить разумные 4 узла, но вы, надеюсь, увидите, что их может быть 300 или 3000. В этом и заключается сила Ansible и других инструментов управления конфигурацией, чтобы иметь возможность настраивать ваши серверы.
Вы можете найти этот файл здесь (Vagrantfile)
Vagrant.configure("2") do |config|
servers=[
{
:hostname => "db01",
:box => "bento/ubuntu-21.10",
:ip => "192.168.169.130",
:ssh_port => '2210'
},
{
:hostname => "web01",
:box => "bento/ubuntu-21.10",
:ip => "192.168.169.131",
:ssh_port => '2211'
},
{
:hostname => "web02",
:box => "bento/ubuntu-21.10",
:ip => "192.168.169.132",
:ssh_port => '2212'
},
{
:hostname => "loadbalancer",
:box => "bento/ubuntu-21.10",
:ip => "192.168.169.134",
:ssh_port => '2213'
}
]
config.vm.base_address = 600
servers.each do |machine|
config.vm.define machine[:hostname] do |node|
node.vm.box = machine[:box]
node.vm.hostname = machine[:hostname]
node.vm.network :public_network, bridge: "Intel(R) Ethernet Connection (7) I219-V", ip: machine[:ip]
node.vm.network "forwarded_port", guest: 22, host: machine[:ssh_port], id: "ssh"
node.vm.provider :virtualbox do |v|
v.customize ["modifyvm", :id, "--memory", 2048]
v.customize ["modifyvm", :id, "--name", machine[:hostname]]
end
end
end
end
Используйте команду vagrant up
, чтобы запустить эти машины в VirtualBox, Вы можете добавить больше памяти, а также определить разные частные_сетевые адреса для каждой машины, но это работает в моей среде. Помните, что наш блок управления - это рабочий стол Ubuntu, который мы установили в разделе Linux.
Если вы ограничены в ресурсах, вы также можете запустить vagrant up web01 web02
, чтобы поднять только веб-серверы, которые мы используем здесь.
Конфигурация хоста Ansible
Теперь, когда наша среда готова, мы можем проверить ansible, и для этого мы будем использовать наш рабочий стол Ubuntu (вы можете использовать его, но вы также можете использовать любую машину на базе Linux в вашей сети, доступную для сети ниже) в качестве нашего управления, давайте также добавим новые узлы в нашу группу в файле ansible hosts, Вы можете считать этот файл инвентаризацией, альтернативой этому может быть другой файл инвентаризации, который вызывается как часть вашей команды ansible с -i filename
, это может быть полезно по сравнению с использованием файла host, так как вы можете иметь разные файлы для разных сред, например, production, test и staging. Поскольку мы используем стандартный файл hosts, нам не нужно его указывать, так как он будет использоваться по умолчанию.
Я добавил следующее в файл hosts по умолчанию.
[control]
ansible-control
[proxy]
loadbalancer
[webservers]
web01
web02
[database]
db01
Прежде чем двигаться дальше, мы хотим убедиться, что можем выполнить команду для наших узлов, давайте выполним ansible nodes -m command -a hostname
, эта простая команда проверит, что у нас есть подключение и сообщит имена наших узлов.
Также обратите внимание, что я добавил эти узлы и IP на мой узел управления Ubuntu в файл /etc/hosts для обеспечения подключения. Нам также может понадобиться выполнить конфигурацию SSH для каждого узла с блока Ubuntu.
192.168.169.140 ansible-control
192.168.169.130 db01
192.168.169.131 web01
192.168.169.132 web02
192.168.169.133 loadbalancer
На этом этапе мы хотим выполнить настройку SSH ключей между узлами управления и сервера. Это то, что мы будем делать дальше, другим способом здесь может быть добавление переменных в ваш файл hosts для указания имени пользователя и пароля. Я бы не советовал этого делать, так как это никогда не будет лучшей практикой.
Чтобы настроить SSH и общий доступ между узлами, выполните следующие шаги, вам будет предложено ввести пароль (vagrant
), и вам, вероятно, придется нажать y
несколько раз, чтобы согласиться.
ssh-keygen
ssh-copy-id localhost
Теперь, если все ваши ВМ включены, вы можете запустить команду ssh-copy-id web01 && ssh-copy-id web02 && ssh-copy-id loadbalancer && ssh-copy-id db01
, которая запросит у вас пароль, в нашем случае пароль vagrant
.
Я не запускаю все свои виртуальные машины, а запускаю только веб-серверы, поэтому я выдал команду sh-copy-id web01 && ssh-copy-id web02
.
Перед запуском любых плейбуков я хочу убедиться, что у меня есть простое соединение с моими группами, поэтому я запустил ansible webservers -m ping
для проверки соединения.
Наш первый “настоящий” плейбук Ansible
Наш первый плейбук Ansible будет настраивать наши веб-серверы, мы сгруппировали их в нашем файле hosts под группировкой [webservers].
Перед запуском нашего плейбука мы можем убедиться, что на web01 и web02 не установлен apache. В верхней части скриншота ниже показано расположение папок и файлов, которые я создал в моей системе управления ansible для запуска этого плейбука, у нас есть playbook1.yml
, затем в папке templates у нас есть файлы index.html.j2
и ports.conf.j2
. Вы можете найти эти файлы в папке, указанной выше в репозитории.
Затем мы подключаемся по SSH к web01, чтобы проверить, установлен ли у нас apache?
Из вышеприведенного видно, что у нас не установлен apache на web01, поэтому мы можем исправить это, запустив следующий плейбук.
- hosts: webservers
become: yes
vars:
http_port: 8000
https_port: 4443
html_welcome_msg: "Hello 90DaysOfDevOps"
tasks:
- name: ensure apache is at the latest version
apt:
name: apache2
state: latest
- name: write the apache2 ports.conf config file
template:
src: templates/ports.conf.j2
dest: /etc/apache2/ports.conf
notify:
- restart apache
- name: write a basic index.html file
template:
src: templates/index.html.j2
dest: /var/www/html/index.html
notify:
- restart apache
- name: ensure apache is running
service:
name: apache2
state: started
handlers:
- name: restart apache
service:
name: apache2
state: restarted
Разбираем вышеприведенный плейбук:
- hosts: webservers
означает, что наша группа, на которой будет запущен этот плейбук, называется webservers.become: yes
означает, что наш пользователь, запускающий плейбук, станет root на наших удаленных системах. Вам будет предложено ввести пароль root.- Затем у нас есть
vars
, и это определяет некоторые переменные окружения, которые мы хотим использовать на наших веб-серверах.
После этого мы приступаем к выполнению наших задач,
- Задача 1 - убедиться, что apache работает на последней версии.
- Задача 2 - написать файл ports.conf из нашего исходного файла, который находится в папке templates.
- Задача 3 - создание базового файла index.html
- Задача 4 - убедиться, что apache запущен.
Наконец, у нас есть раздел обработчиков, Handlers: Running operations on change
“Иногда вы хотите, чтобы задача выполнялась только тогда, когда на машине происходят изменения. Например, вы можете захотеть перезапустить службу, если задача обновляет конфигурацию этой службы, но не перезапускать ее, если конфигурация не изменилась. Для решения этой задачи в Ansible используются обработчики. Обработчики - это задачи, которые выполняются только при получении уведомления. Каждый обработчик должен иметь глобально уникальное имя”.
На этом этапе вы можете подумать, но мы развернули 5 виртуальных машин (включая нашу машину Ubuntu Desktop, которая действует как наш Ansible Control) Остальные системы будут задействованы в оставшейся части раздела.
Запуск нашего плейбука
Теперь мы готовы запустить наш учебник на наших узлах. Для запуска нашего плейбука мы можем использовать ansible-playbook playbook1.yml
Мы определили наши узлы, на которых будет работать наш учебник, и это позволит выполнить наши задачи, которые мы определили.
После завершения команды мы получим результат, показывающий наши пьесы и задачи, это может занять некоторое время, вы можете видеть на изображении ниже, что это заняло некоторое время, чтобы пойти и установить наше желаемое состояние.
Затем мы можем дважды проверить это, зайдя в узел и проверив, что на нашем узле установлено программное обеспечение.
Теперь, когда мы развернули два автономных веб-сервера, мы можем перейти на соответствующие IP, которые мы определили, и получить наш новый веб-сайт.
Мы будем опираться на это руководство по ходу работы над остальной частью этого раздела. Мне также интересно взять наш рабочий стол Ubuntu и посмотреть, сможем ли мы загрузить наши приложения и конфигурацию с помощью Ansible, поэтому мы также можем коснуться этого. Вы видели, что мы можем использовать локальный хост в наших командах, мы также можем запускать плейбуки, например, на нашем локальном хосте.
Еще одна вещь, которую следует добавить, заключается в том, что мы работаем только с виртуальными машинами Ubuntu, но Ansible не зависит от целевых систем. Альтернативы, которые мы уже упоминали ранее для управления системами, могут быть сервер за сервером (не масштабируемый, когда вы получаете большое количество серверов, плюс боль даже с 3 узлами), мы также можем использовать скрипты оболочки, которые мы рассматривали в разделе Linux, но эти узлы потенциально разные, так что да, это можно сделать, но тогда кто-то должен поддерживать и управлять этими скриптами. Ansible бесплатна и позволяет легко справиться с этой задачей по сравнению с необходимостью иметь специализированный скрипт.
Ресурсы
- What is Ansible
- Ansible 101 - Episode 1 - Introduction to Ansible
- NetworkChuck - You need to learn Ansible right now!
- Your complete guide to Ansible
Этот последний плейлист, приведенный выше, является тем местом, откуда было взято много кода и идей для этого раздела, отличным ресурсом и руководством в видеоформате.