Облачные инструменты: OpenStack и Terraform [353.1]

Рейтинг: 78.5% · 14 голосов
Специализация LPIC-3 305 (v3.0): KVM/QEMU и libvirt, Xen, образы дисков, контейнеры (namespaces/cgroups, LXC/LXD, Docker), оркестрация (Compose, Swarm, Kubernetes, Helm), Vagrant/Packer/cloud-init.
Ответить
Аватара пользователя
Sergey_Sysadmin
Сообщения: 134
Зарегистрирован: 11 май 2026, 05:31

Облачные инструменты: OpenStack и Terraform [353.1]

Сообщение Sergey_Sysadmin »

Оглавление курса (16)
  1. Введение в LPIC-3 305: виртуализация и контейнеризация
  2. Концепции и теория виртуализации [351.1]
  3. Xen [351.2]
  4. QEMU и KVM [351.3]
  5. Управление ВМ через libvirt [351.4, часть 1]
  6. libvirt: виртуальные сети и пулы хранилищ [351.4, часть 2]
  7. Управление образами дисков ВМ [351.5]
  8. Концепции контейнеризации [352.1]
  9. LXC и LXD [352.2]
  10. Docker: образы и контейнеры [352.3, часть 1]
  11. Docker: тома, сети, логирование, ресурсы [352.3, часть 2]
  12. Оркестрация контейнеров
  13. Облачные инструменты: OpenStack и Terraform [353.1] (вы здесь)
  14. Packer [353.2]
  15. cloud-init [353.3]
  16. Vagrant [353.4]
Урок 12. Облачные инструменты: OpenStack и Terraform [353.1]

До сих пор мы поднимали виртуалки и контейнеры руками на одном-двух хостах. Когда машин становятся десятки, а команд, которым нужны ресурсы, несколько, ручное управление превращается в источник ошибок и дрейфа. Этот урок про два слоя облака. Первый - OpenStack, открытая платформа, которая из стойки серверов делает частное IaaS-облако с самообслуживанием. Второй - Terraform (и его форк OpenTofu), декларативный инструмент инфраструктуры как кода, который описывает желаемое состояние и приводит реальную инфраструктуру к нему. Задача администратора - понимать, из чего собран OpenStack, и уметь управлять им и любым другим облаком кодом, а не кликами.

Изображение

Как это работает

OpenStack - не один демон, а набор слабо связанных сервисов, общающихся через REST API и общую шину сообщений (RabbitMQ). Каждый сервис отвечает за свой ресурс, и понимать надо именно границы ответственности.

Keystone - служба идентификации. Выдает токены, хранит проекты (бывшие tenant), пользователей, роли и каталог эндпоинтов. Любой запрос к любому сервису сначала проходит через Keystone: без валидного токена Nova даже не станет с вами разговаривать. Glance - реестр образов: хранит готовые шаблоны дисков (qcow2, raw), из которых создаются ВМ. Nova - вычисления: планировщик выбирает гипервизор (обычно KVM через libvirt), создает и управляет жизненным циклом инстансов. Neutron - сети как сервис: виртуальные сети, подсети, маршрутизаторы, security groups, floating IP; под капотом - Open vSwitch или OVN. Cinder - блочные тома, которые подключаются к инстансам как диски и переживают их пересоздание. Поверх этого - Horizon (веб-панель) и Swift (объектное хранилище, аналог S3).

Логика создания ВМ: вы просите Nova запустить инстанс из образа Glance, заданного flavor (CPU/RAM/диск), в сети Neutron, опционально с томом Cinder. Nova-scheduler фильтрует хосты по фильтрам (хватает ли ресурсов, совпадают ли метки) и взвешивает оставшиеся, выбирая лучший. Все это - вызовы API, а значит, автоматизируемо.

Тут на сцену выходит инфраструктура как код. Terraform описывает желаемое состояние в файлах .tf на языке HCL. Ключевая идея - декларативность: вы пишете не как создать, а что должно существовать. Terraform строит граф зависимостей ресурсов и сам вычисляет порядок операций.

Механика держится на трех понятиях. Провайдер - плагин, который умеет говорить с конкретным API (openstack, aws, libvirt, docker). Ресурс - единица инфраструктуры (инстанс, сеть, том). State - файл terraform.tfstate, в котором Terraform запоминает, что он уже создал и с какими реальными ID. State - это карта между вашим кодом и реальным миром. Без него Terraform не знал бы, какой именно инстанс соответствует вашему блоку в коде.

Отсюда вытекает идемпотентность: команда plan сравнивает три вещи - ваш код (желаемое), state (что Terraform думает о реальности) и при refresh реальное API (что есть на самом деле) - и показывает только разницу. Запустите apply дважды без изменений в коде - второй раз не сделает ничего. Это и есть защита от дрейфа конфигурации: если кто-то руками поменял ресурс в обход кода, plan покажет расхождение, а apply вернет все к описанному состоянию.

Команды и примеры

Установка клиента OpenStack и Terraform/OpenTofu различается по семействам.

Код: Выделить всё

# Debian 13 / Ubuntu 24.04
apt install python3-openstackclient
# RHEL 10 / Fedora 41+
dnf install python3-openstackclient

# Terraform ставится из репозитория HashiCorp, либо берем OpenTofu (открытый форк):
# Fedora/RHEL
dnf install opentofu      # бинарь называется tofu, флаги те же
# Debian/Ubuntu
apt install opentofu
Базовая работа с OpenStack через CLI (предварительно загружен файл openrc с переменными окружения и токеном Keystone):

Код: Выделить всё

