Сеть в GCP — это не «галочки где-то в консоли», а то, что определяет главный вопрос: кто до кого может достучаться. От неё зависит и безопасность (не смотрит ли база наружу?), и работоспособность (видит ли приложение базу?). Хорошая новость: вся модель собирается из нескольких понятных кирпичиков. Если базовые понятия облака ещё не на руках, начните с основ GCP.

вход снаружи интернет глобальный балансировщик, внешний IP приложение, внутренний IP Cloud SQL, приватный доступ выход наружу машина без внешнего IP маршрут по умолчанию Cloud NAT интернет к сервисам Google подсеть с Private Google Access сеть Google Cloud Storage

Три пути и три узла: снаружи пускает только глобальный балансировщик, наружу выпускает Cloud NAT по маршруту по умолчанию, а к сервисам Google машины без внешнего адреса ходят по сети Google через приватный доступ на подсети.

Обязательно

VPC и подсети

VPC (Virtual Private Cloud) — ваша изолированная сеть внутри GCP. Важная особенность, которая отличает GCP от AWS и Azure: сеть глобальна. Одна VPC охватывает сразу все регионы, а внутри неё вы создаёте региональные подсети (subnets) — диапазоны адресов вида 10.0.1.0/24, привязанные к региону. Ресурсы из подсетей в разных регионах при этом находятся в одной сети и общаются по внутренним адресам без дополнительных соединений.

gcloud compute networks create my-vpc --subnet-mode=custom
gcloud compute networks subnets create app --network=my-vpc \
  --region=europe-west1 --range=10.0.1.0/24

Это удобно: не нужно, как в других облаках, вручную связывать сети разных регионов — они уже в одной глобальной VPC.

Внешний и внутренний IP

Деление на «доступно снаружи» и «только внутри» проходит по ресурсу — есть ли у него внешний (external) IP.

  • Только внутренний IP — ресурс виден лишь внутри VPC. Сюда попадают приложения, базы, кэши: всё, до чего снаружи не должно быть доступа.
  • Внешний IP — ресурс доступен из интернета. Его выдают точкам входа: балансировщику, иногда bastion-хосту.

Правило: серверы и базы держат без внешнего IP, наружу смотрят только балансировщики и точки входа. Внешний IP базе «чтобы удобно подключаться с ноутбука» — прямая дыра: её тут же начнут сканировать.

Правила файрвола

Трафик фильтруют правила файрвола (firewall rules) — сетевой фильтр на уровне всей VPC. Начинать надо с того, что лежит под вашими правилами: в каждой сети всегда действуют два подразумеваемых правила — весь входящий трафик запрещён, весь исходящий разрешён. Поэтому «до машины не достучаться, хотя запрещающих правил нет» — не загадка: входящее закрыто изначально, и открывает его только явное разрешающее правило.

Дальше — особенности:

  • у правила есть направление: входящее (ingress) или исходящее (egress). gcloud по умолчанию создаёт входящее, и про существование второго легко не узнать. С исходящими картина обратная: там разрешено всё, пока вы сами что-нибудь не запретили;
  • правила бывают разрешающие и запрещающие, и у каждого есть приоритет — число от 0 до 65535, по умолчанию 1000. Здесь интуиция обманывает: меньшее число означает более высокий приоритет. Правило с приоритетом 100 перебивает правило с приоритетом 1000, а не наоборот;
  • файрвол помнит состояние соединения: если входящее соединение разрешено, ответ на него уходит сам, отдельное правило на исходящий трафик не нужно. Если вы пришли из AWS с его сетевыми списками доступа, где правила пишут в обе стороны, — здесь так делать не надо;
  • цель правила (к кому оно применяется) задают не жёсткими IP, а сетевыми тегами или сервисными аккаунтами: например, «разрешить трафик на порт 5432 от машин с тегом app к машинам с тегом db». Адреса меняются — правила не ломаются.
gcloud compute firewall-rules create allow-app-to-db \
  --network=my-vpc --direction=INGRESS --priority=1000 \
  --allow=tcp:5432 \
  --source-tags=app --target-tags=db

Отдельно про балансировщик — на этом спотыкаются при первой же настройке. Проверки здоровья приходят не от пользователей, а с адресов Google: 35.191.0.0/16 и 130.211.0.0/22. Если входящего правила для этих диапазонов нет, все бэкенды окажутся «нездоровы», балансировщик не отдаст им ни одного запроса — а сервис при этом работает и в логах чисто.

