22.8к
3
0
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники
Назад

Как использовать Ansible для простых и сложных задач

Время чтения 22 минуты
Нет времени читать?
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники
22.8к
3
0
Нет времени читать?
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники

Всем привет! Меня зовут Александр Бархатов. В работе администратора есть много действий, которые можно автоматизировать с помощью специального программного обеспечения — систем управления конфигурациями. Я пользуюсь Ansible, с помощью которого можно автоматизировать установку и настройку ПО на любое количество машин. 

В этой статье покажу, как использовать Ansible для раскатки инфраструктурных компонентов, а также для некоторых повседневных задач.

Как использовать Ansible для простых и сложных задач

Почему стоит использовать Ansible

У этого ПО множество достоинств:

  • Простота использования. Достаточно одной master-ноды, с которой будет запускаться конфигурация на языке разметки YAML. Устанавливать агенты и стороннее ПО не нужно — для удаленного подключения хостов используется протокол SSH.
  • Большое количество поддерживаемых модулей. Ansible поставляется с различными модулями, которые позволяют выполнять определенные действия: взаимодействовать с операционными системами, производить настройку сети, работать с файлами, пользователями и правами доступа.
  • Безопасность. Ее обеспечивает протокол SSH, поэтому предпринимать дополнительные шаги нет необходимости.

Установка Ansible

Ansible — это кросс-платформенное ПО, поэтому его можно установить на ОС Windows, Linux и macOS. В этой статье мы будем использовать ОС Ubuntu 22.04.2 LTS. На официальном сайте Ansible приведены подробные инструкции для каждой ОС. Установить его можно несколькими способами, мы воспользуемся официальным репозиторием Ansible.

  1. Обновляем списки пакетов и устанавливаем пакет software-properties-common, необходимый для работы с репозиториями apt:

    sudo apt update && sudo apt -y install software-properties-common

  2. Добавляем официальный репозиторий от Ansible:

    sudo add-apt-repository --yes --update ppa:ansible/ansible

  3. Устанавливаем пакет ansible:

    sudo apt -y install ansible

Когда установка завершится, необходимо убедиться, что она прошла корректно. Для этого выведем версию Ansible с помощью команды:

ansible --version

В первой строке вывода указана установленная версия — 2.15.2. Значит, установка прошла успешно.

Предварительная настройка Ansible

Прежде чем мы перейдем к использованию Ansible, необходимо настроить всего лишь один параметр, а именно выключить проверку ключей (host key verification) при подключении по протоколу SSH. Когда она включена, удаленный сервер просит подтвердить, что хост верный. При этом приходится вводить yes при подключении к каждому серверу. Для удобства выключим эту опцию. 

В Ansible присутствует основной конфигурационный файл с именем ansible.cfg, который по умолчанию располагается в /etc/ansible. 

  1. Открываем этот файл на редактирование:
    sudo nano /etc/ansible/ansible.cfg
  2. В раздел defaults прописываем следующий параметр:

    host_key_checking = False

По умолчанию файл ansible.cfg пустой, если не считать несколько строк комментариев. В этом случае необходимо вписать в него следующие строки:

[defaults]
host_key_checking = False

После этого сохраняем изменения и выходим из файла.

Подготовка файла hosts

Для того чтобы Ansible знал, на каких хостах необходимо выполнять определенные действия, используется файл с именем hosts. В нем указываются IP-адреса или доменные имена необходимых серверов. В нашем примере будут задействованы два сервера с IP-адресами 10.2.47.83 и 10.2.47.84. Подготовим файл hosts со следующим содержанием:

[all]
10.2.47.83 ansible_ssh_private_key_file=/home/alex/.ssh/id_rsa ansible_user=alex
10.2.47.84 ansible_ssh_private_key_file=/home/alex/.ssh/id_rsa ansible_user=alex

  • Параметр ansible_ssh_private_key_file задает полный путь до файла с закрытым ключом.
  • Параметр ansible_user задает имя уже существующего на удаленном сервере пользователя, которое будет использоваться при подключении по SSH.

Проверяем, что связь с удаленными хостами успешно установлена, выполнив команду:

ansible all -m ping -i hosts


