Руководство. Настройка виртуальной машины Linux при первой загрузке с помощью cloud-init в Azure
Область применения: ✔️ Виртуальные машины Linux ✔️ Гибкие масштабируемые наборы
В рамках предыдущего руководства вы узнали, как применить протокол SSH к виртуальной машине и установить nginx. Для быстрого и согласованного создания виртуальных машин, как правило, применяются средства автоматизации. Наиболее распространенный подход к настройке виртуальной машины при первой загрузке — использование cloud-init. Из этого руководства вы узнаете, как выполнить следующие задачи:
- создать файл конфигурации cloud-init;
- создать виртуальную машину, использующую файл конфигурации cloud-init;
- просмотреть выполняющееся приложение Node.js после создания виртуальной машины;
- обеспечить безопасное хранение сертификатов в хранилище ключей;
- автоматизировать безопасные развертывания nginx с помощью файла конфигурации cloud-init.
Если вы решили установить и использовать интерфейс командной строки локально, то для работы с этим руководством вам понадобится Azure CLI 2.0.30 или более поздней версии. Чтобы узнать версию, выполните команду az --version
. Если вам необходимо выполнить установку или обновление, см. статью Установка Azure CLI 2.0.
Обзор cloud-Init
Пакет cloud-init — широко используемое средство, используемое для настройки виртуальной машины Linux при ее первой загрузке. Вы можете использовать cloud-init для установки пакетов, записи файлов или настройки пользователей и параметров безопасности. Так как cloud-init выполняется при начальной загрузке, для применения вашей конфигурации не требуются какие-либо дополнительные действия или обязательные агенты.
Кроме того, cloud-init работает с разными дистрибутивами. Например, для установки пакета не используется apt-get install или yum install. Вместо этого можно определить список пакетов для установки. Файл cloud-init автоматически использует собственный инструмент управления пакетами из выбранного дистрибутива.
Мы и наши партнеры работаем над тем, чтобы сценарии cloud-init были добавлены в образы, предоставляемые для Azure. Подробные сведения о поддержке cloud-init для каждого дистрибутива см. в статье Поддержка cloud-init для виртуальных машин в Azure.
Создание файла конфигурации cloud-init
Чтобы посмотреть, как работает cloud-init, создайте виртуальную машину для установки сервера NGINX и запуска простого приложения Node.js Hello World. Приведенная ниже конфигурация cloud-init устанавливает требуемые пакеты, создает приложение Node.js, а затем инициализирует и запускает это приложение.
В командной строке Bash или в Cloud Shell создайте файл с именем cloud-init.txt и добавьте в него следующую конфигурацию. Например, введите sensible-editor cloud-init.txt
, чтобы создать файл и просмотреть список доступных редакторов. Убедитесь, что весь файл cloud-init скопирован правильно, особенно первая строка:
#cloud-config
package_upgrade: true
packages:
- nginx
- nodejs
- npm
write_files:
- owner: www-data:www-data
path: /etc/nginx/sites-available/default
defer: true
content: |
server {
listen 80;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
- owner: azureuser:azureuser
path: /home/azureuser/myapp/index.js
defer: true
content: |
var express = require('express')
var app = express()
var os = require('os');
app.get('/', function (req, res) {
res.send('Hello World from host ' + os.hostname() + '!')
})
app.listen(3000, function () {
console.log('Hello world app listening on port 3000!')
})
runcmd:
- service nginx restart
- cd "/home/azureuser/myapp"
- npm init
- npm install express -y
- nodejs index.js
Чтобы узнать больше о параметрах конфигурации cloud-init, ознакомьтесь с примерами конфигурации cloud-init.
Создать виртуальную машину
Прежде чем создать виртуальную машину, выполните команду az group create, чтобы создать группу ресурсов. В следующем примере создается группа ресурсов с именем myResourceGroupAutomate в расположении eastus.
az group create --name myResourceGroupAutomate --location eastus
Теперь создайте виртуальную машину командой az vm create. Используйте параметр --custom-data
, чтобы передать файл конфигурации cloud-init. Укажите полный путь к конфигурации cloud-init.txt, если этот файл сохранен вне текущего рабочего каталога. В следующем примере создается виртуальная машина с именем myVM.
az vm create \
--resource-group myResourceGroupAutomate \
--name myAutomatedVM \
--image Ubuntu2204 \
--admin-username azureuser \
--generate-ssh-keys \
--custom-data cloud-init.txt
На создание виртуальной машины, установку пакетов и запуск приложения может потребоваться несколько минут. Некоторые фоновые задачи продолжают работу после возврата к командной строке в Azure CLI. Прежде чем вы получите доступ к приложению, может пройти несколько минут. Когда виртуальная машина будет создана, запишите значение publicIpAddress
, отображаемое Azure CLI. Это адрес для доступа к приложению Node.js через веб-браузер.
Чтобы разрешить передачу веб-трафика для виртуальной машины, откройте порт 80 для Интернета командой az vm open-port.
az vm open-port --port 80 --resource-group myResourceGroupAutomate --name myAutomatedVM
Тестирование веб-приложения
Теперь можно открыть веб-браузер и ввести в адресной строке http://<publicIpAddress>. Укажите собственный общедоступный IP-адрес, настроенный при создании виртуальной машины. Отобразится ваше приложение Node.js, как показано ниже:
Внедрение сертификатов из Key Vault
В этом дополнительном разделе описывается, как безопасно хранить сертификаты в Azure Key Vault и внедрять их во время развертывания виртуальных машин. Вместо того, чтобы использовать пользовательский образ со встроенными сертификатами, можно использовать этот процесс, чтобы обеспечить внедрение наиболее актуальных сертификатов в виртуальную машину при ее первом запуске. При этом сертификат никогда не покидает платформу Azure и не предоставляется в сценарии, журнале командной строки или шаблоне.
Azure Key Vault защищает криптографические ключи и секреты, в том числе сертификаты и пароли. Key Vault помогает оптимизировать управление ключами и позволяет поддерживать контроль над ключами, которые предоставляют доступ к вашим данным и шифруют их. В этом сценарии вводятся некоторые понятия Key Vault, относящиеся к созданию и использованию сертификата. Впрочем, это не все общие сведения о том, как использовать Key Vault.
Далее описывается, как:
- создать Azure Key Vault;
- создать или передать сертификат в Key Vault;
- создать секрет из сертификата для внедрения в виртуальную машину;
- создать виртуальную машину и внедрить сертификат.
создать Azure Key Vault;
Сначала создайте Key Vault командой az keyvault create и включите его использование при развертывании виртуальной машины. У каждого Key Vault должно быть уникальное имя в нижнем регистре. Замените mykeyvault
в следующем примере собственным уникальным именем Key Vault.
keyvault_name=mykeyvault
az keyvault create \
--resource-group myResourceGroupAutomate \
--name $keyvault_name \
--enabled-for-deployment
Создание сертификата и его сохранение в Key Vault
Для использования в рабочей среде следует импортировать действительный сертификат, подписанный доверенным поставщиком, выполнив команду az keyvault certificate import. В следующем примере в этом руководстве показано, как можно командой az keyvault certificate create создать самозаверяющий сертификат, использующий политику сертификата по умолчанию.
az keyvault certificate create \
--vault-name $keyvault_name \
--name mycert \
--policy "$(az keyvault certificate get-default-policy --output json)"
Подготовка сертификата для использования с виртуальной машиной
Чтобы использовать сертификата во время создания виртуальной машины, получите идентификатор сертификата, выполнив команду az keyvault secret list-versions. Виртуальной машине требуется сертификат в определенном формате, чтобы вставить его во время загрузки. Поэтому преобразуйте сертификат с помощью команды az vm secret format. Следующий пример присваивает переменным результаты этих команд, чтобы их было удобно использовать в дальнейшем.
secret=$(az keyvault secret list-versions \
--vault-name $keyvault_name \
--name mycert \
--query "[?attributes.enabled].id" --output tsv)
vm_secret=$(az vm secret format --secret "$secret" --output json)
Создание конфигурации cloud-init для защиты сервера NGINX
При создании виртуальной машины сертификаты и ключи хранятся в защищенном каталоге /var/lib/waagent/. Чтобы автоматизировать добавление сертификата в виртуальную машину и настройку сервера NGINX, используйте обновленную конфигурацию cloud-init из предыдущего примера.
Создайте файл cloud-init-secured.txt и вставьте в него приведенную ниже конфигурацию. Если вы используете Cloud Shell, создайте файл конфигурации cloud-init в этой оболочке, а не на локальном компьютере. Например, введите sensible-editor cloud-init-secured.txt
, чтобы создать файл и просмотреть список доступных редакторов. Убедитесь, что весь файл cloud-init скопирован правильно, особенно первая строка:
#cloud-config
package_upgrade: true
packages:
- nginx
- nodejs
- npm
write_files:
- owner: www-data:www-data
path: /etc/nginx/sites-available/default
defer: true
content: |
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/mycert.cert;
ssl_certificate_key /etc/nginx/ssl/mycert.prv;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
- owner: azureuser:azureuser
path: /home/azureuser/myapp/index.js
defer: true
content: |
var express = require('express')
var app = express()
var os = require('os');
app.get('/', function (req, res) {
res.send('Hello World from host ' + os.hostname() + '!')
})
app.listen(3000, function () {
console.log('Hello world app listening on port 3000!')
})
runcmd:
- secretsname=$(find /var/lib/waagent/ -name "*.prv" | cut -c -57)
- mkdir /etc/nginx/ssl
- cp $secretsname.crt /etc/nginx/ssl/mycert.cert
- cp $secretsname.prv /etc/nginx/ssl/mycert.prv
- service nginx restart
- cd "/home/azureuser/myapp"
- npm init
- npm install express -y
- nodejs index.js
Создание безопасной виртуальной машины
Теперь создайте виртуальную машину командой az vm create. Данные сертификата внедряются из Key Vault с помощью параметра --secrets
. Как и в предыдущем примере, можно передать файл конфигурации cloud-init с помощью параметра --custom-data
.
az vm create \
--resource-group myResourceGroupAutomate \
--name myVMWithCerts \
--image Ubuntu2204 \
--admin-username azureuser \
--generate-ssh-keys \
--custom-data cloud-init-secured.txt \
--secrets "$vm_secret"
На создание виртуальной машины, установку пакетов и запуск приложения может потребоваться несколько минут. Некоторые фоновые задачи продолжают работу после возврата к командной строке в Azure CLI. Прежде чем вы получите доступ к приложению, может пройти несколько минут. Когда виртуальная машина будет создана, запишите значение publicIpAddress
, отображаемое Azure CLI. Это адрес для доступа к приложению Node.js через веб-браузер.
Чтобы разрешить безопасную передачу веб-трафика для виртуальной машины, откройте порт 443 для Интернета командой az vm open-port.
az vm open-port \
--resource-group myResourceGroupAutomate \
--name myVMWithCerts \
--port 443
Тестирование защищенного веб-приложения
Теперь можно открыть веб-браузер и ввести в адресной строке https://<publicIpAddress>. Укажите собственный общедоступный IP-адрес, как показано в выходных данных при создании предыдущей виртуальной машины. Примите предупреждение системы безопасности, если вы использовали самозаверяющий сертификат.
На экране отобразятся защищенный сайт NGINX и приложение Node.js, как в показано следующем примере.
Следующие шаги
В рамках этого руководства вы настроили виртуальные машины при первой загрузке с помощью файла конфигурации cloud-init. Вы научились выполнять следующие задачи:
- создать файл конфигурации cloud-init;
- создать виртуальную машину, использующую файл конфигурации cloud-init;
- просмотреть выполняющееся приложение Node.js после создания виртуальной машины;
- обеспечить безопасное хранение сертификатов в хранилище ключей;
- автоматизировать безопасные развертывания nginx с помощью файла конфигурации cloud-init.
Перейдите к следующему руководству, чтобы научиться создавать пользовательские образы виртуальных машин.