Перейти до змісту

3. Механізм конфігурації

Глибоке занурення в модулі cloud-init

У попередньому розділі ви успішно завантажили хмарний образ та виконали просте налаштування. Хоча й ефективний, справжня потужність, портативність та ідемпотентність cloud-init розкриваються завдяки його модульній системі. Ці модулі є спеціалізованими інструментами в наборі інструментів cloud-init, призначеними для обробки певних завдань конфігурації декларативним та передбачуваним способом.

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

1. Анатомія конфігурації

Що таке модулі cloud-init

Модуль cloud-init — це спеціалізований скрипт Python, розроблений для обробки єдиного, дискретного забезпечення. Уявіть їх як плагіни для таких завдань, як керування користувачами, встановлення пакетів або запис файлів.

Ключова перевага використання модулів над простими скриптами (такими як runcmd) полягає в ідемпотентності. Ідемпотентна операція дає однаковий результат, незалежно від того, чи виконується вона один чи десять разів. Коли ви оголошуєте, що користувач має існувати, модуль гарантує виконання цього стану — він створює користувача, якщо він не існує, але нічого не робить, якщо він вже існує. Це робить ваші конфігурації надійними та повторюваними.

Переосмислення формату #cloud-config

Коли cloud-init бачить заголовок #cloud-config, він інтерпретує файл як набір інструкцій у форматі YAML — ключі верхнього рівня в цьому YAML-файлі безпосередньо відповідають модулям cloud-init.

Виконання та порядок модулів

Модулі запускаються на певних етапах процесу завантаження в послідовності, визначеній у файлі /etc/cloud/cloud.cfg. Спрощений вигляд цього потоку виглядає так:

