기존 배포 방식
서비스를 배포할 때마다 이 프로젝트는 내 AWS 계정에 있었는지, 팀원 계정에 있었는지, 프리티어 기간은 아직 남아 있는지, EC2 보안 그룹은 어디까지 열어뒀는지 같은 것들을 먼저 확인해야 했다.
정작 서비스 자체는 그렇게 크지 않았는데, 배포를 하려면 주변에 붙어 있는 설정들을 매번 다시 떠올려야 했다.
처음에는 그 방식이 크게 불편하지 않았다. AWS 프리티어 인스턴스 하나를 만들고 Docker Compose로 서비스를 올린 다음 nginx를 붙이면 웬만한 개인 프로젝트는 돌아갔고, 필요하면 RDS나 EC2를 하나 더 붙이면 됐으며, 팀 프로젝트에서도 빠르게 결과물을 보여줘야 할 때나 비용 측면에 있어 이 방식이 가장 현실적이었다.. 돈 없는 학생의 삶..
문제는 프로젝트가 하나둘 늘어나면서 같은 세팅을 계속 반복하게 됐고, 어느 순간부터는 서비스를 만드는 일보다 서비스를 둘 곳을 다시 정리하는 일이 더 귀찮아졌다.
대충 이런 흐름이었다.
프로젝트 서비스 배포
-> 프리티어 계정 생성
-> EC2 생성
-> 각종 자원 생성(RDS, Elasticache 등)
-> Docker / nginx / 인증서 설정
-> 배포 스크립트 정리
-> 다음 프로젝트에서 비슷한 과정 반복
DevOps가 어렵다고 느낀 것도 처음부터 거창한 이유는 아니었다. 대규모 트래픽을 받아야 한다거나 복잡한 인프라를 설계해야 한다는 이야기보다, 서버를 만들고 패키지를 설치하고 Docker를 깔고 nginx를 설정하고 인증서를 붙인 뒤 보안 정책과 배포 스크립트와 로그 모니터링까지 다시 챙기는 과정이 프로젝트마다 반복되는 쪽에 가까웠다.
올리려는 서비스는 작아도, 매번 새로 준비해야 하는 작업은 상당히 번거로웠다.
Terraform으로 인프라를 코드화하면 이 불편함을 어느 정도 줄일 수 있겠다는 생각에 실제로 그 방향도 고민해봤지만, 서비스마다 필요한 자원이 제각각이라는 점이 계속 걸렸다.
어떤 서비스는 API 서버와 DB 하나면 충분하고, 어떤 서비스는 DB 여러개가 필요하다. 어떤 서비스는 worker나 주기적으로 실행되는 job이 있어야 한다. 결국 Terraform을 쓰더라도 서비스마다 인스턴스를 어떻게 나눌지 다시 고민하게 됐다.
이쯤 되니 서버 단위로 서비스를 쪼개는 것보다 하나의 클러스터 위에서 pod 단위로 관리하는 쪽이 더 낫겠다는 생각이 들었다. 서비스를 새로 올릴 때마다 인스턴스를 하나 더 만들고 그 서버의 생명주기를 따로 관리하는 방식이 아니라, 이미 준비된 클러스터 위에 필요한 리소스만 얹고 싶었다.
단순히 서버 비용을 아끼려는 목적도 있었지만, 그보다 개인 프로젝트와 팀 프로젝트를 조금 더 운영답게 다뤄보고 싶다는 마음이 컸다.
Docker Compose 쓰면 되는거 아니야?
개인 프로젝트 몇 개를 올리는 정도라면 Docker Compose로도 충분하다. 서버 한 대에 compose 파일을 두고 docker compose up -d로 서비스를 띄운 뒤 nginx나 caddy로 외부 요청을 받아주면 되니까. 작은 서비스라면 이보다 단순한 방법을 찾기도 어렵고, 빠르게 결과물을 보여줘야 하는 상황에서는 여전히 가장 현실적인 선택지라고 생각한다.
서비스가 하나일 때는 이 방식이 단순해서 좋았다. 하지만 여러 개인 프로젝트와 자동화 도구를 계속 올려두려 하니, 단일 서버에 compose 파일을 계속 쌓아두는 방식이 점점 답답하게 느껴졌다. 앱 서버, DB, Redis, worker, 배치 작업, 자동화 도구가 한 서버 안에 섞이기 시작하면 어디까지를 하나의 서비스로 보고 어떻게 나눠서 운영할지도 애매해졌다.
그래서 단순히 컨테이너를 실행하는 것을 넘어, 여러 서비스를 한 환경 안에서 배포하고 관찰하고 관리하는 흐름을 만들어보고 싶었다. 무중단 배포를 조금 더 안정적으로 해보고 싶었고, 서비스별 리소스 배치나 네트워크 경계도 서버 단위가 아니라 워크로드 단위로 다뤄보고 싶었다. Argo CD 같은 GitOps 도구나 모니터링 도구도 실제 서비스가 올라간 환경에서 직접 붙여보고 싶었다.
지금 만들고 있는 코스피 공포 탐욕 지수 서비스나 n8n 같은 자동화 도구도 나중에는 이 환경 위에 올려보고 싶었다. 그러려면 단일 서버에 compose 파일을 쌓아두는 방식보다 잘 유지보수 할수있는 환경이 필요했다.
Docker Compose로도 어느 정도는 가능하지만, 서버 한 대에 모든 걸 몰아넣으면 그 서버가 죽을 때 전부 같이 죽는다. 개인 홈서버에서 SPOF를 완전히 없애겠다는 말은 조금 과하더라도, 적어도 서비스를 어떻게 나누고 배포하고 관찰할지 운영에 가까운 방식으로 연습해보고 싶었다.
ECS 같은 선택지도 있었고 AWS에서 관리형으로 가져가면 편한 부분도 많지만, 공부와 개인 프로젝트를 위해 계속 켜둘 환경에 매달 비용이 들어가면 안됐다. 그래서 여러 클라우드를 서칭을 하다 OCI를 발견하게 되는데..!
OCI Always Free를 만나다

