본문 바로가기
클라우드/Istio

내 요청은 어떻게 목적지를 찾아갈까? Route와 Endpoint 완전 정복 🚀

by gasbugs 2025. 11. 27.

우리가 인터넷으로 쇼핑하고 주문 버튼을 누르는 순간, 수많은 데이터들이 복잡한 길을 따라 서버까지 안전하게 도착합니다. 마치 택배 기사님이 우리 집 주소를 정확히 찾아오는 것처럼 말이죠! 📦

이 과정에서 가장 중요한 두 가지 개념이 바로 경로(Route)엔드포인트(Endpoint)입니다. 많은 분들이 이 둘을 별개의 것으로 생각하지만, 사실은 아주 밀접한 관계를 맺고 있습니다. 오늘은 이 둘의 관계를 속 시원하게 파헤쳐 보겠습니다!

🛣️ 경로(Route): 목적지로 가는 고속도로

경로(Route)는 말 그대로 데이터 트래픽이 어떤 '길'을 따라가야 하는지에 대한 규칙 또는 정책의 집합입니다.

  • "사용자가 /login 페이지를 요청하면, '로그인 처리 서버'로 보내!"
  • "모바일 앱에서 들어온 요청은 'v2 API 서버'로 보내!"
  • "결제 관련 요청의 90%는 신규 서버로, 10%는 안정적인 구버전 서버로 보내서 테스트해!"

이처럼 Route는 교통경찰처럼 들어오는 트래픽의 특징(주소, 헤더 정보 등)을 보고 어디로 가야 할지 방향을 알려주는 역할을 합니다.

하지만 Route는 딱 거기까지입니다. '로그인 처리 서버'라는 목적지 '그룹'을 알려줄 뿐, 그 그룹에 속한 수많은 서버 중 정확히 어떤 서버의 어떤 문(포트)으로 들어가야 하는지는 알려주지 않습니다.

마치 "서울시 강남구"라는 큰 지역까지만 알려주는 것과 같죠.

💡 핵심: Route는 트래픽을 어디로 보낼지에 대한 추상적인 '방향'과 '규칙'입니다.

🚪 엔드포인트(Endpoint): 최종 목적지의 현관문

엔드포인트(Endpoint)는 데이터 트래픽이 최종적으로 도착하는 실제 목적지입니다. 더 이상 나아갈 곳이 없는 길의 끝, 즉 통신이 끝나는 지점이죠.

일반적으로 IP 주소와 포트(Port) 번호의 조합으로 표현됩니다.

  • 10.1.2.3:8080
  • 172.16.0.10:3000

아까의 택배 비유를 다시 가져와 볼까요? Route가 "서울시 강남구"까지의 경로를 알려줬다면, Endpoint는 "테헤란로 123번지, 45층 6호" 와 같은 아주 구체적인 최종 주소입니다. 이 주소가 있어야만 택배 기사님이 정확히 문 앞까지 배송할 수 있겠죠?

💡 핵심: Endpoint는 트래픽이 도달하는 구체적이고 물리적인 '최종 주소'입니다.

🗺️ 전체 그림: Route의 끝에는 반드시 Endpoint가 있다

이제 가장 중요한 질문에 도달했습니다. 이 둘은 어떤 관계일까요?

결론부터 말하면, 엔드포인트는 경로의 일부이자, 경로의 최종 목적지입니다. Route 규칙이 아무리 정교해도, 그 끝에 트래픽을 받아줄 Endpoint가 없다면 아무 의미가 없습니다.

전체 프로세스를 한번 따라가 볼까요?

  1. 요청 발생 📨: 사용자가 http://my-service.com/api 라는 주소로 요청을 보냅니다.
  2. 라우터/게이트웨이 도착 🚦: 요청은 가장 먼저 쿠버네티스 인그레스(Ingress)나 Istio 게이트웨이(Gateway) 같은 트래픽 관문으로 들어옵니다.
  3. 경로(Route) 규칙 확인 📜: 게이트웨이는 설정된 Route 규칙(예: Istio의 VirtualService)을 확인합니다.
    • "음, /api로 들어온 요청이네. 이 요청은 api-service로 보내라고 되어 있군!"
  4. 엔드포인트(Endpoint) 조회 🏠: 이제 시스템은 api-service가 실제로 어디에 있는지 찾기 시작합니다. 쿠버네티스는 이 서비스에 연결된 Pod들의 목록, 즉 Endpoint 목록을 가지고 있습니다.
    • api-service의 Endpoint: 10.1.2.3:8080, 10.1.2.4:8080, 10.1.2.5:8080
  5. 최종 트래픽 전달 🚚: 게이트웨이는 조회된 Endpoint 목록 중 하나(예: 10.1.2.3:8080)를 선택하여 최종적으로 트래픽을 전달합니다.

