Давайте дружить в Телеграме: рассказываем про новые фичи, общаемся в комментах, прислушиваемся к вашим идеям Подписаться

Установка и настройка cloud-init в Linux

Миша Курушин
Миша Курушин
Технический писатель
23 января 2024 г.
223
13 минут чтения
Средний рейтинг статьи: 5

Cloud-init — это свободно распространяемый пакет, предназначенный для настройки виртуальных машин на базе операционной системы Linux при их запуске.

В традиционной (домашней) среде системы устанавливаются либо с компакт-диска, либо с USB-накопителя. Конфигурация выполняется вручную через стандартный установщик.

Однако в облачной среде требуется регулярно конфигурировать множество систем, а также создавать, удалять и перезапускать их экземпляры. В этом случае ручная конфигурация становится непрактичной и невыполнимой задачей. 

Поэтому cloud-init решает задачи автоматической конфигурации и стандартизирует настройку виртуальных машин.

Введение в cloud-init

Что делает cloud-init?

Основная задача cloud-init — обрабатывать входные метаданные (например, параметры пользователя — user-data) и конфигурировать виртуальную машину перед ее запуском.

Таким образом, благодаря cloud-init можно заранее настроить сервер, установить необходимое программное обеспечение, подготовить рабочие директории и создать пользователей с определенными правами.

Cloud-init и облачные серверы Timeweb Cloud

Облачные серверы Timeweb Cloud поддерживают работу со сценариями cloud-init через панель управления.

В документации Timeweb Cloud есть небольшая статья, рассказывающая об использовании сценариев cloud-init непосредственно на облачных серверах Timeweb Cloud.

E5d9634a 23f5 491b B45f 60f3be14d878

По сути, Timeweb Cloud имеет текстовый редактор сценариев cloud-init, который доступен в веб-браузере. С помощью него передаются пользовательские данные непосредственно в саму утилиту перед запуском системы.

Установка Cloud-init

Есть несколько вариантов получения операционной системы на базе Linux вместе с утилитой cloud-init:

  • Использовать специализированный образ операционной системы Linux с предустановленным cloud-init. Таких образов множество — мы упомянем лишь самые основные.

  • Использовать готовые дистрибутивы от облачных провайдеров. Большинство облачных платформ поддерживают cloud-init, хотя процедуры настройки имеют различия. Например, облачные серверы Timeweb Cloud позволяют применять сценарии cloud-init через панель управления.

  • Собрать собственный образ операционной системы с помощью HashiCorp Packer.

  • Установить пакет cloud-init вручную.

Образы с cloud-init

  • Ubuntu. Самый распространенный образ Unix-подобной операционной системы с cloud-initUbuntu 22.04 Cloud Images. Это официальные облачные образы Ubuntu, созданные Canonical (разработчик ОС) специально для работы в общедоступных облаках. Они оптимизированы и настроены под соответствующие задачи.

  • Debian. Аналогично Ubuntu, у Debian есть свои специальные облачные образы — Debian Cloud.

  • Alma Linux. Отдельная версия дистрибутивов Linux, заточенная под развертывание в облаке — Alma Linux Cloud.

  • Astra Linux. У Astra Linux Special Edition есть специальные образы с поддержкой технологии cloud-init.

  • VMWare. Специализированный образ Photon от VMWare, предназначенный для работы в облаке, с заранее установленным cloud-init.

Другой вариант — самостоятельная установка cloud-init.

Установка через APT

В операционную систему cloud-init устанавливается как обычный пакет и существует в виде Трех служб (сервисов) для systemd, расположенных в директории /lib/systemd/system:

  • cloud-init.service

  • cloud-config.service

  • cloud-final.service

Также в пакет cloud-init входят еще две вспомогательные службы systemd:

  • cloud-init-local.service

  • cloud-init-hotplugd.service

Перед установкой лучше обновить список доступных репозиториев:

sudo apt update

Далее пакет cloud-init загружается через apt:

sudo apt-get install cloud-init

В некоторых образах Linux cloud-init уже установлен по умолчанию. Если это так, то после выполнения команды install система сообщит вам об этом.

Стоит добавить, что cloud-init поддерживает дополнительные модули, которые могут расширить возможности конфигурации. Полный список модулей доступен в официальной документации.

Запуск cloud-init