System Boot
    |
    +--- Stage: Generator (Very early boot)
    |    `--- cloud_init_modules (e.g., migrator)
    |
    +--- Stage: Local (Pre-network)
    |    `--- (Modules for local device setup)
    |
    +--- Stage: Network (Network is up)
    |    `--- cloud_config_modules (e.g., users-groups, packages, write_files)
    |
    `--- Stage: Final (Late boot)
         `--- cloud_final_modules (e.g., runcmd, scripts-user)

Порядок критично важливий. Наприклад, модуль users-groups виконується перед runcmd, що гарантує, що скрипт може бути запущений користувачем, якого щойно створили в тій самій конфігурації.

Налаштування поведінки cloud-init

Хоча /etc/cloud/cloud.cfg визначає поведінку за замовчуванням, ніколи не слід редагувати її безпосередньо. Для постійних, системних налаштувань розмістіть власні файли .cfg у каталозі /etc/cloud/cloud.cfg.d/. Це стандартна практика для створення власних образів, яку ми розглянемо в наступному розділі.

2. Високопродуктивні модулі: щоденні рушійні сили

Давайте розглянемо найпоширеніші модулі, використовуючи метод прямого впровадження за допомогою virt-install.

Глибокий огляд модулів: користувачі та групи

Правильне керування обліковими записами користувачів є наріжним каменем безпеки нового екземпляра сервера. Модуль users — ваш основний інструмент для цього, який дозволяє створювати нових користувачів, змінювати існуючих, керувати членством у групах і, найголовніше, вставляти SSH-ключі для безпечного входу без пароля з першого завантаження.

Приклад 1: Створення нового користувача з правами адміністратора

У цьому прикладі ми створимо нового, виділеного користувача-адміністратора з ім'ям sysadmin. Ми надамо цьому користувачеві можливості використання sudo без пароля, додавши його до групи wheel та надавши спеціальне правило sudo. Ми також впровадимо відкритий ключ SSH для забезпечення безпечного доступу.

  1. Створити user-data.yml:

    cat <<EOF > user-data.yml
    #cloud-config
    users:
      - name: sysadmin
        groups: [ wheel ]
        sudo: [ "ALL=(ALL) NOPASSWD:ALL" ]
        shell: /bin/bash
        ssh_authorized_keys:
          - <YOUR_SSH_PUBLIC_KEY_HERE>
    EOF
    
  2. Пояснення ключових директив:

  3. name: Ім'я користувача для нового облікового запису.

  4. groups: Список груп, до яких потрібно додати користувача. У Rocky Linux членство в групі wheel зазвичай використовується для надання прав адміністратора.
  5. sudo: Список правил sudoers, які слід застосовувати. Правило ALL=(ALL) NOPASSWD:ALL надає користувачеві можливість виконувати будь-яку команду з sudo без запиту пароля.
  6. ssh_authorized_keys: Список публічних SSH-ключів для додавання до файлу користувача ~/.ssh/authorized_keys.

  7. Завантаження та перевірка: Завантажте віртуальну машину з цими user-data. Ви повинні мати можливість використовувати SSH як sysadmin та виконувати команди sudo.

Приклад 2: Зміна користувача за замовчуванням

Більш поширеним завданням є просто захистити користувача за замовчуванням, якому надано хмарний образ (rocky). Тут ми змінимо цього користувача, щоб додати наш SSH-ключ.

  1. Створити user-data.yml:

    cat <<EOF > user-data.yml
    #cloud-config
    users:
      - default
      - name: rocky
        ssh_authorized_keys:
          - <YOUR_SSH_PUBLIC_KEY_HERE>
    EOF
    
  2. Пояснення ключових директив:

  3. default: Цей спеціальний запис повідомляє cloud-init про необхідність спочатку виконати налаштування користувача за замовчуванням.

  4. name: rocky: Вказавши ім'я існуючого користувача, модуль змінить цього користувача, а не створить нового. Тут він об'єднує наданий SSH-ключ з обліковим записом користувача rocky.

  5. Завантаження та перевірка: Завантажте віртуальну машину. Тепер ви можете використовувати SSH як користувач rocky без пароля.

Глибокий огляд модулів: пакети

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

У цьому прикладі ми забезпечимо встановлення двох корисних інструментів: nginx (високопродуктивний веб-сервер) та htop (інтерактивний переглядач процесів). Ми також доручимо cloud-init спочатку оновити метадані репозиторію пакетів, щоб переконатися, що він може знайти найновіші версії.

  1. Створити user-data.yml:

    cat <<EOF > user-data.yml
    #cloud-config
    package_update: true
    packages:
      - nginx
      - htop
    EOF
    
  2. Пояснення ключових директив:

  3. package_update: true: Наказує менеджеру пакетів оновити свої локальні метадані. У Rocky Linux це еквівалентно запуску команди dnf check-update.

  4. packages: Список назв пакетів для встановлення.

  5. Завантаження та перевірка: Після завантаження увійдіть через SSH та перевірте встановлення nginx за допомогою rpm -q nginx.

Ідемпотентність у дії

Якщо перезавантажити цю віртуальну машину з тими ж user-data, модуль packages побачить, що nginx та htop вже встановлені, і не зробить жодних подальших дій. Він гарантує бажаний стан (пакети присутні) без зайвих дій. Це ідемпотентність.

Глибокий огляд модуля: write_files

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

Щоб продемонструвати його можливості, ми використаємо write_files для створення власної домашньої сторінки для веб-сервера nginx, який ми також встановлюємо під час того ж запуску.

  1. Створити user-data.yml:

    cat <<EOF > user-data.yml
    #cloud-config
    packages: [nginx]
    write_files:
      - path: /usr/share/nginx/html/index.html
        content: '<h1>Hello from cloud-init!</h1>'
        owner: nginx:nginx
        permissions: '0644'
    runcmd:
      - [ systemctl, enable, --now, nginx ]
    EOF
    
  2. Пояснення ключових директив:

  3. path: Абсолютний шлях у файловій системі, куди буде записано файл.

  4. content: Текстовий вміст, який потрібно записати у файл.
  5. owner: Вказує користувача та групу, яким має належати файл (наприклад, nginx:nginx).
  6. permissions: Дозволи файлу у вісімковому форматі (наприклад, 0644).

  7. Завантаження та перевірка: Після завантаження увійдіть через SSH та скористайтеся командою curl localhost, щоб побачити нову домашню сторінку.

Запис бінарних файлів

Модуль write_files не обмежується текстом. Вказавши encoding, ви можете розгортати двійкові файли. Наприклад, ви можете використовувати encoding: b64 для запису даних у кодуванні base64. Для розширених випадків використання зверніться до офіційної документації write_files.

Що далі

Ви тепер опанували три найбазовіші модулі cloud-init. Поєднуючи їх, ви можете виконувати значну кількість автоматизованого налаштування сервера. У наступному розділі ми розглянемо більш складні сценарії, включаючи конфігурацію мережі та поєднання різних форматів «даних користувача» за один раз.

Author: Wale Soyinka

Contributors: Steven Spencer