보시다시피, Route는 트래픽을 보낼 '서비스'를 지정하는 추상적인 길잡이 역할을 하고, 그 길의 끝에는 항상 구체적인 주소인 Endpoint가 기다리고 있습니다.


🤔 흔한 오해: "Route와 Endpoint는 그냥 별개 아닌가요?"

많은 분들이 쿠버네티스에서 Service나 Ingress (Route 규칙)와 Endpoints (목적지 목록)를 별개의 오브젝트로 관리하기 때문에 이 둘을 완전히 분리된 개념으로 생각하기 쉽습니다.

하지만 이건 사실이 아닙니다. 🙅‍♂️

기능적으로 이 둘은 강하게 결합되어 있습니다. Route 규칙을 정의하는 행위는 결국 "어떤 Endpoint로 트래픽을 보낼 것인가"를 결정하기 위한 과정입니다. Route는 '어떻게' 보낼지를 정의하고, Endpoint는 '어디로' 보낼지에 대한 최종 답안지인 셈이죠.

길(Route)이 있는데 목적지(Endpoint)가 없거나, 목적지는 있는데 길이 없으면 아무것도 할 수 없는 것과 같습니다.


💻 코드로 직접 확인하기: 쿠버네티스 & Istio 예제

백문이 불여일견! 실제 코드로 어떻게 동작하는지 봅시다.

1. 서비스와 엔드포인트 생성 (기본)

먼저, 쿠버네티스에 my-api라는 이름의 서비스를 배포하면, 쿠버네티스는 이 서비스에 연결된 Pod들의 IP와 포트를 자동으로 수집하여 Endpoints 오브젝트를 만듭니다.

# my-api 서비스에 연결된 엔드포인트 목록 확인
kubectl get endpoints my-api

[Raw Data 결과]

NAME     ENDPOINTS                               AGE
my-api   10.1.2.3:8080,10.1.2.4:8080,10.1.2.5:8080   2d

👆 이것이 바로 트래픽이 최종적으로 도달할 수 있는 '실제 주소' 목록입니다.

2. Istio VirtualService로 Route 규칙 정의

이제 Istio의 VirtualService를 사용해 복잡한 라우팅 규칙을 만들어 보겠습니다. "들어오는 요청의 90%는 v1 버전으로, 10%는 v2 버전으로 보내라"는 규칙입니다.

# my-api-route.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-api-virtualservice
spec:
  hosts:
  - "my-api.example.com"
  http:
  - route: # 👈 바로 이 부분이 '경로(Route)' 규칙입니다.
    - destination:
        host: my-api-service # 👈 어느 서비스로 보낼지?
        subset: v1           # 👈 그 서비스의 'v1' 버전 그룹으로!
      weight: 90
    - destination:
        host: my-api-service # 👈 어느 서비스로 보낼지?
        subset: v2           # 👈 그 서비스의 'v2' 버전 그룹으로!
      weight: 10

위 YAML에서 http.route 섹션이 바로 경로입니다. 이 경로는 "요청을 my-api-service로 보내되, v1과 v2 그룹으로 나누어 보내라"고 지시하고 있습니다.

그리고 Istio는 이 v1, v2 그룹에 속한 Pod들의 실제 IP 주소, 즉 위에서 확인했던 Endpoints 목록(10.1.2.3:8080 등)을 참조하여 최종적으로 트래픽을 보냅니다.

결국, VirtualService에 정의된 화려한 Route 규칙도 결국은 구체적인 Endpoint로 트래픽을 보내기 위한 정교한 안내판에 불과한 것이죠.

결론

엔드포인트는 트래픽이 전송되는 경로의 핵심적인 최종 구성 요소입니다.

  • Route (경로): 트래픽을 어디로 보낼지에 대한 정책과 규칙 (고속도로)
  • Endpoint (엔드포인트): 트래픽이 최종적으로 도달하는 실제 주소 (집 현관문)

다음에 네트워크 아키텍처를 설계하거나 트러블슈팅을 할 때, 이 둘의 관계를 꼭 기억하세요. 추상적인 경로 규칙(Route)과 구체적인 목적지(Endpoint)를 함께 바라볼 때, 비로소 전체 트래픽의 흐름을 완벽하게 이해할 수 있을 겁니다! 😉