Если в выводе отобразилось SUCCESS, то подключение по SSH успешно установлено. Если при подключении к хостам будут ошибки, необходимо отправить открытый ключ на требуемые серверы (команда ssh-copy-id).

Ansible Playbook для простых и повседневных задач

Файлы с описанием автоматических действий в Ansible называются playbook. Я приведу несколько примеров таких файлов для повседневных задач, все они запускаются командой:

ansible-playbook my_first_playbook.yaml -i hosts

my_first_playbook.yaml здесь — это имя playbook.

В каждом разделе я приведу полный текст YAML-файла для конкретной задачи.

Проверка свободного места на диске

check_disk_usage.yaml:


- hosts: all
  tasks:
    - name:
      command: df -h
      register: storage
    - debug: var=storage.stdout_lines

Проверка запуска службы

Для примера я использую команду unit systemd-resolved.service, которая выполняет разрешение сетевых имен для локальных приложений. Таким же образом можно проверить статус любой другой службы.

check_resolver_status.yaml:

- hosts: all
  gather_facts: yes
  become: false
  tasks:
  - name: Make sure systemd-resolved.service unit is running
    ansible.builtin.systemd:
      state: started
      name: systemd-resolved.service

Проверка общего количества и свободной оперативной памяти на сервере

memory_check.yaml:

- hosts: all
  tasks:
    - debug: var=ansible_memory_mb
    - debug: msg="total RAM is {{ ansible_memory_mb.real.total }}"

Получение информации об используемом дистрибутиве и его версии

os_version.yaml:

- hosts: all
  gather_facts: yes
  become: false
  tasks:
  - name: Distribution
    debug: msg="{{ ansible_distribution }}"
  - name: Distribution version
    debug: msg="{{ ansible_distribution_version}}"
  - name: Distribution major version
    debug: msg="{{ ansible_distribution_major_version }}"

Установка часового пояса

В этом примере полезно дополнить команду запуска: ansible-playbook set_timezone.yaml -i hosts -K

Опция -K запрашивает пароль перед запуском playbook от пользователя, у которого есть sudo-доступ. В этой задаче используется смена часового пояса от имени пользователя root или пользователя, у которого есть sudo-доступ.

Для примера я взял часовой пояс Лондона:

set_timezone.yaml:

- hosts: all
  become: yes
  tasks:
    - name: set timezone to Europe/London
      timezone:
        name: Europe/London

Playbook для развертывания инфраструктурных компонентов

Далее рассмотрим примеры для развертывания таких компонентов, как LEMP-стек и Docker. 

Установка LEMP-стека

LEMP — это набор программного обеспечения для работы с веб-сайтами. Содержит такие приложения, как Linux, Nginx, MySQL и PHP. 

Структура файлов:

files/nginx.conf.j2 

Конфигурационный файл Nginx в формате j2 (Jinja):

server {
        listen {{ http_port }};
        root /var/www/html;
        index index.php index.html index.htm index.nginx-debian.html;
        server_name {{ http_host }};
        location / {
                try_files $uri $uri/ =404;
        }
        location ~ .php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        }
        location ~ /.ht {
                deny all;
        }
}

hosts

Файл инвентаризации. В нем прописан хост, на который будут установлены пакеты LEPM-стека:

10.2.47.84 ansible_ssh_private_key_file=/home/alex/.ssh/id_rsa  ansible_user=alex

lemp_install.yaml 

Playbook, в котором описаны действия для установки и настройки LEMP-стека.

vars/default.yml 

Содержит переменные:

#пароль для пользователя root в MySQL
mysql_root_password: "mysql_root_password"
#адрес сервера на котором будет работать Nginx
http_host: "10.2.47.83"
#наименование файла сайта Nginx
http_conf: "10.2.47.83.conf"
#Порт  Nginx
http_port: "80"

playbook.yml

Шаги, которые выполняются в этом playbook:

  1. Обновление списка пакетов.
  2. Установка пакетов nginx, mysql-server, python3-pymysql, php-fpm, php-mysql.
  3. Замена дефолтного конфигурационного файла на nginx.conf.j2.
  4. Установка пароля для пользователя root в MySQL.
  5. Удаление анонимных пользователей в MySQL.
  6. Открытие 80-го порта в UFW;
  7. Перезагрузка Nginx.


