archived-old-homelab

(Project) HomeLab Cluster - Service Production with Hybrid Cloud Connectivity (6)

date
Aug 20, 2024
slug
homelab-cluster-service-production-hybrid-architecture
author
status
Public
tags
Archived
summary
HomeLab Cluster와 AWS를 연결하여 On-Premise의 Service Production에서 발생하는 문제들을 해결
type
Post
thumbnail
Overall-Architecture.png
category
archived-old-homelab
updatedAt
Oct 1, 2025 06:22 AM
 

Index

  1. Introduction
  1. Problem Definition
  1. Solution
  1. Hands-On
  1. Result
  1. Conclusion
 

Introduction

안녕하세요 Yureutae입니다.
이번 포스팅은 HomeLab Cluster에서 Service Production을 어떻게 야매(?)없이 해내는 가에 대해 작성되었습니다.
Cloud Club(https://www.cloudclub.kr/) 내에서 HomeLab을 같이 구축하는 스터디원 분들과 해당파트에 대해 정말 많이 고민하고, 가설을 세우고, 테스트해서 해결했습니다. (사실 네트워크 공부를 더 깊게 많이 했더라면 빨리 끝나지 않았을까)

Problem Definition

Service Production

일전에 진행했던 VPN을 통한 클러스터 접근과 달리, Service Production의 경우 불특정 다수를 대상으로 하게 됩니다.
A라는 애플리케이션을 누구나 접속할 수 있게 배포를 하는 상황을 가정해봅시다. AWS에선 간단하게 인스턴스에 EIP를 할당하거나 ELB를 통해 서비스 노출이 가능하며 자본이 허락하는 이상 무한정 할당이 가능합니다.

Public IP

하지만 홈 네트워크에서는 상황이 달라집니다. 일반적으로 ISP(통신사)는 가정용 환경에 대해 Public IP를 동적으로 할당하며, 이 동적 IP는 수시로 변동됩니다. 물론 라우터(공유기)가 꺼지지 않는 이상 변동되긴 쉽지 않은데, 그래도 유의할 부분이죠. 여러 Public IP를 끌어오는 것도 가능은 한데 ISP와 법적으로 충돌할수도…?
정적 IP의 경우는 ISP에 연락해서 대개 추가 요금을 주고 할당을 할 수 있습니다.
Public IP 종류
Public IP 종류
커피한잔 김재호님의 홈서버 운영 관련 리뷰. 거의 안바뀐다고 한다.
커피한잔 김재호님의 홈서버 운영 관련 리뷰. 거의 안바뀐다고 한다.
 

DDNS

이 경우 대체 방안으로 DDNS를 생각해볼 수 있습니다.
(대개 구글에 ‘홈서버 서비스 노출’ 를 검색하면 국내는 포트포워딩과 DDNS 관련 글이 90% 입니다.)
DDNS 컨셉 및 실제 iptime에서의 설정
DDNS 컨셉 및 실제 iptime에서의 설정
DDNS는 쉽게 말해서 외부 DNS 서버에서 Public IP 변동을 잡아내면서 특정 도메인 네임에 동적으로 매핑시키는 기술입니다. 즉 위처럼 iptime 측에서 제공하는 DDNS 서비스를 등록하고나면 ISP에서 Public IP가 변경되더라도 xxx.iptime.com으로 접근이 가능합니다.
다만 iptime이라는 루트 도메인에 서브도메인으로 등록되며, 해당 도메인에 대해 관리가 불가능하며 와일드카드 인증서가 없어 추가적인 서브도메인을 만들 수 없고 CA로부터 TLS 인증서를 받는 것 또한 불가능합니다.
(아래처럼 Cloudflare 등에서 DDNS 인증 프로세스를 HomeLab에서 직접 구성하는 방법도 존재하긴 합니다.)
 
 

Metal LB?

On-Premise Kubernetes에서는 Metal LB 등으로 Load Balancer를 대체하곤 합니다. 문제는 Metal LB를 사용한다고 근본적인 Public IP 부족 문제를 해결할 순 없습니다.
또한 Metal LB 자체가 야매(?)스러운 면이 많고, Calico 등의 CNI와 충돌 이슈도 있습니다. (공식적인 Docs에 명시되어있는 부분)
 
 

Solution

이 부분 해결을 많이 고민해봤고 여러 사람들과도 얘기를 해보았지만, Public IP 관련 부분을 완전히 해결할 순 없었습니다. (근본적으로 불가능한 문제였는데, 어떻게든 가능하지 않을까하면서 쓸데없이 시간을 버린 것 같습니다 ㅋㅋ)
결국 선택한 것은 Cloud를 HomeLab Cluster와 연결하는 것이었습니다. Cloud와 연결함에도 하나의 원칙을 두었는데,Cloud Service에 대한 의존성/비용 등을 최소화하고 세팅 과정을 간소화/자동화 하자 였습니다.
 
아래 이미지는 최종적인 구성도입니다. 트래픽 흐름은 아래와 같다 보시면 될 것 같습니다.
💡
Route53 <-> ALB <-> EC2 (NGINX with NordVPN) <-> Ingress Nginx Controller (NodePort. ip는 vpn ip) <-> Ingress <-> Service (Cluster IP) ↔ Pod Container
왜 이렇게 만들었는지 하나씩 설명해보겠습니다.
Service Production with Hybrid Cloud Connectivity 구조도
Service Production with Hybrid Cloud Connectivity 구조도
 

AWS Site-to-Site VPN (채택 x)

Public IP 관련 문제를 해결할 수 없음을 인정하고 나선, Cloud와 연결하는 방법을 찾기 시작했습니다. 그 중 대표적인 것이 Site-to-Site VPN 이였습니다.
AWS에서 제공하는 관리형 VPN 서비스로 온프레미스 네트워크나 다른 클라우드 네트워크와 AWS의 VPC를 IPsec를 통해서 안전하게 연결할 수 있도록 해줍니다.
이 서비스를 택해서 비교적 쉽게 구성이 가능할 수도 있겠지만…비용이 최소 72$가 발생하며, 해당 클라우드 서비스에 의존하게 됩니다.
저는 제 HomeLab Cluster가 특정 서비스에 의존되지 않기를 원해 해당 옵션은 포기했습니다.
 

Third Party VPN Meshnet Service

AWS로 들어오는 Traffic만 Forwarding하면 끝 아닌가?
AWS Site-to-Site VPN이나 기존에 사용하던 NordVPN Meshnet 이나 현재 구조 목적으로만 보았을 때는 큰 차이가 없는 것 같았습니다. 암튼 간에 클라우드랑 연결만 되면 장땡인 거죠.
그래서 생각한 방법은 다음과 같습니다.
  • Domain, SSL 갱신/인증 과정은 AWS에서 죄다 처리
  • AWS EC2에 NGINX를 설치하고 VPN Meshnet 파티에 가입시킨 후에 트래픽 포워딩만 하는 역할로 할당
이 방법은 비단 AWS 뿐만 아니라 다른 CSP에서의 기초적인 서비스에서도 동일하게 사용이 가능하며, 컴퓨팅 인스턴스의 최소 사양으로도 구축이 가능하기 때문에 도메인 구입과 트래픽 발생 정도에 따른 비용을 제외하면 추가 비용이 거의 없습니다. (도메인 구입, 트래픽 발생 비용은 서비스를 노출하는 시점에서는 당연…그래도 트래픽 비용은 상업용으로 쓰지 않는 이상 거의 없다고 보심 됩니다.)
 

NGINX Ingress Controller on HomeLab Cluster

외부에서 클러스터 내 서비스에 접근이 가능하게 만드는 방법 중 하나에는 Ingress가 있습니다.
  • 클러스터 외부 트래픽을 Ingress 오브젝트 배포를 통해 중앙 관리 가능.
  • NGINX처럼 라우팅/로드밸런싱/HTTPS 가능
 
💡
Ingress는 아래 이미지처럼 Host Name 지정이 가능하기 때문에, Cloud Service에 종속이 생기는 것이 아닌 사용할 Domain에 종속이 생깁니다. Domain과 VPN Meshnet에서 부여된 가상 ip만 있다면 CSP가 뭐든, 이관을 하든 HomeLab Cluster는 Ingress에서 지정한 Host Name으로 오는 트래픽만 신경쓰면 된다는 얘기죠.
notion image
 
Ingress 리소스를 Ingress Controller로 관리하기 때문에, Ingress를 사용하기 위해서는 Ingress Controller를 먼저 배포해야합니다.
On-Premise에서는 당근 CSP에 종속되는 Ingress Controller를 사용하지 못하기 때문에 아래 이미지와 같은 Ingress NGINX Controller를 사용해야합니다.
NGINX Ingress Controller 컨셉
NGINX Ingress Controller 컨셉
 

AWS Services

notion image
AWS의 네트워크 서비스를 끌어올 수 있게 되면서 편의성이 증진되었습니다.
Route 53에서 커스텀 도메인 구입 및 서브 도메인 구성이 가능해졌으며, ACM에서 해당 도메인에 대한 루트 도메인 SSL 인증서, 와일드카드 도메인 SSL 인증서 발급이 가능해졌습니다. Route 53에서 쉽게 AAA record를 통해 AWS ALB에 도메인을 매핑해줄 수 있게 되었으며 ALB 단에서는 ACM으로부터 인증서를 긁어오면 HTTPS 통신이 가능하게 되었습니다.
HomeLab Cluster 내 서비스들은 굳이 개별 도메인 생성이나 인증서를 발급할 필요가 없기에, 와일드카드 SSL 인증서로 모든 서브도메인에 대해 HTTPS 통신이 가능하게 했습니다.

Hands-On

이제 구조도에 따라 실제 구축을 진행해보겠습니다.
테스트 애플리케이션은 Kubernetes Dashboard를 사용했습니다.

HomeLab Cluster

Ingress NGINX Controller

Ingress NGINX Controller를 설치하기 위해 Docs를 들어갑시다. 각종 설치 방법이 있는데 저는 Helm보다 쌩 yaml이 편해서 적혀있는 링크의 것을 wget으로 먼저 다운로드했습니다.
https://kubernetes.github.io/ingress-nginx/deploy/
아래 조건으로 yaml을 편집해봅시다.
  • Service Type을 NodePort로 교체했습니다. (Ingress NGINX Controller의 NodePort를 단일 진입점으로 사용합니다.)
  • 각 노드를 모두 노출시켜 트래픽을 분산처리 할 수 있도록, Deployment 대신 DaemonSet 리소스로 Ingress NGINX Controller Pod를 각 노드마다 배포했습니다.
Service Type NodePort.
Service Type NodePort.
 
DaemonSet. Controle Plane에도 올릴 거면 Tolerations 설정해주자.
DaemonSet. Controle Plane에도 올릴 거면 Tolerations 설정해주자.
결과
결과
 

Ingress Resource

Ingress도 Kubernetes Docs를 참고해서 작성해줍시다. 저는 지정한 host ( k8s-dashboard.yureutae-homelab-cluster.com )로 접근이 오면 동일 namespace 내 kubernetes-dashboard 라는 Service 오브젝트로 향하게 했습니다.
notion image
 

AWS Setting

AWS 관련 포스팅이 아니기 때문에 심플하게 진행하겠습니다. Terraform으로 만들어둬서 거의 결과해석입니다.
 
  • 아래 docs를 참고하여 도메인을 구입해줍시다. 저는 yureutae-homelab-cluster.com 으로 구입했습니다. 서브 도메인의 경우 Route 53에서 루트 도메인 레코드에 NS를 넘겨주면 됩니다.
이렇게 많이 해놔도 상관없음.
이렇게 많이 해놔도 상관없음.
 
  • ACM에서 Route 53을 통해 구매한 도메인에 대해 SSL 인증서를 발급해줍시다. 등록 시 와일드카드를 붙이면 와일드카드 인증서, 루트 도메인 인증서를 같이 발급해줍니다.
와일드카드가 편해~
와일드카드가 편해~
 
 
  • EC2에 NGINX 설치 후 config 작성을 해줍시다. 저는 HomeLab Cluster의 모든 노드(Meshnet IP)를 사용할 것이기 때문에 NGINX 단에서 로드밸런싱 설정을 해줬습니다. 앞서 설명한대로 서브도메인 접근도 후딱 포워딩하도록 와일드카드에 대해 리버스 프록싱 설정을 했습니다. HTTPS를 해당 단까지 넘겨도 되긴한데, 딱히 지금은 필요하지 않아서 HTTP 프록싱 처리만 해두었습니다.
Nginx conf 설정. 으레 그렇듯이 작성 후 sites-enabled로 심볼릭 링크 걸면 끝
Nginx conf 설정. 으레 그렇듯이 작성 후 sites-enabled로 심볼릭 링크 걸면 끝
  • ALB는 사실 써도되고 안써도 됩니다. 그냥 EC2에 때려박아도 돼요. 어차피 지금 구조에서 실질적인 로드밸런싱이나 리버스 프록싱은 EC2-NGINX가 처리하고 있기 때문에… (그냥 프리티어 단에선 어차피 돈 안나와서 하는김에 해놨음) ALB 세팅하고 나선 Route53에서 A Record로 넘겨주면 됩니다.
이상적인 구조면 이게 맞긴 해
이상적인 구조면 이게 맞긴 해
 

Result

 
서비스를 여러 개 구성해서 올려놨는데 잘 접속되고 SSL 인증도 잘 박혀있습니다.
notion image
notion image
트래픽이 아래처럼 거쳐가는 단계가 많아서 느릴까 걱정했는데, 느리지도 않습니다. (사용자가 끽해야 5명도 안될 건데 느릴리도 없고…)
💡
Route53 <-> ALB <-> EC2 (NGINX with NordVPN) <-> Ingress Nginx Controller (NodePort. ip는 vpn ip) <-> Ingress <-> Service (Cluster IP) ↔ Pod Container
각 노드의 ingress nginx controller에도 잘 로드밸런싱 되는 중
각 노드의 ingress nginx controller에도 잘 로드밸런싱 되는 중

Conclusion

최종적인 현재 HomeLab Cluster 구조도
최종적인 현재 HomeLab Cluster 구조도
오늘은 HomeLab Cluster에서 홈 네트워크의 Public IP나 DDNS 없이 서비스 노출을 하는 방향에 대해서 소개했습니다. 일반적으로 구글링을 통해서 많이 나오는 “포트포워딩” “DDNS” “Public IP 끌어오기” 등을 사용하지 않고, 클라우드와 VPN을 통해 연결하되 클라우드 서비스에 대한 의존성을 최소화했습니다.
하이브리드로 구성했지만, Cluster 자체는 클라우드 서비스나 벤더에 의존하지 않게 만들었다는 얘긴데, HomeLab Cluster가 다른 네트워크로 이관되든 클라우드 벤더를 변경하든 상관없이 1) VPN Meshnet 구성 유지 2) Domain 보유 만 지속되면 기존과 동일하게 사용할 수 있는 거죠.
막상 진행하고나니 이렇게 오래 걸릴 거였나라고 생각되지만, 직접 문제를 인식하고 꾸준히 생각하여 아이디어를 스스로 내어 개선한 제대로된 경험이라는 면에서 뿌듯함을 느낍니다.
 
현재 해당 포스팅 작업이 끝난지 한 1달 반 정도 된 것 같은데요, Managed Kubernetes Service 사용처럼 큰 불편함 없이 사용 중입니다. 물론 Jenkins처럼 특정 Application이 SSL 인증서를 Container 단까지 끌고오는 것을 요청하면 머리가 아플 때도 있습니다. (괜히 ACM을 썼나 싶습니다. ACM 발급 SSL 인증서를 On-Premise까지 어케 들고오지….) (+ 아마 Istio 등의 Service Mesh를 건드리기 전까진 위 구조도에서 크게 변경되지 않을 것 같습니다. 아마 한참 걸릴 거 같습니다. Istio의 필요성을 아직 직접 몸으로 체감못하고 있어서…)
 
지금은 제가 느꼈던 HomeLab의 재미(?)와 상호정보교류를 위해서 Cloud Club에 스터디를 열어 멤버들과 진행 중입니다. 근래에는 스터디원들과 CI/CD 구축을 진행하고, 인프랩의 DORA Metric Monitoring을 한번 핸즈온해보는 것을 계획 중입니다.
 
 
+ 2달 간에 노력 끝에 8월 말부터 신입으로 DevOps Engineer 직무로 일하게 되었습니다 🎉🎉🎉. 많은 면접에서 HomeLab을 매우 좋게 봐주시는 것을 느꼈습니다. (면접썰…현직 DevOps Engineer 분들이 이미 많이들 MiniPC로 HomeLab 만들어서 가지고 놀고 옆 엔지니어들에게 열렬하게 구매를 권장한다카더라….듣는사람은 이뭔ㅆ…)
이걸 바라고 프로젝트 한 건 아니지만 앞으로도 HomeLab 프로젝트를 열심히 할 동기를 얻었습니다. 앞으로도 열심히 진행하고 공유하도록 하겠습니다. 감사합니다 ㅎ