• База знань
  • /
  • Блог
  • /
  • Wiki
  • /
  • ONLINE CHAT
+380 (44) 364 05 71

Стаття також доступна російською (перейти до перегляду).

Практикум з віддаленого керування серверами за допомогою Ansible

Вступ

У статті «Інструмент автоматизації Ansible» нами були розглянуті основні концепції віддаленого керування вузлами мережі за допомогою Ansible та виконали початкове налаштування керуючого вузла на ОС Ubuntu. У цій роботі ми реалізуємо процес автоматизованого початкового налаштування серверів Ubuntu з використанням Ansible Playbooks.

Основні концепції Ansible Playbooks

Ansible Playbooks дає можливість організувати гнучку та багаторазову систему керування конфігурацією та розгортанням на багатьох серверах мережі. Зокрема, він дає можливість:

  • Оголошувати конфігурації;
  • Формувати кроки будь-якого впорядкованого вручну процесу на кількох групах вузлів у певній послідовності;
  • Запускати на виконання задачі синхронно або асинхронно.

Перерахуємо загальні концепції правильного використання цього механізму.

Для опису задач та конфігурацій доцільно використовувати мову YAML як таку, що має більш простий та зрозумілий синтаксис у порівнянні із, наприклад, мовою JSON.

Для кращого сприйняття специфікацій проекту бажано елементи файлу playbook.yml розділяти порожньою строкою.

Застосовувати коментування перед кожним блоком або задачею. Це значно прискорить у подальшому їх редагування.

Заздалегідь продумати організацію імен у проекті. Кожна задача, блок або модуль повинні мати узгоджені назви.

Ansible має велику кількість різноманітних функцій та їх розширень, що дозволяє реалізувати повноцінний проект будь-якої складності. Однак, тут треба спиратися на принцип: чим простіше, тим досконаліше. Це дозволить уникнути зайвого ускладнення проекту.

Доцільним буде зберігати свої проекти у будь-якій із систем контролю версій. Це дасть змогу ефективніше ними керувати у подальшому.

Для зберігання конфіденційної інформації проекту краще використовувати методи шифрування текстових даних Ansible Vault.

Для уникнення багатьох помилок бажано здійснювати постійне тестування проекту на всіх етапах його підготовки різноманітними влаштованими сервісами – Ansible Lint, assert та інші.

Реалізація проекту

Реалізація нашого проекту по початковому налаштуванню серверів Ubuntu включає кілька стадій. Перерахуємо їх:

  • Формування завдань;
  • Створення структури каталогів та файлів;
  • Створення Inventory;
  • Перевірка налаштувань та тестування з’єднання;
  • Формування директив файлу playbook;
  • Тестування перед запуском;
  • Запуск та виконання;
  • Вибіркове тестування результатів виконання.

Формування завдань

Набір завдань, котрі формуються, повинен реалізувати основну мету проекту – початкове налаштування віддалених вузлів, котрі працюють на ОС Ubuntu 22. Відповідно до цього, такий набір буде виглядати наступним чином:

  • Встановлення менеджеру пакетів aptitude, який є більш пристосованим для роботи з Ansible у порівнянні з apt;
  • Створення та налаштування адміністраторської групи для користувачів з правами sudo;
  • Створення нового користувача з відповідними правами;
  • Забезпечення можливості входу нового користувача на кожний з вузлів по ключу SSH;
  • Відключення автентифікації на основі паролю для користувача root;
  • Налаштування брандмауера UFW;
  • Встановлення системних пакетів.

У відповідності до визначених завдань буде формуватися структура проекту.

Створення структури каталогів та файлів

У випадку, якщо для роботи використовується система контролю версій, то необхідно забезпечити узгодження даних. Тут є два варіанти.

Варіант перший. Репозиторій do-community/ansible-playbooks використовується вперше. Тоді необхідно клонувати його у локальну директорію вузла керування Ansible. Це можна зробити за допомогою наступної команди:

$ git clone https://github.com/do-community/ansible-playbooks.git

Після чого перейти до відповідної директорії:

$ cd ansible-playbooks

