Traefik vs Nginx: HTTP, TCP, UDP가 뭔지 리버스 프록시로 이해하기
Docker로 서비스를 올리다 보면 반드시 마주치는 두 도구가 있다. Nginx와 Traefik. Nginx는 이름만큼은 들어봤다는 사람이 많지만, Traefik은 “그게 뭔데?”로 시작하는 경우가 태반이다. 그리고 이 두 도구를 제대로 비교하려면 HTTP, TCP, UDP 같은 개념을 피할 수 없다.
이 글은 그 순서대로 간다. 리버스 프록시가 뭔지 → HTTP가 뭔지 → TCP/UDP는 또 뭔지 → 그래서 Nginx와 Traefik이 어떻게 다른지. 개념을 층층이 쌓아가면서 두 도구의 차이가 왜 생기는지 이해하도록 구성했다.
리버스 프록시: 구글 검색 뒤에 숨은 교통정리
브라우저에서 google.com을 치면 검색 페이지가 뜬다. 단순해 보이지만 구글 내부에는 검색 서버, 광고 서버, 이미지 서버, 지도 서버 등 수십 종류의 서버가 따로 돌고 있다. 브라우저의 요청이 이 중 어디로 가야 하는지를 앞단에서 판단하고 분배하는 것이 리버스 프록시(reverse proxy)다.
사용자가 검색어를 입력하면 검색 서버로, 지도를 열면 지도 서버로, 이미지 탭을 누르면 이미지 서버로 — 이 교통정리를 리버스 프록시가 한다. 사용자 입장에서는 google.com이라는 주소 하나만 알면 되고, 뒤에서 어떤 서버가 응답하는지는 전혀 신경 쓸 필요가 없다.
리버스 프록시가 하는 일은 단순 전달만이 아니다. SSL(Secure Sockets Layer) 인증서 처리, 로드밸런싱(부하 분산), 캐싱, 접근 제어, 요청 로깅 등도 여기서 담당한다. 앞단의 복잡한 일을 한 곳에서 처리하기 때문에 뒤쪽 서버들은 비즈니스 로직에만 집중할 수 있다.
그렇다면 이 앞단은 요청을 어떤 규칙으로 읽고 전달할까? 여기서 HTTP와 TCP, UDP 이야기가 나온다.
HTTP/HTTPS: 브라우저와 서버의 대화 방식
HTTP(HyperText Transfer Protocol)는 브라우저가 서버와 대화하는 규약이다. 규약이라는 표현이 낯설면 ‘언어’라고 봐도 된다. 브라우저가 “이 페이지 주세요”라고 요청하고, 서버가 “여기 있습니다”라고 응답하는 방식이 표준화되어 있는 것이다.
요청(Request)은 이런 형태다:
GET /index.html HTTP/1.1
Host: example.com
서버는 200 OK와 함께 HTML을 돌려준다. 이 요청-응답 구조가 HTTP의 핵심이다. 요청 하나에 응답 하나가 대응하는 단순한 구조다 보니, 웹 애플리케이션의 기반으로 자리 잡았다.
HTTPS는 이 대화를 암호화한 버전이다. HTTP 위에 TLS(Transport Layer Security)를 얹어서, 중간에서 누군가 엿들어도 내용을 알 수 없도록 만든다. 브라우저 주소창의 자물쇠 아이콘이 HTTPS가 적용됐다는 신호다. TLS 인증서 처리는 상당히 귀찮은 작업인데, 이 부분을 리버스 프록시가 대신 처리해 준다.
HTTP는 프로토콜 스택의 최상위 계층에 위치한다. 그 아래에 TCP가 있다.
TCP: 웹페이지가 정확히 로딩되는 이유
TCP(Transmission Control Protocol)는 데이터를 주고받기 전에 먼저 연결을 확립한다. 브라우저에서 구글을 열 때 실제로 일어나는 일을 보면 이해가 빠르다. 브라우저가 구글 서버에 “연결할게요”라고 신호를 보내고, 서버가 “준비됐어요”라고 응답하고, 브라우저가 “시작합니다”라고 확인한 뒤에야 비로소 데이터를 주고받기 시작한다.
이 과정을 3-way handshake라고 부른다1:
- SYN: “연결할게요”
- SYN-ACK: “알겠어요, 저도 준비됐어요”
- ACK: “네, 시작합니다”
TCP의 핵심 특성은 신뢰성이다. 데이터가 손실되면 재전송하고, 순서가 뒤바뀌면 순서를 맞춰서 전달한다. 느려지더라도 정확하게 전달하는 게 목표다.
구글 검색 결과 페이지가 깨지지 않고 온전하게 뜨는 건 TCP 덕분이다. HTML, CSS, JS 파일 전송 중 패킷 하나라도 빠지면 페이지가 깨지니까. 그래서 HTTP는 TCP 위에서 동작한다. 반면 모든 상황에서 신뢰성이 최우선인 것은 아니다.
UDP: 유튜브 라이브를 끊김 없이 보는 방법
UDP(User Datagram Protocol)는 연결 없이 데이터를 보낸다. 받았는지 확인하지 않고, 순서도 보장하지 않는다. 빠르지만 신뢰성은 없다.
그렇다면 UDP가 왜 필요할까? 유튜브 라이브 방송을 생각해 보자. 스트리머가 실시간으로 말하고 있는데, 0.5초 전 영상 프레임 하나가 네트워크에서 유실됐다고 재전송을 기다린다면? 그 사이 방송은 계속 진행되고 있으니 시청자 화면은 멈춰 있게 된다. 차라리 유실된 프레임은 건너뛰고 지금 프레임을 바로 보여주는 게 훨씬 낫다.
- 유튜브 라이브/Zoom 화상회의: 실시간성이 핵심이다. 5초 전 영상을 재전송받느니 현재 화면을 바로 받는 게 중요하다.
- 온라인 게임: 1초에 수십 프레임씩 위치 정보를 전송하는데, 패킷 하나 빠졌다고 재전송을 기다리면 캐릭터가 순간이동한다.
- DNS 조회: 브라우저 주소창에
google.com을 치면 먼저 DNS 서버에 “이 도메인의 IP가 뭐야?”라고 물어본다. 짧은 질문에 짧은 답변이라 TCP 연결을 맺는 오버헤드가 불필요하다.
최근의 QUIC 프로토콜(HTTP/3의 기반)도 UDP 위에서 동작한다. TCP의 신뢰성을 애플리케이션 레벨에서 구현하면서 TCP보다 빠른 연결 수립을 실현한 것이 QUIC의 핵심이다2. Google이 주도하고 현재 IETF 표준으로 채택되어, 주요 웹 서비스에서 이미 HTTP/3 기반 QUIC을 사용하고 있다.
OSI 계층: L4와 L7의 차이
네트워크 통신은 역할별로 계층을 나눈다. 이를 OSI 7계층 모델이라고 한다. 리버스 프록시를 이야기할 때 특히 중요한 것은 L4(4계층)와 L7(7계층)의 차이다.
graph TD
L7["L7: 응용 계층<br/>(HTTP, HTTPS, DNS)"]
L6["L6: 표현 계층<br/>(TLS/SSL, 인코딩)"]
L5["L5: 세션 계층<br/>(세션 관리)"]
L4["L4: 전송 계층<br/>(TCP, UDP)"]
L3["L3: 네트워크 계층<br/>(IP, 라우팅)"]
L2["L2: 데이터 링크 계층<br/>(이더넷, MAC)"]
L1["L1: 물리 계층<br/>(케이블, 신호)"]
L7 --> L6 --> L5 --> L4 --> L3 --> L2 --> L1
style L7 fill:#4f46e5,color:#fff
style L4 fill:#0891b2,color:#fff
L4 로드밸런싱은 IP 주소와 포트 번호만 보고 트래픽을 분산한다. 패킷 내용(HTTP 헤더, URL 등)을 열어보지 않는다. 그래서 처리가 빠르지만 세밀한 제어는 불가능하다.
L7 로드밸런싱은 HTTP 헤더, URL, 쿠키 등 애플리케이션 데이터를 보고 라우팅한다. /api/* 요청은 A 서버로, /static/* 요청은 B 서버로 보내는 것이 L7에서 가능하다. HTTP를 이해해야 이런 게 가능하기 때문에, L7 프록시는 반드시 HTTP 파싱 능력을 갖추고 있다.
Nginx와 Traefik은 모두 L7 프록시이면서 TCP/UDP(L4) 프록시 기능도 제공한다. 하지만 설계 철학은 완전히 다르다.
[!KEY] L4 프록시는 IP:포트 기반으로 패킷을 열어보지 않고 전달한다. L7 프록시는 HTTP 헤더와 URL을 읽어서 컨텐츠 기반 라우팅이 가능하다. 대부분의 웹 서비스에서 원하는 것은 L7이다.
Nginx: 검증된 설정 파일 기반 프록시
Nginx(엔진엑스)는 2004년 Igor Sysoev가 개발했다3. 당시 아파치 웹 서버가 동시 접속 처리에 한계를 보이던 시기(C10K 문제), 이를 이벤트 기반 비동기 아키텍처로 해결하면서 등장했다. 현재 Dropbox, Netflix를 포함해 3억 5천만 개 이상의 웹사이트에서 사용 중이다.
Nginx의 강점은 세 가지로 압축된다.
정적 파일 서빙 성능: HTML, CSS, JS, 이미지를 직접 서빙할 때 압도적이다. 메모리 사용량이 낮고 디스크 I/O 최적화가 잘 되어 있다.
검증된 안정성: 20년 이상의 프로덕션 운영 기록이 있다. 에지 케이스에 대한 문서와 커뮤니티 답변이 방대하다.
세밀한 설정 제어: nginx.conf에서 캐시, 헤더 조작, rate limiting, gzip 압축 등을 상세하게 제어할 수 있다.
server {
listen 443 ssl;
server_name example.com;
location /api/ {
proxy_pass http://api-server:8080;
}
location /static/ {
root /var/www;
expires 30d;
}
}
단점도 명확하다. Docker나 Kubernetes 환경에서 컨테이너가 새로 생기거나 IP가 바뀌면 설정 파일을 수동으로 수정하고 reload해야 한다. 자동화하려면 Consul Template, Confd 같은 별도 도구가 필요하다. Let’s Encrypt 인증서 갱신도 Certbot을 따로 붙여야 한다. 서비스 수가 늘어날수록 설정 파일 유지보수 부담이 비례해서 증가한다.
Traefik: 컨테이너 시대를 위한 자동화 프록시
Traefik(트래픽)은 2016년에 처음 공개됐다4. Go로 작성된 클라우드 네이티브 리버스 프록시로, 2026년 3월 기준 최신 버전은 v3.6이다.
설계 철학부터 다르다. Nginx가 “설정 파일에 모든 것을 명시한다”면, Traefik은 “인프라를 스스로 감지해서 설정한다”. Docker를 예로 들면:
- Traefik이 실행 중에 Docker 소켓을 감시한다
- 새 컨테이너가 시작될 때 해당 컨테이너의 라벨을 읽는다
- 라벨에 적힌 호스트 이름과 포트 정보로 라우팅 규칙을 자동 생성한다
# docker-compose.yml 예시
services:
myapp:
image: myapp:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(`myapp.example.com`)"
- "traefik.http.routers.myapp.tls.certresolver=letsencrypt"
이 라벨만 붙이면 Traefik이 Let’s Encrypt에서 인증서를 자동으로 발급받고, HTTPS 라우팅까지 구성한다. 별도 설정 파일 수정이 필요 없다. 컨테이너가 내려가면 라우팅 규칙도 자동으로 제거된다.
Kubernetes 환경에서는 Ingress 리소스나 Gateway API를 감시해서 동일하게 자동 설정한다. 마이크로서비스 수십 개를 운영할 때 각 서비스마다 Nginx 설정을 관리하는 것은 상당한 부담인데, Traefik은 이 문제를 라벨 기반 자동화로 해결한다.
Traefik의 웹 대시보드도 운영에 유용하다. 현재 라우팅 규칙, 미들웨어, TLS 인증서 상태를 UI에서 실시간으로 확인할 수 있다.
[!KEY] Traefik의 핵심 개념은 서비스 디스커버리(service discovery)다. 컨테이너가 뜰 때 별도로 알릴 필요가 없다. Docker 소켓이나 Kubernetes API를 통해 Traefik이 직접 감지하고 라우팅 규칙을 갱신한다.
트래픽 흐름도 비교
flowchart LR
Client["클라이언트<br/>(브라우저)"]
subgraph nginx_box["Nginx 방식"]
NP["Nginx<br/>(nginx.conf 수동 설정)"]
NA["App 서버 A"]
NB["App 서버 B"]
end
subgraph traefik_box["Traefik 방식"]
TP["Traefik<br/>(Docker 라벨 감지)"]
TA["컨테이너 A<br/>(라벨 설정)"]
TB["컨테이너 B<br/>(라벨 설정)"]
DS["Docker 소켓<br/>(감시)"]
end
Client -->|HTTP 요청| NP
NP --> NA
NP --> NB
Client -->|HTTP 요청| TP
TP --> TA
TP --> TB
DS -.->|컨테이너 이벤트 자동 감지| TP
성능: 원시 처리량은 Nginx가 앞선다
벤치마크 결과를 보면 Nginx가 Traefik v3 대비 약 36% 높은 요청 처리량을 보였다5. Nginx의 C 기반 이벤트 루프가 Go 런타임보다 낮은 오버헤드를 가진다는 점에서 예상 가능한 결과다.
다만 이 차이가 실제 운영에서 체감될지는 별개 문제다. 대부분의 웹 서비스에서 병목은 프록시 계층이 아니라 애플리케이션 서버나 데이터베이스다. 초당 수십만 요청을 처리하는 극한 환경이 아니라면, Traefik의 자동화 편의성이 성능 차이를 상쇄하고도 남는다.
언제 뭘 쓸지: 실용 가이드
아래 표는 대표적인 상황별 선택 기준이다.
| 상황 | 추천 | 이유 |
|---|---|---|
| 정적 사이트, 소규모 VM 운영 | Nginx | 설정 단순, 성능 우수 |
| Docker Compose 기반 홈서버 | Traefik | 라벨만으로 HTTPS 자동화 |
| Kubernetes 마이크로서비스 | Traefik (또는 ingress-nginx) | 자동 서비스 디스커버리 |
| 고성능 CDN/엣지 캐싱 필요 | Nginx | 캐싱 기능 성숙도 |
| Let’s Encrypt 자동화 우선 | Traefik | 인증서 발급/갱신 내장 |
| 기존 인프라, 팀 친숙도 | Nginx | 문서·커뮤니티 방대 |
단순하게 정리하면 이렇다. 컨테이너를 자주 올리고 내리는 환경이라면 Traefik이 운영 부담을 크게 줄여준다. 반면 컨테이너 없이 VM에서 Nginx를 쓰고 있고 별 불만이 없다면, 굳이 마이그레이션할 이유는 없다.
두 도구는 경쟁이 아니라 선택지다. 같은 환경에서 프론트엔드 정적 파일 서빙은 Nginx로, 내부 마이크로서비스 라우팅은 Traefik으로 쓰는 조합도 실제로 흔하다.
프로토콜 관점에서 마무리하면, HTTP는 L7에서 URL과 헤더를 보고 라우팅하는 언어이고, TCP/UDP는 그 아래에서 패킷을 실어 나르는 운반 방식이다. 리버스 프록시는 이 두 계층을 모두 다룰 수 있는 도구다. Nginx가 설정 파일로 그 제어권을 쥐는 방식이라면, Traefik은 인프라에 제어권을 위임하는 방식이다. 어느 쪽이 더 낫냐는 운영 환경에 달려 있다.
Footnotes
-
TCP 연결 수립(3-way handshake) 및 신뢰성 메커니즘. IETF RFC 793. https://www.rfc-editor.org/rfc/rfc793 ↩
-
QUIC 프로토콜의 UDP 기반 설계 및 HTTP/3 연관성. IETF RFC 9000. https://www.rfc-editor.org/rfc/rfc9000 ↩
-
NGINX 공식 사이트. https://nginx.org/en/ ↩
-
Traefik 공식 문서. https://doc.traefik.io/traefik/ ↩
-
hhf.technology, “Traefik v3 vs Nginx — Performance Analysis Deep Dive”. https://hhf.technology/blog/traefik-vs-nginx ↩
댓글