Сеть в GCP — это не «галочки где-то в консоли», а то, что определяет главный вопрос: кто до кого может достучаться. От неё зависит и безопасность (не смотрит ли база наружу?), и работоспособность (видит ли приложение базу?). Хорошая новость: вся модель собирается из нескольких понятных кирпичиков. Если базовые понятия облака ещё не на руках, начните с основ GCP.
Три пути и три узла: снаружи пускает только глобальный балансировщик, наружу выпускает 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 для организации, где сеть ведёт одна команда.
- «Не достучались» разбирают проверкой связности, маршрутами, журналом правил и записями о потоках; журналы платные, поэтому потоки пишут с выборкой, а правила логируют на время разбора.
Что почитать дальше
- Cloud IAM — кто что может делать поверх «кто до кого дойдёт».
- Где запускать сервис — где живут сервисы в этой сети.
- Управляемые данные в GCP — как приватно подключают Cloud SQL.
- Сеть в облаке — та же модель без привязки к провайдеру.