사전 서브넷
개념

서브넷

gabury1

인터넷 주소 블록 하나를 더 잘게 나눈 조각입니다. 조직이 네트워크 번호를 하나만 받아도 안에서는 여러 갈래로 갈라 쓸 수 있습니다. 바깥에 알려지는 번호는 그대로 하나입니다.

쉽고 빠른 이해

무슨 일을 하는 물건인가 — 인터넷 주소 블록 하나를 조직 안에서 여러 조각으로 갈라 씁니다. 회사가 인터넷 네트워크 번호를 하나만 받았어도 층마다 한 조각씩 떼어 줄 수 있고, 밖에 알려지는 번호는 그대로 하나입니다.

왜 이렇게 하나 — 네트워크를 하나 더 놓을 때마다 바깥에서 새 번호를 받으면, 그 조직 안의 사정이 어디에나 퍼져 라우팅 표가 부풀기 때문입니다.

어떻게 도나

  1. 주소의 앞쪽은 네트워크, 가운데는 어느 조각인지, 뒤쪽은 그 조각 안의 어느 기계인지로 자릅니다.
  2. 어디서 자르는지는 마스크가 정합니다. 마스크에서 1로 채운 자리까지가 앞쪽입니다.
  3. 보낼 때는 목적지 주소와 내 주소를 각각 마스크로 걸러 견줍니다. 같으면 바로 보내고, 다르면 게이트웨이에 넘깁니다.

대가 — 호스트가 마스크를 하나 더 들고 있어야 하고, 보낼 때마다 이 판정을 거칩니다. 서브넷을 쓰려면 호스트 쪽 소프트웨어가 반드시 이 확장을 지원해야 합니다.

상세

아파트 한 동에 우편번호가 하나 붙습니다. 우체국은 그 번호까지만 보고 동 앞까지 나르고, 몇 층 몇 호로 갈지는 동 안에서 갈립니다.

서브넷은 하나의 인터넷 네트워크 안에서 논리적으로 보이는 하위 구획입니다. RFC(Request for Comments) 950 은 많은 조직이 인터넷 네트워크 번호를 여러 개 받는 대신 인터넷 네트워크 하나를 여러 서브넷으로 나누는 쪽을 골랐다고 적습니다. 행정상의 이유일 수도 있고 기술상의 이유일 수도 있다고 적혀 있습니다. 바깥에 새 네트워크 번호를 더 받은 것이 아니니, 밖이 아는 번호는 여전히 하나입니다.

IP(Internet Protocol, 인터넷 프로토콜) 주소는 네트워크를 가리키는 부분과 호스트를 가리키는 부분으로 갈립니다. 서브넷은 그 사이에 한 겹을 더 끼웁니다. RFC 950 은 인터넷 주소를 이렇게 해석할 수 있다고 적습니다.

<network-number><subnet-number><host-number>

network-number 필드는 인터넷 프로토콜이 정한 그대로입니다. host-number 필드는 최소 1비트입니다. subnet-number 필드의 너비는 주어진 네트워크마다 고정입니다. 두 필드 안에 더 이상의 구조는 요구되지 않습니다. subnet-number 필드의 너비가 0이면 그 네트워크는 서브넷으로 나뉘지 않은 것입니다.

어디까지가 네트워크와 서브넷이고 어디부터가 호스트인지는 주소 마스크가 정합니다. RFC 1122 는 호스트가 IP 의 서브넷 확장을 반드시 지원해야 한다고 적습니다. 그 결과로 호스트의 로컬 IP 주소마다 {-1, -1, 0} 꼴의 주소 마스크가 딸린다고 적혀 있습니다. 여기서 -1 은 그 필드가 전부 1비트라는 표기입니다. 네트워크 자리와 서브넷 자리가 1로 채워지고 호스트 자리가 0으로 남는 모양입니다.

block-beta
columns 4
  t1["주소"] a["네트워크 번호"] b["서브넷 번호"] c["호스트 번호"]
  t2["주소 마스크"] d["1"] e["1"] f["0"]
  t3["마스크가 뽑는 것"] g["여기까지 — 어느 서브넷인가"]:2 h["여기부터 — 그 안의 어느 호스트인가"]

마스크에서 1이 끝나는 자리가 곧 서브넷과 호스트를 가르는 경계입니다. 그 앞은 어느 서브넷인지를 가리키고, 그 뒤는 그 서브넷 안의 어느 호스트인지를 가리킵니다. subnet-number 필드가 몇 비트인지는 네트워크마다 다르므로 자르는 자리도 네트워크마다 다릅니다.

