CS · 기본
개발자를 위한 컴퓨터 사이언스 - 내 코드가 실제로 도는 곳
네트워크 계층 구조 - 캡슐화, 라우팅과 MTU로 경로 읽기 (CS 기초 10장)
캡슐화와 IP 경로 선택, 링크의 크기 제한과 주소 변환을 직접 만든 계산 예제로 살펴보고 작은 요청의 성공만으로 네트워크를 판단하는 오해를 짚는다.
개발자 · 원고 갱신
이 장에서 배우는 것
9장에서는 파일과 소켓으로 이어지는 I/O의 대기 방식을 다뤘다. 이번 장은 바이트가 호스트를 떠나 목적지까지 가는 경로를 읽는다. 선수지식은 버퍼와 I/O 대기의 구분이다.
- 계층마다 덧붙이는 정보와 관찰 질문을 구분한다.
- 목적지 접두어와 경로 선택을 계산한다.
- MTU와 주소 변환이 관측 결과에 주는 영향을 설명한다.
- 큰 요청만 실패하는 증상을 계층별 증거로 좁힌다.
개념
로그인 화면은 열리는데 큰 파일 전송만 멈춘다고 가정한다. 서버 프로세스도 살아 있고 작은 응답도 돌아온다. 이때 연결 성공을 근거로 네트워크 전체가 정상이라고 결론 내리면 조사 범위를 너무 빨리 닫게 된다. 같은 경로라도 데이터 크기와 전송 방향에 따라 다른 문제가 드러날 수 있다.
각 계층은 서로 다른 질문에 답한다
애플리케이션은 전송할 바이트를 만들고 전송 계층은 통신하는 끝점을 다룬다. IP 계층은 목적지 주소를 보고 다음 경로를 고르며 링크 계층은 바로 연결된 구간으로 전달한다. 데이터를 아래로 넘길 때 각 계층이 필요한 정보를 덧붙이는 것이 캡슐화다. 한 계층의 성공을 다른 계층의 성공으로 바꾸어 읽지 않는 것이 장애 분석의 출발점이다.
봉투 비유를 쓴다면 목적지까지 모든 봉투가 그대로 유지된다고 생각하면 안 된다. 라우터를 건널 때 다음 링크에 맞는 포장은 달라지고 IP 헤더에도 전달 과정에서 변하는 필드가 있다. 주소 변환을 거치면 끝점 주소 일부도 바뀔 수 있다. 캡슐화 그림은 무엇이 어디에 속하는지 보여 주는 학습 모델이며 패킷 전체가 불변이라는 선언이 아니다.
계층별 관찰 질문
---------------
애플리케이션 요청이 끝났는가
전송 계층 상대 끝점과 데이터를 교환하는가
IP 계층 목적지로 가는 경로가 있는가
링크 계층 다음 구간으로 전달되는가경로와 크기를 함께 본다
목적지가 직접 연결된 망에 있는지, 게이트웨이를 거쳐야 하는지는 주소와 라우팅 정책에 따라 결정된다. 학습용 단순 경로표에서는 목적지에 일치하는 경로 중 더 구체적인 접두어를 고른다. 실제 장비에는 정책 라우팅 등 추가 조건이 있을 수 있으므로 예제 계산을 모든 환경의 경로 선택 구현으로 착각하지 않는다. 주소 첫 부분이 비슷하다는 눈대중보다 접두어 길이를 포함한 비교가 정확하다.
MTU는 해당 링크에서 전달하는 IP 패킷 크기의 한계를 이야기할 때 사용하는 값이다. 서로 다른 크기 제한을 가진 구간을 지나면 경로 전체에서 보낼 수 있는 크기는 가장 좁은 구간의 영향을 받는다. IPv6에서는 중간 라우터가 패킷을 조각내지 않는다. 크기 초과 정보가 돌아오는 경로까지 고려해야 큰 전송에서만 나타나는 정지를 설명할 수 있다.
| 관찰 | 곧바로 말할 수 있는 것 | 아직 알 수 없는 것 |
|---|---|---|
| 작은 요청 성공 | 그 시점 그 요청의 왕복 성공 | 큰 패킷·다른 경로의 성공 |
| 경로표에 항목 존재 | 로컬 경로 선택 후보 존재 | 다음 장비가 전달하는지 |
| 사설 주소 사용 | 주소 범위의 성격 | 외부 통신 차단 여부 |
| 주소 변환 기록 존재 | 특정 매핑 상태 존재 | 애플리케이션 응답 성공 |
전통적인 IPv4 주소 변환은 내부 주소를 외부에서 사용할 주소로 대응시키고, 포트 변환을 함께 쓰면 여러 내부 흐름을 구분할 수 있다. 이 대응에는 상태와 수명이 있다. 따라서 내부에서 본 주소와 외부에서 본 주소가 다른 것은 기록 오류일 수도 있지만 정상적인 변환일 수도 있다. 주소는 관측 위치와 함께 기록한다.
경로가 양방향으로 완전히 같다고 가정하는 것도 피해야 한다. 요청이 목적지까지 전달됐다는 관측과 응답이 발신자에게 돌아왔다는 관측은 별개다. 성공과 실패를 전송 방향까지 포함해 기록한다. 큰 요청의 응답이 오지 않을 때 서버에 요청 도착 기록이 있다면 조사 범위를 더 좁힐 수 있다. 아직 기록이 없다면 네트워크 미도착과 서버 내부 기록 누락을 구분할 추가 증거가 필요하다. 이처럼 관측하지 않은 구간을 정상이나 실패로 채우지 않는 습관이 계층 구분보다 먼저다. 크기 비교에서도 파일 전체 크기와 패킷 하나의 크기는 다르다. 큰 파일은 여러 단위로 나누어 전달할 수 있으므로 파일이 MTU보다 크다는 이유만으로 실패하지 않는다. 실습의 데이터 예산은 한 패킷 안에 담는다고 가정한 양이며 전체 파일 크기를 제한하는 계산이 아니다.
데이터에 전송 계층과 IP 계층의 정보가 더해지며 라우터 이후에는 다음 링크에 맞는 포장으로 전달된다.
직접 확인하기
사설망 여부보다 접두어 일치부터 계산한다
from ipaddress import ip_address, ip_network
network = ip_network('10.42.8.0/24')
for text in ['10.42.8.7', '10.42.9.7']:
print(text, ip_address(text) in network)Python 3의 ipaddress로 주소 계산만 수행하며 실제 네트워크에 연결하지 않는다. 두 주소가 모두 사설 주소라는 사실과 같은 접두어 안에 있다는 사실은 다르다. 이 예제의 /24는 실습 입력이며 특정 운영망의 기본값을 뜻하지 않는다.
출력
----
10.42.8.7 True
10.42.9.7 False더 구체적인 경로를 고르는 모델
from ipaddress import ip_address, ip_network
routes = [('0.0.0.0/0', 'default'),
('10.42.0.0/16', 'gateway-a'),
('10.42.8.0/24', 'direct')]
destination = ip_address('10.42.8.7')
matches = [(ip_network(net), via) for net, via in routes
if destination in ip_network(net)]
chosen = max(matches, key=lambda item: item[0].prefixlen)
print(str(chosen[0]), chosen[1])결과는 목적지와 가장 길게 일치하는 접두어다. 더 구체적인 경로를 삭제했을 때 어느 후보가 남는지 코드의 입력만 바꿔 비교할 수 있다. 로컬 경로 선택을 계산하는 모델이므로 실제 라우터, 방화벽, 응답 경로의 정상 여부를 시험하지 않는다.
출력
----
10.42.8.0/24 direct학습용 크기 예산과 주소 변환을 분리한다
link_limits = [1500, 1400, 1500]
assumed_headers = 60
path_limit = min(link_limits)
payload_budget = path_limit - assumed_headers
print('path limit:', path_limit)
print('payload budget:', payload_budget)
print('fits:', 1350 <= payload_budget)여기서 1500, 1400, 헤더 60바이트는 계산을 위한 가정이다. 실제 헤더는 IP 버전, 확장, 전송 계층 옵션, 터널 유무에 따라 달라진다. 1350바이트가 작아 보이더라도 주어진 예산보다 크다는 판단을 재현할 뿐, 현재 호스트의 MTU를 측정하지 않는다.
출력
----
path limit: 1400
payload budget: 1340
fits: False직접 만든 주소 변환 예시
------------------------
내부 10.42.8.7:41000 → 외부 주소의 포트 51000
내부 10.42.8.8:41000 → 외부 주소의 포트 51001
같은 내부 포트라도 주소까지 보아야 흐름이 구분된다.표의 포트는 예시용이며 예약된 서비스 포트를 설명하는 숫자가 아니다. 요청을 보낸 쪽의 로그와 받는 쪽의 로그를 비교할 때 변환 뒤 주소를 찾을 수 있어야 같은 사건을 연결할 수 있다. 실제 기록에는 시간과 프로토콜도 함께 남긴다. 주소 문자열 하나만으로 사용자나 요청을 유일하게 식별하지 않는다.
환경별 차이
| 환경 | 경로가 보이는 위치 | 해석의 경계 |
|---|---|---|
| 리눅스 | 해당 네트워크 공간의 인터페이스와 경로표 | 호스트 전체와 같다고 가정하지 않음 |
| macOS | 호스트 인터페이스와 VPN 경로 | VPN 연결 전후 경로가 달라질 수 있음 |
| 컨테이너 | 컨테이너 내부와 호스트 바깥 | 가상 링크·터널·주소 변환 구간 추가 가능 |
같은 URL을 호출해도 회사망, 집, VPN 환경에서 거치는 경로는 달라질 수 있다. 성공한 장비의 설정을 실패한 장비에 그대로 복사하기보다 목적지 주소, 연결 방식, 관측 위치부터 맞춘다. 컨테이너 안의 경로표만으로 물리 네트워크의 모든 구간을 설명할 수 없다. 반대로 호스트가 통신한다는 사실만으로 컨테이너 내부 경로가 정상이라고 확정하지 않는다.
작은 요청과 큰 요청을 비교할 때는 크기 외의 조건을 가능한 한 고정한다. 대상 이름이 여러 주소로 해석되면 서로 다른 서버를 비교하고 있을 수 있다. 새 연결과 재사용 연결을 섞어도 연결 준비 비용이 달라진다. 먼저 같은 목적지와 비슷한 시간대의 결과를 모으고, 실패가 시작되는 크기 범위를 좁히면 다음 관측 지점을 정하기 쉬워진다.
실무에서 자주 틀리는 것
1. 작은 응답이 오면 MTU 문제를 제외한다
증상은 작은 응답은 빠른데 큰 업로드만 멈추는 것이다. 흔한 오진은 애플리케이션 크기 제한이라고 바로 결론 내리는 것이다. 실제 원인은 서버 정책일 수도 있고 경로 크기 제한이나 그 알림의 전달 문제일 수도 있다. 확인은 응답 오류 여부와 전송이 멈춘 위치를 분리하고 크기만 바꾼 비교를 하는 것이다. 운영망의 크기 제한을 무작정 바꾸기 전에 어느 구간이 다른지 증거를 남긴다.
2. 사설 주소면 밖으로 나갈 수 없다고 단정한다
증상은 내부 주소를 쓰는 서버가 외부 서비스에 접속하는 것이다. 흔한 오진은 주소 분류가 잘못됐다고 보는 것이다. 실제로는 게이트웨이의 변환이나 프록시를 거치는 경로가 존재할 수 있다. 확인은 내부 주소, 경로, 외부 관측 주소를 따로 기록하는 것이다. 사설 주소 사용은 라우팅과 통신 정책 전체를 대신 설명하지 않는다.
3. 서버에 보인 주소를 최초 발신 주소로 취급한다
증상은 여러 요청이 하나의 주소에서 온 것처럼 기록되는 것이다. 흔한 오진은 모두 같은 장치가 보냈다고 판단하는 것이다. 실제로는 주소 변환이나 중간 연결 지점 때문에 관측 주소가 합쳐졌을 수 있다. 확인은 기록한 계층과 연결 상대를 구분하는 것이다. 추정한 원래 주소를 검증된 네트워크 사실처럼 분석표에 넣으면 이후 요청 추적까지 흔들린다.
스스로 확인하기
- 실습의 경로 한계 1400바이트와 가정한 헤더 60바이트에서 데이터 1350바이트를 그대로 보낼 수 있는가. 계산하라.
- 10.42.8.7과 10.42.9.7이 모두 사설 주소라는 사실만으로 같은 /24 망이라고 판단할 수 있는가.
- 컨테이너의 작은 요청 성공과 큰 요청 정지가 함께 관측됐다. 크기 외에 고정할 조건 두 가지를 설명하라.
해설 1. 데이터 예산은 1340바이트이므로 10바이트 초과다. 실제 전달 방식은 프로토콜과 경로 조건에 달렸으며 여기서는 예산 계산만 한다.
해설 2. 그렇지 않다. 10.42.8.0/24 포함 여부를 각각 계산해야 하며 두 번째 주소는 해당 범위 밖이다.
해설 3. 같은 목적지 주소와 연결 재사용 조건을 맞출 수 있다. 관측 위치와 시간대도 기록하면 서로 다른 경로를 비교하는 오류를 줄인다.
출처·작성 안내: 본문 설명, 예제, 문제와 도식은 이 장을 위해 직접 작성했다. 아래 문서는 기술적 사실 확인에 참고했으며 원문 문장·표·그림·코드를 발췌하거나 번역하지 않았다.
참고: RFC 8200 IPv6, RFC 1191 경로 MTU 탐색, RFC 3022 전통적 NAT
다음 11장에서는 이 경로 위에서 TCP와 UDP가 어떤 전달 약속을 제공하는지 살펴본다.
READER FEEDBACK
질문·오탈자·의견
내용에 관한 질문이나 오탈자, 더 나은 설명을 위한 의견을 남겨 주세요. 이 댓글은 원래 게시글과 같은 자리에 쌓입니다.
댓글 0
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.