Cloud-init позволяет автоматически настраивать сервер сразу при запуске: создавать пользователей, устанавливать нужные пакеты, настраивать файрвол и выполнять произвольные команды. В статье разбираем, как работает Cloud-init в Ubuntu 24.04 и как использовать его на VPS.
Введение
Cloud-init — стандартный инструмент для автоматической первичной настройки серверов в Ubuntu и других Linux-дистрибутивах. Он запускается при первом старте системы и выполняет различные задания: от добавления пользователей до установки пакетов и настройки служб. В Ubuntu 24.04 Cloud-init включён по умолчанию и поддерживает различные сценарии автоматизации. В этой статье обсудим, как работает Cloud-init, как его использовать для настройки VPS и что нужно знать, чтобы избежать типичных ошибок.
Как работает Cloud-init
Cloud-init запускается при первом старте виртуальной машины или VPS и настраивает систему согласно предоставленной конфигурации. Работа cloud-init делится на несколько последовательных этапов:
- init — обнаружение источника данных и инициализация. Cloud-init определяет, откуда загружать конфигурацию (user-data, meta-data);
- config — применение параметров конфигурации: создание пользователей, установка пакетов, настройка сетевых параметров;
- final — запуск пользовательских команд (runcmd, bootcmd, scripts) и завершение настройки.
Этапы можно запускать по отдельности или повторно вручную — это удобно при тестировании и отладке.
Cloud-init поддерживает несколько типов источников конфигурации (datasource). Наиболее распространённые:
- NoCloud — используется при ручной установке на VPS или в локальной среде. Источник данных — файлы user-data и meta-data;
- EC2 — используется в облаках (например, Yandex Cloud);
- ConfigDrive — часто применяется в OpenStack и на некоторых хостинг-платформах. Данные доступны как смонтированный ISO-том.
Источник определяется автоматически. Его можно переопределить в конфигурации или вручную указать при загрузке.
Cloud-init интегрируется с systemd. Основные юниты:
- cloud-init.service — основной сервис, запускающий инициализацию;
- cloud-config.target — таргет, активирующий конфигурационные модули.
Также Cloud-init может быть зависимостью для других юнитов — например, для автоматической настройки SSH или запуска пользовательских сервисов.
Для диагностики cloud-init можно использовать следующие файлы и каталоги.
Логи:
- /var/log/cloud-init.log — основной лог cloud-init;
- /var/log/cloud-init-output.log — вывод пользовательских команд (runcmd, bootcmd).
Кеш и состояние:
- /var/lib/cloud/ — основное хранилище состояния cloud-init, включая:
- instances/ — директории с данными конкретных запусков,
- sem/ — флаги выполнения этапов,
- scripts/ — выполненные скрипты пользователя,
- seed/ — источник данных при использовании NoCloud или ConfigDrive.
При необходимости можно удалить кеш и принудительно переинициализировать cloud-init, но это следует делать с осторожностью — особенно на рабочих системах.
Проверка наличия и версии Cloud-init
Перед тем как использовать Cloud-init для автоматической настройки VPS, стоит убедиться, что он установлен, корректно работает и не выполнил настройки раньше. Чтобы проверить, установлен ли он и какая версия используется, выполните:
cloud-init --version
В ответе вы увидите версию. Если команда не найдена, Cloud-init можно установить вручную:
sudo apt update
sudo apt install cloud-init
Cloud-init запускается поэтапно и завершает работу после первого старта. Чтобы узнать текущий статус:
sudo cloud-init status
Если написано status: running, значит инициализация ещё продолжается. Статус status: error указывает на проблемы — в этом случае просмотрите логи. Основной лог, содержащий все действия:
sudo cat /var/log/cloud-init.log
Чтобы просмотреть только вывод (результаты выполнения пользовательских команд, ошибки и предупреждения на финальной стадии инициализации):
sudo cat /var/log/cloud-init-output.log
Основы конфигурации Cloud-init
Cloud-init использует файлы конфигурации в формате YAML. Эти файлы называются cloud-config и обычно подаются через источник данных. Конфигурация должна начинаться со специальной строки #cloud-config, чтобы Cloud-init распознал её корректно.
cloud-config состоит из логических блоков, каждый из которых отвечает за отдельный тип действий:
- users — создание и настройка пользователей, добавление SSH-ключей, установка паролей;
- packages — список пакетов, которые нужно установить через системный пакетный менеджер (в Ubuntu — apt);
- runcmd — команды, которые выполняются после остальных этапов настройки, на этапе final;
- write_files — создание или модификация файлов с заданными правами доступа.
Пример простого cloud-config для создания пользователя, установки пакетов и запуска команды:
#cloud-config
users:
- name: devuser
groups: sudo
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC…
packages:
- htop
- curl
write_files:
- path: /etc/motd
content: |
Добро пожаловать на сервер Ubuntu 24.04
runcmd:
- systemctl enable --now ssh
Эта конфигурация:
- создаёт пользователя devuser с правами sudo и SSH-доступом;
- устанавливает утилиты htop и curl;
- записывает приветствие в /etc/motd;
- включает SSH-сервис.
Ещё один пример — полный user-data.yml файл, который можно использовать при развёртывании VPS на базе Ubuntu 24.04. Эта конфигурация:
- создаёт пользователя admin, добавляет ему SSH-ключ и права sudo;
- устанавливает пакеты nginx, openssh-server, ufw, fail2ban;
- включает и настраивает ufw для открытия 22 и 80 портов;
- запускает nginx, openssh-server и fail2ban.
user-data.yml:
#cloud-config
users:
- name: admin
groups: [sudo]
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCy1…
packages:
- nginx
- openssh-server
- ufw
- fail2ban
runcmd:
- systemctl enable nginx
- systemctl start nginx
- systemctl enable sshd
- systemctl start sshd
- ufw allow OpenSSH
- ufw allow "Nginx HTTP"
- ufw --force enable
- systemctl enable fail2ban
- systemctl start fail2ban
Перед применением обязательно убедитесь, что YAML-синтаксис валиден — особенно важно соблюдать отступы (используйте пробелы, а не табы) и структуру. Можно использовать онлайн-валидаторы, например yamllint.
Использование Cloud-init при создании VPS
Cloud-init удобно применять уже при создании VPS. Ниже описаны основные способы подачи user-data, а также создание собственного ISO-образа с данными Cloud-init.
Где вводить user-data
В большинстве случаев хостинг-платформа предоставляет удобный способ задать конфигурацию:
- Панели управления хостингов. В большинстве облачных платформ (например, Yandex Cloud) предусмотрено поле User data при создании виртуальной машины. Туда вставляется YAML-конфигурация с #cloud-config.
- Через ISO-образ с поддержкой NoCloud. Если вы создаёте VPS вручную (например, в KVM), можно использовать datasource NoCloud. Для этого создаётся ISO с метаданными, который монтируется в виртуальную машину как диск.
Генерация ISO с метаданными
Чтобы использовать Cloud-init через NoCloud, необходимо подготовить два файла:
- user-data — основной конфиг Cloud-init (в формате YAML);
- meta-data — простой файл с минимумом информации:
instance-id: vps001
local-hostname: ubuntu-vps
Оба файла должны быть размещены в одном каталоге, например cloud-init/. Затем создаётся ISO-образ:
genisoimage -output seed.iso -volid cidata -joliet -rock user-data meta-data
Этот ISO нужно подключить к виртуальной машине в качестве CD-диска. При загрузке Cloud-init определит источник NoCloud и применит настройки.
Путь к данным Cloud-init
После запуска Cloud-init можно убедиться, что конфигурация была применена, посмотрев логи (/var/log/cloud-init.log), кеш и обработанные данные (/var/lib/cloud/). Также можно проверить статус:
sudo cloud-init status
Если всё выполнено корректно, вы получите готовую к работе систему с нужными пакетами, пользователями и настройками.
Повторный запуск Cloud-init на VPS
Cloud-init рассчитан на однократное выполнение при первом запуске системы. Однако при тестировании или отладке конфигураций бывает нужно очистить его состояние и запустить заново. Для сброса состояния используется команда:
sudo cloud-init clean
Она удаляет:
- кеш и временные данные из /var/lib/cloud/,
- файлы с логами выполнения,
- флаги, указывающие, что Cloud-init уже отработал.
После этого Cloud-init будет воспринимать систему как новую.
Важно: если выполнить команду на рабочем сервере, можно потерять доступ, так как она удаляет всех пользователей, созданных через Cloud-init (включая текущего).
После очистки можно повторно инициировать выполнение модулей. Последовательность команд зависит от того, какие этапы нужно повторить.
Полный запуск и инициализация:
sudo cloud-init init
Только определённые этапы:
sudo cloud-init modules --mode=config
sudo cloud-init modules --mode=final
Запуск одного конкретного модуля:
sudo cloud-init single --name <имя_модуля>
Примеры модулей, которые можно запускать:
- users-groups — создание пользователей и групп,
- package-update-upgrade-install — установка и обновление пакетов,
- runcmd — выполнение команд.
Например, чтобы повторно применить блок runcmd:
sudo cloud-init single --name runcmd
Обратите внимание
Не все модули можно выполнить повторно. Повторная попытка создать пользователя, который уже существует, вызовет ошибку.
Заключение
Cloud-init экономит время при развёртывании и упрощает создание типовых конфигураций, но требует внимательного подхода к безопасности. Основные рекомендации:
- Не храните пароли в открытом виде в user-data. Это особенно опасно в публичных облаках или при совместном использовании шаблонов.
- Проверяйте источник данных Cloud-init (datasource), особенно если работаете в окружениях, где он может быть переопределён злоумышленником.
- Проверяйте, какой user-data будет применён при создании VPS.
Читайте в блоге:
- Продвинутая настройка брандмауэра: гибкость, автоматизация, масштабируемость
- Как сделать бекап PostgreSQL на удалённое хранилище
- Как автоматизировать задачи на сервере через Ansible