Варіант другий. Репозиторій був клонований раніше. У цьому випадку необхідно отримати доступ до існуючої копії ansible-playbook та оновити вміст репозиторію за допомогою відповідної команди:

$ cd ansible-playbooks
$ git pull

У нашому випадку, замість назви ansible-playbooks для репозиторію використана назва ansible.

Після цього можна починати створювати структуру каталогів. Насамперед, створимо директорію нашого проекту із назвою setup_all_node_ubuntu:

$ mkdir /etc/ansible/setup_all_node_ubuntu

Створення директорії проекту.

Після цього створимо директорію для зберігання файлу загальних параметрів для всіх задач:

$ mkdir /etc/ansible/setup_all_node_ubuntu/all_vars

Створення директорії для збергіання файлу загальних параметрів.

Створимо файл def.yml загальних параметрів за допомогою редактора nano та додамо в нього наступні записи:

create_user: admin
copy_local_key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"
sys_packages: [ 'curl', 'vim', 'git', 'ufw']

Перший запис визначає ім'я користувача (admin), під яким буде здійснюватись вхід на віддалені вузли.

Другий запис задає функції пошуку і копіювання та шлях доступу до файлу з відкритим ключем SSH. Відповідно до цього, вказаний ключ буде поміщений у файл ~.ssh/authorized_keys для облікового запису admin для всіх вузлів.

Третій запис конкретизує назви системних пакетів для встановлення.

Введемо у терміналі:

$ nano /etc/ansible/setup_all_node_ubuntu/all_vars/def.yml

Відкриття файлу в редакторі nano

Вміст файлу показаний нижче.

Вміст файлу def.yml

Збережемо результат та вийдемо з редактора (Ctrl+O, Ctrl+X).

Ключ SSH був згенерований нами незадовго до цього за допомогою команди:

$ ssh-keygen

Генерація SSH ключа

Встановлення пароля для ключа SSH

Вміст ключа SSH

Відповідний закритий ключ id_rsa знаходиться у тій же директорії, що і відкритий. Слід зазначити, що вказаний ключ було створено спеціально для облікового запису користувача admin віддалених вузлів і тому, щоб уникнути плутанини бажано такі ключі зберігати в окремо створених каталогах або ж потім перейменувати їх за допомогою команди rename.

Створення Inventory

У термінології Ansible під Inventory розуміється список віддалених вузлів разом із параметрами для входу. Місцезнаходження списку: /etc/ansible/hosts. Сформуємо його:

$ sudo nano /etc/ansible/hosts

Запуск редактора nano

У вікні редактору внесемо у файл відповідні зміни.

Редагування файлу hosts

Ми створили групу webservers, в яку внесли лише один хост із ім'ям server1. За допомогою параметру ansible_host вказали IP-адресу хоста та пароль доступу по SSH-з'єднанню. У розділі all:vars ми маємо змогу вказати будь-які загальні параметри доступу для всіх груп хостів. Наприклад, ім'я користувача, якщо воно однакове для всіх хостів. Ми також можемо вказати параметри окремо для будь-якої групи чи хоста. Для цього достатньо ввести їх у блоці під назвою хоста або групи, взятої у квадратні дужки, наприклад, [server1]. Після внесення змін збережемо дані та вийдемо з редактора.

Перевірка налаштувань та тестування з’єднання

Перед тим, як почати процес керування вузлами необхідно перевірити працездатність каналу з'єднання з ними та правильність встановлених налаштувань. На першому етапі перевіряється правильність налаштування керуючого вузла. На другому етапі встановлюється перший зв'язок із віддаленими машинами та тестується з'єднання з ними за допомогою Ansible. Введемо у терміналі:

$ ansible all --list-hosts

Перевірка налаштуваня з'єднаня з віддаленим сервером.

За допомогою цієї команди ми перевірили список хостів, котрий був ідентифікований програмою. Він співпадає із нашим списком – server1.

Далі, введемо у терміналі:

$ ansible-inventory --list -y

Cписок хостів

Тут ми перевірили повний список груп, хостів та правильність внесених нами вхідних параметрів. Як можна переконатися, він повністю відповідає дійсності.