클래스 A/B/C 로 경계를 나누던 방식은 걷혔습니다. RFC 4632 는 그 자리를 클래스 없는 계층적 주소 블록, 곧 프리픽스로 바꿨다고 적습니다. CIDR(Classless Inter-Domain Routing, 클래스 없는 도메인 간 라우팅) 표기에서 프리픽스는 4옥텟 값 뒤에 / 를 붙이고 그 뒤에 0에서 32 사이의 십진값을 적습니다. 그 십진값이 유효 비트 수입니다. 32비트 IPv4(Internet Protocol version 4) 주소 중 어디까지를 사이트에 딸린 네트워크 번호로 읽고 어디부터를 사이트 안의 개별 종단 시스템 번호로 읽을지를 명시하는 것입니다. 프리픽스 배정은 밑에 깔린 인터넷 지형을 대체로 따르도록 의도됐습니다. 그래야 집약을 써서 전역 라우팅 시스템의 규모 확장을 거들 수 있다고 적혀 있습니다.

IPv6(Internet Protocol version 6) 에도 같은 자리가 있습니다. RFC 4291 은 자기가 붙은 링크의 서브넷 프리픽스를 아는 호스트를 두고 주소를 두 조각으로 그립니다. 앞쪽 n비트가 서브넷 프리픽스(subnet prefix)이고 나머지 128-n비트가 인터페이스 식별자(interface ID)입니다.

block-beta
columns 2
  a["서브넷 프리픽스 · 앞 n 비트"] b["인터페이스 식별자 · 나머지 128-n 비트"]

주소마다 n 값이 다를 수 있습니다.

링크 자체를 장비에서 갈라 놓는 VLAN(Virtual Local Area Network, 가상 근거리 통신망)과는 자리가 다릅니다. 서브넷은 주소를 가르는 구획이고, RFC 4291 은 서브넷을 가리키는 값을 사이트 안의 링크 하나를 가리키는 식별자라고 적습니다.

배경

랜(LAN, Local Area Network, 근거리 통신망)을 하나보다 많이 써야 하게 된 조직은 인터넷 주소를 배정할 방법을 셋 중에서 골라야 했습니다. RFC 950 이 그 셋을 적어 두었습니다.

선택지 무엇을 하나 RFC 950 이 붙인 이름
1 케이블마다 별개의 인터넷 네트워크 번호를 받는다 서브넷을 아예 쓰지 않는다
2 조직 전체가 네트워크 번호 하나를 쓰되, 호스트가 어느 랜에 있는지 상관없이 호스트 번호를 배정한다 transparent subnets
3 네트워크 번호 하나를 쓰면서, 랜마다 서브넷 번호를 배정해 호스트 주소 공간을 나눈다 explicit subnets

셋 다 단점이 있다고 적혀 있습니다. 첫째 방식은 새 프로토콜도 고친 프로토콜도 요구하지 않지만 인터넷 라우팅 표의 크기를 폭발시킵니다. 로컬 연결의 내부 사정이 어디에나 퍼집니다. 그 조직 밖에서는 쓸모가 거의 없거나 아예 없는 정보입니다. 당시 게이트웨이 구현 중에는 라우팅 표에 쓸 공간이 넉넉하지 않은 것도 있어서, 이 문제는 피하는 쪽이 낫다고 적혀 있습니다. 세 번째 방식에 붙은 이름이 explicit subnets 이고, 서브넷이라는 말이 여기서 나옵니다.

서브넷으로 번호 하나를 쪼개 쓰게 됐지만 배정 단위 자체는 여전히 클래스에 묶여 있었습니다. 1992년 1월에 모인 ROAD 그룹은 큰 문제 셋을 짚었습니다. 클래스 B 네트워크 주소 공간의 고갈, 인터넷 라우터의 라우팅 표가 당시의 소프트웨어와 하드웨어와 사람이 효과적으로 관리할 수 있는 범위를 넘어 자라는 것, 그리고 32비트 IPv4 주소 공간이 결국 소진되는 것입니다. RFC 4632 는 클래스 B 고갈의 근본 원인 하나로 중간 규모 조직에 맞는 크기의 네트워크 클래스가 없다는 점을 듭니다. 최대 254개 호스트 주소를 담는 클래스 C 는 너무 작고, 최대 65534개를 담는 클래스 B 는 대부분의 조직에 너무 크지만, 서브넷팅과 함께 쓰기에는 쓸 수 있는 것 중 가장 잘 맞는 선택지였습니다. 그 답으로 나온 것이 클래스 폐기와 프리픽스, 곧 CIDR 입니다.

