Выберите продукт

Cloud-init на VDS: пользователи, SSH-ключи, сеть и авторасширение диска (Ubuntu/Debian/AlmaLinux)

Cloud-init ускоряет ввод VDS в работу: на первом старте вы создаёте пользователей, добавляете SSH-ключи, настраиваете сеть и автоматически расширяете раздел и файловую систему под размер диска. Ниже — рабочие шаблоны cloud-config и быстрая диагностика проблем.
Cloud-init на VDS: пользователи, SSH-ключи, сеть и авторасширение диска (Ubuntu/Debian/AlmaLinux)

Cloud-init — это стандартный механизм «первой настройки» виртуальной машины: на самом первом старте он читает метаданные от провайдера (datasource), применяет их (hostname, сеть, SSH-доступ), а затем выполняет ваш user-data в формате cloud-config. Для админа это означает предсказуемый provisioning: вместо ручных действий в консоли вы описываете желаемое состояние в YAML и получаете одинаковые инстансы.

Ниже — практичный чек-лист и готовые шаблоны: как правильно создавать пользователей, задавать SSH-ключи, аккуратно работать с сетью на Ubuntu/Debian и AlmaLinux, а также как включить growpart и resize_rootfs, чтобы диск и файловая система автоматически «доросли» до размера, который вы выдали VM.

Как cloud-init устроен на VDS: datasource, стадии и где смотреть логи

Ключевые понятия:

  • datasource — источник метаданных и user-data (например, NoCloud, ConfigDrive, OpenStack, EC2-совместимые источники). От него зависит, откуда cloud-init возьмёт сеть, SSH-ключи и ваш cloud-config.
  • cloud-config — YAML-описание, которое cloud-init понимает «из коробки»: пользователи, пакеты, файлы, команды, настройки диска.
  • стадии — обнаружение datasource, настройка сети, применение конфигов, запуск команд.

Почти вся диагностика начинается с трёх команд:

cloud-init status --long
cloud-init query --all
journalctl -u cloud-init -u cloud-config -u cloud-final --no-pager

И ещё полезны файлы:

  • /var/log/cloud-init.log — подробный лог.
  • /var/log/cloud-init-output.log — вывод того, что выполнялось на стадии final.
  • /run/cloud-init и /var/lib/cloud — текущее состояние и артефакты.

Если изменения в user-data «не применяются», частая причина в том, что инстанс уже проходил первый запуск cloud-init. Многие модули выполняются один раз.

Для повторного прогона (осторожно на проде) обычно чистят состояние и перезагружают:

sudo cloud-init clean --logs
sudo reboot

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

sudo cloud-init clean --logs
sudo cloud-init init
sudo cloud-init modules --mode=config
sudo cloud-init modules --mode=final

Базовый каркас cloud-config: пользователи, sudo, SSH и запрет пароля

Типовая задача: создать админ-пользователя, выдать ему sudo, положить SSH-ключи и запретить password login. Делайте это в user-data, а не руками: так проще масштабировать и снижать риск «расхождения» серверов.

Пример: один пользователь, только ключи, парольный вход выключен

#cloud-config
users:
  - name: deploy
    gecos: Deploy User
    groups: [sudo]
    shell: /bin/bash
    sudo: ["ALL=(ALL) NOPASSWD:ALL"]
    lock_passwd: true
    ssh_authorized_keys:
      - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... your-key-comment"

ssh_pwauth: false
disable_root: true

package_update: true
package_upgrade: false

Нюансы, на которых чаще всего ошибаются:

  • lock_passwd: true блокирует пароль у пользователя, оставляя вход по ключам.
  • ssh_pwauth: false просит cloud-init отключить парольную аутентификацию SSH, но финально проверьте конфиг sshd.
  • disable_root: true отключает root-логин, если образ это поддерживает (иногда провайдерские образы ведут себя по-своему).

Пароль всё-таки нужен: как задавать безопасно

Иногда пароль требуется для аварийного доступа через консоль/VNC/serial. Тогда задавайте хэш, а не plaintext. Хэш удобно получить так:

