내 $70 쿠버네티스 클러스터를 인터넷에 노출시켰다 (포트를 하나도 열지 않고)
Source: Dev.to
문제
로컬에서는 http://192.168.0.173:30300 로 Grafana에 접근했습니다.
인터넷에 포트를 열어두는 것은 현관문을 잠그지 않는 것과 같습니다. GTX 1070 Ti에서 암호화폐 채굴기가 실행될 위험을 감수하고 싶지 않았습니다.
필요한 조건은 다음과 같습니다:
- 보안 – 포트를 열지 않음.
- 무료 – 예산을 절감.
- 공개 –
subdomain.domain.com으로 접근 가능.
그 해법이 Cloudflare Tunnel 입니다.
제로 트러스트 전환
DNS 마이그레이션
| 기존 방식 | 새로운 방식 |
|---|---|
| Squarespace Registrar → Netlify DNS | Squarespace Registrar → Cloudflare DNS → Netlify (메인 사이트) + Tunnel (서브도메인) |
네임서버를 Cloudflare로 이전했으며, 기존 레코드가 자동으로 가져와져 다운타임 없이 전환되었습니다.
Kubernetes에 cloudflared 배포
각 노드(예: Pop!_OS 데스크톱, Ubuntu 노트북)마다 바이너리를 실행하는 대신, 터널 커넥터를 네이티브 Kubernetes 배포로 만들었습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: cloudflared
spec:
replicas: 2
template:
spec:
containers:
- name: cloudflared
image: cloudflare/cloudflared:latest
args:
- tunnel
- --no-autoupdate
- run
- --token
- $(TUNNEL_TOKEN)
이제 클러스터가 자동으로 Cloudflare에 연결됩니다. 노드가 재부팅되면 Kubernetes가 포드를 재스케줄하고 터널이 즉시 재연결됩니다.
NodePort는 안녕, 서브도메인은 안녕
Cloudflare 대시보드(Network > Tunnels)에서 공개 호스트명을 내부 ClusterIP(또는 NodePort)와 매핑했습니다:
grafana.bhargavmantha.dev → http://192.168.0.173:30300ollama.bhargavmantha.dev → http://192.168.0.173:31434uptime.bhargavmantha.dev → http://192.168.0.173:30001
SSL 인증서는 Cloudflare가 엣지에서 자동으로 처리하므로, 클러스터 내에서 cert‑manager나 Let’s Encrypt를 설정할 필요 없이 자물쇠 아이콘을 얻을 수 있습니다.
배운 교훈
교훈 1 – 홈랩에서는 Ingress Controller가 과도함
MetalLB와 함께 Traefik 또는 Nginx Ingress를 설정하려고 며칠을 보냈습니다. Cloudflare Tunnel은 그 전체 레이어를 우회합니다. Ingress Controller가 필요 없고, 커넥터만 있으면 됩니다.
교훈 2 – 보안은 편리할 수 있다
모든 트래픽을 Cloudflare 뒤에 두면 나중에 Access Application 레이어를 추가할 수 있습니다. 예를 들어 grafana.bhargavmantha.dev에 Google/GitHub 로그인 화면을 적용해 2FA를 제공함으로써, 기본적으로 2FA를 지원하지 않는 앱도 보호할 수 있습니다.
현재 상태
- 공개 접근 가능: Grafana, Uptime Kuma, Open WebUI.
- 비용: $0 (Cloudflare 무료 플랜).
- 보안: 열려 있는 포트 0개.