Google Cloud Platform — это большой набор облачных сервисов: серверы, базы данных, хранилища, сеть и ещё сотни вещей. На первый взгляд это стена из названий, и легко растеряться. Но почти всё стоит на четырёх опорах. Разберитесь с ними — и остальное встроится в понятную картину.
Эти четыре опоры: иерархия ресурсов (где всё лежит и кто за это платит), Cloud IAM (кто и что имеет право делать), регионы и зоны (где физически живут ресурсы и как пережить сбой) и VPC (как устроена ваша сеть). Дальше — по порядку. Если вы знакомы с AWS, по ходу будут пометки, что чему соответствует.
Сверху вниз наследуются политики организации и привязки ролей, а границей всего остального служит проект: у него свой счёт, свои квоты и свой набор включённых служб.
Иерархия: организация, папка, проект
Тестовый стенд и продакшен в одной куче — и удаление «лишней» базы однажды сносит боевую. Чтобы среды не смешивались, а счета и права раздавались по границам, ресурсы в GCP раскладывают по трём уровням.
В GCP ресурсы разложены по матрёшке из трёх видов уровней — папки при этом вкладываются друг в друга, так что в реальной компании уровней обычно больше трёх.
- Организация (organization) — верхний уровень, привязанный к вашей компании (домену). Здесь общие политики и настройки. Есть она не у всех: организация появляется, только если на домене заведён Cloud Identity или Google Workspace. Зашли с личной почты — организации у вас нет вовсе, проекты висят сами по себе, и искать этот уровень в консоли бесполезно.
- Папка (folder) — промежуточная группировка: по отделам, командам или средам.
- Проект (project) — то, внутри чего создаются сами ресурсы: виртуальные машины, базы, сети. Проект — это главная единица изоляции и биллинга: к нему привязан платёжный аккаунт, у него свои квоты и права.
Ключевая единица здесь — проект. Практика та же, что в других облаках: под разные среды заводят разные проекты — отдельный под production, отдельный под staging, отдельный «песочницу». Зачем так: если кто-то случайно удалит ресурсы или утечёт доступ, беда не выйдет за пределы одного проекта, а в счёте сразу видно, какой проект сколько потратил. (В терминах AWS проект примерно соответствует аккаунту.)
Главный практический вывод: «у нас есть GCP» всегда тянет вопрос «а в каком проекте?».
Службы в проекте надо включать
Самая первая неожиданность в GCP, и она случается со всеми: вы создали проект, пробуете поднять что-нибудь — и получаете отказ примерно такого вида:
Cloud Run Admin API has not been used in project 123456789 before or it is disabled.
Enable it by visiting https://console.developers.google.com/apis/api/run.googleapis.com/overview?project=123456789
Это не ошибка прав и не опечатка. В GCP каждая служба (API) в каждом проекте выключена по умолчанию, и её надо включить — один раз на проект. Включение бесплатно и занимает секунды.
gcloud services list --enabled # что уже включено
gcloud services enable run.googleapis.com \
artifactregistry.googleapis.com \
sqladmin.googleapis.com \
secretmanager.googleapis.com
Зачем так сделано: включённая служба — это ещё и разрешение расходовать деньги и квоты; выключенная не может быть использована даже случайно. Плюс у каждой службы своя квота, привязанная к проекту.
Практические следствия. Список нужных служб держат в коде инфраструктуры — иначе развёртывание в новом проекте падает на первом шаге, и никто не помнит, чего не хватает. Включение службы иногда требует минуту на распространение, поэтому сразу после включения вызов может ещё раз ответить отказом — это нормально. И наоборот, выключение службы в живом проекте ломает всё, что ею пользуется, поэтому чистку «лишних» служб делают осторожно.
Ярлыки: чтобы в счёте было видно, кто потратил
Разговор про биллинг без этого не работает: чтобы затраты делились по сервисам и средам, на ресурсах должны быть ярлыки (labels) — пары «ключ — значение».
gcloud run services update orders --region europe-west4 \
--update-labels=env=prod,service=orders,owner=platform
Минимальный набор такой же, как в любом облаке: среда, сервис, владелец, центр затрат. Дальше в отчётах по затратам появляется группировка по ярлыку, и вопрос «сколько стоят стенды» получает ответ за минуту.
Три особенности GCP. Ярлыки не наследуются от папки или проекта к ресурсам — их назначает тот, кто создаёт ресурс (то есть код инфраструктуры). Зато сам проект — естественная граница затрат: в GCP принято разносить среды по отдельным проектам, и тогда разбивка по проектам уже даёт большую часть картины без всяких ярлыков. И у ярлыков есть ограничения на символы (нижний регистр, цифры, дефисы) — это ловит те, кто пробует писать русские названия или заглавные буквы.
Cloud IAM: кто и что может делать
Cloud IAM отвечает на один вопрос: кто имеет право делать что и с каким ресурсом. Здесь три ключевых понятия.
Роль (role) — набор разрешений. Есть базовые роли (basic roles) на весь проект — Viewer (только смотреть), Editor (создавать и менять), Owner (плюс раздавать права). В старых текстах их зовут примитивными, но в документации Google они давно называются базовыми, и по слову «примитивные» вы их там не найдёте. А есть множество узких предопределённых ролей вида roles/storage.objectAdmin (управлять объектами в хранилище) или roles/cloudsql.client (подключаться к базе). Узкие роли — то, что нужно на практике.
Привязка (binding) — это назначение «кому — какую роль — на каком ресурсе». Роль выдают на организацию, папку, проект или отдельный ресурс, и права наследуются вниз.
Участник (member) — тот, кому выдают роль: человек (аккаунт Google или корпоративная учётка через federation), группа или сервисный аккаунт — учётная запись для программ и виртуальных машин.
Два правила, которые экономят нервы и деньги.
Первое: ваш код не должен носить с собой ключи. Когда программа работает на виртуальной машине GCP, к машине привязывают сервисный аккаунт, и приложение получает временный токен прямо из сервера метаданных — без секретов в коде. В GKE ту же роль играет Workload Identity. Это тот же принцип, что instance profile в AWS. Ключи сервисного аккаунта в виде JSON-файла в git — классический путь к утечке.
Второе: минимум прав (least privilege). Давайте роли ровно то, что нужно: сервису — доступ к своему бакету и своей базе, а не Editor на весь проект. Подробный разбор — в статье про Cloud IAM.
Регионы и зоны
Регион — географическая площадка: например, europe-west1. Большинство ресурсов привязано к региону, а то и к конкретной зоне, и данные сами между регионами не путешествуют — копию настраивают отдельно.
Но привязаны не все. Часть ресурсов в GCP глобальна: сама сеть VPC, образы дисков, глобальный балансировщик, мультирегиональные бакеты. Это одно из главных отличий от AWS, где сеть живёт внутри региона, и место, где интуиция подводит чаще всего.
Зона (zone) — изолированный дата-центр внутри региона (europe-west1-b, -c, -d): своё питание, охлаждение и сеть, чтобы авария в одной зоне не задела соседнюю. Зоны одного региона связаны быстрыми каналами.
Зачем это знать новичку:
- Отказоустойчивость строят на нескольких зонах одного региона. Копии приложения и реплики базы разносят по зонам, сверху — балансировщик; упадёт зона — сервис продолжит работать.
- Крупная авария региона — редкость; защита от неё (мультирегион) стоит дороже и настраивается отдельно. Это тема отказоустойчивости и восстановления.
- Трафик между зонами и регионами стоит денег — это видно в счёте.
Как строить высокую доступность — в статье про масштабирование и доступность.
VPC: ваша сеть
VPC (Virtual Private Cloud) — ваша сеть внутри GCP. Особенность GCP: сеть глобальна, а подсети привязаны к регионам. То есть одна VPC охватывает все регионы, а внутри неё вы заводите региональные подсети. Минимальный набор понятий:
- Подсети (subnets) — региональные диапазоны адресов; ресурсы получают внутренний IP, а чтобы стать доступным из интернета, ресурсу нужен внешний IP (или он прячется за балансировщиком).
- Правила файрвола (firewall rules) — сетевой фильтр на уровне VPC с разрешающими и запрещающими правилами и приоритетами; цель правила задают тегами или сервисными аккаунтами. Поверх ваших правил всегда действуют два подразумеваемых: весь входящий трафик запрещён, весь исходящий разрешён. Отдельная ловушка — сеть
default, которую GCP заводит сам: в ней уже лежат разрешающие правила, включая доступ по SSH с любого адреса. Машина, поднятая вdefaultс внешним IP, открыта на 22-й порт сразу, без единого вашего действия. - Для исходящего доступа из внутренних ресурсов используют Cloud NAT, а до сервисов Google по приватной сети дотягиваются через Private Google Access.
Правило простое: серверы и базы держат без внешнего IP, наружу смотрят только балансировщики и точки входа. Глубже — в статье про сеть.
Где это применяется
Эти четыре опоры всплывают в любой работе с GCP. Создаёте ресурс — выбираете проект, регион и зону. Запускаете приложение — привязываете сервисный аккаунт вместо ключей. Поднимаете базу — держите её без внешнего IP и закрываете правилами файрвола. Любой следующий сервис (вычисления, функции, управляемые базы) стоит на этом фундаменте.
Где спотыкаются начинающие:
- Хранят JSON-ключ сервисного аккаунта в коде или git вместо привязки аккаунта к машине — самая частая и дорогая ошибка.
- Раздают
Editor/Ownerшироко «чтобы заработало» и забывают сузить. - Дают базе внешний IP ради удобства — и получают сканирование извне.
- Путают регион и зону или не понимают, почему ресурс «не виден» — часто он в другом проекте или регионе.
Глубже: три разных имени у проектарасширенное
В командах, в адресах и в правах встречаются три разные вещи, и путаница между ними стоит времени.
Идентификатор проекта (project ID) — строка вида acme-orders-prod, уникальная во всём GCP. Именно её принимают почти все команды и она встречается в адресах ресурсов. Задаётся один раз при создании и не меняется никогда — то есть имя, выбранное в спешке, останется с вами навсегда.
Номер проекта (project number) — число вида 123456789012, присваивается автоматически. Встречается в служебных учётных записях (123456789012-compute@developer.gserviceaccount.com), в некоторых правах и в сообщениях об ошибках — как в примере выше.
Название (display name) — человеческое имя для консоли, меняется свободно и ни на что не влияет.
gcloud projects describe acme-orders-prod --format="value(projectId,projectNumber,name)"
Практический совет по именам: идентификатор собирают по схеме «компания-сервис-среда» (acme-orders-prod, acme-orders-dev), потому что он уникален глобально и простое orders уже занято. И раз он неизменяем, схему имён стоит придумать до того, как будет создан первый проект.
Глубже: квоты: на проект и на регионрасширенное
Ещё одна причина, по которой «не создаётся»: квоты. В GCP они считаются на проект и, для большинства вычислительных ресурсов, на регион отдельно.
gcloud compute regions describe europe-west4 \
--format="table(quotas.metric,quotas.limit,quotas.usage)"
Что обычно упирается первым: число процессоров в регионе (у нового проекта это десятки), число внешних адресов, число дисков и их суммарный объём, число правил балансировщика. У части квот есть ещё и предел на всю организацию.
Повышение — заявка из консоли (раздел квот), обрабатывается от минут до суток, и не всякая квота повышается автоматически: часть требует обоснования. Отсюда практика: квоты поднимают до нагрузочного испытания и до выката в новый регион, а не в момент, когда автомасштабирование упёрлось в потолок. И отдельно проверяют резервный регион — там квоты по умолчанию низкие, а нужны именно в аварии.
Глубже: политики организации: запретить на весь доменрасширенное
Правило вроде «у машин не должно быть внешних адресов» можно объявить в документе, а можно применить. За второе отвечают политики организации (organization policies) — ограничения, которые действуют на организацию, папку или проект и которые нельзя обойти правами внутри.
Самые употребительные:
- запрет внешних адресов у машин (
compute.vmExternalIpAccess) — закрывает целый класс ошибок: машина, случайно выставленная в интернет; - запрет публичного доступа к хранилищу (
storage.publicAccessPrevention) — то же для бакетов; - запрет создания ключей служебных учётных записей (
iam.disableServiceAccountKeyCreation) — главный рычаг против долгоживущих ключей, о которых статья про доступ; - разрешённые регионы (
gcp.resourceLocations) — требование по хранению данных, выраженное механизмом, а не договорённостью.
gcloud resource-manager org-policies set-policy policy.yaml --organization=123456789012
Отличие от прав: права отвечают на вопрос «кому можно», политики — «что вообще возможно в этом домене». Владелец проекта с полными правами не создаст внешний адрес, если политика его запрещает.
Практика внедрения: начинают с запрета внешних адресов и публичного доступа к хранилищу, применяют сначала к папке со стендами (там видно, что сломается), потом ко всей организации. Для законных исключений есть точечное разрешение на конкретный проект — и у него, как у любого исключения, должна быть причина и дата пересмотра.
Глубже: какой трафик стоит денеграсширенное
«Трафик между зонами и регионами стоит денег» — верно и слишком общо, чтобы этим пользоваться. Разложим по видам (порядки величин, точные значения — в калькуляторе).
| Куда идёт трафик | Порядок цены |
|---|---|
| Внутри одной зоны, по внутренним адресам | бесплатно |
| Между зонами одного региона | около 1 цента за гигабайт |
| Между регионами (внутри GCP) | от 1 до 5 центов за гигабайт, зависит от направления |
| К сервисам Google внутри того же региона (хранилище, реестр) | обычно бесплатно |
| В интернет | порядка 8–12 центов за гигабайт, зависит от направления и объёма |
| Входящий трафик | бесплатно |
Что из этого важно на практике. Приложение и база в разных зонах платят за каждый запрос: сам по себе это мелочь, но сервис с тысячей запросов в секунду и заметными ответами даёт ощутимую строку. Отсюда правило: то, что много общается, держат в одной зоне, а дублирование делают между зонами — то есть платят за надёжность осознанно, а не случайно.
Реплика базы в другом регионе — это постоянный межрегиональный трафик, и у него есть цена, которую стоит прикинуть заранее.
Обращение к хранилищу объектов из того же региона обычно бесплатно — и это довод держать данные и вычисления в одном регионе, а не «где было место».
Самое дорогое — выход в интернет. Сервис, который отдаёт файлы пользователям напрямую из хранилища, платит за каждый гигабайт; сеть доставки содержимого перед ним обычно дешевле и быстрее.
Проверить свой профиль просто: в отчёте по затратам трафик виден отдельными позициями с указанием направления. Если в первой тройке расходов оказался трафик — почти всегда это либо межзонный обмен с базой, либо отдача файлов напрямую пользователям.
Коротко
- Иерархия: организация, папки, проект; проект это главная единица изоляции, квот и биллинга, и под каждую среду заводят свой.
- Каждая служба в проекте выключена по умолчанию: список нужных API держат в коде инфраструктуры, а у проекта три имени, из которых команды принимают идентификатор, заданный один раз навсегда.
- Квоты считаются на проект и на регион: процессоры, внешние адреса, диски; поднимают до нагрузочного испытания и заранее в резервном регионе.
- Ярлыки не наследуются и назначаются кодом инфраструктуры, а сам проект уже граница затрат; политики организации запрещают внешние адреса, публичные бакеты и ключи сервисных аккаунтов независимо от прав.
- Cloud IAM выдаёт роль привязкой на организацию, папку, проект или ресурс с наследованием вниз; коду не дают ключей, сервисный аккаунт привязывают к машине, а права режут предопределёнными ролями вместо Editor.
- Регион и зоны как везде, но сеть VPC, образы и глобальный балансировщик глобальны; отказоустойчивость строят на зонах, мультирегион настраивают отдельно.
- Трафик внутри зоны бесплатен, между зонами около цента за гигабайт, в интернет 8–12 центов; данные и вычисления держат в одном регионе, а раздачу файлов ставят за сеть доставки.
- Серверы и базы живут без внешнего IP; правила файрвола на уровне VPC с тегами и сервисными аккаунтами, исходящий трафик через Cloud NAT, к сервисам Google через Private Google Access.
Что почитать дальше
- Сеть в GCP — подсети, правила файрвола и приватный доступ по шагам.
- Cloud IAM — сервисные аккаунты, привязки и разбор отказов.
- Где запускать сервис — Compute Engine, GKE, Cloud Run или функции.
- Terraform в GCP — чтобы не создавать всё руками в консоли.