Тепер встановимо перше з'єднання з хостами зі списку. Це дозволить уникнути у подальшому затримок у роботі з-за необхідності підтвердження згоди на з'єднання, оскільки ці вузли вже будуть ідентифіковані ОС Ubuntu, як такі, що є дозволеними. Для цього введемо наступну команду:

$ ssh root@178.20.157.79

Підключення до серверу та підтвердження достовірности хосту

Ubuntu пропонує підтвердити достовірність хоста, що ми і робимо, набравши yes.

Внесення хосту в білий список

Як можна переконатися з повідомлення на останньому скрині, адреса хоста зі списку inventory була внесена до списку дозволених хостів Ubuntu, як ми і хотіли.

Перевіримо це за допомогою тієї ж команди:

$ ssh root@178.20.157.79

Підключеня до віддаленого серверу

Тепер одразу ж пропонується ввести пароль, тобто хост ідентифіковано. Після введення паролю відбувається підключення, як показано нижче.

Успешне подключення до віддаленого серверу

Закриємо сеанс з'єднання з віддаленим вузлом за допомогою команди exit та повернемось до управління керуючим вузлом.

Тільки після цього можна починати тестування з'єднання вже за допомогою Ansible. Введемо у терміналі:

$ ansible all –m ping

Успішний пінг

В результаті пінгування команда повернула відповідь «pong», тобто з'єднання зі всіма хостами зі списку Inventory є працездатними і можуть бути використані для керування вузлами за допомогою Ansible.

Ми тепер маємо змогу більш детально дослідити стан кожного з хостів. Для прикладу, перевіримо стан дискових ресурсів на кожному з хостів:

$ ansible all -a "df -h"

Перевірка дисків на кожному з хостів

Також тепер ми маємо змогу перевірити час безвідмовної роботи кожного з хостів або ж якогось окремого. Для цього введемо команду:

$ ansible server1 -a "uptime"

Перевірка uptime на кажному з хостів.

Можна переконатися, що нам це вдалося. Тепер можна переходити до формування директив файлу playbook.

Формування директив файлу playbook

Доцільно у структурі проекту мати кілька файлів директив із різними назвами. У нашому випадку вказаний файл буде мати назву playbook_one.yml. Сформуємо його вміст відповідно до завдань.

playbook_one.yml

---
- hosts: all
  become: true
  vars_files:
    - all_vars/def.yml

  tasks:
    - name: Install package manager
      apt: name=aptitude update_cache=yes state=latest force_apt_get=yes

  # Group 
    - name: Create admin group 'main' 
      group:
        name: main
        state: present

    - name: Setting privileges sudo no passwd for 'main' 
      lineinfile:
        path: /etc/sudoers
        state: present
        regexp: '^%main'
        line: '%main ALL=(ALL) NOPASSWD: ALL'
        validate: '/usr/sbin/visudo -cf %s'

  # User remote ubuntu
    - name: Create a new user ubuntu with rights sudo
      user:
        name: "{{ create_user }}"
        state: present
        groups: main
        append: true
        create_home: true
        shell: /bin/bash

    - name: Setting up an authorization key for a user ubuntu
      authorized_key:
        user: "{{ create_user }}"
        state: present
        key: "{{ copy_local_key }}"

    - name: Setting up root authentication without a password
      lineinfile:
        path: /etc/ssh/sshd_config
        state: present
        regexp: '^#?PermitRootLogin'
        line: 'PermitRootLogin prohibit-password'


 # UFW 
    - name: Set permission to connect via SSH 
      ufw:
        rule: allow
        name: OpenSSH

    - name: Deny any other connections
      ufw:
        state: enabled
        policy: deny
        direction: incoming

# Packages
    - name: Update apt
      apt: update_cache=yes

    - name: Installing packages for the system     
      apt: name={{ sys_packages }} state=latest

Директиви сформовані відповідно до рекомендацій, наведених нами на початку статті. Кожна з задач має свою назву, коментар і т.д. Головний принцип, якого ми дотримувалися, це максимальне спрощення проекту. Цьому також сприяло наявність лише однієї групи серверів з однаковими параметрами. Тепер сформуємо відповідний файл за допомогою наступної команди:

