GoCD Server Monitoring Dashboard


GoCD Server Grafana 대시보드 메트릭 정리. GoCD Server는 내부적으로 Jetty 웹서버를 내장한 JVM 애플리케이션이므로, K8s / JVM / Jetty 세 레이어를 함께 봐야 한다.

대시보드 소스: grafana-dashboards/dashboards/core-platform/cd-pipeline/build-infra/gocd-server.json

1. K8s Resources

Pod Memory

메트릭 Prometheus 쿼리 의미
Working Set k8s_pod_memory_working_set_bytes 커널이 쉽게 회수할 수 없는 활성 메모리. K8s가 OOMKill 판단에 사용하는 기준값
RSS k8s_pod_memory_rss_bytes Resident Set Size. 프로세스가 실제 RAM에 올려놓은 메모리 (anonymous memory만, file cache 제외)
Limit k8s_container_memory_limit_bytes resources.limits.memory 설정값. 초과 시 OOMKill 발생. 빨간 점선
Request k8s_container_memory_request_bytes resources.requests.memory 설정값. 스케줄러 배치용 최소 보장. 초록 점선

관계: Request(보장) ≤ 실제 사용량 ≤ Limit(상한)

  • Working Set > Limit → OOMKill
  • 실 사용량 > Request → 노드 메모리 압박 시 eviction 우선 대상
  • RSS는 단조 증가하는 것이 JVM 특성상 정상 (JVM은 GC 후에도 OS에 메모리를 반환하지 않음)

Pod CPU

메트릭 의미
Usage 실제 CPU 사용량 (cores)
Limit resources.limits.cpu. 초과 시 throttling 발생
Request resources.requests.cpu. 스케줄러 배치용

2. G1 Memory

GoCD Server는 G1 GC를 사용한다. Heap은 Region 단위로 Eden / Survivor / Old Gen으로 나뉜다.

G1 Eden

새 객체가 최초 할당되는 영역. 가득 차면 Young GC 발생.

메트릭 의미
Used 현재 Eden에 할당된 객체 크기. 톱니 패턴 (할당 → GC 시 급락)
Committed JVM이 OS로부터 Eden용으로 확보한 메모리. G1은 Region 단위로 동적 조절
Peak JVM 시작 이후 Committed 최대치. 단조 증가
After GC Young GC 직후 Eden에 남은 객체 크기. 항상 0 또는 0에 가까운 고정값이 정상 (Eden의 살아남은 객체는 전부 Survivor/Old로 이동하므로)

G1 Old Gen

Young GC에서 살아남아 승격(promotion)된 장기 생존 객체가 저장되는 영역.

메트릭 의미
After GC Old Gen GC 후 남은 객체 크기. 이 값이 GC마다 점점 올라가면 회수 안 되는 객체가 누적되고 있다는 신호 → 결국 Full GC → OOM

G1 Survivor

Young GC에서 살아남았지만 아직 Old Gen으로 승격되지 않은 객체가 임시 저장되는 영역.

3. Jetty HTTP Server

Sessions (org_eclipse_jetty_server_session)

GoCD Server의 Jetty가 메모리에 보관하는 HTTP 세션 관련 메트릭.

메트릭 의미
sessionscurrent 현재 활성 세션 수
sessionscreated 누적 생성된 세션 수

세션 = 서버가 클라이언트별로 메모리에 유지하는 상태 정보. 클라이언트가 첫 요청 시 세션 생성 + 쿠키(JSESSIONID) 발급 → 이후 요청에서 쿠키를 보내면 기존 세션 재사용.

세션 누수 패턴: 클라이언트가 쿠키를 전달하지 않으면 매 요청마다 새 세션이 생성된다. 각 세션은 JVM Heap(Old Gen)에 객체로 유지되므로, 세션이 만료되지 않으면 메모리가 계속 증가한다.

의심 대상:

  • Load Balancer / Ingress 헬스체크 (쿠키 없이 수초 간격 호출)
  • Prometheus 등 모니터링 도구의 metrics endpoint scrape
  • cd-api 등 API 클라이언트가 쿠키를 유지하지 않고 매번 새 HTTP 클라이언트로 호출

확인 방법: GoCD Server access log에서 JSESSIONID 쿠키 없이 들어오는 요청의 빈도와 출처 확인.

4. 현상 분석 기록 (2026-04-15)

관측된 현상:

  • RSS 단조 증가, Working Set 오르락내리락, Request 지속 초과
  • sessionscurrent 938K (약 94만) — 명백한 세션 누수
  • Eden After GC 변동 없음 (정상)

분석:

  1. RSS 단조 증가는 JVM 특성 + 세션 누수 복합 원인
  2. Working Set이 오르락내리락하는 것은 GC가 정상 동작 중이라는 의미
  3. 938K 세션이 Old Gen에 쌓여 GC로 회수되지 않아 메모리 지속 증가
  4. cd-api가 GoCD Server API를 매번 새 HTTP 클라이언트로 호출하여 쿠키를 유지하지 않는 것이 유력한 원인

대응:

우선순위 조치
즉시 GoCD Server 재시작으로 세션 초기화 (임시)
단기 session-timeout 값 단축
단기 GoCD 버전 업그레이드 (세션 관련 버그 픽스 확인)
중기 cd-api의 HTTP 클라이언트가 쿠키를 유지하도록 수정, 또는 세션 생성이 불필요한 endpoint에서 세션 비활성화
🔒 Admin 로그인