Compute Engine: виртуальные машины

Виртуальная машина в облаке — это тот же самый сервер, только вы получаете его за полминуты и платите посекундно. Разбираемся, как поднять VM в Compute Engine, как выбрать железо и как не платить втридорога.

Compute Engine — сервис Google Cloud, который выдаёт вам виртуальные машины (VM) в дата-центрах Google: вы выбираете процессор, память, образ операционной системы и регион, а взамен получаете root-доступ к готовому Linux или Windows.

Зачем нужна виртуалка, если есть serverless

Логично спросить: если Google так продвигает Cloud Run и функции, зачем вообще возиться с VM? Ответ прост — виртуалка даёт то, чего не даёт ни одна управляемая платформа: полный контроль.

  • Любой софт. Старый Java-монолит, 1С, самописный демон на C, база данных, которую вы хотите администрировать сами, — всё это ставится на VM и работает.
  • Состояние на диске. Serverless-платформы забывают всё между запросами. У VM есть настоящий диск, который переживает перезагрузку.
  • Долгоживущие процессы. Игровой сервер, стриминг, задача на 12 часов — здесь serverless упрётся в таймауты, а VM просто работает.
  • Спецжелезо. GPU для машинного обучения, много памяти, локальные SSD — всё это заказывается прямо в момент создания машины.
  • Переезд «как есть». Классический lift-and-shift: у вас был физический сервер, вы поднимаете такую же VM и переносите всё как было. Не самый красивый путь, но самый быстрый.

Плата за свободу — вы сами обновляете систему, чините утечки памяти, настраиваете мониторинг и сами следите за счётом. Виртуалка не масштабируется до нуля: пока она включена, счётчик тикает.

Первая машина за одну команду

Ниже — реальная команда, которая поднимает виртуалку в зоне us-central1-a. Она делает всё сразу: заказывает железо, ставит Debian 12, создаёт загрузочный диск и вешает сетевой тег.

gcloud compute instances create web-1 \
  --project=my-project \
  --zone=us-central1-a \
  --machine-type=e2-medium \
  --image-family=debian-12 \
  --image-project=debian-cloud \
  --boot-disk-size=20GB \
  --boot-disk-type=pd-balanced \
  --tags=http-server

Результат:

Created [https://www.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/instances/web-1].
NAME   ZONE           MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP   STATUS
web-1  us-central1-a  e2-medium                  10.128.0.2   34.171.12.34  RUNNING

Тридцать секунд — и у вас есть сервер с публичным IP. Но зайти на 80-й порт снаружи пока нельзя: в Google Cloud весь входящий трафик по умолчанию закрыт файрволом. Тег http-server, который мы повесили, — это метка, по которой правило файрвола находит нужные машины:

gcloud compute firewall-rules create allow-http \
  --allow=tcp:80 \
  --target-tags=http-server \
  --source-ranges=0.0.0.0/0

Что означают ключи

КлючСмысл
--zoneКонкретный дата-центр. Зона входит в регион: us-central1-a — это зона «a» региона us-central1. VM всегда живёт в одной зоне.
--machine-typeСколько vCPU и памяти. e2-medium — 2 vCPU и 4 ГБ.
--image-familyСемейство образов. Указав семейство, а не конкретный образ, вы всегда получаете свежую версию с последними патчами.
--boot-disk-typeТип диска: pd-standard (HDD, дёшево), pd-balanced (SSD, золотая середина), pd-ssd (быстро и дорого).
--tagsСетевые теги — «крючки» для правил файрвола.

Типы машин: как не платить за воздух

Имя типа машины читается как семейство-профиль-число_vCPU. Например, n2-highmem-8 — это семейство n2, профиль «много памяти», 8 vCPU.

СемействоДля чего
e2Рабочая лошадка и самое дешёвое семейство общего назначения. Веб-серверы, небольшие API, тестовые стенды, CI-раннеры.
n2, n2dОбщее назначение с предсказуемой производительностью и более свежими процессорами (n2d — на AMD, обычно дешевле).
c3, c2Compute-optimized: максимальная частота ядра. Игровые серверы, кодирование видео, HPC.
m1, m3Memory-optimized: сотни гигабайт памяти. In-memory базы, SAP, аналитика.
t2dScale-out на AMD: отличная цена за производительность для горизонтально масштабируемых сервисов.
a2, g2С GPU: обучение и инференс моделей.

Профиль после семейства меняет соотношение CPU и памяти: -standard (4 ГБ на vCPU), -highmem (8 ГБ на vCPU), -highcpu (1 ГБ на vCPU). А если ни один готовый размер не подходит, Compute Engine умеет собирать машину под заказ:

# 2 vCPU и ровно 4096 МБ памяти — платим только за то, что заказали
gcloud compute instances create batch-1 \
  --zone=us-central1-a \
  --machine-type=e2-custom-2-4096

Custom machine types — недооценённый способ сэкономить: если вашему приложению нужно 6 ГБ памяти, не надо брать машину с 16 ГБ только потому, что «следующий размер такой».

Spot-инстансы: та же машина за треть цены

Spot VM — это виртуалка из «излишков» мощностей Google. Железо ровно то же самое, но Google оставляет за собой право забрать машину в любой момент, прислав внутрь сигнал за 30 секунд до выключения. За этот риск даётся скидка 60–91%.

Старое название — preemptible. Разница между ними важная: preemptible-машину принудительно убивали через 24 часа в любом случае, а Spot может жить сколько угодно, пока Google не понадобится ёмкость. Новые проекты стоит делать на Spot.

gcloud compute instances create render-worker \
  --zone=us-central1-a \
  --machine-type=e2-standard-4 \
  --provisioning-model=SPOT \
  --instance-termination-action=DELETE

Посчитаем выгоду на примере e2-medium (цены ориентировочные, для региона us-central1; в месяце считаем 730 часов):

price_on_demand = 0.0335  # $ за час, обычная VM
price_spot = 0.0100       # $ за час, Spot VM
hours = 730               # часов в среднем месяце

for name, price in [("On-demand", price_on_demand), ("Spot", price_spot)]:
    print(f"{name:10} {price * hours:6.2f} $/мес")

economy = (1 - price_spot / price_on_demand) * 100
print(f"Экономия: {economy:.0f}%")

Результат:

On-demand   24.46 $/мес
Spot         7.30 $/мес
Экономия: 70%

Где Spot уместен: пакетная обработка данных, рендеринг, CI-раннеры, обучение моделей с чекпоинтами, stateless-воркеры, разбирающие очередь. Если машину убьют — задача просто вернётся в очередь и её подхватит другая.

Где Spot — самоубийство: единственный сервер с продовой базой, узел с состоянием в памяти, машина, которую некому пересоздать в три часа ночи.

Подключение по SSH

Ключи вручную генерировать не нужно — gcloud сделает это за вас, положит публичный ключ в метаданные проекта и подключится:

gcloud compute ssh web-1 --zone=us-central1-a

Правильная (и более безопасная) практика — вообще не давать машине внешний IP, а ходить внутрь через IAP TCP forwarding: туннель, который проверяет ваши права в IAM и пробрасывает SSH прямо в приватную сеть. Порт 22 при этом наружу не торчит вообще:

gcloud compute instances create private-1 \
  --zone=us-central1-a --no-address

gcloud compute ssh private-1 \
  --zone=us-central1-a --tunnel-through-iap

Как это работает

Несколько вещей «под капотом», понимание которых экономит часы отладки.

Диск — не часть машины

Persistent Disk — это сетевое хранилище, живущее отдельно от VM. Виртуалку можно удалить, а диск останется (и продолжит стоить денег). Можно наоборот — отцепить диск от одной машины и прицепить к другой. Именно поэтому VM в GCP переживает миграцию между физическими серверами: данные-то не на локальном железе.

Метаданные и startup-script

Внутри каждой VM доступен служебный адрес metadata.google.internal (он же 169.254.169.254). Оттуда машина узнаёт своё имя, зону, токены сервисного аккаунта и произвольные метаданные, которые вы ей передали:

curl -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/instance/name

Самая полезная метаданная — startup-script: скрипт, который выполняется от root при каждом старте машины. Так VM настраивает сама себя, без ручного SSH:

gcloud compute instances create web-2 \
  --zone=us-central1-a \
  --machine-type=e2-small \
  --tags=http-server \
  --metadata=startup-script='#! /bin/bash
apt-get update
apt-get install -y nginx
echo "Привет из $(hostname)" > /var/www/html/index.html'

Live migration и посекундная оплата

Когда Google обновляет физический хост, обычная VM не выключается — она «переезжает» на другую машину на живую, с паузой в доли секунды. У Spot-инстансов этой роскоши нет: их просто останавливают.

Счёт считается посекундно (с минимумом в одну минуту), а за долгую непрерывную работу автоматически даётся скидка — sustained use discount. Никаких кнопок нажимать не надо, она применяется сама.

Частые ошибки

  • «Я же выключил машину, почему счёт растёт?» Остановленная VM не берёт денег за vCPU и память, но диск и зарезервированный статический IP оплачиваются всегда. Более того, статический IP, который никуда не привязан, стоит дороже, чем привязанный — Google так штрафует за удержание адресов.
  • Осиротевшие диски. Загрузочный диск удаляется вместе с VM, а вот дополнительные диски по умолчанию — нет. Через полгода экспериментов у вас в проекте могут висеть десятки «ничьих» дисков. Проверяйте: gcloud compute disks list --filter="-users:*".
  • Бесплатный уровень не там, где вы думаете. Free tier Compute Engine — это одна e2-micro в месяц и только в регионах us-west1, us-central1, us-east1. Создали e2-micro во Франкфурте «чтобы ближе» — платите полную цену.
  • Машина «с запасом». Взять n2-standard-16 под сайт с сотней посетителей в день — классика. Смотрите на графики загрузки в Cloud Monitoring и слушайте рекомендации Recommender: GCP сам подсказывает, какую машину можно ужать.
  • Файрвол настежь. --source-ranges=0.0.0.0/0 на порт 22 означает, что ваш SSH круглосуточно перебирают боты. Используйте IAP-туннель или хотя бы ограничьте диапазон адресов.
  • Забытый Premium network tier. Исходящий трафик по умолчанию идёт по премиальной сети Google. Для внутренних сервисов и батчей Standard tier дешевле — и разницы вы не заметите.
  • Нет бюджета и алерта. Первое, что стоит сделать в новом проекте, — Budget с уведомлением на почту. Забытая GPU-машина за выходные съедает сотни долларов.

Итоги

  • Compute Engine — это обычные виртуалки: полный контроль, любой софт, диск и долгоживущие процессы. Расплата — вы всё администрируете сами и платите, пока машина включена.
  • gcloud compute instances create поднимает VM за секунды; входящий трафик закрыт, пока вы не откроете его правилом файрвола по сетевому тегу.
  • Тип машины = семейство + профиль + число vCPU. Есть custom machine types — не переплачивайте за «следующий размер».
  • Spot-инстансы дают скидку 60–91% ценой того, что машину могут забрать за 30 секунд. Идеальны для батчей и воркеров, недопустимы для единственного продового сервера.
  • gcloud compute ssh сам управляет ключами; --tunnel-through-iap позволяет вообще не выдавать машине внешний IP.
  • Диск живёт отдельно от VM и продолжает стоить денег после её удаления. Статический IP без привязки — тоже.
Проверьте себя
1. Вы остановили виртуальную машину кнопкой Stop. За что Google продолжит брать деньги?
AНи за что — остановленная VM полностью бесплатна
BЗа загрузочный диск и зарезервированный статический IP
CТолько за vCPU, память освобождается
DЗа сетевые теги и правила файрвола
2. Для какой задачи Spot-инстанс — плохой выбор?
ACI-раннер, который собирает pull request'ы
BВоркер, разбирающий задачи из очереди
CЕдинственный сервер с продовой базой данных
DРендеринг видео по кадрам с сохранением прогресса