Cloud NAT: выход в интернет

Часто внутреннему сервису нужен исходящий доступ — скачать обновление, дёрнуть чужой API. Входящий при этом не нужен. Для этого служит Cloud NAT: управляемый механизм, который выпускает исходящий трафик из ресурсов без внешнего IP, но не пускает входящий извне. Он работает как односторонний турникет и, в отличие от аналогов в других облаках, не требует отдельной виртуальной машины-шлюза.

Совсем без настройки, правда, не обходится. Cloud NAT опирается на Cloud Router и заводится на конкретный регион и выбранные подсети — кнопки «включить на всю VPC» нет. И есть особенность, о которой узнают по симптому «часть исходящих соединений отваливается»: внешние адреса и порты NAT раздаёт машинам пачками, и машина, открывающая много соединений наружу, свою пачку портов вычерпывает. Лечится увеличением числа портов на машину или добавлением внешних адресов.

Приватный доступ к сервисам Google

До сервисов Google — Cloud Storage, баз, API — дотягиваются, не выходя в интернет. Механизма для этого два, и делают они разное.

Private Google Access включают на подсети: машины без внешнего IP получают возможность обращаться к публичным адресам API Google, и трафик при этом идёт по сети Google, а не через интернет. Адрес у сервиса остаётся общий, гугловский.

Private Service Connect заводит внутри вашей VPC внутренний адрес — конечную точку, за которой стоит сервис Google или сервис стороннего поставщика. Приложение ходит на ваш собственный адрес из вашего диапазона.

Выбирают между ними по разным причинам: первый — самый дешёвый способ убрать внешние IP с машин, второй — когда нужен именно свой внутренний адрес.

Балансировщики: точки входа

Точками входа для пользователей служит Cloud Load Balancing. Его сильная сторона — глобальный HTTP(S)-балансировщик: один внешний адрес принимает пользователей со всего мира и направляет каждого в ближайший регион, где работает ваш сервис. Есть и региональные балансировщики уровня соединений (L4). Балансировщик прячет приложения во внутренней сети и раздаёт им трафик.

Где это применяется

Сеть — фундамент, на котором стоит всё остальное. Балансировщик с внешним адресом, приложение и база с внутренними IP, Cloud NAT для исходящих вызовов, правила файрвола, описывающие «кто до кого» — эту схему вы встретите почти в любом боевом развёртывании, продублированную по зонам.

Типичные ошибки новичков:

  • дают базе внешний IP — она доступна из интернета, прямая дыра;
  • ждут выхода наружу без Cloud NAT — исходящие вызовы зависают;
  • путают приоритеты правил файрвола — более общее правило перекрывает частное;
  • пишут правила через IP-адреса вместо тегов и сервисных аккаунтов — они ломаются при смене адресов.
Дополнительно: при первом чтении можно пропустить

Глубже: размеры подсетей и что можно изменитьрасширенное

Числа, которые определяют, во что вы упрётесь через полгода.

Подсеть в автоматическом режиме — /20 (около четырёх тысяч адресов на регион). Это щедро и потому удобно для старта; в ручном режиме размер выбираете вы.

Из каждой подсети GCP забирает четыре адреса — первый, шлюз, предпоследний и последний. То есть в /24 остаётся 252 адреса.

Расширить подсеть можно, сузить нельзя. Диапазон подсети увеличивается на живой сети без остановки — и это приятная особенность GCP. Обратная операция невозможна: чтобы уменьшить, подсеть придётся удалить (а значит, вынести из неё все ресурсы).

gcloud compute networks subnets expand-ip-range app-subnet \
  --region europe-west4 --prefix-length 22

Кластеру Kubernetes нужно заметно больше, чем кажется. В обычном режиме каждому поду выдаётся адрес, и кластеру выделяют отдельные диапазоны под поды и службы — считают их по формуле «узлы × поды на узел», с запасом на рост. Это самая частая причина «кластер не масштабируется дальше», и исправляется она только пересозданием.

Практическое правило: адресное пространство планируют один раз на всю компанию (иначе соединить сети будет нельзя, см. ниже), подсети берут с запасом, а под кластеры выделяют отдельные диапазоны заранее.