source ~/admin-openrc.sh           # OS_AUTH_URL, OS_PROJECT_NAME, OS_USERNAME...
openstack token issue               # проверяем, что Keystone нас пускает
openstack image list                # образы из Glance
openstack flavor list               # типоразмеры
openstack network list              # сети Neutron
openstack server create \
  --image debian-13 --flavor m1.small \
  --network internal --key-name mykey web01    # Nova поднимает инстанс
openstack volume create --size 10 data01       # том Cinder
openstack server add volume web01 data01
То же самое, но как код. Минимальный проект Terraform для OpenStack:

Код: Выделить всё

# main.tf
terraform {
  required_providers {
    openstack = { source = "terraform-provider-openstack/openstack" }
  }
}
provider "openstack" {}   # читает переменные OS_* из окружения

resource "openstack_compute_instance_v2" "web" {
  name        = "web01"
  image_name  = "debian-13"
  flavor_name = "m1.small"
  key_pair    = "mykey"
  network { name = "internal" }
}

resource "openstack_blockstorage_volume_v3" "data" {
  name = "data01"
  size = 10
}

resource "openstack_compute_volume_attach_v2" "att" {
  instance_id = openstack_compute_instance_v2.web.id   # неявная зависимость
  volume_id   = openstack_blockstorage_volume_v3.data.id
}
Рабочий цикл одинаков для terraform и tofu:

Код: Выделить всё

terraform init      # скачивает плагин провайдера в .terraform/
terraform fmt       # причесывает форматирование
terraform validate  # проверяет синтаксис и типы
terraform plan      # показывает diff: + создать, ~ изменить, - удалить
terraform apply     # применяет; спросит подтверждение
terraform destroy   # сносит все, что описано в коде
Ссылка openstack_compute_instance_v2.web.id в блоке тома автоматически создает ребро графа: Terraform создаст инстанс и том, а потом подключение - в правильном порядке, без ручного указания очередности.

Частые грабли
  • State хранится локально и попадает в git вместе с секретами. На проде выносите его в remote backend (Swift, S3, Postgres) с блокировкой, иначе два инженера затрут изменения друг друга.
  • Правка ресурса руками в Horizon в обход кода. Дрейф всплывет на следующем plan как неожиданное изменение, а apply молча откатит вашу ручную правку.
  • Путаница floating IP и fixed IP в Neutron. Инстанс с приватным адресом недоступен снаружи, пока не назначен и не связан floating IP, а security group не открыла порт.
  • Смена immutable-поля (например image_name) ведет не к правке, а к пересозданию инстанса. Всегда читайте план: -/+ означает destroy и create, данные на эфемерном диске пропадут.
  • Удаление ресурса из .tf не равно удалению ресурса. Если убрать блок, apply его уничтожит. Чтобы перестать управлять, не разрушая, используйте terraform state rm.
  • Версии провайдера не закреплены. Без блока required_providers с version у соседа init подтянет другую версию и план разойдется. Коммитьте .terraform.lock.hcl.
Мини-лаба
  • Если нет доступа к OpenStack, разверните учебный стенд DevStack в отдельной ВМ или возьмите провайдер libvirt - цикл Terraform идентичен.
  • Загрузите openrc, выполните openstack token issue и openstack catalog list - разберите, какие эндпоинты Keystone отдает.
  • Создайте проект Terraform из примера выше, выполните init и plan. Прочитайте план вслух: сколько ресурсов и в каком порядке.
  • Сделайте apply, затем зайдите в Horizon и вручную поменяйте имя или размер security group инстанса.
  • Запустите plan еще раз и найдите дрейф. Решите: вернуть кодом (apply) или зафиксировать в коде.
  • Добавьте второй том и подключение, снова plan/apply - убедитесь, что существующий инстанс не пересоздается.
  • Выполните destroy и проверьте в CLI, что все ресурсы исчезли, а tfstate опустел.
Контрольные вопросы
  • Какой сервис OpenStack выдает токены, и почему запрос к Nova без него обречен?
  • Чем Cinder отличается от эфемерного диска инстанса, и что переживет пересоздание ВМ?
  • Что хранится в файле terraform.tfstate и почему его потеря - серьезная проблема?
  • Объясните разницу plan и apply и как из них следует идемпотентность.
  • Как Terraform определяет порядок создания ресурсов без явного указания очередности?
  • Что покажет plan, если ресурс изменили вручную в обход кода, и как это связано с дрейфом конфигурации?
👍2 ❤️3 🔥2 😄 🤔1
Аватара пользователя
artem8
Сообщения: 1
Зарегистрирован: 11 май 2026, 07:30

Re: Облачные инструменты: OpenStack и Terraform [353.1]

Сообщение artem8 »

Подскажите, а tofu реально полностью совместим с terraform по конфигам? Хочу слезть с лицензии BSL, но боюсь что провайдер openstack отвалится на init.
👍 ❤️2 🔥 😄 🤔1
Аватара пользователя
park08
Сообщения: 1
Зарегистрирован: 24 май 2026, 11:19

Re: Облачные инструменты: OpenStack и Terraform [353.1]

Сообщение park08 »

Поймал ровно ту граблю с image_name: поменял образ, plan показал -/+, а я на автомате нажал yes. Инстанс пересоздался, эфемерный диск в ноль. Теперь читаю план как договор перед подписью.
👍 ❤️ 🔥 😄 🤔
Ответить
← Предыдущая глава
Оркестрация контейнеров
Следующая глава →
Packer [353.2]

Все главы курса «LPIC-3 305: виртуализация и контейнеризация»

Поделиться темой: ✈ Telegram VK

Вернуться в «LPIC-3 305: виртуализация и контейнеры»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость