65. Ansible Playbooks - Часть 1

Обновлено: 2024-03-12
9 мин

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 бесплатна и позволяет легко справиться с этой задачей по сравнению с необходимостью иметь специализированный скрипт.

Ресурсы

Этот последний плейлист, приведенный выше, является тем местом, откуда было взято много кода и идей для этого раздела, отличным ресурсом и руководством в видеоформате.