openssl passwd -6

И применить в cloud-config:

#cloud-config
users:
  - name: admin
    groups: [sudo]
    shell: /bin/bash
    sudo: ["ALL=(ALL) ALL"]
    passwd: "$6$rounds=4096$....$...."
    lock_passwd: false
    ssh_authorized_keys:
      - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI..."

ssh_pwauth: false

Даже в этом варианте обычно лучше оставить ssh_pwauth: false, чтобы пароль не работал по SSH, но оставался для локальной консоли.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

SSH keys в cloud-init: частые ошибки и быстрая диагностика

Когда «ключ добавлен, но вход не работает», сначала проверьте базовые факты, а уже потом «копайте» datasource и приоритеты образа.

  • Пользователь действительно создан: getent passwd deploy.
  • Права на каталоги и файлы: ls -ld /home/deploy /home/deploy/.ssh (обычно 700 на .ssh и 600 на authorized_keys).
  • Что ключи реально записались: sudo cat /home/deploy/.ssh/authorized_keys.
  • Логи SSH: journalctl -u ssh --no-pager -n 200 (Ubuntu/Debian) или journalctl -u sshd --no-pager -n 200 (AlmaLinux).

Если ключ «точно правильный», проверьте, не отдаёт ли провайдер ключи через metadata, а вы параллельно управляете ими в user-data. У разных образов приоритеты могут отличаться.

Если вы строите воспроизводимые серверы и дальше планируете тиражировать конфигурации, полезно зафиксировать подход: «источник истины» для ключей либо metadata провайдера, либо user-data, но не оба одновременно.

Вывод cloud-init status и фрагменты логов в терминале для диагностики

Сеть и cloud-init network: Netplan (Ubuntu) vs NetworkManager (AlmaLinux)

Ошибки в сети — это самый быстрый способ потерять SSH-доступ. Общая рекомендация: если провайдер гарантирует рабочую сеть через metadata, не переопределяйте её без необходимости. Если нужно — держите под рукой консоль в панели и план отката.

Проверяем, кто управляет сетью и что cloud-init реально применил

На Ubuntu чаще всего используется Netplan (который генерирует конфиг для systemd-networkd или NetworkManager). На AlmaLinux чаще встречается NetworkManager.

Минимальный набор диагностики:

cloud-init query network
cloud-init query datasource
ip -br a
ip r
resolvectl status

