홍쌤의 인포클래스AI + X · 기술 블로그

← 목록

학교 서버 두 대로 서비스 여러 개를 운영하며 배운 것: 터널, 백업, 멈춘 AI 서버와 감시 장치

작성 2026.10.31 · 홍창민

학교에 있는 NVIDIA GB10 워크스테이션 두 대로 학생용 AI, 온라인 저지, 데이터 분석 도구, 보안 게임, 연수용 가상 공간, 그리고 이 블로그까지 돌리고 있다. 10월에 서비스가 늘면서 터널, 백업, 감시에서 틀리고 고친 것을 적는다. 숫자는 모두 내가 돌린 시험과 운영 기록에서 가져왔다.

두 대의 역할을 나눴다

1호기는 웹 서비스 대부분과 주 언어모델을 맡고, 2호기는 언어모델 복제본과 학생 GPU 실습실(JupyterHub)을 맡는다. 두 대는 1Gb 망으로만 이어져 있어서 하나로 묶기보다 역할을 나눠 쓴다. 새 모델을 시험해 보는 일도 2호기에서 한다.

두 대를 함께 쓰는 시험도 했다. 10월 21일에 시나브로 AI가 질문을 두 대에 나눠 보내게 했다. 40명이 동시에 질문하는 시험에서 40명 모두 답을 받았고, 답이 끝나는 시간은 중간값 29.6초, 가장 늦은 것이 53초였다. 2호기를 끈 상태로 20명을 보내도 20명 모두 답을 받았다. 답을 만들던 중에 2호기 쪽을 일부러 멈췄을 때도 20명 모두 답을 받았고, 그중 7건은 서버가 1호기로 다시 보냈다.

10월 28일 밤에는 2호기 책상 화면의 전원 메뉴로 컴퓨터가 꺼졌다. 20시 16분에 꺼져 23시 57분에 다시 켜질 때까지 GPU 실습실은 열리지 않았지만, 시나브로 AI는 1호기만으로 답했다. 다시 켜진 뒤에는 감시 스크립트가 2분 만에 AI 복제본을 되살렸다. 다음 날 2호기는 관리자가 아니면 끄기·재시작·절전을 할 수 없게 막았고, 전원 버튼과 절전 키, Ctrl+Alt+Del도 무시하게 했다.

10월 30일 기준으로 2호기는 해커톤용 코딩 모델을 돌리고 있어서, 시나브로 AI는 1호기만 쓴다.

터널: 학교 컴퓨터를 바깥에 여는 유일한 길

1호기의 웹 서비스는 모두 자기 컴퓨터 안에서만 요청을 받고, 인터넷에서 들어오는 길은 Cloudflare Tunnel 하나다. 원격 접속, Jupyter, 관리 대시보드는 Cloudflare Access 로그인을 한 번 더 거친다. 이 구조는 단순하지만, 터널에서 틀린 일이 몇 번 있었다.

첫째, 10월 16일 보안 업데이트를 하고 재부팅하자 블로그에 문제가 생겼다. 예전에 쓰던 정적 블로그 서버가 먼저 떠서 블로그 앱이 써야 할 자리를 차지한 것이다. 블로그 터널이 블로그 앱이 뜬 뒤에 시작하도록 묶고, 옛 서비스는 꺼 두었다.

둘째, 10월 29일 데이터 랩용 터널을 새로 만들고 주소(DNS)를 연결했는데, 새 주소가 기존 터널로 가 있었다. 연결 명령이 기본 설정 파일에 적힌 터널을 대신 썼기 때문이다. 새 설정 파일을 명시하고 덮어쓰기로 다시 연결해 15초쯤 만에 바로잡았다. 그 뒤로 새 터널의 DNS를 연결할 때는 설정 파일을 꼭 붙인다.

# 기본 설정 파일의 터널로 연결돼 버린 명령
cloudflared tunnel route dns <새 터널> <주소>
# 고친 명령: 새 설정 파일을 명시하고 덮어쓰기
cloudflared tunnel --config <새 설정 파일> \
  route dns --overwrite-dns <새 터널> <주소>

셋째, 저지 화면 파일을 배포하기 전에 새 버전 주소를 curl로 미리 열어 봤다. 그 바람에 Cloudflare가 그 주소에 옛 파일을 4시간 동안 담아 두었다. 버전 번호를 하나 건너뛰어 다음 번호로 올렸다. 10월 21일에는 파이썬 기본 User-Agent로 보낸 시험 요청을 Cloudflare가 1010 오류로 막았다. 시험 스크립트에는 User-Agent를 따로 적어야 한다.

터널에는 대가도 있다. Cloudflare를 거치면 요청마다 0.4~0.6초가 더 걸린다. 한국 접속이 먼 데이터센터로 돌아가는 것으로 보이고, 서버 부하와는 상관이 없다. 사이버 인생게임은 서버 안에서 잰 페이지 응답 p95가 0.18초였지만, Cloudflare를 거친 150명 시험에서는 실패 0에 중간값이 2.6초였다. 이 숫자에는 시험한 맥의 회선도 섞여 있다.

백업: 배포 전에 한 번, 매일 새벽에 한 번

규칙은 단순하다. 배포 전에는 매번 백업한다. 파일은 고치기 전에 .bak-날짜로 복사하고, DB 구조를 바꾸는 배포 앞에서는 DB를 따로 떠 둔다. 데이터 랩은 3차 배포와 AI 기능 배포 앞에서 각각 DB를 백업했고, 배포 스크립트가 직전 버전을 보관해 명령 하나로 되돌릴 수 있다.

