Как создать 100 серверов в облаке за минуту? Базовая работа с OpenStack клиентом

nmzwe_jjmcy2dqvs6oy1pdj6sxa.png


Для управления облачной инфраструктурой в индустрии накопилось достаточно много инструментов: terraform, pulumi, ansible, управление через SDK или напрямую через REST API.

При этом, часто упускают из виду CLI инструменты в связке с shell-автоматизацией. А зря! Они помогают экономить время, которое тратится на ручное создание серверов или изучение сложных инструментов.

Предположим, что нам нужно создать пачку серверов для каких-то тестов или калькуляций. Можно только предположить, сколько времени потратится на ручное создание серверов через панель управление и сколько будет допущено ошибок из-за человеческого фактора.

А с помощью CLI клиента OpenStack можно создать наши условные 100 серверов одной командой.

openstack server create --image "Ubuntu 22.04 LTS 64-bit" --network my_network --flavor SL1.1-2048-16  --max 100 my_server


Собственно, все. На этом можно закончить статью. Но для тех, кому интересно, что тут происходит и как работать с CLI, рассмотрим происходящее более подробно.

Используйте навигацию, если не хотите читать текст полностью:
→ Знакомство с OpenStack CLI
→ Практика
→ Работа с сетевыми объектами
→ Работа с сетевыми дисками
→ Итоги и шпаргалка

Знакомство с OpenStack CLI


Сразу оговорка — создание виртуальной машины (сервера, инстанса) с локальным диском отличается от создания ВМ с сетевым диском. В первом случае локальный диск является частью флавора, и из образа диска сразу создается ВМ. Во втором — из образа диска делается вольюм, и уже вольюм передается при создании ВМ.

Давайте представим исходную ситуацию: у вас есть пустой проект в облачной платформе Selectel. И работать мы будем с консольным инструментом OpenStack CLI.

Подготовительные этапы:


Загружаем RC-файл с переменными окружения, необходимыми для авторизации OpenStack клиента. Работа с указанным выше RC-файлом предполагает введение пароля из консоли. Можно отредактировать файл и прописать пароль в файле, чтобы не вводить его каждый раз при инициализации переменных окружений. Но это не совсем безопасно.

Активируем переменные окружения:

source rc.sh


Базово создать один сервер с локальным диском можно следующей командой:

openstack server create --image 'Ubuntu 22.04 LTS 64-bit' --network my_network --flavor SL1.1-2048-16 my_server


Необходимые аргументы:

  • image — исходный образ диска, из которого создаётся ВМ,
  • flavor — объект флавор, содержащий конфигурацию ВМ,
  • network — сеть, в которой создается ВМ.


С сетевым диском алгоритм будет чуть другой — такой пример рассмотрим далее, а пока упростим себе задачу и будем работать с локальным диском.

OpenStack состоит из нескольких компонентов, отвечающих за свою часть работы и предоставляющих собственные эндпоинты. При работе с клиентом мы можем об этом не думать, т.к. он сделает все за нас. Но хочется выделить логические блоки для понимания концепций:

  • Keystone — сервис авторизации и получения эндпоинтов компонентов и регионов,
  • Nova (Compute) — сервис для создания ВМ (серверов, инстансов),
  • Neutron (Network) — сервис по управлению сетевыми ресурсами,
  • Glance (Images) — сервис для хранения образов (с ОС), из которых создаётся непосредственно сама ВМ или Volume,
  • Cinder (Volume) — сетевые диски.


1hdqmj1bvguax5hnugdz0ci_jbw.jpeg


Практика


Перейдем к практике и через CLI поработаем с объектами образов, сети и флавора.

Получаем список образов:

openstack image list


Пример использования (вывод обрезан для более удобного отображения):

