“큰 다운로드는 VPN 밖으로 보내고 작은 응답은 VPN 위에 두라”는 말은 라우팅 정책처럼 들리지만 그렇지 않다. 라우터는 그 순간 이용할 수 있는 정보로 결정한다. 주소, 포트, 프로토콜, firewall 표시, 식별된 흐름. 응답의 최종 크기는 그 집합에 없다. 아직 도착하지 않았기 때문이며, 라우터가 바이트를 잴 수 있을 때에는 이미 그것을 전달하고 있다. 작업 단위로 나누고 싶다면 결정은 작업을 아는 지점으로 옮겨가야 하고, 아래 점검표는 당신의 설계에 그런 지점이 있는지 확인하는 방법이다.

라우터가 응답 크기를 잴 수 없는 이유

패킷에 경로가 필요한 순간 라우터가 본 것은 흐름의 처음 몇 패킷이 고작이다. 누가 누구와 이야기하는지, 어떤 프로토콜로, 어떤 표시로, 지금까지 몇 바이트가 지났는지는 알 수 있다. 지나온 바이트는 과거를 말한다. 응답의 크기는 아직 만들어지지 않은 응답의 속성이며, 분할되거나 스트리밍되는 응답에서는 미리 알 수 없을 수도 있다.

프로토콜 자체의 메타데이터도 보기보다 약하다. HTTP는 본문 전에 길이를 알리지 않는 응답을 허용하고, 한 번의 사용자 행동이 여러 요청을 만들어 그 합산 비용이 어떤 헤더 값과도 비슷하지 않을 수 있다. 헤더를 작업의 크기로 다루는 것은 라우팅 오류가 되기 전에 모델링 오류다.

점검 1: 경로를 고를 결정 지점이 있는가

선택을 할 구성 요소를 지목하라, 그런 다음 고르는 순간 그것이 무엇을 아는지 말하라. 문서화된 호스트 집합에서 받아 오는 업데이터는 전송이 시작되기 전에 자기 목적을 안다. 메타데이터를 살핀 뒤 요청을 여는 다운로드 서비스는 연결이 생기기 전에 작업을 안다. 협력하는 proxy는 자기가 라우터인 척하지 않고 요청 수준 정책을 적용하거나 응답을 캐시할 수 있다.

답이 “게이트웨이”라면 점검표는 이미 실패했다. 게이트웨이는 알려진 흐름을 목적지, 표시, 클라이언트 구간으로 분류해 첫 패킷부터 정해진 경로로 보낼 수 있다. 승인된 업데이터에는 흔히 충분하고, 알 수 없는 응답 크기에는 결코 충분하지 않다.

점검 2: 메타데이터는 실제로 무엇을 말하는가

애플리케이션을 아는 분기는 읽는 필드 이상의 것이 아니다. HTTP의 의미론의 응답 길이 규칙은 시작 시점에 길이를 알 수 없는 경우를 허용하고, 내용 인코딩은 전송된 바이트 수를 표현 크기와 애초에 다르게 만든다. 그래서 헤더가 임계값을 넘을 때 경로를 바꾸는 정책은 일관성 없이 동작하며, 하필 잡으려던 대용량 전송에서 그렇게 된다.

애플리케이션 메타데이터가 뒷받침할 수 있는 것은 작업에 대한 결정이다. 이 워크플로는 대량 동기화, 이쪽은 대화형, 저쪽은 알려진 출처의 소프트웨어 업데이트. 이것은 의도의 언어로 쓴 정책이며 시험할 만큼 안정적이다. “이 응답은 사십 메가바이트보다 클 것이다”는 그런 정책이 아니다.

점검 3: 흐름이 이미 존재하는가

경로는 연결의 정체성을 바꾸지 않고 흐름에 대해 바뀔 수 있고, 그 구분은 정확히 유지할 가치가 있다. TCP 연결은 양 끝의 주소와 포트로 식별되며, 경로 표가 그 아래에서 바뀌면 패킷은 다른 길을 갈 수 있다. 보이지 않게 바뀔 수 없는 것은 네트워크 주소 변환 상태다. 트래픽을 다른 출구로 옮기면 대개 공인 출발지 튜플이 바뀌고, 먼 쪽은 맞는 상태가 없는 다른 상대를 보게 된다.

conntrack -L -p tcp --dport 443 | head -5
ip route get 203.0.113.10
ss -tn state established dst 203.0.113.10

그래서 실무 규칙은 연결 중간에 출구를 옮기는 것이 이전이 아니라 새로운 관계라는 것이다. 같은 연결이 이어져야 한다면 결정은 첫 SYN 전에 내려야 했고, 나중에 추가한 어떤 패킷 규칙도 그것을 깨끗하게 재구성할 수 없다.

점검 4: 진짜 요구는 출구가 아니라 지연인가

“대량 트래픽을 다른 곳으로 보내라”는 요청의 상당수는 사실 큰 전송 때문에 대화형 작업이 느리게 느껴진다는 불만이다. 그것은 스케줄링 문제이고 스케줄링 답이 있다. 기존 경로에서 공정한 대기열이나 지원되는 대역폭 정책을 쓰면 둘 중 어느 것도 옮기지 않고 대량 흐름이 채팅 메시지를 굶주리게 하는 것을 막는다.

tc qdisc replace dev eth0 root cake bandwidth 100mbit

증상을 이렇게 다루면 출구 결정은 보안 정책이 둔 자리에 남고, 명령 하나로 되돌릴 수 있다. 트래픽 종류 전체의 출구를 바꾸는 것은 인증, 기록, 접근 규칙에 영향을 주는 정책 변경이므로 지연 불만에 처음 꺼낼 도구여서는 안 된다.

요구가 정말 다른 인터넷 출구라면 그 말로 밝히고 지원되는 경계에서 구현하라. 승인된 워크플로에서 새 연결을 열거나, 고른 출구로 자기 요청을 여는 애플리케이션. 그런 다음 어느 작업이 어느 출구를 쓰는지 기록해, 다음 사람이 경로 표에서 추측하지 않게 하라.

점검표를 변경 기록에 남겨라. 결정 지점, 그것을 움직이는 필드나 작업, 흐름이 이미 있는지, 잰 증상이 지연이었는지 출구였는지. 네 가지 질문, 그리고 넷 모두에 답하는 정책은 지키는 것이 아니라 운영할 수 있는 정책이다.

관련 글