쿠버네티스(Kubernetes)를 공부하며 클러스터 내부의 서비스를 외부에 노출하는 방법을 NodePort와 공유기 설정에서 포트 포워딩(Port Forwarding)이라는 번거로운 과정을 거쳤습니다.
하지만 Cloudflare Tunnel을 만나면 이야기가 달라집니다. 우리 집에 있는 서버의 K8s 클러스터도 공인 IP 하나 없이 단 몇 분 만에 안전한 도메인으로 연결할 수 있습니다.
어떻게 외부에서 들어오는 문을 열지 않고도 트래픽이 클러스터 내부의 Pod까지 안전하게 배달되는 걸까요? 오늘은 취업 준비를 하며 깊게 파고들었던 Cloudflare Tunnel의 아키텍처와 트래픽 흐름을 정리해 보려 합니다.
1. 핵심 매커니즘: Reverse Tunneling
일반적인 웹 서버는 외부 사용자가 접속할 수 있도록 방화벽에서 특정 포트(80, 443 등)를 열어둬야 합니다. 하지만 Cloudflare Tunnel은 정반대입니다.
- Outbound Connection: K8s 클러스터 내부에서 실행 중인 cloudflared라는 경량 데몬(에이전트)이 Cloudflare의 가장 가까운 Edge 서버로 먼저 아웃바운드 연결을 시도합니다.
- Persistent Connection: 이 연결은 HTTP/2 기반의 암호화된 터널로 유지됩니다.
- No Inbound Ports: 결과적으로 외부에서 클러스터로 직접 들어오는 포트를 하나도 열지 않아도(Inbound 0개), 이미 연결된 통로를 통해 트래픽이 거꾸로 들어올 수 있게 됩니다.

2. Kubernetes 내부에서의 트래픽 흐름
사용자가 도메인(예: myapp.example.com)에 접속했을 때의 과정입니다.
Step 1: Cloudflare Edge
사용자의 요청이 Cloudflare 네트워크에 도착합니다. Cloudflare는 이 도메인이 특정 터널 ID와 연결되어 있음을 인지하고, 해당 터널을 뚫어놓은 cloudflared로 트래픽을 보냅니다.
Step 2: cloudflared Pod (Connector)
K8s 클러스터 안에서 Deployment 형태로 떠 있는 cloudflared Pod가 이 트래픽을 수신합니다.
이때 cloudflared는 외부 인터넷과 통신하는 Gateway 역할을 수행합니다.
Step 3: K8s Service (Internal Routing)
cloudflared 설정 파일(config.yaml)에는 특정 호스트네임이 어떤 내부 주소로 가야 하는지 적혀 있습니다.
- 예: service: http://frontend-service:80
- cloudflared는 K8s 내부 DNS를 이용해 frontend-service라는 Service IP로 트래픽을 전달합니다.
Step 4: Target Pods
마지막으로 K8s Service는 내부 로드밸런싱을 통해 실제 애플리케이션이 돌아가는 Pod로 트래픽을 최종 전달합니다.

3. 이 방식의 장점
- 보안 (Zero Trust): 공인 IP가 필요 없고 방화벽의 모든 인바운드 포트를 닫아도 됩니다. DDoS 공격이 클러스터에 도달하기 전에 Cloudflare 단에서 차단됩니다.
- 고가용성 (HA): cloudflared를 Deployment로 배포하고 복제본(Replicas)을 늘리면, 여러 개의 터널이 동시에 맺어져서 하나가 죽어도 끊기지 않는 가용성을 확보할 수 있습니다.
- 간편한 설정: 별도의 Ingress Controller(Nginx, Traefik 등)나 복잡한 LoadBalancer 타입의 서비스 설정 없이도 외부 노출이 가능합니다.