openstack image list
+--------------------------------------+------------------------------------------+--------+
| ID                                   | Name                                     | Status |
+--------------------------------------+------------------------------------------+--------+
| 41383415-4c61-46e5-8cc4-ead5a6f78cf8 | CentOS 7 64-bit                          | active |
| 159f6bfa-d2fd-4d90-b2cc-e19d8aeafd22 | CentOS 7 Minimal 64-bit                  | active |
| 49653158-53a4-4cfe-95e0-b70509e6c1ac | CentOS 8 64-bit                          | active |
| 0b6fb188-0df5-46cf-9111-2840195df219 | CentOS 8 Stream 64-bit                   | active |
| a1b081d7-9eff-44b0-8d3f-85fabf2c88a6 | CentOS 9 Stream 64-bit                   | active |
| 7a827898-058b-4faf-bf8a-0d2311bef7c3 | Ubuntu 20.04 LTS 64-bit                  | active |
| 1fd341e8-82c2-4421-8a37-912cd5ee3ae3 | Ubuntu 22.04 LTS 64-bit                  | active |
......
+--------------------------------------+------------------------------------------+--------+


Получаем список флаворов.

В OpenStack при создании ВМ необходимо передать идентификатор объекта Flavor. Можно считать это конфигурацией сервера — память, диск, количество CPU.

Смотрим доступные флаворы.

openstack flavor list


Пример команды. Вывод обрезан.

openstack flavor list
+--------------------------------------+------------------------------------+--------+------+-----------+-------+-----------+
| ID                                   | Name                               |    RAM | Disk | Ephemeral | VCPUs | Is Public |
+--------------------------------------+------------------------------------+--------+------+-----------+-------+-----------+
| 1                                    | m1.tiny                            |    512 |    0 |         0 |     1 | True      |
| 1011                                 | SL1.1-1024                         |   1024 |    0 |         0 |     1 | True      |
| 1012                                 | SL1.1-2048                         |   2048 |    0 |         0 |     1 | True      |
| 1013                                 | SL1.2-4096                         |   4096 |    0 |         0 |     2 | True      |
| 1014                                 | SL1.2-8192                         |   8192 |    0 |         0 |     2 | True      |
| 1015                                 | SL1.4-16384                        |  16384 |    0 |         0 |     4 | True      |
| 1016                                 | SL1.6-32768                        |  32768 |    0 |         0 |     6 | True      |
| 1017                                 | SL1.8-32768                        |  32768 |    0 |         0 |     8 | True      |
| 1018                                 | SL1.12-49152                       |  49152 |    0 |         0 |    12 | True      |
| 1019                                 | SL1.16-65536                       |  65536 |    0 |         0 |    16 | True      |
| 1020                                 | SL1.24-98304                       |  98304 |    0 |         0 |    24 | True      |
| 1311                                 | SL1.1-1024-8                       |   1024 |    8 |         0 |     1 | True      |
| 1312                                 | SL1.1-2048-16                      |   2048 |   16 |         0 |     1 | True      |
| 1313                                 | SL1.2-4096-32                      |   4096 |   32 |         0 |     2 | True      |
| 1314                                 | SL1.2-8192-64                      |   8192 |   64 |         0 |     2 | True      |
| 1315                                 | SL1.4-16384-128                    |  16384 |  128 |         0 |     4 | True      |
| 1316                                 | SL1.6-32768-256                    |  32768 |  256 |         0 |     6 | True      |
| 1317                                 | SL1.8-32768-384                    |  32768 |  384 |         0 |     8 | True      |
| 1318                                 | SL1.12-49152-512                   |  49152 |  512 |         0 |    12 | True      |
| 1319                                 | SL1.16-65536-768                   |  65536 |  768 |         0 |    16 | True      |
| 1320                                 | SL1.24-98304-1024                  |  98304 | 1024 |         0 |    24 | True      |


При необходимости можно создать Flavor командой openstack flavor create

Обратите внимание, что у одних флаворов поле Disc нулевое, а у других со значениями. Для использования flavor с нулевым диском нужно предварительно создать volume (сетевой диск). С ненулевым значением будет использоваться локальный диск.

bwp16wo3ot4rghlhkz7laacofdi.png

Для начала создадим приватную сеть:

openstack network create my_network


Создадим в ресурс subnet в созданном network:

openstack subnet create --subnet-range 192.168.0.0/24 --network my_network my_subnet


Ремарка — сейчас не создается роутер и не настраивается маршрутизация. Таким образом, не будет работать «выход» в интернет. Об этом далее.

