A /8 has the netmask 255.0.0.0 and holds 16,777,216 addresses, 16,777,214 of them usable hosts once the network and broadcast addresses are taken out. Only the first octet is fixed. Before CIDR (RFC 4632) this was a class A network, and the one most people meet is 10.0.0.0/8, the largest of the three private ranges in RFC 1918.
The numbers
Network 10.0.0.0/8
Broadcast 10.255.255.255
Netmask 255.0.0.0
Wildcard 0.255.255.255
First host 10.0.0.1
Last host 10.255.255.254
Kind Private (RFC 1918)
How it fits
A /8 is 1/256 of the whole IPv4 space. It splits into 2 /9s, 16 /12s, 256 /16s or 65,536 /24s. The tool below splits it into /16s, from 10.0.0.0/16 to 10.255.0.0/16.
Where you’ll see it
Nobody puts 16 million hosts on one network, so a /8 is an address plan, not a subnet. A common plan hands out /16s, one per VPC, region or site. That suits AWS, where a VPC’s CIDR runs from /16 down to /28: 10.0.0.0/8 holds 256 VPCs of the largest size.
Platforms draw from it too. kubeadm’s default service range is 10.96.0.0/12, so the cluster’s API service sits at 10.96.0.1, inside 10/8. Docker Swarm’s default pool for overlay networks is 10.0.0.0/8, cut into /24s. The other /8 everyone has is 127.0.0.0/8: all of it is loopback.
Gotchas
- Everyone starts at 10.0. VPC wizards and Terraform examples reach for
10.0.0.0/16first. VPC peering refuses overlapping CIDRs, and a route table can’t point the same range at two different networks, so give each account, environment and region its own /16 before they need to connect. 10.0.0.0/8in a firewall rule is broad. It admits every peered VPC, VPN client and container network that lives in 10/8, not just your subnet. Scope rules to the /16 or /24 you mean.- AWS won’t take it whole. A /8 is too large for a VPC. Create a /16 and add secondary CIDR blocks when it runs low.
- Swarm and the office. If the corporate network already uses parts of 10/8, overlay networks from Swarm’s default pool can land on the same addresses. Set
--default-addr-poolondocker swarm initto a range nothing else uses.
In your stack
# Terraform: the /16 for environment 20, or the first three in a row
cidrsubnet("10.0.0.0/8", 8, 20) # "10.20.0.0/16"
cidrsubnets("10.0.0.0/8", 8, 8, 8) # ["10.0.0.0/16", "10.1.0.0/16", "10.2.0.0/16"]
import ipaddress
plan = ipaddress.ip_network("10.0.0.0/8")
plan.num_addresses # 16777216
ipaddress.ip_address("10.96.0.1") in plan # True
nft add rule inet filter input ip saddr 10.0.0.0/8 tcp dport 5432 accept