Post

젠킨스 빌드가 갑자기 5배 느려진 날 — NCP NAS 모니터링의 한계를 마주하다

발단

어느 날 백엔드 서비스 빌드 시간이 평소 1~2분에서 6분 28초로 늘어났다. 실패는 아니었다. 그냥 느렸다. 이런 종류의 지연은 오히려 원인을 찾기가 까다롭다 — 에러 로그 한 줄 없이 “그냥 느려진” 상태이기 때문이다.

이 글은 그 원인을 추적해간 과정과, 그 끝에서 마주친 NCP와 AWS 모니터링 체계의 근본적인 차이에 대한 기록이다.

1. 소스 코드 문제부터 지웠다

가장 먼저 의심한 건 코드 자체였다. 같은 소스로 로컬에서 빌드해봤다. 로컬에서는 평소처럼 빠르게 끝났다. 이 시점에 소스 코드나 의존성 문제라는 가능성은 지웠고, Jenkins 환경 쪽으로 방향을 좁혔다.

2. 정상 빌드와 구간별로 비교했다

Jenkins 콘솔 로그를 열어 단계별 타임스탬프를 뽑고, 과거 정상이었던 빌드 로그와 같은 구간끼리 대조했다.

구간정상지연배율
스캔~clean 시작12초68초5.7배
리소스 복사8초81초10배
컴파일39초129초3.3배
jar 빌드+repackage8초83초10배
전체1분 8초6분 28초5.7배

파일 개수는 두 빌드가 거의 같았다. 그런데도 파일을 읽고 쓰는 구간일수록 더 심하게 느려졌다. 리소스 복사와 jar 패키징처럼 파일을 자잘하게 많이 다루는 작업이 10배씩 늘어난 반면, 컴파일(CPU 위주 작업)은 상대적으로 덜한 3.3배였다. 이 패턴은 CPU가 아니라 디스크 I/O 쪽 병목을 가리키고 있었다.

3. 워크스페이스가 어디에 붙어 있는지 확인했다

Jenkins 에이전트가 Kubernetes 위에서 pod로 뜨는 구조라, PVC 설정을 확인해봤다.

1
2
3
metadata:
  annotations:
    pv.kubernetes.io/provisioned-by: nas.csi.ncloud.com

워크스페이스가 로컬 디스크가 아니라 NCP NAS(네트워크 스토리지)에 마운트되어 있었다. NAS는 파일 하나하나마다 네트워크 왕복이 붙기 때문에, 자잘한 파일을 대량으로 다루는 작업에서 로컬 디스크보다 손해를 본다. 2번에서 본 패턴과 정확히 맞아떨어졌다.

4. 디스크 용량부터 직접 확인했다

가장 먼저 의심한 건 용량이었다. 에이전트 pod에 직접 접속해 df -h로 확인했다.

1
169.254.170.73:/~/pvc~   200G  4.4G  196G   3%  /home/jenkins/agent

사용률 3%. 용량 문제는 이 한 줄로 완전히 제외됐다.

5. 전임자도 겪었던 흔적을 발견했다

용량이 아니라면 뭘까 고민하던 중, 이 NAS의 과거 NCP 이벤트 설정을 다시 살펴봤다. 이 Jenkins 플랫폼은 원래 전임자가 처음 구축해둔 것이었고, 나는 이후 이를 기반으로 Kubernetes 위에 새롭게 개선해 재구축하는 작업을 맡았다.

과거 설정을 보니 디스크 사용률 90%·95%를 기준으로 알람이 걸려 있었다. 짐작건대 전임자도 원인을 특정하기 어려운 지연을 한 번쯤 겪었고, 그때 손댈 수 있는 선에서 용량 알람을 걸어 대응해두려 했던 것 같다. 그런데 이번에 확인한 대로 용량은 3%밖에 안 찬 상태였다 — 즉 이 알람으로는 애초에 잡히지 않을 문제였다. 전임자가 끝내 완전히 풀지 못하고 남겨둔 흔적이었던 셈이다.

그리고 재구축을 마친 지금, 나도 똑같은 자리에서 막혔다. 원인은 특정하지 못했지만 증상은 같았다 — 원인을 알 수 없는 지연, 용량은 정상, 그런데 이걸 확인할 지표가 없다는 것.

6. NCP가 제공하는 지표의 한계

NCP NAS 콘솔에서 제공하는 모니터링 이벤트를 다시 살펴보니, 디스크 사용률(용량) 외에는 걸 수 있는 알람이 없었다. 용량은 여유로운데 왜 느려졌는지 — 즉 “그 순간 처리 성능이 한계에 가까웠는지”를 확인할 방법이 NCP 콘솔 상에는 없었다.

반면 AWS의 네트워크 파일 스토리지인 EFS는 CloudWatch를 통해 훨씬 세분화된 지표를 기본 제공한다.

  • PercentIOLimit — IOPS 한도에 얼마나 근접했는지 퍼센트로 직접 표시
  • BurstCreditBalance — 버스트 처리량 크레딧 잔량. 이게 바닥나면 처리 성능이 기본치로 뚝 떨어진다
  • PermittedThroughput / ThroughputUtilization — 그 순간 허용된 처리량과 실제 사용률
  • DataReadIOBytes / DataWriteIOBytes / MetadataIOBytes — 읽기·쓰기·메타데이터 처리량을 항목별로 분리해서 제공
  • ClientConnections — 동시 접속 클라이언트 수

정확히 이번에 궁금했던 질문 — “용량은 멀쩡한데 처리 성능이 순간적으로 부족했던 거 아닐까” — 을 AWS EFS라면 지표로 바로 확인할 수 있었다. NCP는 이 질문에 답할 지표 자체가 없었다.

결론

이번 지연은 재현되지 않았다. 다음 날 같은 조건으로 다시 빌드하니 정상적으로 끝났다. 그래서 “그 순간 NAS에 일시적인 병목이 있었다”는 것 이상으로 원인을 확정하지는 못했다.

다만 이번 조사에서 확인한 건 원인 하나가 아니라, 전임자와 내가 시기를 달리해 같은 자리에서 부딪힌 같은 벽이었다. 전임자는 용량 알람으로 최선을 다해 대응해뒀지만, 그건 애초에 이 문제의 답이 될 수 없는 지표였다. 나 역시 재구축을 마친 뒤 같은 유형의 원인 불명 지연을 만나고 나서야 그 이유를 알았다 — NCP NAS는 애초에 용량 외의 지표, 즉 처리 성능(IOPS·처리량)을 걸 수 있는 방법 자체를 제공하지 않는다. 두 사람이 각자 다른 시점에 부딪혔던 벽이, 사실은 같은 플랫폼의 구조적 한계였다는 걸 이번에야 알게 됐다.

반면 AWS EFS는 CloudWatch를 통해 정확히 이 지점을 겨냥한 지표(PercentIOLimit, BurstCreditBalance 등)를 기본으로 제공한다. 클라우드를 고르는 기준은 결국 “장애가 안 나는 클라우드”가 아니라 “장애가 났을 때 원인을 빠르게 좁힐 수 있는 클라우드”라고 생각한다. 이건 전임자의 실수도, 내 실수도 아니었다 — 같은 문제에 두 번 부딪히고 나서야 보인, NCP가 가진 관측 가능성(observability)의 구조적 한계였다.

This post is licensed under CC BY 4.0 by the author.

© noah. Some rights reserved.