SSH Keypair


Если сейчас создать сервер, то заходить по SSH можно будет только по паролю. Это может быть неудобно и небезопасно, поэтому добавим публичную часть персонального ssh-ключа в хранилище. Затем можем указывать данный ключ при создании ВМ.

openstack keypair create --public-key ~/.ssh/id_rsa.pub my_keypair


Теперь можно создать наши условные 100 серверов:

openstack server create --image "Ubuntu 22.04 LTS 64-bit" --network my_network --flavor SL1.1-2048-16 --key-name my_keypair --max 100  my_server


Проверим созданные серверы с помощью команды openstack server list:

openstack server list


Пример команды, вывод обрезан.

openstack server list
+--------------------------------------+---------------+--------+--------------------------+-------------------------+---------------+
| ID                                   | Name          | Status | Networks                 | Image                   | Flavor        |
+--------------------------------------+---------------+--------+--------------------------+-------------------------+---------------+
| 031080fa-3aa0-4848-8551-fd1e6f6ec65f | my_server-94  | ACTIVE | my_network=192.168.0.58  | Ubuntu 22.04 LTS 64-bit | SL1.1-2048-16 |
| 03864c9b-6b9b-4bea-8679-93367ca52250 | my_server-87  | ACTIVE | my_network=192.168.0.24  | Ubuntu 22.04 LTS 64-bit | SL1.1-2048-16 |
| 0efb6875-c481-4ec0-bc80-3392d84c89d6 | my_server-82  | ACTIVE | my_network=192.168.0.110 | Ubuntu 22.04 LTS 64-bit | SL1.1-2048-16 |
| 14c1677d-ef4c-4369-a64d-d4be73416eb9 | my_server-67  | ACTIVE | my_network=192.168.0.116 | Ubuntu 22.04 LTS 64-bit | SL1.1-2048-16 |
| 1619eaf7-c7ab-4db0-a875-38c39acabdac | my_server-76  | ACTIVE | my_network=192.168.0.52  | Ubuntu 22.04 LTS 64-bit | SL1.1-2048-16 |
| 1eadae93-f394-4301-a26f-b496f1e023ae | my_server-73  | ACTIVE | my_network=192.168.0.81  | Ubuntu 22.04 LTS 64-bit | SL1.1-2048-16 |
| 218bdd45-01a9-4b49-aa26-fb25ce7f7329 | my_server-80  | ACTIVE | my_network=192.168.0.76  | Ubuntu 22.04 LTS 64-bit | SL1.1-2048-16 |
| 24642e7f-b265-41a4-8d73-c29434655b30 | my_server-84  | ACTIVE | my_network=192.168.0.120 | Ubuntu 22.04 LTS 64-bit | SL1.1-2048-16 |
| 2e0c2dd3-8a07-421f-ba18-067e5fa320d9 | my_server-81  | ACTIVE | my_network=192.168.0.194 | Ubuntu 22.04 LTS 64-bit | SL1.1-2048-16 |


И посчитаем, что 100 серверов в активном состоянии:

openstack server list -f value | grep ACTIVE -c
100


Работа с сетевыми объектами


Мы получили 100 серверов, но как на них зайти и работать с ними? Можно использовать схему с дополнительным bastion-хостом, у которого будет выход в интернет. Заодно познакомимся поближе с сетевой частью.

В сетевую схему нужно добавить роутер, связать его с нашей приватной и внешней сетями, создать плавающий адрес (floating ip, внешний адрес) и привязать данный адрес к ВМ bastion:

openstack router create my_router
openstack router add subnet my_router my_subnet


Чтобы роутер позволял ВМ «выходить» в интернет из приватной сети (в данном случае из my_subnet) через NAT (для установки пакетов, обновления ПО и т.д.), нужно связать роутер с внешней сетью.

Получим имя внешней сети:

openstack network list --external -f value -c Name
external-network


Привяжем внешнюю сеть к роутеру:

openstack router set --external-gateway external-network my_router


Создадим floating IP, в выводе получим адрес:

openstack floating ip create external-network


