MeetBack 2026.09.03 7 min read

팀장으로서 기능과 운영을 함께 책임진 MeetBack 회고

MeetBack에서 팀장과 인프라 담당을 맡아 구축한 범위를 돌아봤다. 팀의 완료 기준, 일정 때문에 남긴 작업, 마지막 검증과 사용자 기능의 미해결 문제를 기록했다.

MeetBack은 가능한 시간을 공유하고 모임을 만들어 의견을 나누며 약속을 정하는 팀 프로젝트다. 팀장을 맡았고 인프라를 주로 담당했다. Google 로그인과 Redis Pub/Sub 실시간 공통 모듈도 직접 구현했다.

여러 App 복제본이 같은 DB와 파일을 사용하고, 외부 사용자가 접속할 수 있는 환경을 만드는 것이 목표였다. 배포 후에는 복제, 백업, 모니터링, 접근 권한까지 확인할 수 있도록 구성했다.

내가 책임진 범위

직접 설계하고 구축한 인프라는 아래와 같다.

  • Docker Swarm Manager 3대와 Worker 2대
  • Worker별 Spring Boot App 복제본
  • MySQL Primary 1대와 읽기 전용 Replica 1대
  • 서비스 파일용 NFS와 DB 백업·로그용 NFS
  • VyOS를 이용한 DB 전용망
  • Cloudflare Tunnel 기본 경로와 NGINX Proxy Manager 예비 경로
  • Redis Pub/Sub과 ACL
  • Prometheus, Grafana, Alertmanager, Loki, Alloy
  • Linux 서비스 계정의 최소권한과 역할별 iptables 규칙

기능 개발에서는 Google이 서명한 ID Token을 서버에서 검증하고 sub로 소셜 계정을 식별하도록 했다. 실시간 기능은 여러 JVM 사이에 이벤트를 전달할 공통 publisher와 Redis 전송 형식을 설계했다.

서버 수보다 장애 경계를 먼저 정했다

서버를 배치할 때는 한 대가 멈추면 어느 요청과 데이터가 영향을 받는지 먼저 확인했다. 복제본 수만 늘려도 해결되지 않는 부분이 있었다.

Swarm Manager는 3대로 정족수를 유지하고 App은 Worker에 배치했다. DB는 VyOS 뒤 전용망에 두고, 업로드 파일과 백업은 NFS export를 나눴다. 모니터링도 App과 별도 서버에서 실행했다.

Worker 한 대가 중단되면 남은 App이 응답하지만 복제본 2개 분량의 용량은 유지하지 못한다. MySQL 승격은 수동이며 NFS 서버와 VyOS는 각각 단일 장애점이다. 이 영향을 기준으로 이후 확장 순서를 정리했다.

팀장으로서 가장 자주 한 일은 기준을 맞추는 일이었다

후반에는 로컬에서 된 기능이 운영에서 막히는 일이 늘었다. 필요한 Secret이 없거나, 두 JVM의 상태가 다르거나, 접속은 되지만 로그인 상태가 유지되지 않는 경우였다.

팀원들과 기능별로 어디까지 확인해야 하는지 맞췄다.

  • 인증: 콜백과 토큰 검증, 세션 또는 JWT 유지까지 확인
  • 실시간 기능: WebSocket 101 이후 STOMP CONNECTED와 복제본 간 전달 확인
  • DB: 실제 쓰기와 복제본 반영, 검증 데이터 정리 확인
  • 백업: gzip 무결성과 복원 가능 여부 확인
  • 배포: 컨테이너 상태와 외부 /readyz, NFS 쓰기, DB 연결 확인

기능 우선순위나 구현 방법에 의견이 다를 때도 있었다. 재현 명령과 로그를 함께 보고 완료 조건을 정리했다. 같은 결과를 기준으로 이야기하니 어떤 작업이 더 필요한지 좁혀 갈 수 있었다.

일정이 짧을수록 하지 않을 일도 정해야 했다

2주 남짓한 일정에 자동 장애 전환, Redis HA, NFS·라우터 이중화와 CI/CD를 모두 구성하기는 어려웠다. 기간 안에 구축하고 검증할 수 있는 범위를 정해야 했다.

MySQL은 GTID·TLS 복제와 수동 전환 절차를 준비했다. Redis의 역할은 실시간 상태 캐시로 제한했다. CI/CD는 제외하고 커밋 기반 이미지 태그, 배포 전 테스트, 스택 배포와 원복 확인 절차를 남겼다.

자동화한 부분과 운영자가 직접 처리해야 하는 부분을 나눠 기록했다.

마지막 검증에서 확인한 것

프로젝트를 마칠 때는 도구별 상태와 실제 요청 경로를 다시 점검했다.

  • Swarm 노드 5/5 Ready
  • MeetBack App 2/2, Worker마다 1개
  • cloudflared 커넥터 5/5
  • 기본 Tunnel·예비 NPM 경로의 /readyz HTTP 200
  • MySQL Replica IO/SQL 스레드 Yes, 복제 지연 0초
  • 한 Worker에서 NFS 파일을 쓰고 다른 Worker에서 읽기·삭제
  • Prometheus 수집 대상 23/23 UP
  • 알림 규칙 21/21 healthy, 발생 중인 알림 0개
  • Telegram 시험 알림 발생과 해제
  • Linux 10대의 계정·SSH·iptables 점검 통과

인프라 점검은 통과했지만 사용자 기능에는 문제가 남았다. HTTPS 요청 뒤 HTTP 리디렉션이 생성됐고 세션 쿠키에는 Secure가 없었다. Presence는 WebSocket 업그레이드 이후 STOMP 연결 성공률이 낮았다. Kakao 콜백에서는 사용된 인가 코드를 다시 교환할 때 생기는 오류도 관찰됐다.

정상으로 확인한 네트워크 경로와 아직 수정이 필요한 애플리케이션 동작을 나눠 기록했다. 이 문제들은 후속 작업으로 남겼다.

이 프로젝트에서 얻은 가장 큰 변화

이번에는 구축 결과를 설명할 때 확인한 명령과 결과를 함께 남기게 됐다. 특히 서비스가 실행 중이어도 실제 요청이나 권한 시험에서 실패하는 경우가 있어 상태 표시만으로 끝내기 어려웠다.

어느 경로로 요청했는지, 어떤 계정으로 실행했는지, 장애가 났을 때 무엇이 멈추는지까지 기록했다. 나중에 다시 확인하거나 다른 사람이 이어서 작업할 때도 같은 조건으로 점검할 수 있게 하려는 목적이었다.

정해진 기간 안에 기능을 배포하고 데이터, 보안, 모니터링을 연결했다. 이중화하지 못한 서버와 애플리케이션 오류도 감추지 않고 다음 작업 목록에 넣었다. 팀장으로서는 완료 범위와 남은 일을 함께 정리한 점이 의미 있었다.

직접 구현한 Google 로그인과 Redis 실시간 공통 모듈의 세부 내용은 별도 글에 정리했다.

실제 검증 화면

  1. 프로젝트 종료 다음 날 다시 확인한 Swarm 상태다. Manager 3대와 Worker 2대가 모두 Ready·Active였고 Leader와 Reachable 상태도 유지됐다.
  2. App 복제본이 Worker 1과 Worker 2에 하나씩 배치됐다. 같은 화면에서 복제본 수, VIP, 노드당 최대 1개 제한과 stop-first 업데이트 설정도 확인했다.
    Docker Swarm의 관리자 3대와 Worker 2대가 모두 Ready·Active이고 Leader가 한 대인 노드 목록

앱 복제본 2개가 Worker에 분산되고 cloudflared가 5개 노드에서 실행 중인 서비스 배치 결과

SEARCH JOURNAL

기록 검색

글 제목, 요약, 태그에서 찾습니다.

검색을 준비하고 있어요.

검색어를 입력해 주세요.

    Ctrl/⌘ K 검색 Esc 닫기 ↑ ↓ 결과 이동