동작

호스트는 데이터그램을 보내기 전에 목적지가 자기가 붙은 네트워크 안인지부터 정해야 합니다. RFC 1122 는 그 판정에 반드시 다음 절차를 써야 한다고 적습니다.

flowchart TD
    A["목적지 주소"] --> C["주소 마스크로 비트를 뽑는다"]
    B["출발지 주소"] --> C
    C --> D{"뽑은 비트가 같나"}
    D -->|같다| E["붙어 있는 네트워크 · 목적지로 직접 보낸다"]
    D -->|다르다| F["게이트웨이로만 닿는다"]

주소 마스크는 32비트 마스크입니다. 해당 IP 주소에서 네트워크 번호 필드와 서브넷 번호 필드를 골라냅니다. 인터페이스가 여럿인 호스트에서는 로컬 IP 주소마다 따로 붙습니다. 목적지 주소에서 이 마스크로 뽑아낸 비트가 같은 마스크로 출발지 주소에서 뽑아낸 비트와 맞으면, 목적지는 그 붙어 있는 네트워크 위에 있고 데이터그램은 목적지 호스트로 직접 전송됩니다. 맞지 않으면 목적지는 게이트웨이를 통해서만 닿습니다. 어느 게이트웨이를 고르는지는 그다음 자리의 일입니다.

RFC 950 은 같은 판정을 호스트 소프트웨어의 코드로 적습니다. 서브넷을 지원하려면 32비트 값 하나를 더 저장해야 합니다. my_ip_mask 라 부르는 이 값은 IP 네트워크 번호에 해당하는 필드의 비트가 켜져 있고, 서브넷 번호 필드에 해당하는 비트가 추가로 켜져 있는 비트 마스크입니다.

IF bitwise_and(dg.ip_dest, my_ip_mask)
                          = bitwise_and(my_ip_addr, my_ip_mask)
    THEN
        send_dg_locally(dg, dg.ip_dest)
    ELSE
        send_dg_locally(dg,
               gateway_to(bitwise_and(dg.ip_dest, my_ip_mask)))

목적지 주소와 내 주소를 각각 마스크와 AND 해서 결과가 같으면 로컬로 보냅니다. 다르면 그 AND 결과에 해당하는 게이트웨이로 보냅니다. 갈림은 이 하나입니다.

예시

사설 주소 대역

IANA(Internet Assigned Numbers Authority, 인터넷 할당 번호 관리 기관)가 사설 인터넷용으로 예약해 둔 세 블록입니다. RFC 1918 이 이렇게 적습니다.

10.0.0.0        -   10.255.255.255  (10/8 prefix)
172.16.0.0      -   172.31.255.255  (172.16/12 prefix)
192.168.0.0     -   192.168.255.255 (192.168/16 prefix)

각각 24비트 블록 · 20비트 블록 · 16비트 블록이라 부릅니다. CIDR 이전 표기로 보면 첫 블록은 클래스 A 네트워크 번호 하나이고, 둘째 블록은 연속된 클래스 B 네트워크 번호 16개이며, 셋째 블록은 연속된 클래스 C 네트워크 번호 256개입니다.

IPv6 글로벌 유니캐스트 주소

RFC 4291 이 적는 일반 형식입니다. 같은 128비트가 세 조각으로 갈리고, 서브넷을 가리키는 값은 앞뒤 두 조각 사이에 낍니다.

block-beta
columns 5
  a["global routing prefix · n 비트"]:2 b["subnet ID · m 비트"]:1 c["interface ID · 128-n-m 비트"]:2

global routing prefix 는 사이트 하나에 배정되는 값으로, 대개 계층 구조를 갖습니다. 사이트는 서브넷 또는 링크의 무리입니다. subnet ID 는 그 사이트 안의 링크 하나를 가리키는 식별자입니다.

AWS VPC 의 서브넷

AWS(Amazon Web Services) 문서는 서브넷을 VPC(Virtual Private Cloud, 가상 사설 클라우드) 안의 IP 주소 범위라고 적습니다. EC2(Elastic Compute Cloud) 인스턴스 같은 자원을 특정 서브넷 안에 만듭니다. 서브넷 하나는 반드시 가용 영역 하나 안에 온전히 들어가야 하고 영역을 걸칠 수 없습니다.