- hosts: all
  become: true
  vars_files:
    - vars/default.yml
  tasks:
    - name: Install Prerequisites
      apt: name={{ item }} update_cache=yes state=latest force_apt_get=yes
      loop: [ 'aptitude' ]
    - name: Install LEMP Packages
      apt: name={{ item }} update_cache=yes state=latest
      loop: [ 'nginx', 'mysql-server', 'python3-pymysql', 'php-fpm', 'php-mysql' ]
# Nginx Configuration
    - name: Sets Nginx conf file
      template:
        src: "files/nginx.conf.j2"
        dest: "/etc/nginx/sites-available/{{ http_conf }}"
    - name: Enables new site
      file:
        src: "/etc/nginx/sites-available/{{ http_conf }}"
        dest: "/etc/nginx/sites-enabled/{{ http_conf }}"
        state: link
      notify: Reload Nginx
    - name: Removes "default" site
      file:
        path: "/etc/nginx/sites-enabled/default"
        state: absent
      notify: Reload Nginx
# MySQL Configuration
    - name: Sets the root password 
      mysql_user: 
        name: root 
        password: "{{ mysql_root_password }}"
        login_unix_socket: /var/run/mysqld/mysqld.sock
    - name: Removes all anonymous user accounts
      mysql_user:
        name: ''
        host_all: yes
        state: absent
        login_user: root
        login_password: "{{ mysql_root_password }}"
    - name: Removes the MySQL test database
      mysql_db: 
        name: test 
        state: absent
        login_user: root
        login_password: "{{ mysql_root_password }}"
# UFW Configuration
    - name: "UFW - Allow HTTP on port {{ http_port }}"
      ufw:
        rule: allow
        port: "{{ http_port }}"
        proto: tcp
  handlers:
    - name: Reload Nginx
      service:
        name: nginx
        state: reloaded
    - name: Restart Nginx
      service:
        name: nginx
        state: restarted

Переходим по IP-адресу или доменному имени, которые указаны в директории vars файл default.yml. Такое сообщение показывает, что Nginx успешно установлен:

Установка Docker с помощью Ansible

Создадим еще один playbook, который установит Docker на сервер, а также запустит один контейнер с образом Ubuntu.

Файл hosts возьмем из предыдущего примера.

Порядок действий в playbook по установке Docker:

  1. Установка пакетов для работы с HTTPS-репозиториями.
  2. Добавление официального репозитория Docker.
  3. Установка Docker.
  4. Создание контейнера с Ubuntu.

Содержимое файла docker_install.yaml:

- hosts: all
  become: true
  vars:
    container_count: 1
    default_container_name: docker
    default_container_image: ubuntu
    default_container_command: sleep 1d
  tasks:
    - name: Install required system packages
      apt:
        pkg:
          - apt-transport-https
          - ca-certificates
          - curl
          - gnupg
          - software-properties-common
          - python3-pip
          - virtualenv
          - python3-setuptools
        state: latest
        update_cache: true
    - name: Add signing key
      ansible.builtin.apt_key:
        url: "https://download.docker.com/linux/{{ ansible_distribution | lower }}/gpg"
        state: present
    - name: Set the stable docker repository
      apt_repository: 
        repo: "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_lsb.codename }} edge"
        state: present
        update_cache: yes  
    - name: Install Docker
      ansible.builtin.apt:
        name:
          - docker-ce
        state: latest
        update_cache: true
    - name: Install Docker Module for Python
      pip:
        name: docker
    - name: Pull default Docker image
      community.docker.docker_image:
        name: "{{ default_container_image }}"
        source: pull
    - name: Create default containers
      community.docker.docker_container:
        name: "{{ default_container_name }}{{ item }}"
        image: "{{ default_container_image }}"
        command: "{{ default_container_command }}"
        state: present
      with_sequence: count={{ container_count }}

Запускаем playbook командой:

ansible-playbook docker_install.yaml -i hosts -K

Проверяем, что на сервере с Docker появился контейнер с образом Ubuntu:

sudo docker ps -a

Контейнер успешно создан:

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

Комментарии0
Тоже интересно
Комментировать
Поделиться
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники