그림으로 보는 클라우드 하모니 구성도
글로만 설명하던 구조를 그림 세 장으로 정리했습니다. 파란 선이 실제 운영(prd) 요청과 자동 배포 경로입니다.
1. Kubernetes 클러스터 — 요청이 지나가는 길
사용자 요청은 Cloudflare 터널 → Envoy Gateway → HTTPRoute → web 으로 들어오고, web 이 클러스터 안에서 api 를 호출합니다
- 서버는 사무실 Mac 한 대이고, 그 안의 Docker 컨테이너 두 개가 Kubernetes 노드 역할을 합니다 (kind).
- 바깥 요청은 Cloudflare 터널로만 들어옵니다. 사무실이 이중 NAT라서 포트를 여는 대신, 클러스터 안의
cloudflared가 바깥으로 연결합니다. - Envoy Gateway 하나가 모든 요청을 받습니다. Host 헤더가
dev.localhost면 dev Namespace, 그 외에는 prd Namespace로 보냅니다. - api는 Gateway에 연결되지 않은 내부 전용입니다. web만 클러스터 DNS(
http://api)로 호출할 수 있습니다.
2. 애플리케이션 — 서버와 프론트
web 모노레포의 apps/web 이 api 의 interfaces 계층을 REST 로 호출하고, api 는 네 계층으로 나뉘어 markdown 글을 읽습니다
- web (SvelteKit): 홈페이지와 블로그를 서버에서 렌더링(SSR)합니다.
packages/api-client는 나중에 만들 Tauri 관리자 앱도 같이 씁니다. - api (Spring Boot):
interfaces → application → domain ← infrastructure네 계층으로 나눴습니다. 저장소 인터페이스는 domain에 있어서, 글을 DB로 옮겨도 infrastructure 구현체만 바꾸면 됩니다. - 지금 보고 계신 이 그림도 api 저장소의 SVG 파일입니다. 서버가 글을 렌더링할 때 본문에 그대로 넣기 때문에 다크 모드 색도 따라갑니다.
3. CI/CD — push 에서 배포까지
develop 에 push 하면 사무실 Mac 의 runner 가 빌드 → kind load → terraform apply 로 배포하고 기록을 infra 저장소에 남깁니다
develop에 push하면 dev에 자동 배포되고,release/YYYYMMDD브랜치에서 Deploy prd를 수동으로 실행하면 운영에 배포됩니다.- 이미지 레지스트리 없이, 같은 Mac에서 빌드한 이미지를
kind load로 노드에 바로 넣습니다. - 어떤 이미지가 배포됐는지는 infra 저장소에 커밋으로 남습니다. 롤백할 때는 그 파일을 이전 값으로 되돌리면 됩니다.
← 기술블로그 목록지금은 학습과 사내 운영 단계입니다. 상시 운영 서버(k3s 또는 EKS/GKE)와 고정 도메인으로 옮기더라도 2·3번 그림은 거의 그대로이고, 1번에서 kind와 터널 부분만 바뀝니다.