Глубже: маршруты: чем вообще определяется путь пакетарасширенное

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

У каждой сети есть таблица маршрутов, и она заполняется сама:

  • маршрут ко всем подсетям сети — создаётся автоматически при создании подсети, поэтому машины видят друг друга по внутренним адресам без всяких настроек;
  • маршрут по умолчанию (0.0.0.0/0) — в интернет-шлюз, тоже создаётся автоматически.

Именно второй маршрут объясняет, как работает выход в интернет. Машина с внешним адресом уходит наружу прямо по этому маршруту. Машина без внешнего адреса тоже пытается — и вот здесь вступает преобразование адресов (Cloud NAT): оно перехватывает такой трафик и выпускает его от своего адреса. То есть само по себе преобразование не создаёт путь, он уже есть; оно даёт машинам без внешнего адреса возможность им воспользоваться.

Что с маршрутами делают руками:

  • удаляют маршрут по умолчанию, чтобы сделать сеть полностью закрытой (тогда наружу не выйдет никто, даже с внешним адресом) — и добавляют приватный доступ к сервисам Google, о котором ниже;
  • добавляют маршрут через своё устройство, если весь исходящий трафик должен идти через межсетевой экран или прокси;
  • смотрят маршруты при разборе: gcloud compute routes list отвечает на вопрос «а есть ли вообще путь» — до всякой отладки правил фильтрации.
gcloud compute routes list --filter="network=app-vpc"

Правила фильтрации и маршруты работают вместе и отвечают на разные вопросы: маршрут — «куда пакет пойдёт», правило — «пропустят ли его». Если нет маршрута, никакое разрешающее правило не поможет, и наоборот.

Глубже: как подключаются управляемые сервисырасширенное

Отдельный механизм, который «ломает голову всем»: база (Cloud SQL, Memorystore и другие управляемые сервисы) живёт не в вашей сети, а в сети, которой управляет Google. Как тогда обращаться к ней по внутреннему адресу?

Ответов два, и они разные.

Приватный доступ к сервисам (private services access). Вы выделяете в своей сети диапазон адресов специально для управляемых сервисов и создаёте соединение: сеть Google связывается с вашей через пиринг, и база получает адрес из выделенного диапазона. Дальше приложение обращается к ней по внутреннему адресу, как к своему ресурсу.

gcloud compute addresses create google-managed-services-range \
  --global --purpose=VPC_PEERING --prefix-length=16 --network=app-vpc

gcloud services vpc-peerings connect --service=servicenetworking.googleapis.com \
  --ranges=google-managed-services-range --network=app-vpc

Две особенности, о которые спотыкаются. Диапазон нужно выделить заранее и с запасом (/16 — обычный выбор), потому что его расширение потом это отдельная операция. И пиринг не транзитивен: база, подключённая к сети A, не видна из сети B, даже если A и B связаны между собой — это классическая причина «из другого проекта база недоступна».

Private Service Connect. Более современный способ: вы создаёте в своей подсети точку входа к сервису, и она получает адрес из обычной подсети. Гибче (нет отдельного диапазона, нет пиринга, работает через границы сетей и проектов) и настраивается чуть подробнее.

Что выбирают: для простой установки — приватный доступ к сервисам (он проще и его предлагают по умолчанию); для корпоративной установки с общей сетью и несколькими проектами — точки входа, потому что они не упираются в нетранзитивность пиринга.

И третий, отдельный механизм с похожим названием, который стоит не путать: приватный доступ к самим API Google (Private Google Access). Он включается на подсети и позволяет машинам без внешнего адреса обращаться к хранилищу объектов, реестру образов и остальным службам, не выходя в интернет. Это не про базу, а про сервисы платформы, и в закрытой сети его включают всегда — иначе машина без внешнего адреса не сможет даже скачать образ контейнера.

Глубже: соединение сетей и общая сетьрасширенное

Два механизма, без которых не обходится ни одна корпоративная установка.

Пиринг сетей (VPC Network Peering) — прямая связь двух сетей, в том числе в разных проектах и разных организациях. Два ограничения, оба уже упоминались и оба важны: диапазоны адресов не должны пересекаться (это первое, что ломает соединение), и связь не транзитивна — A видит B, B видит C, A не видит C.