И посмотрите, какие файлы/профили созданы:

  • Ubuntu: /etc/netplan/*.yaml
  • systemd-networkd: /etc/systemd/network/*.network
  • AlmaLinux NetworkManager: nmcli con show

Пример network-config (v2) для NoCloud: статический IPv4

Если ваш сценарий — datasource NoCloud, то сеть часто задают отдельным документом network-config (не в user-data). Формат v2 выглядит так:

version: 2
ethernets:
  eth0:
    dhcp4: false
    addresses:
      - 203.0.113.10/24
    gateway4: 203.0.113.1
    nameservers:
      addresses:
        - 1.1.1.1
        - 8.8.8.8

Критично: имя интерфейса (eth0) должно совпадать с реальным. На «предсказуемых именах» это может быть ens3, enp1s0 и т.д. Проверяйте по:

ip -br link

DHCP, IPv6 и маршруты

Если сеть выдаётся через DHCP, обычно лучше не трогать network-config и сосредоточиться на пользователях/ключах. При dual-stack (IPv4+IPv6) внимательно проверьте маршрутизацию:

ip -6 r
sysctl net.ipv6.conf.all.disable_ipv6

Если IPv6 включён, но провайдер не выдал корректный route/RA, некоторые приложения могут «подвисать» на попытках соединения по IPv6. Это чаще всего не проблема cloud-init, а исходных сетевых параметров.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Growpart и resize_rootfs: авторасширение диска «как в облаке»

Ситуация из практики: вы увеличили диск у сервера в панели, перезагрузили — а внутри ОС всё ещё старый размер. Нужно расширить раздел и файловую систему. Cloud-init умеет делать это автоматически (чаще на первом старте; дальнейшее зависит от образа и конфигурации модулей).

Обычно участвуют два шага:

  • growpart — расширяет раздел (partition) до доступного размера диска.
  • resize_rootfs — расширяет файловую систему root (ext4/xfs и т.д.) после growpart.

Пример cloud-config: включаем growpart и resize_rootfs

#cloud-config
growpart:
  mode: auto
  devices: ["/"]
  ignore_growroot_disabled: false

resize_rootfs: true

Практические замечания:

  • devices: ["/"] часто работает для root, но на некоторых образах нужно указывать конкретный девайс (например, /dev/vda1).
  • Если root на LVM, цепочка другая: расширяется PV, затем LV, затем ФС. Некоторые образы это автоматизируют, некоторые — нет.
  • Если у образа отключён автогроу (например, через настройки growroot), cloud-init может проигнорировать расширение.

Проверка: что реально расширилось

Проверяйте цепочку «диск → раздел → ФС»:

lsblk -f
df -hT

Если lsblk показывает диск увеличенного размера, но раздел прежний — не сработал growpart. Если раздел вырос, а df нет — не отработало расширение файловой системы.

Datasource: почему cloud-init «не видит» user-data и как диагностировать

От datasource зависит, где именно cloud-init ищет метаданные. Типовые симптомы проблем:

  • cloud-init status зависает на стадии network;
  • cloud-init query userdata пустой;
  • в логах виден перебор источников и итоговый DataSourceNone.

Быстрая диагностика:

cloud-init query datasource
grep -R "DataSource" /var/log/cloud-init.log | tail -n 50

Иногда есть смысл ограничить список источников, чтобы ускорить boot и убрать «ложные» попытки. Делается через /etc/cloud/cloud.cfg.d/:

sudo sh -c 'cat > /etc/cloud/cloud.cfg.d/90-datasource.cfg << "EOF"
datasource_list: [ NoCloud, ConfigDrive ]
EOF'

Меняйте datasource_list только если уверены, что провайдер использует эти источники. Иначе можно «отрезать» правильный datasource и сломать сеть/ключи на первом старте.

Если вы делаете собственные «золотые образы», полезно отдельно выстроить процесс сборки и проверки cloud-init. В тему: как собрать golden image с cloud-init и Packer.

Схема цепочки расширения: диск, раздел и файловая система (growpart и resize_rootfs)

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

1) Безопасный старт: пользователь + ключи + базовые пакеты

Минимально разумный набор для нового сервера: создать пользователя, отключить парольный SSH, поставить базовые утилиты.

#cloud-config
users:
  - name: ops
    groups: [sudo]
    shell: /bin/bash
    sudo: ["ALL=(ALL) NOPASSWD:ALL"]
    lock_passwd: true
    ssh_authorized_keys:
      - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI..."

ssh_pwauth: false
disable_root: true

packages:
  - curl
  - wget
  - vim
  - htop
  - git

package_update: true
package_upgrade: true

Если вы подбираете площадку под такие сценарии и вам важны быстрые переустановки и доступ к консоли, ориентируйтесь на админские возможности панели и образов. По теме можно свериться с обзором: сравнение панелей и сценариев управления VDS. Тарифы и параметры — на странице облачных VDS.

2) Запись конфигов через write_files

Если нужно положить конфиг-файл (например, для sysctl или агента мониторинга), используйте write_files. Это обычно предсказуемее, чем «echo в heredoc» внутри runcmd.

#cloud-config
write_files:
  - path: /etc/sysctl.d/99-custom.conf
    permissions: "0644"
    content: |
      vm.swappiness = 10
      net.core.somaxconn = 1024

runcmd:
  - sysctl --system

3) Команды: runcmd vs bootcmd и идемпотентность

runcmd выполняется ближе к концу, когда сеть обычно уже поднята. bootcmd — очень рано, и там проще всего «прострелить ногу» (особенно с сетью/диском). Для большинства задач админа runcmd безопаснее.

Думайте об идемпотентности: если вы повторно прогоните cloud-init, команды должны либо ничего не менять, либо корректно обновлять состояние. Где возможно — используйте модули cloud-init вместо «сырого bash».

Частые проблемы и короткие решения

Cloud-init отработал, но SSH всё равно просит пароль

  • Проверьте реальную конфигурацию sshd: sshd -T | grep -E "passwordauthentication|kbdinteractiveauthentication|permitrootlogin"
  • Убедитесь, что используются правильные drop-in файлы (в Ubuntu часто /etc/ssh/sshd_config.d/).

Сеть пропала после правок network-config

  • Сверьте имя интерфейса: ip -br link.
  • Проверьте маршруты: ip r.
  • Проверьте DNS: resolvectl query example.com.
  • Смотрите логи: journalctl -b --no-pager | grep -i -E "netplan|networkd|NetworkManager|cloud-init".

Growpart не сработал

  • Проверьте, действительно ли диск расширен на уровне гипервизора: lsblk.
  • Проверьте схему разметки (GPT/MBR), номер раздела, root на LVM.
  • Проверьте логи cloud-init по модулю growpart: grep -i growpart /var/log/cloud-init.log | tail -n 50.

Рекомендованный шаблон user-data для старта (Ubuntu/Debian/AlmaLinux)

Универсальная база, которая закрывает 80% потребностей: hostname, пользователь, ключи, обновления, базовые пакеты, авторасширение root (где это поддерживается образом).

#cloud-config
hostname: vds-node
manage_etc_hosts: true

users:
  - name: ops
    gecos: Operations
    groups: [sudo]
    shell: /bin/bash
    sudo: ["ALL=(ALL) NOPASSWD:ALL"]
    lock_passwd: true
    ssh_authorized_keys:
      - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI..."

ssh_pwauth: false
disable_root: true

package_update: true
package_upgrade: true
packages:
  - curl
  - ca-certificates
  - git
  - vim
  - htop

growpart:
  mode: auto
  devices: ["/"]

resize_rootfs: true

final_message: "cloud-init finished in $UPTIME seconds"

После первого старта зафиксируйте результат: снимок/backup или «золотой» образ, если тиражируете одинаковые VDS. Это ускоряет развёртывание и упрощает поддержку.

Итоги

Cloud-init — это не «магия», а инженерный инструмент: datasource даёт исходные параметры, а ваш cloud-config доводит систему до нужного состояния. На практике стоит начать с трёх вещей: пользователи и SSH-ключи, аккуратная работа с сетью и автоматическое расширение диска через growpart и resize_rootfs. Дальше вы постепенно превращаете ручной сетап в воспроизводимый provisioning-пайплайн.

Поделиться статьей

Вам будет интересно

OpenSearch vs Elasticsearch в 2026: лицензии, безопасность, ILM/ISM и эксплуатация OpenAI Статья написана AI (GPT 5)

OpenSearch vs Elasticsearch в 2026: лицензии, безопасность, ILM/ISM и эксплуатация

Разбор для админов и DevOps: чем в 2026 отличаются OpenSearch и Elasticsearch по лицензированию, безопасности, ILM/ISM, ingest pip ...
2026: GlusterFS vs CephFS vs NFS для shared storage в CI — что выбрать и почему OpenAI Статья написана AI (GPT 5)

2026: GlusterFS vs CephFS vs NFS для shared storage в CI — что выбрать и почему

Shared storage в CI часто упирается в small files и операции с метаданными. Разбираю NFS, GlusterFS и CephFS в 2026: POSIX locks, ...
Containerd vs Docker Engine в 2026: rootless, cgroups v2, логи и сеть на VDS OpenAI Статья написана AI (GPT 5)

Containerd vs Docker Engine в 2026: rootless, cgroups v2, логи и сеть на VDS

Что выбрать на VDS в 2026: containerd или Docker Engine? Разбираем rootless, работу с cgroups v2, сбор логов через journald, нюанс ...