cloud-init
Стандартный механизм первичной настройки облачных серверов: при первом запуске машина сама применяет переданную ей конфигурацию.
Что такое cloud-init
cloud-init — стандартный механизм первичной настройки виртуальных машин в облаке. При первом запуске сервер забирает конфигурацию, переданную при создании, и применяет её сам: заводит пользователей, кладёт SSH-ключи, настраивает сеть, ставит пакеты, выполняет команды.
Именно cloud-init объясняет, почему в облаке свежесозданная машина сразу пускает вас по ключу, хотя вы ничего не настраивали. Он предустановлен в официальных облачных образах Ubuntu, Debian, RHEL, Rocky, AlmaLinux и является отраслевым стандартом: один и тот же файл работает и в OpenStack, и в AWS, и в Proxmox.
Задача у него узкая — довести машину от «пустой образ» до «готова принимать управление». Дальше начинается зона Ansible и CI/CD.
Как он получает конфигурацию
Создание сервера с --user-data
↓
datasource: метаданные по 169.254.169.254, ConfigDrive или NoCloud
↓
Стадии: local → init (после поднятия сети) → config → final
↓
Модули: users-groups → write_files → packages → runcmd
↓
Отметка в /var/lib/cloud/ — при перезагрузке не повторяется
Ключевое: user-data отрабатывает один раз, при первой загрузке. Это регулярный источник недоумения — правка конфигурации у существующего сервера ничего не даёт, нужен либо новый сервер, либо cloud-init clean.
Пример конфигурации
Файл начинается строкой #cloud-config — без неё содержимое не считается конфигурацией:
#cloud-config
users:
- name: deploy
groups: [sudo, docker]
sudo: ['ALL=(ALL) NOPASSWD:ALL']
ssh_authorized_keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... deploy@workstation
ssh_pwauth: false
disable_root: true
package_update: true
packages: [docker.io, nvidia-driver-550, nvtop]
write_files:
- path: /etc/docker/daemon.json
content: '{ "default-runtime": "nvidia" }'
runcmd:
- systemctl enable --now docker
- nvidia-smi -L > /var/log/gpu-inventory.log
Порядок модулей фиксирован: write_files отрабатывает раньше runcmd, поэтому в командах уже можно опираться на созданные файлы.
Отладка
cloud-init status --wait # дождаться завершения: done или error
cloud-init schema --system # проверить синтаксис применённого конфига
cat /var/log/cloud-init-output.log # вывод команд — сюда смотреть при ошибке
sudo cloud-init clean --logs --reboot # сбросить отметку и прогнать заново
Проверять YAML лучше до создания сервера: ошибка отступа не откатывается, а тихо оставляет машину недонастроенной, причём cloud-init status может вернуть done — модуль просто не выполнился.
Типовые грабли:
- Забыт
#cloud-configв первой строке — файл проигнорирован целиком. - Ожидание идемпотентности. cloud-init не Ansible: он не приводит систему к состоянию, а выполняет шаги один раз.
- Слишком много логики в
runcmd. Десятки команд превращают его в нечитаемый скрипт без обработки ошибок. Порог простой: поднять машину и передать управление Ansible или IaC-инструменту.
Зачем это на GPU-серверах
На арендованных GPU-машинах cloud-init экономит больше всего времени: серверы здесь берут под задачу и удаляют после неё, а окружение каждый раз одинаковое — драйвер NVIDIA, CUDA, NVIDIA Container Toolkit, Docker. Описав это один раз, вы поднимаете десять одинаковых облачных серверов под распределённое обучение без ручной установки драйверов и без расхождений версий, которые потом ловятся как «работает только на первом узле».
Практичный компромисс: тяжёлое (драйверы, CUDA) запекать в образ, а через cloud-init подавать только изменчивое — ключи, конфиги, номер узла. Установка драйвера при каждом старте добавляет минуты к оплачиваемому времени.
Связанные термины
- Облачный сервер — то, что настраивает cloud-init
- SSH-ключ — самое частое содержимое user-data
- OpenStack — передаёт user-data при создании инстанса
- Ansible — принимает эстафету после первичной настройки
- GitOps / IaC — подход, частью которого является cloud-init
- NVIDIA Driver — типичная задача для GPU-серверов
Готовы запустить GPU-задачу?
Запустить GPU-сервер