Общая сеть (Shared VPC) — то, что стоит почти во всех корпоративных установках GCP, и устроено это иначе, чем пиринг. Сеть создаётся в одном проекте (его называют хост-проектом), а другие проекты (их называют сервисными) пользуются её подсетями напрямую: машина в сервисном проекте получает адрес из подсети хост-проекта.

gcloud compute shared-vpc enable host-project-id
gcloud compute shared-vpc associated-projects add service-project-id \
  --host-project host-project-id

Зачем так делают: сеть, правила фильтрации, маршруты и соединения с офисом ведёт одна команда в одном проекте, а команды продуктов работают в своих проектах, где у них полные права на приложения и никаких прав на сеть. Это разделение и есть главная причина популярности схемы: границы прав совпадают с границами ответственности.

Что это меняет для разработчика: вы создаёте ресурсы в своём проекте, а подсеть указываете чужую (из хост-проекта), и права на её использование выдаёт сетевая команда. Отсюда типичная ошибка первого дня: «не хватает прав на подсеть» — нужна роль пользователя сети в хост-проекте, а не права в своём.

И практический выбор: две-три сети своей команды — пиринг; организация с несколькими командами и общим управлением сетью — общая сеть; и почти всегда оба механизма рядом, потому что к общей сети всё равно приходится подключать сети партнёров и управляемых сервисов.

Глубже: наблюдаемость сети: чем разбирают «не достучались»расширенное

Когда соединение не работает, в GCP есть два журнала и один инструмент проверки.

Журналирование правил фильтрации. Включается на конкретном правиле, и дальше каждое решение (разрешено или запрещено) попадает в журнал с адресами, портами и именем правила. Это прямой ответ на вопрос «какое правило меня отвергло».

gcloud compute firewall-rules update allow-app --enable-logging

Записи о потоках (VPC Flow Logs). Включаются на подсети и пишут сведения о соединениях: кто с кем, сколько пакетов, сколько байт. Отвечают на вопрос «дошёл ли трафик вообще» и полезны для разбора задержек и для подсчёта межзонного трафика (того самого, который стоит денег).

Проверка связности (Connectivity Tests). Инструмент, который не отправляет пакеты: вы указываете источник и получателя, а он проходит по маршрутам, правилам и настройкам и говорит, пройдёт ли трафик и что именно его остановит. Это лучший первый шаг при разборе: минута работы вместо получаса на машине.

Порядок разбора, который закрывает почти все случаи: проверка связности (что говорит платформа) → маршруты (есть ли путь) → правила фильтрации с журналированием (кто отвергает) → разрешение имён (если речь о сервисе по имени) → и только потом настройки приложения.

Оплата у журналов за объём, поэтому на боевой сети записи о потоках включают с частичной выборкой, а журналирование правил — точечно на время разбора.

Коротко

  • VPC глобальна, подсети региональны: связывать сети разных регионов не нужно; подсеть можно расширить на живой сети, но не сузить, а GCP забирает четыре адреса из каждой.
  • Кластеру нужны отдельные диапазоны под поды и службы, адресное пространство планируют один раз на всю компанию.
  • Доступ снаружи определяется внешним IP: его дают только балансировщику и точкам входа, приложения и базы живут с внутренними адресами.
  • Правила файрвола действуют на всю VPC поверх двух подразумеваемых: у правила есть направление, приоритет, где меньшее число сильнее, память состояния и цель по тегам или сервисным аккаунтам; проверки здоровья приходят с адресов Google, и их надо разрешить.
  • Маршрут отвечает «куда пакет пойдёт», правило «пропустят ли»: маршруты к подсетям и по умолчанию создаются сами, закрытая сеть получается удалением маршрута по умолчанию.
  • Cloud NAT выпускает исходящий трафик машин без внешнего адреса, опирается на Cloud Router и заводится на регион и подсети.
  • К сервисам Google ходят через Private Google Access на подсети или Private Service Connect со своим адресом; управляемые базы живут в сети Google и подключаются приватным доступом к сервисам с заранее выделенным диапазоном или точкой входа.
  • Глобальный HTTP(S)-балансировщик даёт один адрес на весь мир; пиринг для двух-трёх сетей своей команды, Shared VPC для организации, где сеть ведёт одна команда.
  • «Не достучались» разбирают проверкой связности, маршрутами, журналом правил и записями о потоках; журналы платные, поэтому потоки пишут с выборкой, а правила логируют на время разбора.

Что почитать дальше