Sandcorp샌드코프 · 웹·AI 제품 개발

새 프로젝트 받는 중 · 갱신 2026.10sandcorp.co.krGitHub

← 기록

인프라백업모니터링CI/CD운영

서버 다섯 대에 일 하나씩 — 한 대가 죽으면 무엇이 같이 죽나

운영·빌드·감시·작업·집 서버로 나뉜 Sandcorp 인프라가 지금 모양이 된 사흘의 기록입니다. 운영 서버가 자기 자신을 감시하던 구조, 있다고 믿었던 백업, 맥북을 들고 나가자 멈춘 빌드를 어떻게 나눠서 풀었는지 적었습니다.

서버 다섯 대에 일 하나씩

운영 서버가 자기 자신을 감시하고 직접 빌드하던 구조를, 한 대가 죽어도 다른 일은 멈추지 않게 나눈 기록

왜 나눴나

Sandcorp의 서비스(이 블로그와 포트폴리오, AI 뉴스, 코딩 교육, 챗봇 등)는 클라우드의 arm64 서버 한 대에서 돕니다. 그 밖에 집 서버, 작업 서버, 맥, 감시 서버가 있고, 대표 PC에서 Claude 조율 세션이 전체를 지휘합니다.

처음부터 역할을 나눠 설계한 것은 아닙니다. 2026년 10월 말 서버 지도를 그리면서 「이 서버가 죽으면 무엇이 같이 죽나」를 하나씩 따져 봤고, 그 답이 마음에 들지 않는 곳을 사흘(10/30~11/01) 동안 고쳤습니다.

  • 운영 서버가 자기 자신을 감시하고 있었습니다. 운영이 죽으면 알림도 같이 죽습니다.
  • 운영 서버가 직접 이미지를 빌드하는 서비스가 있었습니다. 빌드가 4코어를 다 쓰면 사이트가 느려집니다.
  • 백업이 있다고 생각했지만, 밖으로 매일 나가는 백업은 서비스 두 곳뿐이었습니다.

그래서 규칙 하나로 정리했습니다. 감시하는 쪽, 백업을 받는 쪽, 빌드하는 쪽은 그 대상과 다른 기계에 둔다.

서버마다 맡은 일 하나

  1. 운영

    서비스가 실제로 도는 곳. 이미지를 받아 띄우기만 하고 빌드하지 않는다

    클라우드 arm64 4코어
  2. 빌드

    맥이 1순위. 3분 안에 작업을 못 잡으면 집 서버가 대신 굽는다

    맥 · 집 서버
  3. 감시

    지표·로그·사이트·백업 상태를 모으고, 문제가 생기면 디스코드로 알린다

    다른 클라우드의 작은 VM
  4. 작업

    AI 작업자가 저장소 사본에서 코드를 짜고 PR을 올린다

    작업 서버
  5. 보관

    CI 본체와 운영 백업의 평문 사본을 받아 둔다

    집 서버
  6. 조율

    조율 세션이 작업자를 띄우고 운영을 확인한다

    대표 PC

한 대가 죽으면 무엇이 같이 죽나

죽는 기계같이 멈추는 것멈추지 않는 것
운영 서버공개 서비스 전부알림(감시 서버가 밖에 있다), 백업 사본 두 곳, 빌드
맥1순위 빌드3분 뒤 집 서버가 대신 빌드한다(느려질 뿐)
집 서버CI(배포), 백업 평문 사본운영 서비스, 암호화 백업
작업 서버AI 작업자의 개발운영, 빌드, 감시
감시 서버알림운영, 빌드, 백업
  • 관리형 MySQL과 Object Storage는 클라우드 회사가 운영하는 서비스라 표에서 뺐습니다.

부딪힌 문제와 해결

1. 운영 서버가 자기 자신을 감시하고 있었다

운영 서버 안에 Prometheus, Grafana, Loki, Alertmanager 등 감시 도구 일곱 개가 함께 돌고 있었습니다. 지표와 경보 규칙은 충분했지만, 운영 서버가 멈추면 경보를 보낼 Alertmanager도 같이 멈춥니다.

원인은 「감시 도구는 감시할 서버 옆에 둔다」는 편의였습니다. 설치하기 쉽고, 네트워크를 따로 열 필요가 없습니다.

→ 다른 회사의 클라우드에 메모리 1GB짜리 작은 VM을 하나 두고 감시를 옮겼습니다. Grafana 스택은 이 VM에 무거워서 실행 파일 하나로 도는 도구로 바꿨습니다. 서버 지표는 Beszel, 사이트·인증서·백업 상태는 Gatus, 로그는 VictoriaLogs가 모읍니다. 셋 다 docker 없이 systemd로 띄우고 메모리 상한을 걸었습니다. 각 서버의 에이전트와 로그 전송기(vector)는 사설망(Tailscale)으로만 보냅니다. 옛 스택은 11/01에 내렸고, 운영 서버에서 이미지만 약 3GB가 비었습니다.

옮긴 다음 날 바로 쓸모가 드러났습니다(위 ② 카드). 운영 서버를 커널 패치로 재부팅하자 DNS 설정이 사설망 쪽으로 바뀌었고, 다음 새벽 백업 컨테이너가 저장소 주소를 찾지 못해 실패했습니다. 감시 서버의 Gatus가 그 실패를 받아 디스코드로 알렸습니다. 백업 컨테이너를 호스트 네트워크로 돌리게 고쳐 다음 실행부터 성공했습니다.

2. 백업이 있다고 믿었다

10/30에 서버마다 「무엇이 어디에 사본으로 있나」를 조사했습니다. 밖으로 매일 백업되는 것은 서비스 두 곳뿐이었습니다. 집 서버의 CI(Jenkins) 설정, 개인 서비스 데이터, 운영 서버의 일부 DB는 사본이 없었습니다. 관리형 MySQL의 자동 백업은 보존 기간이 1일이었고, 모든 백업이 같은 클라우드 계정 안에 있었습니다.

→ 백업을 두 갈래로 보냈습니다.

  • 암호화 사본: restic으로 Object Storage 전용 버킷에 올립니다. 일 7·주 4·월 6개를 보존합니다.
  • 평문 사본: 같은 DB 덤프를 사설망으로 집 서버에 보냅니다. 클라우드 계정이 통째로 막혀도 다른 곳에 사본이 남습니다.

백업 컨테이너는 끝날 때마다 감시 서버에 성공·실패를 알리고, 26시간 동안 소식이 없어도 알림이 갑니다. 그리고 실제로 되살려 봤습니다. 11/01에 집 서버의 평문 사본으로 DB 두 개를 복원해, 테이블 수(98개, 26개)가 운영과 같은지 확인했습니다. 복원해 보기 전까지는 백업이 아니라 「백업일 것」이었습니다.

3. 맥북을 들고 나가자 빌드가 멈췄다

운영 서버는 arm64입니다. arm64 이미지를 가장 빨리 굽는 기계는 같은 arm64인 맥이라, CI의 arm64 빌드를 맥에 맡겼습니다. 10/25에 맥북을 들고 외출하자, 맥을 기다리던 빌드 단계가 그대로 멈췄습니다.

반대쪽 문제도 있었습니다. 일부 서비스는 운영 서버에서 직접 이미지를 빌드했습니다. 빌드가 4코어를 다 쓰면 사이트가 느려지고, 빌드 캐시가 쌓였습니다. 10/30에 운영 서버 디스크가 144GB까지 찼는데, 그중 빌드 캐시만 62.5GB였습니다.

→ 운영 서버는 받아서 띄우기만 하게 바꿨습니다. 빌드는 맥이 1순위로 맡고, 맥이 3분 안에 작업을 잡지 못하면 집 서버가 QEMU로 대신 굽습니다. 3분을 기다리는 이유는 맥 실행기 하나를 여러 저장소가 나눠 쓰기 때문입니다. 맥에서 빌드가 실패했을 때는 집 서버로 다시 굽지 않습니다. 실패는 기계 탓이 아니라 코드 탓일 가능성이 높아서입니다. 작업 서버는 AI 작업자가 전체 시험을 돌려 CPU가 붐비므로 빌드에서 뺐습니다.

AI 뉴스 서비스를 처음 옮겼을 때 운영 서버의 배포 시간이 109초에서 41초로 줄었습니다. 디스크는 정리 뒤 49GB가 됐고, 매일 새벽 오래된 이미지와 빌드 캐시를 지우는 작업을 붙였습니다.

4. 지운 에이전트가 40분 뒤 다시 깔렸다

감시 서버(작은 VM)를 만들면서 클라우드 회사의 기본 감시 에이전트를 지웠습니다. 그런데 며칠 뒤 보니 밖으로 나가는 트래픽의 약 80%를 그 에이전트가 쓰고 있었습니다. VM에 붙은 운영 정책이 지운 지 40분 만에 다시 설치한 것입니다.

→ 패키지만 지우지 않고, 다시 깔게 만드는 정책과 VM 라벨까지 지웠습니다. 밖으로 나가는 트래픽이 분당 355KB에서 79KB로 줄었습니다. 무료 등급 VM은 트래픽 한도가 곧 비용이라, 감시 서버 자신의 트래픽도 살펴야 합니다.

하지 않은 것: Kubernetes

역할을 나누다 보면 「그냥 Kubernetes로 묶으면 되지 않나」라는 질문이 나옵니다. 10/30에 검토했고, 쓰지 않기로 했습니다.

  • 꺼지는 기계는 노드가 될 수 없습니다. 맥과 대표 PC는 들고 나가거나 끕니다.
  • 늘 켜진 서버가 두 대뿐이라 고가용성을 만들 수 없습니다.
  • 자원이 모자라지 않습니다. 지금 문제는 「한 대가 죽으면 무엇이 같이 죽나」였고, 이건 역할을 나누는 것으로 풀렸습니다.

대신 서버마다 docker compose로 띄우고, 배포는 CI가 만든 이미지를 운영 서버가 받아 띄우는 한 가지 방식으로 맞췄습니다.

다음 글에서는 지도의 다른 축, 작업 서버의 AI 작업자가 짠 코드 한 줄이 PR과 빌드를 거쳐 운영 서버에 닿기까지를 따라가 보겠습니다.

문의 →