Introduction
IP addressing is the foundational design decision every Google Cloud network architect makes before deploying a single VM. Unlike on-premises networks where you can re-IP a subnet over a weekend, a GCP subnet's primary IPv4 range cannot be shrunk and cannot be modified once instances exist inside it — only expanded. Choosing the wrong RFC 1918 block, ignoring Google's reserved ranges, or undersizing a GKE pod range turns into a multi-quarter migration project. For the PCNE exam, expect at least three to five questions that hinge on whether you can recognise which CIDR block is legal in which context, what happens when an alias range overlaps a peer VPC, how IPv6 dual-stack interacts with Cloud NAT, and when a Private Service Access range eats into your usable address space.
A subnet in Google Cloud is a regional resource that owns one primary IPv4 range (used for VM nic0 addresses) and zero or more secondary IPv4 ranges (used for alias IPs and GKE pods/services). A subnet can additionally be IPv6-enabled in internal, external, or dual-stack mode. The maximum primary range is a /8 and the smallest usable is a /29.
RFC 1918 Ranges and Where They Live in GCP
RFC 1918 defines three private IPv4 blocks that the public internet routing tables must not carry: 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16. Google Cloud VPC subnets accept any of the three as primary or secondary ranges, but the choice has architectural consequences for hybrid connectivity.
10.0.0.0/8 — the default for large enterprises
The 10.0.0.0/8 block gives you 16.7 million addresses, which is enough to carve /12 regional aggregates with room for hundreds of subnets each. Google's own auto-mode VPC default subnets pull from 10.128.0.0/9 (regions provisioned after auto-mode launched) and 10.140.0.0/20-style blocks for older regions. If you plan to peer with multiple corporate VPCs or use Network Connectivity Center hubs, reserve a /13 or /14 per region inside 10.0.0.0/8 so that your aggregates remain summarisable on Cloud Router BGP sessions.
172.16.0.0/12 — the safe middle ground
The 172.16.0.0/12 block (1 million addresses) is the least likely to overlap with home-office VPNs and AWS default VPCs (which lean on 172.31.0.0/16). Use it for landing zones that will sit behind a Cloud VPN or Interconnect to an on-prem environment that already burned through 10.0.0.0/8.
192.168.0.0/16 — small environments only
The 192.168.0.0/16 block (65,536 addresses) is fine for greenfield sandbox projects but constrained for any environment that needs GKE clusters with /14 pod ranges. Most home routers also default to 192.168.0.0/24 or 192.168.1.0/24, so using this block guarantees client-VPN headaches.
PCNE explicitly tests overlap. A Cloud VPN tunnel or VPC Peering connection will silently drop traffic to overlapping prefixes — Cloud Router will accept the BGP advertisement but routes for overlapping CIDRs become invalid. Always document your global CIDR plan in a single source of truth before creating the first subnet.
Reserved IPv4 Ranges Google Cloud Does Not Allow
Several IPv4 blocks are reserved by IETF or by Google for internal plumbing. Attempting to use them as subnet primary or secondary ranges either fails at gcloud compute networks subnets create time or causes silent breakage on instances.
169.254.0.0/16 — link-local
The link-local block is used by Google's metadata server (169.254.169.254), by Cloud Router BGP sessions over Cloud VPN and Interconnect (169.254.0.0/16 is the recommended BGP peering range), and by various agent-to-host RPCs on the VM. You cannot assign 169.254.0.0/16 to a subnet primary range, but you can — and must — use /30 slices of it on BGP sessions for HA VPN and Partner Interconnect VLAN attachments.
100.64.0.0/10 — Carrier-Grade NAT (RFC 6598)
This block is reserved for Carrier-Grade NAT and is used internally by GKE for master_ipv4_cidr_block on private clusters and by Cloud SQL for the proxy on shared VPC. Some Google services (notably the IP-masquerade agent on GKE) silently translate traffic when it crosses 100.64.0.0/10. Do not use this block for your own primary subnet ranges — it conflicts with managed-service implementations and you will lose connectivity to internal Google APIs.
Other blocked or special ranges
127.0.0.0/8— loopback, refused at subnet creation224.0.0.0/4— multicast, not routable in GCP VPC (Google Cloud does not support IP multicast on VPC)0.0.0.0/8and255.255.255.255/32— broadcast/this-network, refused35.199.192.0/19— Google-controlled range used for Cloud DNS forwarding and Cloud SQL private connection; subnets cannot collide with it
A common PCNE distractor proposes "use 100.64.0.0/10 for a high-density GKE pod range to avoid eating RFC 1918 space". This will appear to work at cluster creation but conflicts with Google-managed services using the same range and will cause intermittent failures on internal load balancers and Private Google Access. The correct answer is to allocate a dedicated RFC 1918 /14 or use GKE Privately Used Public IPs (PUPI) if RFC 1918 is exhausted.
Primary vs Secondary IP Ranges (Alias IPs)
A subnet owns exactly one primary IPv4 range plus up to 30 secondary IPv4 ranges. The primary range supplies the address that ends up on nic0 (eth0 inside the VM). Secondary ranges supply alias IPs assigned to that same NIC without consuming additional NICs.
Primary range mechanics
The primary range is configured at gcloud compute networks subnets create SUBNET --range=10.10.0.0/20. Each VM in the subnet gets one primary IPv4 address. The range can be expanded (gcloud compute networks subnets expand-ip-range) but never shrunk. Four addresses are reserved by Google per subnet: network address, default gateway (.1), second-to-last (DHCP/control plane), and broadcast. A /29 therefore yields only 4 usable IPs and a /24 yields 252.
Secondary ranges and alias IP assignment
Secondary ranges are created with --secondary-range RANGE_NAME=CIDR. They never appear on the VM's IP routing table directly — instead, when you create a VM you assign one or more alias IP blocks via --aliases RANGE_NAME:/24 or --aliases /28. The address is then NATed by the host hypervisor onto the VM's primary NIC. From the VM's perspective the OS only sees nic0's primary address; from VPC's perspective the VM owns the entire alias block.
GKE pods and services consumption
A GKE cluster in VPC-native (alias IP) mode requires two secondary ranges on the cluster's subnet: one for pods (default /14 = 262,144 addresses) and one for services (default /20 = 4,096 addresses). Each node gets a /24 slice carved out of the pod range, so a /14 supports up to 1,024 nodes at 110 pods/node. PCNE loves to test the math: if the exam says "the customer plans 200 nodes, 30 pods per node, plus 1,000 ClusterIP services", you need a pod range of at least /19 (8,192 addresses, accounting for /24-per-node slicing) and a service range of at least /22.
GKE alias IP defaults: pod range = /14, service range = /20, node CIDR slice = /24. To right-size, multiply max-nodes × node-CIDR-size, then round up. A /16 pod range only supports 256 nodes at the default /24 slice — too small for many production clusters.
External IP Addresses: Ephemeral vs Static, Regional vs Global
External IPs are public IPv4 addresses that route from the Internet to a Google Cloud resource. They come in two lifecycles and two scopes.
Ephemeral external IPs
Assigned at resource creation with --address ephemeral (or by omitting the flag for VMs). Released when the resource is stopped or deleted. Ephemeral IPs cost nothing while attached but offer no SLA on persistence — Google can return a different IP after every restart. Use them for short-lived dev VMs and stateless backends that sit behind a load balancer.
Static external IPs
Reserved with gcloud compute addresses create NAME --region=REGION (regional, for VM NICs and regional LBs) or --global (global, for global LBs and Anycast). A reserved static IP costs $0.004/hour (~$2.92/month) while unused and is free while attached to a running resource. The free-while-attached rule is critical: a static IP attached to a stopped VM is billed.
Global vs regional static IPs
- Regional static IPs anchor regional resources: VM external IPs, Cloud NAT gateways (one or more static IPs per region per NAT), regional external Application Load Balancers, regional external proxy Network Load Balancers.
- Global static IPs anchor global resources: global external Application Load Balancers, global external proxy Network LBs, and the Premium-Tier-only global Anycast IPs that ride Google's backbone.
BYOIP (Bring Your Own IP)
You can import publicly routable IPv4 (and IPv6) prefixes you already own into Google Cloud. The minimum is /24 for IPv4 and /48 for IPv6. Google handles BGP advertisement; you keep your IP reputation, your allowlist entries, and your RDAP record. BYOIP prefixes are first provisioned (gcloud compute public-advertised-prefixes create), then carved into delegated prefixes, then public-delegated-prefixes-sub-prefixes that anchor specific resources.
Reserved Static External vs Reserved Internal
Reserving an internal IP is a different SKU and lifecycle from reserving an external IP.
Reserving an internal static address
gcloud compute addresses create NAME --subnet=SUBNET --addresses=10.10.0.50 --region=REGION carves a single internal IP out of the subnet's primary range and marks it RESERVED. The address is free. Use this for the front-end of an internal load balancer, the static address of a database VM, or a service mesh egress gateway. Reserved internal addresses prevent the auto-allocator from handing the same IP to another VM in the future.
Reserving an external static address
gcloud compute addresses create NAME --region=REGION (no --subnet) reserves a public IP. The IP is billed when unused at $0.004/hour. Always tear down unused external reservations or pin them to a load balancer to avoid surprise bills.
Use gcloud compute addresses list --filter="status:RESERVED AND addressType:EXTERNAL" weekly in cost-optimised environments to surface orphaned external IPs. A single forgotten /32 from a deleted dev LB costs $35/year, and a fleet of 50 across an org is $1,750/year of pure waste.
IPv4 vs IPv6 Dual-Stack
Google Cloud VPC supports IPv6 in three modes per subnet: IPv4-only (default), IPv6-only (limited preview at exam time), and dual-stack (the production-recommended IPv6 path).
Enabling dual-stack
gcloud compute networks subnets update SUBNET --stack-type=IPV4_IPV6 --ipv6-access-type=EXTERNAL (or INTERNAL for ULA). Google allocates a /64 IPv6 range per subnet from its own pool (you cannot bring your own IPv6 to internal subnets, but BYOIP is supported for external /48s). Each VM with a dual-stack NIC gets one IPv6 /96 from the subnet's /64.
External vs internal IPv6
- External IPv6 uses globally routable GUA addresses Google advertises. Traffic egresses through Cloud NAT64 or directly via the VM's
/96. - Internal IPv6 uses ULA addresses from
fd20::/20. They are private to your VPC and peer VPCs and never advertised to the internet.
Cloud NAT64 and IPv6-only backends
A dual-stack subnet allows IPv6-only frontends (mobile carrier networks, T-Mobile, Comcast IPv6) to reach IPv4 backends via Cloud NAT64. Configure the global external Application LB with an IPv6 VIP; the LB synthesises IPv4 backend requests automatically. For internal traffic, dual-stack subnets let GKE pods speak both protocols when ipv6Access = INTERNAL and the cluster is in IPv6-enabled mode.
Private Service Access (PSA) Ranges
Google managed services (Cloud SQL, Memorystore, Filestore, AlloyDB, Dataproc Metastore) connect to your VPC through Private Services Access, which requires you to allocate a dedicated CIDR block for the service provider.
Allocating a PSA range
gcloud compute addresses create google-managed-services-RANGE --global --purpose=VPC_PEERING --addresses=10.200.0.0 --prefix-length=20 --network=VPC reserves a /20 for Google to peer their services VPC into yours. Then gcloud services vpc-peerings connect --service=servicenetworking.googleapis.com --ranges=google-managed-services-RANGE establishes the peering.
Sizing PSA ranges
A /24 PSA range supports ~250 instances of all PSA-backed services combined. A /20 supports ~4,000 and is the recommended default for production landing zones. PSA ranges cannot overlap with any subnet range, secondary range, or peer-VPC range — they are carved from your global CIDR plan.
Why PSA range exhaustion is silent
When the PSA range is full, new Cloud SQL instances fail at creation with an opaque error. Memorystore for Redis instances simply remain in CREATING state for 30 minutes before timing out. Always provision PSA ranges large enough for 5× current need, and monitor consumption with gcloud services vpc-peerings list --network=VPC.
PSA ranges are per-VPC, not per-project. If you use Shared VPC, the PSA allocation lives in the host project and every service project consumes from the same pool. A noisy data-science project that spins up 200 Memorystore instances can exhaust the shared PSA range and break production Cloud SQL creation.
Link-Local Addresses and Cloud Router BGP
Cloud Router establishes BGP sessions to peer routers over Cloud VPN tunnels and Interconnect VLAN attachments. Those sessions ride link-local /30 or /29 slices of 169.254.0.0/16.
Recommended BGP peering CIDR scheme
Google recommends carving 169.254.0.0/16 into per-tunnel /30 blocks. For HA VPN, you get two tunnels, so allocate 169.254.0.0/30 for tunnel 0 (Cloud Router .1, peer .2) and 169.254.0.4/30 for tunnel 1. For Partner Interconnect with four VLAN attachments, allocate four /30 blocks contiguously.
Why link-local matters for the exam
PCNE asks "which IP range can be used for the BGP peering address between Cloud Router and an on-prem ASR1000?" — the answer is always inside 169.254.0.0/16. The only exception is when on-prem already uses a private ASN with public-IP peering, which is uncommon. You also cannot use 169.254.0.0/16 for VM addresses or for any subnet range.
Avoiding overlap on multiple Cloud Routers
If a single VPC hosts ten Cloud VPN tunnels and four Partner Interconnect VLAN attachments, each needs its own non-overlapping /30 slice of 169.254.0.0/16. A simple convention is to allocate 169.254.0.0/24 to HA VPN (64 /30s, enough for 32 tunnel pairs) and 169.254.1.0/24 to Interconnect VLAN attachments. The metadata server lives at 169.254.169.254/32 and is never reachable from BGP, so peering ranges can safely sit anywhere except that single address.
Cloud Router's own internal addressing
Cloud Router itself does not consume an address from your subnet — it sits in Google's control plane. It only consumes the /30 link-local for BGP and advertises your subnet ranges out to the peer. This is why creating a Cloud Router is free and only the underlying Cloud VPN tunnels or VLAN attachments incur cost.
CIDR Planning for Hybrid Networks
A production landing zone connecting multiple VPCs, an on-prem data centre, and a few SaaS partners needs a deliberate global CIDR plan. Mistakes here are the most expensive to fix because every subnet, every peering, every Interconnect, and every Cloud SQL instance is locked in.
Top-down aggregation strategy
- Reserve a
/8or/9aggregate (e.g.10.0.0.0/9) for all of Google Cloud. - Allocate a
/12per region (e.g.10.0.0.0/12forus-central1,10.16.0.0/12foreurope-west1). - Inside each
/12, allocate a/16per environment (prod / staging / dev) and a/16for GKE pods. - Inside each
/16, allocate/20or/22subnets per tier (web / app / data).
Avoiding overlaps with on-prem
List every on-prem CIDR before you start. Walk it against the GCP plan and reject any overlap. If on-prem uses 10.0.0.0/8 densely, push GCP into 172.16.0.0/12 or a non-overlapping /12 slice of 10.0.0.0/8.
Plan for GKE early
GKE pod ranges are the single biggest consumer of address space. Reserve a dedicated /12 or /13 per region purely for pods so that subnet expansion later does not require renumbering nodes.
Document and version-control the plan
Store the CIDR plan in a Terraform module or a YAML in a shared repo. Every new subnet PR must reference the plan. This avoids the all-too-common scenario of two teams allocating overlapping /20s on the same shared VPC.
Hybrid summarisation on Cloud Router
Cloud Router supports custom route advertisements with summarisation: gcloud compute routers update-bgp-peer PEER --advertisement-mode=CUSTOM --set-advertisement-ranges=10.0.0.0/12. Advertising a single summary /12 to on-prem instead of fifty individual /20 subnets keeps your on-prem core router's RIB small and avoids hitting the 1000-route limit Google enforces per BGP session on Cloud Router. Cloud Router itself can receive up to 100 routes from a peer by default (raisable to 1000), so reciprocate the favour by asking on-prem to summarise too. Document the summarised aggregates next to the CIDR plan so future engineers do not advertise a more-specific /20 and accidentally pull traffic out of the wrong region.
Multi-region failover considerations
When designing for DR across us-central1 and us-east1, keep each region's aggregate non-overlapping but summarisable from a single parent. If us-central1 owns 10.0.0.0/12 and us-east1 owns 10.16.0.0/12, both fit inside 10.0.0.0/11 — a single static route on a partner appliance reaches either region. This pattern also lets Cloud DNS routing policies fail over without re-advertising prefixes.
IPv6 in the global plan
Even if today's workload is IPv4-only, reserve a /48 BYOIP block now if you have one available, and enable --stack-type=IPV4_IPV6 on at least one subnet per region for future-proofing. Adding IPv6 to an existing subnet requires no VM downtime, but adopting BYOIPv6 after services are running requires re-anchoring every external resource — much more painful than allocating once upfront.
白話文解釋(Plain English Explanation)
Apartment Complex Analogy — Internal vs External IPs
Picture a large apartment complex with thousands of units. Your internal IP is your apartment number (Unit 402): everyone inside the building uses it to find you, the post office sorts mail by it, but the outside world cannot dial it directly. The complex's front-desk phone number is the external IP: callers from anywhere in the world dial that single number, and the receptionist (Google's Cloud NAT or 1-to-1 forwarding rule) routes the call to your unit. A static external IP is a phone number you pay to keep listed in the directory even when no one is home; an ephemeral external IP is a temporary number the building assigns each time someone moves in and reclaims when they move out.
City Planning Analogy — CIDR Ranges and Aggregation
Designing CIDR for GCP is like zoning a new city. You first declare the city limits (your /8 global aggregate), then districts (regional /12s), then neighbourhoods (subnet /20s), then individual lots (VMs). If two districts overlap on a map, mail-sorting machines get confused and packages disappear — that is exactly what Cloud Router does when two peer VPCs advertise overlapping prefixes. The GKE pod range is a sprawling suburb that always grows faster than you planned: zone it big from day one or you will be bulldozing houses to add streets later. PSA ranges are like the city's industrial park reserved for utility companies (Google managed services) — fence it off early so residential zoning never encroaches on it.
Office Building Phone System — Alias IPs and Secondary Ranges
A VM with an alias IP range is like a single office desk with one main phone line plus a bank of extension numbers the company can hand out without buying more desks. Each extension (alias IP) rings on the same physical phone (the VM's nic0), but callers see distinct numbers. GKE uses this to give every container its own routable address while still running on one VM. The secondary range on the subnet is the block of extension numbers the office building reserved upfront — if you allocated only 100 extensions and your business grows to 1,000 employees, you have to renumber the whole company. That is why right-sizing the pod range matters so much.
FAQs
Can I change a VM's internal IP without recreating it?
No. The primary internal IP is bound to the VM at creation. You can add or remove alias IPs at any time via gcloud compute instances network-interfaces update, but the primary IP requires deleting and recreating the instance (or detaching and reattaching nic0, which is effectively the same thing).
Do I pay for reserved internal IPs?
No. Reserved internal static addresses are free regardless of whether they are attached. Only reserved external addresses are billed when unattached, at $0.004/hour (~$2.92/month per IP).
Can I use 100.64.0.0/10 for my own subnet?
Technically the API will let you create a subnet there, but you will conflict with GKE private cluster master CIDRs, Cloud SQL proxy ranges, and the IP-masquerade agent. Treat 100.64.0.0/10 as reserved for Google-managed services and use RFC 1918 or BYOIP-PUPI instead.
What is the smallest subnet I can create in GCP?
/29 (8 addresses, 4 usable after Google reserves network/gateway/DHCP/broadcast). For IPv6 the subnet is fixed at /64. The largest primary IPv4 range is /8, but practical limits start hurting at /20 for the API response size.
How do I bring an existing on-prem IPv4 range into Google Cloud (BYOIP)?
Open a support case to validate ownership via RPKI or a Letter of Authorization, then gcloud compute public-advertised-prefixes create the parent block (minimum /24), carve public-delegated-prefixes, and attach to resources. Google begins BGP advertising the prefix within 24 hours. The minimum advertisable block is /24 for IPv4 and /48 for IPv6.
Why does my Cloud SQL instance fail to create with "no available IP"?
The PSA range allocated to servicenetworking.googleapis.com is exhausted. Run gcloud services vpc-peerings list --network=VPC to see the current allocation, then expand the PSA range with gcloud compute addresses update and gcloud services vpc-peerings update --force. Cloud SQL creation will succeed on the next retry.