$ nano /etc/ansible/setup_all_node_ubuntu/playbook_one.yml

Запуск редактора файлу nano

Редагування файлу playbook_one.yml

Збережемо файл та повернемося до терміналу.

Тестування файлу playbook перед запуском

Таке тестування допомагає позбутися багатьох помилок у playbook, у тому числі і синтаксичних. Одним із найпотужніших механізмів для цього є модуль ansible-lint, котрий може бути встановлений за допомогою відповідної команди. Введемо у терміналі:

$ apt install ansible-lint

Запуск встановлення ansible-lint

Процес інсталяції ansible-lint

Тепер ми можемо використовувати встановлену програму для тестування нашого файлу playbook. Для цього запустимо команду:

$ ansible-lint /etc/ansible/setup_all_node_ubuntu/playbook_one.yml

Тестування файлу playbook_one.yml

Результат виконання команди показаний нижче.

Результат тестуваня файлу playbook_one.yml

Для аналізу та виправлення помилок у директивах можна скористатися довідковою інформацією по програмі за посиланням: ansible-lint default rules.

Окрім вказаного вище механізму, для перевірки коректності директив playbook ще до його запуску, може використовуватися команда їх запуску ansible-playbook із відповідними параметрами. Це такі параметри: --list-tasks, --diff, --syntax-check, --check та --list-hosts. Для прикладу, переглянемо доступний для програми список задач. Введемо:

ansible-playbook /etc/ansible/setup_all_node_ubuntu/playbook_one.yml --list-tasks

Список завдань файлу playbook

Можна переконатися, що набір задач ідентифіковано вірно. Тепер перевіримо синтаксис:

ansible-playbook /etc/ansible/setup_all_node_ubuntu/playbook_one.yml --syntax-check

Ідентифікація набору завдань файлу playbook

Результат перевірки – з синтаксисом у нашому playbook усе гаразд.

Існують також і інші інструменти для перевірки та тестування директив. Вони детально описані у документації Ansible: Validating playbooks.

Запуск та виконання

Після проходження всіх перевірок та виправлення помилок файл з директивами може бути запущений на виконання. Для цього введемо:

ansible-playbook /etc/ansible/setup_all_node_ubuntu/playbook_one.yml -l server1

Запуск файлу playbook

Параметр -l походить від limit, тобто обмежений. Це означає, що він дає змогу вказати лише окремі хости чи групи, що іноді буває необхідним. У нашому випадку вказаний один хост server1.

Результат виконання команди показаний нижче.

Результат виконання файлу playbook

Судячи з результатів, виконання сценарію на віддаленому вузлі пройшло успішно і відповідні зміни на вузлах відбулись.

Вибіркове тестування результатів виконання

Для вибіркової перевірки результатів внесених змін на віддалених вузлах, відкриємо сеанс з'єднання від імені нового користувача із ім'ям admin:

$ ssh admin@178.20.157.79

Подключення до віддаленого серверу під логіном admin

Можемо переконатися, що з'єднання відбулось, тобто створення нового користувача пройшло успішно. Тепер перевіримо статус брандмауера на віддаленому хості:

$ sudo ufw status

Перевірка роботи брандмаузера на віддаленому хості.

Результат: налаштування UFW успішно виконано. А це була одна з останніх задач сценарію, що говорить про те, що сценарій виконано повністю.

Дата-центр FREEhost.UA надає якісний VDS хостинг та послуги оренди серверів з підтримкою 24/7. На нашому сайті Ви можете підібрати сервер для оренди під будь які задачі.

Підписуйтесь на наш телеграм–канал https://t.me/freehostua, щоб бути в курсі нових корисних матеріалів.

Дивіться наш канал Youtube на https://www.youtube.com/freehostua.

Ми у чомусь помилилися, чи щось пропустили?

Напишіть про це у коментарях, ми з задоволенням відповімо та обговорюємо Ваші зауваження та пропозиції.

Дата: 08.02.2023
Автор: Євген
Голосування

Авторам статті важлива Ваша думка. Будемо раді його обговорити з Вами:

comments powered by Disqus
navigate
go
exit
Дякуємо, що обираєте FREEhost.UA