Oracle Cloud Infrastructure(OCI). 4 OCPU에 24GB RAM을 무료로 쓸 수 있다는 조건은 AWS 프리티어 인스턴스 1 OCPU 1GB RAM을 쓰던 나에게는 정말 엄청났다.. 물론 무료라는 말만 보고 아무거나 만들 수는 없고, OCI도 부트 볼륨이나 LB, NAT Gateway 같은 리소스를 잘못 만들면 비용이 나올 수 있었지만 4코어 24GB를 무료로 쓸 수 있다면 뭐든 만들 수 있을거 같았다.

처음부터 현업처럼 Kubernetes 운영을 하려는 건 아니었다. OKE를 쓰거나 관리형 DB를 붙이거나 LB를 바로 만드는 방향은 제외했다. 대신 4코어 24GB를 3대 VM으로 나누고 그 위에 k3s를 올린 뒤, 무료 한도 안에서 필요한 도구를 하나씩 붙여보기로 계획했다.
K8s은 꽤 무겁기도 했고 지금 내가 감당할 수 있도록 규모를 천천히 키워가기로.
k3s를 선택한 이유도 내가 하려는 규모에서는 일반 Kubernetes보다 부담이 적고, 단일 server와 여러 agent 구성으로 시작하기도 좋으며, Kubernetes API는 그대로 쓰기 때문에 Deployment와 Service, Ingress, CRD, Controller 같은 흐름을 익히기에도 충분하다 판단했다.
단순히 컨테이너를 띄우는 경험보다 운영 도구들이 클러스터 안에서 리소스를 만들고 관리하는 과정을 직접 보고 싶었다. Argo CD가 Git 상태를 보고 클러스터를 맞추는 과정, cert-manager가 인증서를 발급하고 갱신하는 과정, 모니터링 도구가 노드와 pod 상태를 수집하는 과정을 내 서비스가 올라간 환경에서 겪어보고 싶었다.
일단은 작게 나눠서 시작하자
현재 생각한 구성은 3노드다. OCI A1 무료 한도인 4 OCPU와 24GB RAM 안에서 역할을 나눠 아래처럼 계획했다.
노드 자원 역할
| ryuwon-core | 1 OCPU / 8GB | k3s server, Argo CD, 운영 도구 |
| ryuwon-data | 1 OCPU / 6GB | DB, Redis, PVC, 백업 대상 데이터 |
| ryuwon-app | 2 OCPU / 10GB | public ingress, 웹앱, worker |
처음에는 data 노드에 메모리를 더 주는 것도 고민했다. DB를 많이 올릴 거라면 그게 더 자연스러울 수 있지만, 지금은 DB보다 클러스터 운영 도구와 GitOps 흐름을 먼저 안정화하는 게 우선이라고 봐서 일단 core에 8GB를 줬다. 실제 메모리 사용량을 보고 나면 이 배치는 다시 바뀔 수 있고, 홈랩을 처음부터 정답처럼 설계하려고 하기보다 지금 이해할 수 있는 구조로 시작한 뒤 관찰하면서 바꾸는 쪽이 나에게는 더 맞다고 봤다.

네트워크도 처음부터 크게 열지 않으려고 해서, 기본 방향은 ryuwon-app만 외부 진입점으로 두고 나머지 노드는 내부 관리용으로 두는 방식이다.
Internet
-> ryuwon-app
-> Ingress / Gateway
-> internal services
인터넷에서 들어오는 80/443 요청은 ryuwon-app의 Ingress나 Gateway를 지나 내부 서비스로 전달한다. ryuwon-core와 ryuwon-data는 외부 HTTP를 열지 않는 쪽으로 잡았다.
참고했던 PMH 홈랩처럼 세 노드를 모두 public edge로 쓰는 구성도 있지만, 현재는 내 IP에서만 접근하도록 제한한 다음 단순하게 시작하고 필요해지면 그때 확장하는 쪽이 낫다고 판단했다.
앞으로 쓸 내용
이 글은 완성된 홈랩 소개가 아니라 시작 단계의 기록이다. 중간에 분명히 많이 막힐 듯해서, 이 시리즈는 정답 아키텍처를 설명하기보다 내가 어떤 선택을 했으며, 왜 그런 선택을 했고 어디서 막혔는지 남기고자 한다.
지금 생각해둔 내용은 음..
- VCN, Subnet, NSG를 어떻게 잡았는지
- k3s server와 agent를 어떻게 붙였는지
- Argo CD로 DevOps
- Ingress와 TLS를 붙이는 과정
- 모니터링과 백업 전략을 잡는 과정
처음부터 완벽하게 만드는건 불가능하다 생각하기에 이해할 수 있고, 유지보수를 생각하는 구조로 시작하고자 한다. 잘 되면 개인 프로젝트를 하나씩 올리면 되고, 안 되면 삽질한 내용을 글로 남기면 된다..!

이제는 계정별 EC2에 흩뿌려두는 방식에서 탈출하고 싶다.. 사실 얼마전에 프리티어 만료된지 모르고 그대로 두다가 금액이 꽤 나와서... 이번에는 흩어진 배포 환경을 정리하며 유지보수를 편하게 할 수 있는 환경을 만들어보려고 한다.