По причине того, что cloud-init существует в виде служб, он запускается сразу после старта утилиты systemd — то есть в момент старта физической машины и до подключения системы к сети. Это позволяет заранее сконфигурировать сетевые настройки, шлюзы, DNS-адреса и т.д.

Этапы работы cloud-init

Можно выделить три основных этапа работы cloud-init, за время которых конфигурируется система. На каждом этапе запускаются определенные службы cloud-init.

  1. До сети (init). Первоначальная, самая ранняя конфигурация еще до запуска сети. Выполняются настройка системы, настройка сетевых параметров, подготовка дискового пространства и т.д.

    • cloud-init-local.service

    • cloud-init.service

  2. После сети (config). На этом этапе появляется сеть, поэтому выполняется установка обновлений и загрузка необходимых пакетов.

    • cloud-config.service

  3. В конце (final). Завершающий этап, на котором выполняются самые последние настройки. Например, создание пользователей, назначение прав доступа и т.д.

    • cloud-final.service

    • cloud-init-hotplugd.service

Модули cloud-init

В cloud-init доступны дополнительные модули, расширяющие возможности конфигурации системы. Все они выполняются последовательно и поэтапно.

Модули могут запускаться на каждом из трех существующих этапах — зависит от конкретного случая. В конфигурационном файле запуск модулей регулируется тремя списками:

  • cloud_init_modules. Модули выполняются на этапе инициализации (init) еще до запуска сети.

  • cloud_config_modules. Модули выполняются на этапе конфигурации (cloud) уже после запуска сети.

  • cloud_final_modules. Модули выполняются на заключительном этапе (final).

В этом смысле, если развернуть описанные выше три этапа и рассмотреть их работу немного подробнее, общее число этапов будет равно пяти:

  1. Утилита systemd определяет, нужно ли запускать cloud-init при загрузке системы.

  2. Запущенный cloud-init ищет локальные источники данных и применяет описанные конфигурации. На этом же этапе настраивается сеть.

  3. На этапе настройки cloud-init обрабатывает пользовательские данные и запускает модули, перечисленные в разделе cloud_init_modules конфигурационного файла.

  4. На этапе конфигурации cloud-init аналогично запускает модули, описанные в разделе cloud_config_modules конфигурационного файла.

  5. На этапе завершения cloud-init запускает модули, которые были описаны в разделе cloud_final_modules конфигурационного файла. Тут же выполняется загрузка и установка указанных пакетов.

Более подробно про этапы работы cloud-init можно узнать на отдельной странице в официальной документации.

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

  • per instance. Модуль запускается каждый раз при первой загрузке экземпляра системы, который клонируется или создается из сохраненного образа.

  • per once. Модуль запускается только один раз. То есть при старте клонов или новых экземпляров образа модуль уже не будет работать.

  • per always. Модуль запускается при каждой загрузке системы.

Настройка Cloud-init

Как правило, в каждом публичном (AWS, GCP, Azure, Timeweb Cloud) или частном облаке (OpenStack, CloudStack, выделенный сервер Timeweb Cloud) есть своего рода сервис, сообщающий виртуальной машине данные об окружении.

Эти данные можно разделить на несколько типов, каждый из которых cloud-init использует в определенном порядке:

  • Пользовательские данные (user-data). Настройки и директивы, прописанные в конфигурационном файле cloud.cfg. Данные могут представлять собой указанные файлы для запуска, пакеты для установки и сценарии оболочки. Обычно user-data необходимы для конфигурации конкретного экземпляра виртуальной машины.

  • Метаданные (meta-data). Информация об окружении. Например, имя сервера или идентификатор экземпляра системы. Метаданные используются после пользовательских данных.

  • Данные поставщиков (vendor-data). Информация о поставщиках (облачных услуг) и разработчиках, которые помогают правильно настроить образ для последующего запуска в рабочей среде. Обычно vendor-data требуется для общей конфигурации по умолчанию. Данные поставщиков используются после метаданных.

Например, метаданные могут быть доступны по адресу:

http://localhost/latest/meta-data/

Как правило, это:

  • Внутренний IP адрес

  • Публичный IP адрес

  • Имя сервера

  • Публичный SSH-ключ

  • Тип виртуальной машины

Пользовательские данные, которые можно редактировать, могут быть размещены по адресу:

http://localhost/latest/user-data/

Пользовательские данные используются в облаке для автоматизации разного рода шаблонов или сценариев, задача которых — устанавливать необходимое ПО, настраивать сервер, управлять конфигурациями и т.д.

То есть такие данные может использовать не только cloud-init, но и любая другая утилита.

Cloud-init читает пользовательские данные и, если они заданы в формате, понятном cloud-init, выполняются действия, описанные в этих данных.

Сценарии cloud-init

Когда система загружается, cloud-init сперва проверяет конфигурационные файлы со сценариями на языке YAML, после чего выполняет прописанные в них инструкции.

YAML (рекурсивный акроним «YAML Ain't Markup Language», т.е. «YAML не язык разметки») — это особый формат для сериализации (хранения) данных, который визуально выглядит как язык разметки, хотя таковым не является.

Основной YAML-файл с настройками cloud-init находится по адресу /etc/cloud/cloud.cfg.

Этот файл представляет собой основной сценарий конфигурации. В нем прописываются директивы и их параметры. При этом каждая директива соотносится с конкретным модулем cloud-init, который выполняет свою узкую функцию.

Сценарии для cloud-init можно писать как в виде текстовых файлов на YAML (через #cloud-config), так и в виде обычных shell-скриптов (через #!/bin/sh).

При этом shell-скрипты автоматически преобразовываются в формат с #cloud-config.

Простейший пример сценария с пользовательскими данными — это задание имени хоста при загрузке виртуальной машины:

#cloud-config
hostname: my-host
fqdn: my-address.ru
manage_etc_hosts: true
  • #cloud-config — указание на то, что все дальнейшие инструкции предназначены для cloud-init и написаны в формате YAML

  • hostname — короткое имя хоста

  • fqdn — полное имя хоста

  • manage_etc_hosts — разрешение для cloud-init на управление файлом /etc/hosts. Если впоследствии потребуется изменение этого файла, опция должна быть выставлена в false. В противном случае вручную внесенные изменения будут переписаны после очередной перезагрузки с cloud-init.

Примеры сценариев cloud-init 

Конфигурация cloud-init с использованием YAML должна начинаться с #cloud-config.

Пользователи и группы

На старте виртуальной машины вы можете заранее определять пользователей через директиву users:

#cloud-config
users:
	- name: userOne
	gecos: This is the first user
	groups: sudo
	shell: sh
	system: true

	- name: userTwo
	gecos: This is the second user
	groups: sudo
	shell: /bin/bash
	system: false
	expiredate: '2030-01-02'

Как видно, имя каждого нового пользователя начинается с тире, а сами параметры определяются в формате «ключ: значение».

Указанные параметры означают следующее:

  • name. Имя учетной записи пользователя

  • gecos. Небольшая информация о пользователе

  • groups. Группы, к которым относится пользователь

  • shell. Оболочка, устанавливаемая ​​для пользователя. Указано значение по умолчанию в виде самой простой оболочки — sh.

  • system. Является ли учетная запись системной. Если true, то у такого пользователя не будет домашнего каталога.

  • expiredate. Дата истечения срока действия пользователя в формате «ГГГГ-ММ-ДД».

Более подробное описание всех параметров пользователя можно увидеть в примерах официальной документации.

Смена паролей созданных пользователей

Еще одна несложная директива — chpasswd. С помощью нее можно перезадать пароль уже существующего пользователя. Рассмотрим конфигурацию:

#cloud-config
chpasswd:
	list: |
		userOne:passOne
		userTwo:passTwo
		userThree:passThree
	expire: false

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

Пароль записывается в явном виде. При этом параметр expire сообщает о том, потребуется ли его изменение по истечении срока действия.

Поэтому эту директиву лучше использовать только в во время отладки, ведь установленное значение будет доступно всем пользователям системы.

Обновление списка репозиториев

В cloud-config есть отдельная директива для обновления списка доступных пакетов — package_update. Она является декларативным аналогом команды APT:

sudo apt-get update

Значением по умолчанию является true — перед запуском системы cloud-init всегда автоматически обновляет список пакетов. Отключить обновление можно так:

#cloud-config
package_update: false

Явное обновление пакетов

Для обновления (или установки) конкретных пакетов нужна другая директива — packages:

#cloud-config
packages:
	- nginx
	- nodejs

Выполнение команд

Директива runcmd позволяет выполнять консольные команды через конфигурацию cloud-config. Нужно просто передать список команд, которые cloud-init последовательно запустит в во время старта системы, как если бы вы их вводили вручную:

#cloud-config
runcmd:
	- echo 'Команда в виде строки!' >> /somefile.txt
	- [ sh, -c, "echo 'Команда в виде списка!' >> /somefile.txt" ]

В этом примере используется два способа записи команды, которая записывает текст в файл:

  • В виде обычной строки

  • В виде YAML-списка с указанием исполняемого файла и его параметров

Однако есть похожая директива для выполнения команд — bootcmd. Правила записи аналогичные, но есть одно важное отличие от runcmd:

  • Директива runcmd выполняет команды только при первичной загрузке системы

  • Директива bootcmd выполняет команды при каждом старте системы

#cloud-config
bootcmd:
	- echo 'Команда записана строкой и выполняется при каждой загрузке системы!'
	- [ sh, "echo 'Команда записана списком и выполняется при каждой загрузке системы!' " ]

Создание и выполнение скрипта

Директиву runcmd можно комбинировать с директивой написания файла — write_files.

Например, можно создать скрипт в отдельном файле и сразу же его выполнить:

#cloud-config
write_files:
	- path: /run/scripts/somescript.sh
		content: |
			#!/bin/bash
			echo 'Какой-то скрипт только что выполнился!'
		permissions: '0755'

runcmd:
	- [ sh, "/run/scripts/somescript.sh" ]

Параметр permissions со значением 0755 указывает на то, что файл со скриптом будет доступен для чтения и выполнения всем, но редактирование возможно только пользователю.

Переопределение выполнения модулей

Список модулей, которые будут выполняться на определенном этапе конфигурации, можно переопределять. Например, список модулей по умолчанию на этапе cloud_config_modules выглядит так:

#cloud-config
cloud_config_modules:
	- emit_upstart
	- snap
	- ssh-import-id
	- locale
	- set-passwords
	- grub-dpkg
	- apt-pipelining
	- apt-configure
	- ubuntu-advantage
	- ntp
	- timezone
	- disable-ec2-metadata
	- runcmd
	- byobu

На всякий случай стоит напомнить, что этапов 3:

  • cloud_init_modules

  • cloud_config_modules

  • cloud_final_modules

Обратите внимание, в примере выше указана уже известная нам директива (модуль) runcmd — предпоследняя позиция в списке. Если ее убрать, то команды, прописанные в runcmd, не будут выполнены.

Обновление репозиториев и установка пакетов через shell-скрипт

Конфигурация cloud-init может также содержать только shell-скрипты. Для этого в начале сценария вместо привычного #cloud-config прописывается #!/bin/sh.

Вот пример того, как можно выполнить стандартное обновление APT и установить необходимые пакеты:

#!/bin/sh
apt-get update
apt-get -y install nodejs
apt-get -y install nginx

Флаг -y нужен для автоматического ответа «yes» на все вопросы во время установки.

Заключение

В этом руководстве было рассказано о теоретическом и практическом аспектах использования технологии cloud-init:

  • Механизм работы cloud-init

  • Способы «общения» с cloud-init для конфигурации системы

  • Написание сценариев на YAML или в виде shell-скриптов

  • Примеры возможных конфигураций cloud-init

Важно помнить, что cloud-init выполняет свои функции до старта системы, после чего настроенный экземпляр следует той конфигурации (сеть, директории, пакеты, обновления), которая была в него заложена.

Утилита cloud-init имеет поддержку модулей, каждый из которых отвечает за свой аспект конфигурации. При этом настройка системы выполняется поэтапно:

  • init (до сети)

  • config (после сети)

  • final (в конце)

Подробная информация о технологии cloud-init доступна на официальном сайте, который поддерживается компанией Canonical — основным разработчиком дистрибутива Ubuntu.

Зарегистрируйтесь и начните пользоваться
сервисами Timeweb Cloud прямо сейчас

15 лет опыта
Сосредоточьтесь на своей работе: об остальном позаботимся мы
165 000 клиентов
Нам доверяют частные лица и компании, от небольших фирм до корпораций
Поддержка 24/7
100+ специалистов поддержки, готовых помочь в чате, тикете и по телефону