Table of contents
- 주소가 없으면 편지도 없다
- IPv4 — 32비트 주소
- 주소는 “네트워크 부분 + 호스트 부분”으로 나뉜다
- 서브넷 마스크 — 경계선을 긋는 비트
- CIDR — 슬래시 뒤의 숫자 하나
- ”클래스”는 왜 버려졌는가
- 사설 IP와 공인 IP
- NAT — 사설과 공인을 잇는 다리
- IPv6 — 주소 고갈의 해답
- 루프백과 특수 주소
- 리눅스에서 IP 다루기
- 실무에서 서브넷을 설계할 때
주소가 없으면 편지도 없다
집에 우편물을 받으려면 주소가 있어야 한다. 컴퓨터가 네트워크에서 데이터를 주고받으려면 각자의 이름표가 필요하다. 그 이름표가 IP 주소다. 앞선 1편에서 IP는 3계층(Network)에서 동작한다고 했다. 이 계층의 핵심은 “서로 다른 네트워크 사이에서 목적지를 찾아가는 것”이고, IP 주소는 그 출발점이자 목적지가 된다.
IP 주소를 다룰 줄 모르면 서브넷 설계도 못 하고, 방화벽 규칙도 못 쓰고, Kubernetes의 Pod CIDR이나 Service CIDR 같은 설정도 뭐라고 쓰는지 모른다. 이번 편은 그 바닥을 다진다. IPv4의 숫자 뒤에 숨어 있는 비트 연산을 머릿속에 넣는 것이 목표다.
IPv4 — 32비트 주소
IPv4(Internet Protocol version 4)는 1981년 RFC 791로 표준화된 프로토콜이다. 주소를 32비트로 표현한다. 2의 32제곱이니까 약 43억 개다. 얼핏 많아 보이지만, 1981년 설계 당시에는 상상도 못 했던 규모로 인터넷이 커졌고, 지금은 IPv4 주소가 사실상 고갈됐다. 이 이야기는 뒤에서 다시 한다.
32비트를 사람이 읽기 좋게 표현하려고 8비트씩 네 묶음으로 쪼개고, 각 묶음을 10진수로 표기한 다음 점으로 잇는다. 이걸 dotted decimal notation이라고 부른다.
192 . 168 . 1 . 10
11000000.10101000.00000001.00001010
각 묶음을 옥텟(octet)이라고 한다. 한 옥텟은 0~255 범위의 숫자다(2의 8제곱 = 256). 192.168.1.10이라는 주소는 사실 32비트짜리 이진수를 사람 편하라고 적어둔 것뿐이다. 라우터와 스위치 안에서는 전부 비트 단위로 연산된다.
주소는 “네트워크 부분 + 호스트 부분”으로 나뉜다
IP 주소의 진짜 구조는 숫자 그 자체가 아니라 네트워크 부분과 호스트 부분으로 쪼개진다는 데 있다. 우편 주소로 치면 “성남시 분당구”는 네트워크, “각 아파트 동·호수”가 호스트에 해당한다.
flowchart LR
subgraph IP["IP 주소 192.168.1.10"]
NW["네트워크 부분<br/>192.168.1"]
HO["호스트 부분<br/>.10"]
end
같은 네트워크 부분을 가진 호스트들은 같은 LAN(같은 브로드캐스트 도메인)에 속한다. 이들끼리는 라우터를 거치지 않고 스위치만으로 통신할 수 있다. 네트워크 부분이 달라지는 순간, 라우터를 반드시 거쳐야 한다. 이 구분이 서브넷의 전부다.
그런데 “어디까지가 네트워크고 어디부터가 호스트냐”를 누가 알려주는가? 그 경계선을 지정하는 것이 서브넷 마스크다.
서브넷 마스크 — 경계선을 긋는 비트
서브넷 마스크는 IP 주소와 같은 32비트 값인데, 상위 쪽은 1로, 하위 쪽은 0으로 채운다. 1인 비트가 네트워크 부분, 0인 비트가 호스트 부분이다.
IP : 192.168.1.10 → 11000000.10101000.00000001.00001010
마스크: 255.255.255.0 → 11111111.11111111.11111111.00000000
AND : 11000000.10101000.00000001.00000000
= 192.168.1.0 (네트워크 주소)
IP와 마스크를 비트별 AND 연산하면 네트워크 주소가 나온다. 같은 네트워크 주소를 가진 호스트들이 같은 서브넷이다. 반대로 마스크를 뒤집어 AND하면 호스트 번호만 추출할 수 있다.
서브넷 마스크를 매번 255.255.255.0 같은 10진수로 쓰는 건 번거롭다. 그래서 현대 네트워크는 CIDR 표기법을 쓴다.
CIDR — 슬래시 뒤의 숫자 하나
CIDR(Classless Inter-Domain Routing) 표기법은 서브넷 마스크의 1이 몇 개인지를 숫자 하나로 줄여서 쓴다. 192.168.1.0/24라고 쓰면 “상위 24비트가 네트워크 부분”이라는 뜻이다.
| CIDR | 서브넷 마스크 | 호스트 수 |
|---|---|---|
| /8 | 255.0.0.0 | 약 1,677만 |
| /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 (단일 호스트) |
호스트 수는 단순히 2의 (32 - CIDR) 제곱에서 2를 뺀 값이다. 왜 2를 빼는가? 네트워크 주소(호스트 부분이 전부 0)와 브로드캐스트 주소(호스트 부분이 전부 1)는 호스트에 할당할 수 없기 때문이다.
예를 들어 192.168.1.0/24의 경우,
- 네트워크 주소:
192.168.1.0 - 브로드캐스트:
192.168.1.255 - 할당 가능한 호스트:
192.168.1.1~192.168.1.254(254개)
이 계산을 빠르게 할 수 있어야 방화벽 규칙이나 Kubernetes의 podCIDR 설정을 보고 “아 이 범위면 몇 개의 Pod가 뜨는구나”가 머릿속에 그려진다.
”클래스”는 왜 버려졌는가
옛날 IP 주소에는 클래스(Class A, B, C) 개념이 있었다. 주소를 무조건 8비트, 16비트, 24비트 단위로만 쪼개던 시절의 유산이다.
- Class A: 첫 비트 0, 네트워크 8비트 / 호스트 24비트 (
0.0.0.0/8~127.0.0.0/8) - Class B: 첫 두 비트 10, 네트워크 16비트 / 호스트 16비트
- Class C: 첫 세 비트 110, 네트워크 24비트 / 호스트 8비트
문제는 이 세 가지 크기로만 나눠주니까 낭비가 심했다. 중소기업이 Class B를 받으면 6만 5천 개의 IP 중 수백 개만 쓰고 나머지가 놀았다. 1990년대에 인터넷이 폭발적으로 커지면서 주소가 부족해지자, 이 고정된 구분을 폐기하고 CIDR로 마음대로 쪼개 쓰게 했다. 지금도 “Class C 대역”이라는 표현은 관습적으로 남아 있지만, 실무에서는 CIDR로만 생각한다.
사설 IP와 공인 IP
IP 주소는 크게 두 종류로 나뉜다. 공인(Public) IP는 인터넷에서 유일한 주소로, 외부에서 직접 접근할 수 있다. 사설(Private) IP는 집이나 회사 내부망에서만 유효하고, 인터넷에서는 라우팅되지 않는다.
RFC 1918이 사설 대역을 지정해뒀다. 외워두면 평생 쓴다.
| 대역 | CIDR | 주로 쓰는 곳 |
|---|---|---|
| 10.0.0.0/8 | 10.0.0.0 ~ 10.255.255.255 | 대기업 내부망, 클라우드 VPC |
| 172.16.0.0/12 | 172.16.0.0 ~ 172.31.255.255 | 중형 조직, Docker 기본 |
| 192.168.0.0/16 | 192.168.0.0 ~ 192.168.255.255 | 가정용 공유기 |
집 공유기를 열어서 연결된 기기의 IP를 보면 십중팔구 192.168.0.x나 192.168.1.x다. 이 주소는 내 집 안에서만 의미 있고, 외부 세상으로는 공유기의 공인 IP 하나를 통해 나간다. 이 변환이 바로 다음에 나올 NAT다.
NAT — 사설과 공인을 잇는 다리
NAT(Network Address Translation)는 패킷이 사설망과 공인망의 경계를 지날 때 IP 주소(와 포트)를 바꿔치기하는 기술이다. 가장 흔한 형태는 PAT(Port Address Translation), 업계에서는 NAT 오버로딩이라고도 부른다. 여러 내부 호스트가 하나의 공인 IP를 공유하게 만든다.
sequenceDiagram
participant H1 as 노트북<br/>192.168.1.10:54321
participant R as 공유기<br/>사설: 192.168.1.1<br/>공인: 203.0.113.42
participant S as 웹서버<br/>93.184.216.34:443
H1->>R: src=192.168.1.10:54321<br/>dst=93.184.216.34:443
Note over R: NAT 테이블에 기록<br/>내부:54321 ↔ 외부: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: 역방향 매핑 조회
R->>H1: src=93.184.216.34:443<br/>dst=192.168.1.10:54321
NAT가 없었다면 IPv4의 주소 고갈은 이미 수십 년 전에 왔다. NAT 덕분에 가정집 수백만 가구가 각자 공인 IP를 받지 않아도 인터넷을 쓸 수 있다. 동시에 NAT는 방화벽 역할도 한다. 외부에서 공유기 뒤의 사설 IP로 직접 들어오려면 공유기가 포트포워딩을 허락해야만 한다.
단점도 있다. 외부에서 내부 서버로 먼저 연결을 걸기가 어렵다. P2P 통신, VoIP, 게임 서버 같은 곳에서 “NAT 뚫기”라는 골치 아픈 주제가 생기는 이유다. Kubernetes에서 Pod가 외부로 나갈 때도 NAT(혹은 SNAT)가 관여하고, 이게 잘못 설정되면 “내 Pod에서는 외부가 보이는데 외부에서는 Pod가 안 보인다” 같은 현상이 생긴다.
IPv6 — 주소 고갈의 해답
IPv4의 43억 개 주소가 고갈되자 나온 해답이 IPv6다. 주소 공간을 128비트로 확장했다. 2의 128제곱은 사실상 무한한 숫자 — 지구상의 모래알마다 주소를 할당해도 남는다.
IPv6는 16비트씩 여덟 묶음을 16진수로 표기하고, 콜론으로 구분한다.
2001:0db8:85a3:0000:0000:8a2e:0370:7334
# 0으로 시작하는 묶음은 생략할 수 있고, 연속된 0은 '::' 로 축약
2001:db8:85a3::8a2e:370:7334
IPv4와 비교해서 달라진 핵심은 이렇다.
- 주소가 거의 무한: NAT 없이 모든 기기에 공인 주소 할당 가능
- 헤더가 단순: IPv4의 가변 길이 헤더를 고정 40바이트로 단순화. 라우터 처리 속도 향상
- IPsec 기본 내장: IP 계층에서 암호화/인증이 표준
- Stateless Address Autoconfiguration(SLAAC): 호스트가 DHCP 서버 없이도 스스로 주소를 생성
실제 보급은 생각보다 느렸다. 2025년 기준으로도 인터넷 트래픽에서 IPv6 비중은 약 40% 수준이다. IPv4 NAT가 너무 잘 돌아가다 보니 급하지 않고, 새 프로토콜로 넘어가는 데 따르는 비용이 크기 때문이다. 현실의 많은 네트워크는 듀얼 스택(IPv4와 IPv6를 동시에 지원)으로 운영된다.
루프백과 특수 주소
몇 가지 외워둬야 할 특수 주소가 있다.
127.0.0.0/8(루프백): 자기 자신을 가리킨다.127.0.0.1은 “이 컴퓨터”. 네트워크를 안 타고 커널이 바로 처리한다0.0.0.0: “모든 인터페이스”를 의미. 서버가0.0.0.0:8080으로 바인딩하면 이 머신의 모든 IP에서 8080 포트를 연다169.254.0.0/16(Link-local): DHCP 서버를 못 찾았을 때 OS가 임시로 할당하는 주소. 이 주소가 보이면 보통 네트워크가 잘못된 상태255.255.255.255: 로컬 네트워크 브로드캐스트. 같은 LAN의 모든 호스트에 전달
IPv6에는 대응되는 개념이 각각 ::1, ::, fe80::/10 등으로 있다.
리눅스에서 IP 다루기
추상만 이어가면 감이 안 잡히니 명령어로 내려본다. 리눅스에서 IP와 서브넷을 확인하는 핵심 명령은 ip 하나다.
# 인터페이스별 IP와 CIDR 확인
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
# 라우팅 테이블 — 어느 대역이 어디로 가는지
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
ip addr에서 나오는 inet 192.168.1.10/24가 바로 CIDR이다. 뒤의 /24가 이 인터페이스가 속한 서브넷의 크기를 알려준다. ip route의 default via 192.168.1.1은 “라우팅 테이블에 없는 주소는 게이트웨이(192.168.1.1)로 보낸다”는 뜻이다.
서브넷 계산을 직접 해보고 싶으면 ipcalc가 편하다.
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
이 한 번의 실행이 “네트워크 주소, 브로드캐스트, 호스트 범위”를 다 계산해준다. CIDR을 직접 나눠볼 때 계산 실수를 막아주는 도구다.
실무에서 서브넷을 설계할 때
VPC를 새로 파거나 Kubernetes 클러스터를 만들 때 서브넷을 정해야 한다. 몇 가지 경험칙을 정리해둔다.
- 미래를 여유 있게 잡는다:
/24(254개)는 생각보다 빨리 차는 경우가 있다. VPC는/16을 많이 쓴다 - Pod CIDR과 Service CIDR은 절대 겹치지 않게: Kubernetes에서 이 둘이 같은 대역이면 라우팅이 망가진다. 클러스터 간에도 겹치지 않게 설계해야 VPN 연결 시 곤란해지지 않는다
- 사설 대역 중복을 피한다: 여러 회사 VPN을 연결할 때 양쪽이 모두
192.168.1.0/24를 쓰면 NAT 없이는 못 붙는다. 회사 내부망은 가능하면10.x.x.x대역을 쪼개 쓴다 - 가용 영역마다 서브넷을 나눈다: AWS의 경우 AZ별로 서브넷을 따로 두는 게 기본. 하나의 AZ가 죽어도 다른 AZ에서 서비스가 살아 있어야 하기 때문
이런 실수들은 대개 클러스터를 만든 뒤에 발견된다. 그리고 주소 대역은 한번 정하면 바꾸기가 아주 까다롭다. 그래서 처음에 종이에 그려놓고 한 번 더 검토하는 습관이 중요하다.
다음 편에서는 포트와 소켓, 그리고 TCP/UDP의 세계로 들어간다. 왜 TCP는 연결을 맺기 위해 세 번 악수를 해야 하는지, 어떻게 신뢰성을 보장하는지, UDP는 왜 신뢰성을 포기했는지 파고든다.

Loading comments...