Table of contents
- No Address, No Mail
- IPv4 — 32-Bit Addresses
- An Address Is Split Into “Network Part + Host Part”
- Subnet Mask — Drawing the Boundary with Bits
- CIDR — A Single Number After the Slash
- Why “Classes” Were Abandoned
- Private IP vs. Public IP
- NAT — The Bridge Between Private and Public
- IPv6 — The Answer to Address Exhaustion
- Loopback and Special Addresses
- Working with IP on Linux
- Designing Subnets in Practice
No Address, No Mail
You need an address to receive mail at home. For a computer to send and receive data on a network, each one needs its own label. That label is the IP address. In Part 1, we said IP operates at Layer 3 (Network). The core job of this layer is “finding the destination across different networks,” and the IP address serves as both the origin and the destination.
If you can’t work with IP addresses, you can’t design subnets, write firewall rules, or make sense of settings like Kubernetes’ Pod CIDR or Service CIDR. This post lays that foundation. The goal is to internalize the bit-level arithmetic hidden behind IPv4’s numbers.
IPv4 — 32-Bit Addresses
IPv4 (Internet Protocol version 4) is a protocol standardized as RFC 791 in 1981. It represents addresses in 32 bits. That’s 2 to the 32nd power — roughly 4.3 billion. It might seem like a lot, but the internet grew to a scale unimaginable in 1981, and IPv4 addresses are now effectively exhausted. We’ll revisit this later.
To make 32 bits human-readable, they’re split into four groups of 8 bits, each group expressed in decimal and joined with dots. This is called dotted decimal notation.
192 . 168 . 1 . 10
11000000.10101000.00000001.00001010
Each group is called an octet. A single octet ranges from 0 to 255 (2 to the 8th = 256). The address 192.168.1.10 is really just a 32-bit binary number written for human convenience. Inside routers and switches, everything is computed at the bit level.
An Address Is Split Into “Network Part + Host Part”
The real structure of an IP address lies in the fact that it’s divided into a network part and a host part. In postal terms, “Bundang-gu, Seongnam-si” is the network, and “each apartment unit number” is the host.
flowchart LR
subgraph IP["IP Address 192.168.1.10"]
NW["Network part<br/>192.168.1"]
HO["Host part<br/>.10"]
end
Hosts sharing the same network part belong to the same LAN (the same broadcast domain). They can communicate through switches alone, without passing through a router. The moment the network part differs, a router must be involved. This distinction is the entirety of subnetting.
But who tells us “where does the network end and the host begin?” The boundary is specified by the subnet mask.
Subnet Mask — Drawing the Boundary with Bits
A subnet mask is a 32-bit value just like an IP address, with the upper bits set to 1 and the lower bits set to 0. The 1-bits represent the network part, and the 0-bits represent the host part.
IP : 192.168.1.10 → 11000000.10101000.00000001.00001010
Mask : 255.255.255.0 → 11111111.11111111.11111111.00000000
AND : 11000000.10101000.00000001.00000000
= 192.168.1.0 (network address)
Performing a bitwise AND of the IP and the mask yields the network address. Hosts sharing the same network address are in the same subnet. Conversely, inverting the mask and ANDing extracts just the host number.
Writing the subnet mask as 255.255.255.0 every time is cumbersome. That’s why modern networking uses CIDR notation.
CIDR — A Single Number After the Slash
CIDR (Classless Inter-Domain Routing) notation condenses the subnet mask into a single number: the count of 1-bits. Writing 192.168.1.0/24 means “the upper 24 bits are the network part.”
| CIDR | Subnet Mask | Host Count |
|---|---|---|
| /8 | 255.0.0.0 | ~16.77 million |
| /16 | 255.255.0.0 | 65,534 |
| /24 | 255.255.255.0 | 254 |
| /25 | 255.255.255.128 | 126 |
| /26 | 255.255.255.192 | 62 |
| /28 | 255.255.255.240 | 14 |
| /30 | 255.255.255.252 | 2 |
| /32 | 255.255.255.255 | 1 (single host) |
The host count is simply 2 to the power of (32 - CIDR) minus 2. Why subtract 2? Because the network address (host part all 0s) and the broadcast address (host part all 1s) cannot be assigned to hosts.
For example, with 192.168.1.0/24:
- Network address:
192.168.1.0 - Broadcast:
192.168.1.255 - Assignable hosts:
192.168.1.1~192.168.1.254(254 addresses)
Being able to do this calculation quickly means that when you see a podCIDR setting in Kubernetes, you can mentally picture “this range fits X number of Pods.”
Why “Classes” Were Abandoned
In the old days, IP addresses had a class (Class A, B, C) concept. This was a relic from when addresses were divided only at fixed 8-bit, 16-bit, or 24-bit boundaries.
- Class A: First bit 0, network 8 bits / host 24 bits (
0.0.0.0/8~127.0.0.0/8) - Class B: First two bits 10, network 16 bits / host 16 bits
- Class C: First three bits 110, network 24 bits / host 8 bits
The problem was that having only these three sizes caused massive waste. When a mid-sized company received a Class B, they’d use only a few hundred of the 65,000+ IPs while the rest sat idle. As the internet exploded in the 1990s and addresses ran short, this rigid classification was abandoned in favor of CIDR, which allows addresses to be divided freely. You’ll still hear the expression “Class C range” out of habit, but in practice everyone thinks in CIDR.
Private IP vs. Public IP
IP addresses fall into two broad categories. Public IPs are unique addresses on the internet, directly reachable from the outside. Private IPs are valid only within internal networks like homes or offices and are not routed on the internet.
RFC 1918 defines the private ranges. Memorize them once and you’ll use them for life.
| Range | CIDR | Common Use |
|---|---|---|
| 10.0.0.0/8 | 10.0.0.0 ~ 10.255.255.255 | Enterprise internal networks, cloud VPCs |
| 172.16.0.0/12 | 172.16.0.0 ~ 172.31.255.255 | Mid-sized organizations, Docker default |
| 192.168.0.0/16 | 192.168.0.0 ~ 192.168.255.255 | Home routers |
Open your home router settings and check the IPs of connected devices — nine times out of ten they’ll be 192.168.0.x or 192.168.1.x. These addresses are meaningful only inside your home, and traffic to the outside world goes through a single public IP on the router. This translation is the NAT we’ll cover next.
NAT — The Bridge Between Private and Public
NAT (Network Address Translation) is a technique that rewrites IP addresses (and ports) as packets cross the boundary between private and public networks. The most common form is PAT (Port Address Translation), also known as NAT overloading in the industry. It allows multiple internal hosts to share a single public IP.
sequenceDiagram
participant H1 as Laptop<br/>192.168.1.10:54321
participant R as Router<br/>Private: 192.168.1.1<br/>Public: 203.0.113.42
participant S as Web Server<br/>93.184.216.34:443
H1->>R: src=192.168.1.10:54321<br/>dst=93.184.216.34:443
Note over R: Record in NAT table<br/>Internal:54321 ↔ External:61001
R->>S: src=203.0.113.42:61001<br/>dst=93.184.216.34:443
S->>R: src=93.184.216.34:443<br/>dst=203.0.113.42:61001
Note over R: Reverse mapping lookup
R->>H1: src=93.184.216.34:443<br/>dst=192.168.1.10:54321
Without NAT, IPv4 address exhaustion would have arrived decades ago. Thanks to NAT, millions of households can use the internet without each needing a public IP. At the same time, NAT acts as a firewall. For an external party to reach a private IP behind the router, the router must explicitly allow port forwarding.
There are downsides too. It’s difficult for external parties to initiate connections to internal servers. This is why the headache of “NAT traversal” arises in areas like P2P communication, VoIP, and game servers. In Kubernetes, when a Pod communicates outbound, NAT (or SNAT) is involved, and misconfiguration leads to situations like “my Pod can see the outside, but the outside can’t see my Pod.”
IPv6 — The Answer to Address Exhaustion
The answer to IPv4’s 4.3 billion address exhaustion is IPv6. It expands the address space to 128 bits. 2 to the 128th is a virtually infinite number — enough to assign an address to every grain of sand on Earth with plenty to spare.
IPv6 is written as eight groups of 16 bits each in hexadecimal, separated by colons.
2001:0db8:85a3:0000:0000:8a2e:0370:7334
# Leading zeros in groups can be omitted, and consecutive zero groups can be shortened to '::'
2001:db8:85a3::8a2e:370:7334
The key differences from IPv4 are:
- Nearly infinite addresses: Every device can get a public address without NAT
- Simplified header: IPv4’s variable-length header was simplified to a fixed 40 bytes, improving router processing speed
- Built-in IPsec: Encryption/authentication is standard at the IP layer
- Stateless Address Autoconfiguration (SLAAC): Hosts can generate their own addresses without a DHCP server
Actual adoption has been slower than expected. As of 2025, IPv6 accounts for roughly 40% of internet traffic. IPv4 NAT works so well that there’s no urgency, and the cost of migrating to the new protocol is high. Many real-world networks run dual stack (supporting both IPv4 and IPv6 simultaneously).
Loopback and Special Addresses
There are a few special addresses worth memorizing.
127.0.0.0/8(loopback): Refers to the machine itself.127.0.0.1means “this computer.” It doesn’t hit the network — the kernel handles it directly0.0.0.0: Means “all interfaces.” When a server binds to0.0.0.0:8080, it opens port 8080 on every IP of the machine169.254.0.0/16(link-local): An address the OS temporarily assigns when it can’t find a DHCP server. Seeing this address usually means the network is misconfigured255.255.255.255: Local network broadcast. Delivered to all hosts on the same LAN
IPv6 has corresponding concepts: ::1, ::, fe80::/10, etc.
Working with IP on Linux
Sticking with abstractions won’t build intuition, so let’s get into commands. The essential command for checking IP and subnets on Linux is ip.
# Check IP and CIDR per interface
ip addr show
# 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
# inet 192.168.1.10/24 brd 192.168.1.255 scope global eth0
# Routing table — which range goes where
ip route show
# default via 192.168.1.1 dev eth0
# 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.10
The inet 192.168.1.10/24 from ip addr is CIDR notation. The /24 at the end tells you the size of the subnet this interface belongs to. The default via 192.168.1.1 in ip route means “send any address not in the routing table to the gateway (192.168.1.1).”
If you want to try subnet calculations yourself, ipcalc is handy.
ipcalc 192.168.1.0/26
# Network: 192.168.1.0/26
# Netmask: 255.255.255.192 = 26
# Broadcast: 192.168.1.63
# HostMin: 192.168.1.1
# HostMax: 192.168.1.62
# Hosts/Net: 62
A single run calculates the network address, broadcast, and host range. It’s a tool that prevents calculation mistakes when manually dividing CIDRs.
Designing Subnets in Practice
When creating a new VPC or setting up a Kubernetes cluster, you need to decide on subnets. Here are some rules of thumb.
- Leave generous room for the future: A
/24(254 addresses) fills up faster than you’d think. VPCs commonly use/16 - Never overlap Pod CIDR and Service CIDR: If these two share the same range in Kubernetes, routing breaks. They should also not overlap across clusters, or VPN connections will cause headaches
- Avoid private range collisions: When connecting multiple company VPNs, if both sides use
192.168.1.0/24, they can’t talk without NAT. Internal networks should preferably carve out ranges from10.x.x.x - Separate subnets by availability zone: In AWS, having separate subnets per AZ is standard practice — so that if one AZ goes down, the service survives in another
These mistakes are usually discovered after the cluster has been created. And address ranges are extremely difficult to change once set. That’s why it’s important to sketch things out on paper and review once more before committing.
In the next post, we enter the world of ports, sockets, TCP, and UDP. We’ll explore why TCP needs to shake hands three times to establish a connection, how it guarantees reliability, and why UDP chose to give up reliability.

Loading comments...