Посмотреть созданные адреса можно командой:

openstack floating ip list


В моем случае адрес 31.129.42.122, и далее в тексте будет фигурировать именно он. У вас будет другой адрес.

Теперь применим подход с bastion на практике. Выберем, например, первую ВМ как bastion-хост (можно создать отдельно ВМ с более подходящей конфигурацией и хостнеймом, но для упрощения пропустим этот шаг). Через бастион можно будет подключиться ко всем остальным ВМ. В моем случае выберу ВМ 99.

Ассоциируем Floating IP и ВМ 1:

openstack server add floating ip my_server-1 31.129.42.122


Получаем внутренний адрес (адрес из приватной сети 192.168.0.0/24) ВМ 99:

openstack server show my_server-99 -f value -c addresses
{'my_network': ['192.168.0.111']}


В моем случае адрес 192.168.0.111.
Подключимся к ВМ-99 и проверим, что все работает, как и задумывалось:

ssh -J root@31.129.42.122 root@192.168.0.111
root@my-server-99:~#


Работа с сетевыми дисками


Мы уже работали с локальными дисками. Давайте чуть усложним задачу и создадим 100 хостов с сетевыми дисками.

Для начала удалим все текущие ВМ.

Важно: при выполнении следующей команды удалятся все ВМ в текущем проекте. Проверьте, что вы находитесь в нужном проекте.

openstack server list -f value -c ID | xargs -i -P 10 bash -c 'openstack server delete {}'


Сначала нужно создать volume (сетевой диск). В данном случае в API нет инструмента для создания 100 дисков, и нужно обернуть простые shell-команды в циклы.

Можно выполнить их в цикле for i in {1…100}; do COMMAND; done. В таком случае операции будут выполняться по одной. Процесс займет некоторое время, зато будет наглядным. Или можно использовать утилиту xargs для параллельного выполнения.

Для нашего примера используем сгенерированную последовательность от 1 до 100. И в 10 поток (-P 10) выполняем команду по созданию вольюма — {} раскроется xargs«ом в полученный аргумент от seq:

seq 1 100 | xargs -i -P 10 bash -c 'openstack volume create --size 10 --image "Ubuntu 22.04 LTS 64-bit" my_volume_{}'


Для примера давайте создадим свой флавор:

openstack flavor create --private --disk 0 --vcpus 1 --ram 1024  my_flavor_net_hdd


И в финале создадим 100 ВМ с сетевым диском:

seq 1 100 | xargs -i -P 10 bash -c 'openstack server create  --network my_network --key-name my_keypair --flavor my_flavor_net_hdd --volume volume_{} my_server_{}'


Итоги и шпаргалка


Мы рассмотрели, как управлять инфраструктурой, используя CLI инструменты при работе в терминале. А также, разобрали на базовые «кирпичики» автоматизацию более сложных процессов.

Вот шпаргалка с базовыми командами, которые помогут освоиться с управлением ресурсов OpenStack.

openstack keypair create
openstack keypair delete
openstack keypair list
openstack keypair show
openstack server create
openstack server delete
openstack server list
openstack server show
openstack server add floating ip
openstack server remove floating ip
openstack volume create
openstack volume delete
openstack volume list
openstack volume show
openstack router create
openstack router delete
openstack router list
openstack router show
openstack router add subnet
openstack router remove subnet
openstack router add route
openstack router remove route
openstack flavor list
openstack network create
openstack network list
openstack network show
openstack network delete
openstack subnet create
openstack subnet list
openstack subnet show
openstack subnet delete
openstack network list --external
openstack floating ip create
openstack floating ip list
openstack floating ip delete


Пишите в комментариях вопросы или альтернативные способы создать 100 серверов.

Возможно, эти тексты тоже вас заинтересуют:
→ Импортозамещение по-американски: развертывание собственного производства полупроводников идет не совсем по плану
→ И снова конденсаторы: как я ноутбук HP Spectre X360 13 ремонтировал и что из этого вышло
→ Не мытьем, так катаньем: NVIDIA начнет поставки в Китай мощных видеокарт, которые не подпадают под санкции США

© Habrahabr.ru