회사 업무를 하다 보면 서브넷 마스크를 종종 접하게 됩니다. AWS VPC 설정에서 10.0.0.0/16, Docker 네트워크에서 172.17.0.0/16, 사내 서버 접속 시 192.168.1.0/24 같은 표기를 자주 보셨을 겁니다.
그런데 정작 왜 /24인지, /16과 뭐가 다른지는 잘 모르는 경우가 많습니다. "그냥 인프라팀에서 준 대로 쓰면 되지"라고 생각할 수도 있지만, 서브넷을 이해하고 있으면 IP 대역 부족, 네트워크 간 통신 불가 같은 이슈가 생겼을 때 문제를 빨리 인지하고 인프라팀과 원활하게 커뮤니케이션할 수 있습니다.
이 글에서는 서브넷 마스크가 무엇이고, 왜 필요하며, 어떻게 동작하는지를 정리해 보겠습니다.
먼저 IP 주소(IPv4)의 구조를 이해해야 합니다.
192 . 168 . 1 . 100
│ │ │ │
8bit 8bit 8bit 8bit = 총 32bit
IP 주소는 32bit로 구성되며, 이 32bit는 네트워크 부분과 호스트 부분으로 나뉩니다.
네트워크 주소: "어느 네트워크에 속해 있는가"를 나타냅니다. 같은 네트워크에 있는 장치들끼리는 라우터 없이 직접 통신이 가능합니다.
호스트 주소: "그 네트워크 안에서 어떤 장치인가"를 나타냅니다. 동일 네트워크 내에서 고유해야 합니다.
아파트 주소에 비유하면 이렇습니다:
서울시 강남구 테헤란로 123번지 / 456호
──────────────────────── ────
네트워크 주소 호스트 주소
(어느 건물인가?) (건물 내 어느 집인가?)
서브넷 마스크는 32bit IP 주소에서 네트워크와 호스트의 경계를 결정합니다.
IP 주소: 192.168.1.100
서브넷 마스크: 255.255.255.0
─────────── ─
네트워크부분 호스트부분
"서브넷 마스크"라는 명칭은 컴퓨팅의 비트 마스크(Bit Mask) 개념에서 유래했습니다. 마스크는 특정 비트를 선택적으로 추출하거나 가리는 용도로 사용됩니다. 마치 가면(mask)처럼 일부를 가리고 일부만 보이게 하는 것이죠.
원본 데이터: 10110101
마스크: 11110000
결과물: 10110000
────
마스크가 1인 부분만 "통과"
마스크가 0인 부분은 "차단"
서브넷 마스크도 동일한 원리입니다. 마스크가 IP 주소에서 네트워크 부분만 드러나게 하고, 호스트 부분은 가려버립니다.
IP 주소: 11000000.10101000.00000001.01100100
서브넷 마스크: 11111111.11111111.11111111.00000000
────────────────────────── ────────
1 = 네트워크 비트 통과 0 = 호스트 비트 차단
서브넷 마스크를 2진수로 변환하면 그 원리가 명확해집니다:
255.255.255.0
↓
11111111.11111111.11111111.00000000
────────────────────────── ────────
1 = 네트워크 0 = 호스트
| 비트 값 | 의미 |
|---|---|
| 1 | 네트워크 주소로 사용 |
| 0 | 호스트 주소로 사용 |
IP 주소와 서브넷 마스크를 비트 AND 연산하면 네트워크 주소를 구할 수 있습니다.
IP: 192.168.1.100
Mask: 255.255.255.0
──────────────────────
2진수 변환:
IP: 11000000.10101000.00000001.01100100
Mask: 11111111.11111111.11111111.00000000
─────────────────────────────────────
AND: 11000000.10101000.00000001.00000000
결과: 192.168.1.0 ← 네트워크 주소
AND 연산: 두 비트가 모두 1일 때만 1, 그 외에는 0
- 마스크가 1인 곳: IP 값 그대로 유지
- 마스크가 0인 곳: 무조건 0으로 변환
이 방식으로 두 IP가 같은 네트워크에 있는지 판단할 수 있습니다:
PC-A: 192.168.1.10 AND 255.255.255.0 = 192.168.1.0
PC-B: 192.168.1.20 AND 255.255.255.0 = 192.168.1.0
─────────────
같음 → 직접 통신 가능
PC-C: 192.168.2.10 AND 255.255.255.0 = 192.168.2.0
─────────────
다름 → 라우터 필요
255.255.255.0 같은 표기는 길고 불편합니다. 그래서 CIDR(Classless Inter-Domain Routing) 표기법을 사용합니다.
192.168.1.0/24
──
네트워크 비트 수 (1의 개수)
| CIDR | 서브넷 마스크 | 1의 개수 | 호스트 비트 | 사용 가능 호스트 |
|---|---|---|---|---|
| /8 | 255.0.0.0 | 8 | 24 | 16,777,214 |
| /16 | 255.255.0.0 | 16 | 16 | 65,534 |
| /24 | 255.255.255.0 | 24 | 8 | 254 |
| /25 | 255.255.255.128 | 25 | 7 | 126 |
| /26 | 255.255.255.192 | 26 | 6 | 62 |
| /27 | 255.255.255.224 | 27 | 5 | 30 |
| /28 | 255.255.255.240 | 28 | 4 | 14 |
호스트 수 계산 공식:
2^(32-CIDR) - 2-2를 하는 이유: 네트워크 주소와 브로드캐스트 주소는 장치에 할당할 수 없기 때문
192.168.1.0/24 예시로 살펴보면:
호스트 부분 8bit → 2^8 = 256개 조합 가능 (0~255)
192.168.1.0 호스트 부분: 00000000 → 네트워크 주소 (할당 불가)
192.168.1.1~254 호스트 부분: 00000001 ~ 11111110 → 실제 사용 가능
192.168.1.255 호스트 부분: 11111111 → 브로드캐스트 주소 (할당 불가)
따라서: 256 - 2 = 254개 사용 가능
네트워크 주소: 네트워크 자체를 식별하는 주소. 라우팅 테이블에서 "이 네트워크로 가려면"을 지정할 때 사용
브로드캐스트 주소: 해당 네트워크의 모든 장치에 동시에 패킷을 전송할 때 사용
192.168.1.0/24 네트워크를 시각화하면:
┌───────────────────────────────────────────────────┐
│ Network: 192.168.1.0/24 │
│ │
│ PC-A PC-B Server │
│ 192.168.1.10 192.168.1.20 192.168.1.100 │
│ │ │ │ │
│ ────┴──────────────┴───────────────┴──── │
│ Switch │
└───────────────────────────────────────────────────┘
│
[Router] 192.168.1.1 (Gateway)
│
─── Internet ───
이 네트워크에서 사용되는 특수 주소들:
| 주소 | 용도 | 설명 |
|---|---|---|
| 192.168.1.0 | 네트워크 주소 | 네트워크 자체를 지칭 |
| 192.168.1.1 | 게이트웨이 | 보통 라우터에 할당 |
| 192.168.1.2~254 | 호스트 | 실제 장치에 할당 |
| 192.168.1.255 | 브로드캐스트 | 네트워크 전체에 전송 |
하나의 네트워크를 더 작은 네트워크로 나눌 수 있습니다. /24를 /25 두 개로 분할하면:
네트워크 : 192.168.1.0/24 (254 hosts)
↓ 분할
┌────────────────────────────────────────┐
│ Subnet A: 192.168.1.0/25 │
│ ──────────────────────── │
│ Network: 192.168.1.0 │
│ Hosts: 192.168.1.1 ~ .126 │
│ Broadcast: 192.168.1.127 │
│ Available: 126 │
├────────────────────────────────────────┤
│ Subnet B: 192.168.1.128/25 │
│ ──────────────────────── │
│ Network: 192.168.1.128 │
│ Hosts: 192.168.1.129 ~ .254 │
│ Broadcast: 192.168.1.255 │
│ Available: 126 │
└────────────────────────────────────────┘
왜 128부터 시작하는가?
/25 마스크: 255.255.255.128
128 = 10000000 (2진수)
마지막 옥텟 기준:
서브넷 A: 0xxxxxxx (0~127) ← 첫 비트가 0
서브넷 B: 1xxxxxxx (128~255) ← 첫 비트가 1
↑
25번째 비트가 서브넷 구분
# VPC 생성 시 흔히 사용하는 CIDR
VPC: 10.0.0.0/16 # 65,534개 IP
├── Public: 10.0.1.0/24 # 254개 (웹 서버, ALB)
├── Private: 10.0.10.0/24 # 254개 (애플리케이션)
└── Database: 10.0.20.0/24 # 254개 (RDS)
$ docker network inspect bridge
"Subnet": "172.17.0.0/16"
"Gateway": "172.17.0.1"
# Calico 기본 설정
podNetwork: 192.168.0.0/16
| 개념 | 설명 |
|---|---|
| 서브넷 마스크 | IP에서 네트워크/호스트 경계를 결정 |
| 네트워크 주소 | IP AND 마스크 결과, 같으면 직접 통신 가능 |
| CIDR /n | 네트워크 비트가 n개 |
| 호스트 수 | 2^(32-n) - 2 |
| 서브넷 분할 | 큰 네트워크를 작은 네트워크로 분리 |
서브넷 마스크를 이해하면 VPC 설계, 컨테이너 네트워킹, 방화벽 규칙 설정 등에서 "왜 이렇게 되어 있는지"가 보이기 시작합니다.
인프라 문제를 디버깅할 때도 "혹시 서브넷이 달라서 통신이 안 되는 건가?"라는 가설을 세울 수 있게 됩니다.