flowchart TD
    subgraph V["VPC"]
        subgraph Z1["가용 영역"]
            S1["서브넷"]
        end
        subgraph Z2["가용 영역"]
            S2["서브넷"]
        end
    end

서브넷은 VPC 안에 들어가고, 그 서브넷은 다시 가용 영역 하나 안에 통째로 들어갑니다. 한 서브넷이 두 영역에 걸쳐 놓이는 모양은 없습니다.

서브넷에 쓸 수 있는 IPv4 CIDR 블록 크기는 /28 넷마스크에서 /16 넷마스크 사이입니다. 각 서브넷 CIDR 블록의 앞 IP 주소 네 개와 마지막 IP 주소 하나는 쓸 수 없고 자원에 배정되지 않습니다. CIDR 블록이 10.0.0.0/24 인 서브넷이라면 다음 다섯 개가 예약됩니다.

10.0.0.0     네트워크 주소
10.0.0.1     VPC 라우터용으로 AWS 가 예약
10.0.0.2     AWS 가 예약. DNS 서버 주소는 VPC 네트워크 범위의 시작 더하기 2 다
10.0.0.3     앞으로 쓰려고 AWS 가 예약
10.0.0.255   네트워크 [[브로드캐스트 주소]]. VPC 는 브로드캐스트를 지원하지 않아 예약해 둔다

쿠버네티스 노드마다 잘리는 파드 CIDR

kube-controller-manager 의 플래그가 클러스터 대역을 노드마다 잘라 나눠 줍니다.

--allocate-node-cidrs           파드용 CIDR 을 배정해 클라우드 제공자에 설정할지
--node-cidr-mask-size           클러스터의 노드 CIDR 마스크 크기. IPv4 는 24, IPv6 는 64 가 기본값
--node-cidr-mask-size-ipv4      듀얼 스택 클러스터의 IPv4 노드 CIDR 마스크 크기. 기본값 24
--node-cidr-mask-size-ipv6      듀얼 스택 클러스터의 IPv6 노드 CIDR 마스크 크기. 기본값 64

--allocate-node-cidrs 설명에는 --cluster-cidr 이 필요하다고 딸려 있습니다.

리눅스 호스트에 프리픽스 길이를 붙이는 자리

ip-address(8) 의 예제입니다. 주소 뒤에 /64 를 붙여 어디까지가 서브넷 프리픽스인지를 같이 답니다.

ip address add 2001:0db8:85a3::0370:7334/64 dev eth1

목적지가 자기 서브넷 밖일 때 넘길 자리는 경로로 답니다. ip-route(8) 의 예제입니다. 장치 eth0 에서 닿을 수 있는 로컬 게이트웨이 192.168.1.1 을 통하는 기본 경로를 답니다.

ip route add default via 192.168.1.1 dev eth0

관련 항목

주소를 가르는 표기와 값

서브넷 마스크 · 주소 마스크 · CIDR · CIDR 표기법 · 프리픽스 길이 · 네트워크 주소 · 브로드캐스트 주소 · 호스트 부분 · 서브넷 프리픽스 · 인터페이스 식별자 · 사설 주소 · 클래스풀 주소 · VLSM(Variable Length Subnet Mask)

경계 판정 다음에 오는 라우팅 단계

로컬 원격 판정 · 기본 게이트웨이 · 라우팅 · 라우팅 테이블 · 최장 프리픽스 매치 · 직접 라우팅 · 간접 라우팅 · 다음 홉 · ARP(Address Resolution Protocol) · 경로 집약

주소를 나눠 주고 관리하는 프로토콜·기관

DHCP(Dynamic Host Configuration Protocol) · 주소 자동 설정 · NAT(Network Address Translation) · DNS(Domain Name System, 도메인 네임 시스템) · IANA · 지역 인터넷 레지스트리

서브넷이 속하는 상위 분류

IP 주소 · IPv4 · IPv6

서브넷이 놓이는 네트워크 인프라

VPC · 가용 영역 · 파드 CIDR · 클러스터 CIDR · VLAN · 네트워크 인터페이스 · 랜

서브넷에서 자주 나는 오류·장애

대역 겹침 · IPv4 주소 고갈 · 라우팅 표 증가 · 마스크 불일치 · 주소 충돌

다른 이름: subnet · 서브네트워크 · subnetwork · 부분망