LabHub
배우기 러닝패스 코스

Addresses, Subnets and Gateways

How Does a Packet Choose Its Path

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

한 줄 요약

호스트는 목적지가 내 서브넷 안이면 직접, 밖이면 기본 게이트웨이로 보낸다. 라우팅 테이블은 그 판단 규칙의 목록이고, 가장 긴 프리픽스가 이긴다.

Flow map: 내 서브넷 안이면 직접 · 기본 게이트웨이로 · 직접 붙어 있다. · 가장 긴 프리픽스

왜 이게 필요했나

"핑은 되는데 접속이 안 된다", "어떤 대역만 안 된다" 같은 신고는 대부분 라우팅에서 나온다. 그런데 라우팅 테이블을 읽을 줄 모르면 무엇을 봐야 할지조차 모른다.

어떻게 동작하나

ip route
# default via 192.168.219.1 dev eth0
# 10.244.0.0/16 dev cilium_host scope link
# 192.168.219.0/24 dev eth0 proto kernel scope link src 192.168.219.50

세 줄의 뜻은 이렇다.

목적지가 여러 줄에 걸리면 가장 긴 프리픽스가 이긴다. 10.244.1.5default(/0)와 10.244.0.0/16 둘 다에 맞지만 /16 이 더 길어서 이긴다. 이걸 최장 접두사 일치(longest prefix match)라 한다.

특정 목적지의 실제 경로는 물어보면 된다.

ip route get 8.8.8.8
ip route get 10.244.1.5

이 명령은 커널에게 "이 주소로 보내면 어디로 나가나" 를 직접 묻는다. 테이블을 눈으로 읽고 추론하는 것보다 정확하다.

라우팅을 읽는 순서

ip route 의 목록을 위에서부터 읽으면 안 됩니다. 커널은 가장 긴 프리픽스 (most-specific)를 먼저 고릅니다. 같은 길이면 metric 이 작은 것을 씁니다.

10.0.5.0/24  dev eth1                  ← /24. 10.0.5.7 은 여기로
10.0.0.0/8   via 10.0.0.1 dev eth0     ← /8. 10.0.5.7 도 여기 포함되지만 진다
default      via 192.168.1.1 dev eth0  ← /0. 아무 데도 안 맞을 때

목록을 눈으로 훑는 대신 커널에게 직접 물어보는 편이 확실합니다.

ip route get 10.0.5.7
10.0.5.7 dev eth1 src 10.0.5.2 uid 1000

src 가 중요합니다. 나가는 인터페이스가 정해지면 출발지 IP 도 함께 정해지고, 그 주소가 상대의 방화벽에 허용되어 있지 않으면 통신이 안 됩니다. "내 IP 는 203.x 인데 왜 10.x 로 나가지" 같은 문제가 여기서 보입니다.

규칙 → 테이블 → 경로

리눅스에는 라우팅 테이블이 여러 개 있고, 어느 것을 볼지는 ip rule 이 정합니다.

ip rule show
0:      from all lookup local        ← 자기 주소. 건드리지 않는다
32766:  from all lookup main         ← ip route 가 기본으로 보여 주는 것
32767:  from all lookup default

VPN·다중 회선·정책 라우팅에서는 여기에 규칙이 추가됩니다.

100:    from 10.8.0.0/24 lookup vpn   ← VPN 대역은 다른 테이블을 본다

이 경우 ip route (main 테이블)만 보면 "설정이 맞는데 안 나간다" 가 됩니다. ip route show table vpn 으로 그 테이블을 따로 봐야 합니다. 규칙은 번호가 작은 것부터 평가되고, 맞는 첫 규칙의 테이블을 씁니다.

ARP 와 이웃 캐시

같은 서브넷 안이면 라우터를 거치지 않고 MAC 주소로 직접 보냅니다. 그 대응표가 이웃 캐시입니다.

ip neigh show
10.0.5.1 dev eth1 lladdr 00:1a:2b:3c:4d:5e REACHABLE
10.0.5.9 dev eth1  FAILED                  ← 응답이 없다

FAILED 는 그 IP 를 가진 장비가 없거나 응답하지 않는다는 뜻입니다. 라우팅은 맞는데 통신이 안 될 때 여기를 봅니다. IP 를 옮긴 직후에는 옛 MAC 이 캐시에 남아 몇 분간 안 되는 일도 있습니다 — ip neigh flush dev eth1 로 지웁니다.

흔한 착각

게이트웨이가 같은 서브넷에 있어야 한다. 기본 게이트웨이는 ARP 로 찾아야 하므로 반드시 직접 붙은 대역 안에 있어야 한다. 다른 대역의 주소를 게이트웨이로 넣으면 Network is unreachable 이 난다.

핑이 되면 네트워크가 정상이라는 착각. 핑은 ICMP 이고 서비스는 TCP 다. 방화벽이 ICMP 만 열어 두면 핑은 되고 접속은 안 된다. 반대로 ICMP 만 막아 두면 핑은 안 되는데 서비스는 멀쩡하다.

실무에서 진짜 중요한 것

컨테이너 안에서 ip route 를 보면 대개 이렇게 단순하다.

default via 10.244.1.1 dev eth0
10.244.1.0/24 dev eth0

파드는 자기 노드의 게이트웨이만 안다. 다른 노드의 파드로 가는 길은 노드가 안다. 그래서 파드 간 통신이 안 될 때는 파드 안이 아니라 노드의 라우팅과 CNI 를 봐야 한다.

리눅스에는 테이블이 여러 개 있고 ip rule 이 어느 테이블을 볼지 정한다. VPN 이나 다중 회선 환경에서 "라우팅 테이블은 맞는데 안 나간다" 면 ip rule 을 봐야 한다.