
About
카카오 AIaaS · Peakly
하이브리드 클라우드(KakaoCloud + AWS DR) · GitOps · 부하 테스트로 처리 한계 5배
Wanted AI Championship 2026 · 애정 지방법원
4인 팀의 인프라·백엔드·DB 담당 · 공개 포트 없는 배포 · 동시 제출·만료·권한을 DB가 보장
종합설계 · TeamTalk
홈서버 한 대로 멀티 에이전트 추론 인프라 구축 · 응답 5분 → 3분 · 메타버스SW아카데미 최우수상
지존소프트 인턴
NAS 사내 인프라 구축 · 504 장애를 Nginx DNS 캐싱까지 추적하고 재발 방지
홈서버 운영 · 기술 블로그
컨테이너 28개 운영 · 보안 강화 · 모니터링 CPU 60%→1% · GPU 온디맨드 운용
Project 01 · 카카오 AIaaS
장르·배우 같은 메타데이터가 아니라, AI가 대사를 분석해 만든 감정 곡선이 비슷한 영화를 추천합니다. 4인 팀 팀장으로 인프라·백엔드·DB·ML·DevOps를 맡았고, 팀원들은 기획·데이터 라벨링·디자인과 와이어프레임을 맡았습니다.
Project 01 · 카카오 AIaaS
Project 01 · 카카오 AIaaS
Project 01 · 카카오 AIaaS
Project 01 · 카카오 AIaaS
Project 01 · 카카오 AIaaS
Project 01 · 카카오 AIaaS
Project 01 · 카카오 AIaaS
Project 01 · 카카오 AIaaS
| 단계 | 발견한 병목 | 조치 | 결과 |
|---|---|---|---|
| 1 | ~713 VU에서 단일 DB 노드 CPU 100%. 자동 확장되는 앱이 아니라 DB가 천장 | 라우트 캐싱(1h) + 페이로드 축소 | 한계 ~700 → 2000+ VU, p95 4.5s → 0.66s, DB CPU 100% → 20% |
| 2 | FE HPA 최대치(8)에 도달 | FE HPA max 8 → 16 | 붕괴점 ~3600 VU (초기 대비 약 5배). 천장이 app 워커 노드로 이동 → 노드 증설안 도출 |
| 3 | 외부 스코어 API: 인증 처리와 DB 커넥션 | 인증 결과 캐싱(60s) + PostgREST 커넥션 풀 10 → 40 | 한계 ~500 → ~3777 VU (약 7배) |
Project 01 · 카카오 AIaaS
Project 01 · 카카오 AIaaS
앱 티어를 아무리 늘려도 단일 DB 노드가 천장이었습니다. 경로별로 나눠 재지 않았다면 엉뚱한 곳을 확장했을 것입니다.
부하 도구가 캐시를 우회하면 개선 효과가 측정되지 않고, 부하 생성기 자체의 한계(ulimit)를 서비스 한계로 오인할 수 있다는 것을 진단 과정에서 확인했습니다.
관리형 서비스의 편의와 비용, 보안 사이의 트레이드오프를 수치로 비교하고, 선택하지 않은 대안(NAT 복원)까지 문서로 남겼습니다.
인프라·DevOps와 달리 ML 도메인 지식이 부족해 MLOps 구상이 여러 번 바뀌었습니다. 파이프라인 자동화까지 마무리하며 전체 흐름을 익혔습니다.
Project 02 · Wanted AI Championship
연인에게 서운했던 일을 AI와 이야기하면 장난스러운 고소장으로 정리해 링크로 보내고, 상대가 같은 링크에서 사과하거나 맞고소합니다. 로그인이 없고 결과는 7일 뒤 파기됩니다. 4인 팀에서 인프라·백엔드·DB 를 맡았습니다.
애정 지방법원 — 카카오톡 링크 미리보기 · 클릭하면 원본Project 02 · Wanted AI Championship
GITHUB_TOKEN 으로 인증했습니다.Project 02 · Wanted AI Championship
.env 와 컨테이너 주입용 env_file 을 혼동 ② 수동 재기동 때 pull 을 빼먹어 옛 이미지가 뜸.Not Found 면 라우트가 없는 옛 이미지, 우리 코드의 Case not found 면 DB까지 정상, Storage unavailable 이면 DB 주소 없음.git reset --hard origin/main 으로 서버를 강제 동기화하고, 서버마다 다른 값은 .env 로만 두게 했습니다. 배포 후 실제로 뜬 이미지를 로그에 남깁니다.Project 02 · Wanted AI Championship
case_id PK·UNIQUE로 DB가 한 번 더 막습니다.public_token 과 A 전용 writer_token 을 발급하고 서버는 SHA-256 해시만 저장합니다. B에게는 토큰을 요구하지 않습니다. 요구하면 "링크 하나로 전달"이 깨집니다.| 실DB 동시 제출 (스레드 8개) | 200 | 409 | 저장된 행 |
|---|---|---|---|
| A 고소장 | 1 | 7 | 카드 1장 |
| 응답 방식 선택 (사과·맞고소 섞어서) | 1 | 7 | 한쪽으로만 확정 |
| 사과문 | 1 | 7 | 사과문 1장 |
Project 02 · Wanted AI Championship
Supabase 자동 마이그레이션이 무료 플랜에서 동작하지 않아 이틀간 한 번도 적용되지 않았는데, 기본 제공 확장 덕에 적용된 것처럼 보였습니다. 결과물이 아니라 적용 이력 테이블로 확인합니다.
단위 테스트는 통과했지만, 실제 Postgres에 올리자 nullable 컬럼 때문에 조회가 500이 나는 버그가 나왔습니다. CI에 테스트 실행도 없어서 추가했습니다.
"라우트 없음", "사건 없음", "저장소 없음"을 서로 다른 문구로 둔 덕분에 운영 사고의 원인을 응답 하나로 갈랐습니다.
인프라·DB·API 계약은 모든 팀원이 기대는 부분이라, 설계 문서를 구현과 대조해 고치며 같은 카드를 세 곳이 다르게 쓰던 문제와 감정 목록 유실 버그를 찾았습니다.
Project 03 · TeamTalk
범용 대형 LLM을 한 번 호출하는 대신, 개발자·디자이너·기획자 역할의 소형 모델들을 협업시켜 적은 비용으로 다각적인 답을 만듭니다. 4인 팀 팀장으로 추론 인프라와 데이터 흐름을 설계·구축했습니다.
TeamTalk 대화 화면 · 클릭하면 원본Project 03 · TeamTalk
Project 03 · TeamTalk
Project 03 · TeamTalk
Project 03 · TeamTalk
Project 03 · TeamTalk
Project 03 · TeamTalk
학부 프로젝트의 목표는 최고 성능이 아니라 개념 검증과 완성이라고 봤습니다. 범위를 줄이는 결정이 데모와 논문까지 가는 길을 만들었습니다.
메모리가 부족할 때 동시성을 늘리는 것이 오히려 느려진다는 것을 겪고, 로드 방식과 처리 순서를 바꾸는 것으로 해결했습니다.
수평 확장이 안 되는 구조, 수동 배포, 최소한의 보안. 이 세 가지가 다음 프로젝트에서 Kubernetes·GitOps·보안 그룹 설계로 이어졌습니다.
Project 04 · 지존소프트 인턴
LLM + 컴퓨터 비전으로 고객마다 다른 견적서를 하나의 양식으로 정리하고 품목을 매칭하는 물류 IT 스타트업입니다. 개발부 인턴으로 Synology NAS(DSM) 위에 인프라를 직접 구축·운영했습니다.
Project 04 · 지존소프트 인턴
| 가설 | 확인 방법 | 결과 |
|---|---|---|
| 백엔드(n8n) 서버가 죽었다 | NAS에서 n8n으로 직접 curl | 정상 응답 → 서버는 살아 있음 |
| DNS가 깨졌다 | Nginx 컨테이너 안에서 nslookup | 새 IP로 정상 해석 → DNS도 정상 |
| Nginx가 엉뚱한 곳에 연결한다 | Nginx 에러 로그의 upstream 주소 확인 | 이전 서버의 옛 IP 로 연결 시도 → 30초 타임아웃 |
Nginx는 proxy_pass에 도메인을 적으면 시작할 때 DNS를 한 번만 해석해 IP를 고정한다. 서버 IP가 바뀌어도 재시작 전까지 옛 IP를 계속 쓴다. curl은 매번 새로 해석하기 때문에 성공했다.
Project 04 · 지존소프트 인턴
resolver + 변수 기반 proxy_pass 로 바꿔 10초마다 도메인을 다시 해석하도록 했습니다.# 변경 전: 시작 시 1회 해석 후 고정 proxy_pass http://n8n.example.com; # 변경 후: 변수로 넘기면 요청 시점에 resolver로 재해석 resolver <DNS 서버> valid=10s; set $n8n_upstream http://n8n.example.com; proxy_pass $n8n_upstream;
Project 04 · 지존소프트 인턴
"서버가 죽었나, DNS인가, 프록시인가"를 하나씩 독립적으로 확인하고, 로그를 결정적 단서로 삼는 디버깅 방식을 익혔습니다.
서버 위치를 옮기는 단순한 작업이 프록시 뒤의 모든 요청을 막았습니다. 변경의 영향 범위를 먼저 생각하는 습관이 생겼습니다.
개인 서버와 달리 기업에서는 예측하기 어려운 포트를 쓰고 반드시 문서로 남겨야 했습니다. 인턴을 마칠 때 코드와 구성·트러블슈팅 문서를 인수인계했습니다.
Project 05 · 홈서버 운영
학교에서 다루지 않는 인프라를 직접 운영해 보려고 홈서버를 세웠습니다. 서비스 이전, 장애, 보안, 모니터링, GPU 운용까지 부딪힌 문제를 "현상 → 원인 추적 → 조치 → 재발 방지" 순서로 블로그에 기록하고 있습니다.
Portainer 컨테이너 목록 (28개 중 일부) · 클릭하면 원본Project 05 · 홈서버 운영
PG_VERSION(17)이 새 이미지와 같은지 먼저 확인한 뒤 붙였고, Supabase 컨테이너 11개가 모두 healthy로 올라왔습니다.curl --resolve 로 도메인 요청을 새 서버로 강제로 보내 웹 4개(200)·API(401, 정상)를 확인했습니다.Project 05 · 홈서버 운영
| 의심 | 확인 | 결과 |
|---|---|---|
| 정전으로 서버 IP가 바뀜 | 공유기 DHCP 고정 예약 | 그대로. 정상 |
| 포트포워딩이 풀림 | 포워딩 규칙 | 새 서버로 정상 |
| 방화벽 · VPN | 방화벽 규칙, Tailscale 상태 | 원인 아님 |
| 실제로 어디에 연결하나 | 접속 순간 netstat 로 소켓 확인 | 꺼진 옛 서버 IP로 SYN_SENT |
게임 클라이언트의 서버 목록에 "이름"은 도메인, "주소"는 옛 서버의 내부 IP로 저장돼 있었다. → 3시간 동안 사실은 옛 서버에서 플레이했고, 옛 서버를 끄자 연결이 끊긴 것. → 주소를 새 서버로 수정. 집 안에서는 공유기가 NAT 루프백을 지원하지 않아 내부 IP를, 밖에서는 도메인을 쓰도록 정리.
Project 05 · 홈서버 운영
authorized_keys 에 키가 있는 걸 보고 키 인증을 켰는데, 그 키는 CI 배포용 키였고 제 개인 키가 아니었습니다. 세션이 끊기면 잠기는 상황이라 즉시 롤백 → 개인 키 생성·등록 → 새 터미널에서 로그인 확인 → 재적용했습니다.Project 05 · 홈서버 운영
dockerd 와 containerd 가 각각 CPU 60%대 를 24시간 쓰고 있었습니다.| 측정 | dockerd | containerd |
|---|---|---|
| Netdata 동작 중 | 64% | 65% |
| Netdata 정지 | 1.8% | 1.2% |
| docker 수집기만 OFF | 3% | 2% |
| 조치 후 (최종) | 1% | 1% |
Project 05 · 홈서버 운영
| 재로딩 비용 | 콜드 | 웜 |
|---|---|---|
| ComfyUI (20-step 생성 전체) | 252.0초 | 244.2초 |
| Ollama (load_duration) | 10.2초 | 0.001초 |
Project 05 · 홈서버 운영
방화벽·VPN을 차례로 의심하는 동안 원인에 다가가지 못했고, netstat 한 줄이 답을 줬습니다. "어디로 가야 하나"보다 "지금 실제로 어디로 가고 있나"를 먼저 봅니다.
키가 있다고 내 키는 아니었고, "설치 완료"라는 답에도 패키지는 없었습니다. 설정을 바꾸면 파일을 다시 열어 보고, 적용했으면 실제로 동작하는지 검증합니다.
GPU 로드 시간처럼 잘못 잰 값을 근거로 판단할 뻔한 일이 있었습니다. 틀린 결론도 지우지 않고, 왜 틀렸는지와 함께 정정해 남깁니다.
옛 서버가 켜져 있어 문제가 숨었습니다. 이제는 옛 서버의 서비스만 먼저 멈추고, 새 서버 로그에 실제 접속이 찍히는지 확인한 뒤 끕니다.