1. 개요

1편이 격리 얘기였다면 이번 편은 “요청이 서버까지 가는 길” 얘기다. 인프라 구성도를 보면 거의 항상 앱 앞에 Nginx 나 Envoy, ALB 같은 게 하나 더 있다. 왜 앱이 직접 요청을 받지 않고 굳이 하나를 더 거치는지, 포워드 프록시와는 뭐가 다른지 정리한다.


2. 핵심 내용

2-1. 포워드 프록시 vs 리버스 프록시

둘 다 “중간에서 대신 요청을 보내주는 것” 이라는 점은 같은데, 누구를 대신하는가 가 다르다.

  • 포워드 프록시는 클라이언트 편이다. 회사 네트워크에서 외부 사이트에 나갈 때 프록시 서버를 거치는 경우가 이거다. 클라이언트는 프록시가 있다는 걸 알고, 서버는 프록시 뒤에 누가 있는지 모른다.
  • 리버스 프록시는 서버 편이다. 클라이언트는 자기가 프록시에 붙는지 실제 서버에 붙는지 모른다. 도메인에 요청을 보내면 Nginx 가 먼저 받아서 내부의 실제 애플리케이션 서버로 전달한다.

방향이 반대라서 헷갈리기 쉬운데, “누구 앞에 서 있는가” 로 기억하면 편하다.

2-2. 리버스 프록시가 실제로 하는 일

앱 서버 하나만 있다면 굳이 필요 없어 보일 수 있는데, 실무에서 리버스 프록시가 붙는 이유는 대개 이렇다.

  • TLS 종료(TLS termination): 인증서 관리와 암복호화 연산을 프록시 한 곳에 몰아준다. 뒤의 앱 서버 여러 대가 각자 인증서를 들고 있을 필요가 없다.
  • 여러 서비스를 도메인/경로로 분기: api.example.com 은 백엔드로, example.com 은 프론트로, 이런 라우팅을 프록시 레이어에서 처리한다.
  • 로드밸런싱: 뒤에 앱 서버가 여러 대면 요청을 분산한다. 이 얘기는 6편에서 더 다룬다.
  • 버퍼링과 연결 관리: 클라이언트 연결과 백엔드 연결을 분리해서, 느린 클라이언트가 앱 서버의 워커를 오래 붙잡지 않게 한다.

예전에 Proxmox 마이그레이션 글에서 서비스들을 정지시킬 때 마지막까지 살려둔 게 NPM(Nginx Proxy Manager) 이었는데, 그게 바로 이 역할이다. 앱들은 다 내려도 프록시가 살아 있어야 최소한 안내 페이지라도 보여줄 수 있다.

2-3. Nginx 와 Envoy, 뭐가 다른가

둘 다 리버스 프록시로 쓰이지만 설계 철학이 다르다. Nginx 는 설정 파일을 미리 써두고 리로드하는 방식이 기본이라 정적인 구성에 강하다. Envoy 는 xDS 라는 API 로 라우팅 규칙을 런타임에 동적으로 받아올 수 있게 설계됐다. 그래서 쿠버네티스처럼 서비스가 계속 뜨고 내려가는 환경, 즉 Envoy Gateway 나 Istio 같은 서비스 메시 구현체의 데이터 플레인으로 Envoy 가 많이 쓰인다. Nginx Ingress Controller 도 결국 쿠버네티스 리소스가 바뀔 때마다 내부적으로 설정 파일을 다시 쓰고 리로드하는 식으로 이 간극을 메운다.

2-4. 프록시도 자원을 쓴다

리버스 프록시는 클라이언트와의 연결, 백엔드와의 연결을 각각 따로 유지한다. 즉 커넥션 하나당 소켓을 최소 두 개씩 쓴다는 뜻이다. 동시 접속이 늘어나면 프록시 프로세스의 파일 디스크립터가 먼저 바닥날 수 있다. 예전에 이 한도 때문에 Nginx 가 (24: No file descriptors available) 에러를 뱉으며 죽은 적이 있는데, 그 얘기는 File Descriptor에 정리해뒀다. 리버스 프록시를 앞단에 둔다는 건 그만큼 프록시 자체의 용량 계획도 따로 세워야 한다는 뜻이다.


3. 마무리

요약

  • 포워드 프록시는 클라이언트 편, 리버스 프록시는 서버 편이다. 방향이 반대다.
  • 리버스 프록시는 TLS 종료, 도메인/경로 라우팅, 로드밸런싱, 느린 클라이언트 격리를 한곳에 모아준다.
  • Nginx 는 정적 설정에, Envoy 는 xDS 로 런타임에 라우팅을 바꾸는 동적 환경에 강하다.
  • 프록시도 연결마다 소켓을 이중으로 쓰므로 FD 한도 같은 자체 용량 계획이 필요하다.

다음은 3편: DNS 조회 한 번에 정리하기 다.