정기 백업은 서비스마다 둔다. 저지와 데이터 랩은 매일 새벽 DB를 복사해 14일치를 남기고, 해커톤 플랫폼은 6시간마다 백업한다. PixelPlaza는 배포 전에 DB, 올린 파일, 코드, 설정을 한 묶음으로 떴다.

실수는 지우는 쪽에서 났다. 해커톤 시험 프로젝트 837개를 압축해 보관한 뒤 rm -rf run-* runs*로 지웠는데, 이름이 run-으로 시작하는 시험 서버 실행 스크립트까지 함께 지워졌다. 스크립트는 그날 밤 다시 썼다. 와일드카드로 지울 때는 같은 글자로 시작하는 파일이 있는지 먼저 봐야 했다.

프로세스를 끄다가 생긴 일도 있다. pkill -f로 프로세스를 끄다 내 셸까지 죽은 적이 있어서 규칙으로 적어 두었다. 그런데 10월 30일에 메모리 감시 스크립트를 끄면서 pgrep -f로 찾은 번호를 그대로 kill 했다가 같은 일을 또 겪었다. 피해는 없었다. 이름으로 찾지 말고, 포트로 PID를 확인해 그 번호만 끈다.

'준비됨'이라는데 답을 안 하던 AI 서버

10월 29일 20시 20분쯤부터 학교 AI 서버가 답을 만들지 않았다. 요청 2개가 처리 중으로 걸린 채 진행이 0이었고, 엔진의 반복 카운터도 멈춰 있었다. GPU 사용률은 96%인데 전력은 17W였다. 바빠 보이지만 계산은 하지 않는 상태였다.

정기 점검은 이것을 잡지 못했다. 점검이 보는 준비 상태 주소가 멈춘 동안에도 계속 ready를 돌려줬기 때문이다. 20시 59분에 진단 기록을 먼저 저장하고 모델 서버 컨테이너를 다시 시작했다. 84초 뒤 정상으로 돌아왔고, 그 뒤 171건이 끝까지 처리됐다.

'살아 있음'과 '답을 만듦'은 다르다. 그래서 짧은 답을 실제로 만들어 보는 감시 장치를 두었다. 처음에는 10분마다 확인하는 안을 냈고, 10월 30일 오전에 실제로 둔 규칙은 이렇다.

5분마다:
  4토큰짜리 짧은 답을 요청한다
  45초 안에 답이 오지 않고 엔진 카운터도 그대로면 → 실패 1회
  두 번 연속 실패하면 → 진단 기록을 남기고 모델 서버를 다시 시작한다
제한:
  다시 시작은 30분에 한 번, 하루 3번까지
  모델을 바꾸는 중이거나 일부러 꺼 둔 때는 손대지 않는다

두 조건을 같이 보는 데는 이유가 있다. 수업 중에 질문이 몰리면 짧은 답도 늦게 올 수 있다. 그때 엔진은 일을 하고 있으니 카운터가 움직인다. 답이 늦다는 것만으로 다시 시작하면 학생들이 받던 답까지 끊긴다. 판단 규칙은 시험 8개로 확인했다.

메모리가 조금씩 새던 축전 앱

10월 28일 오후에는 융합축전 앱이 메모리 상한(3GB)에 걸려 응답을 멈췄다. 먼저 다시 시작해 살려 두고 원인을 찾았다. 분석 기능이 2초마다 답변 112개를 형태소 분석기(Kiwi)로 처음부터 다시 나누고 있었는데, 이 일을 백그라운드 스레드에서 하면 메모리가 계속 늘었다. 똑같이 재현하니 2분에 74MB씩 늘었다.

문장마다 형태소 결과를 기억해 두는 캐시(최대 5,000개)를 넣어, 같은 문장은 다시 나누지 않게 고쳤다. 분석 결과가 고치기 전과 같은지 비교했고, 파이썬 시험 9개와 자바스크립트 시험 13개도 통과했다. 18시 26분에 다시 시작한 뒤 9시간 동안 메모리는 늘지 않았다(1.99GB → 1.06GB). 상한을 걸어 둔 서비스는 상한에 닿으면 멈춘다. 그래서 상한과 함께, 메모리가 시간에 따라 어떻게 변하는지도 봐야 한다.

부하 시험 숫자

서비스를 새로 열거나 크게 바꿀 때는 한 반이나 한 학년이 동시에 쓰는 상황을 흉내 내 부하 시험을 했다. 10월에 잰 숫자를 모았다. 데이터 랩과 PixelPlaza는 운영과 섞이지 않게 격리 인스턴스에서 쟀고, 사이버 인생게임과 시나브로 AI는 운영 서버에서 쟀다.

서비스 시험 결과
시나브로 데이터 랩 학생 60명과 AI 과제를 하는 학생 10명이 동시에 요청 1,733개 오류 0, 계산 95%가 2.8초 안, 메모리 최대 3.9GB
사이버 인생게임 학생 300명이 20초에 걸쳐 접속 요청 7,800개 실패 0, 페이지 p95 0.18초
PixelPlaza 봇 50·100·150·200명 접속 실패·끊김 0, 지연 p99 9ms 이하, 메모리 124MB
시나브로 AI 40명 동시 질문, 두 대에 나눠 보냄 40명 모두 답, 중간값 29.6초, 최대 53초

사이버 인생게임은 기존 설계대로 동시 연결 64칸 제한이 있다. 한순간에 100개 넘게 몰아치면 바로 503을 돌려준다. 20초에 걸쳐 들어오는 300명은 문제없었다. 데이터 랩은 첫 시험에서 가장 늦은 계산이 54초 걸려 설계를 바꿨는데, 그 이야기는 데이터 랩 글에 따로 적었다.

정리

관련 주소