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 이벤트 설정을 다시 살펴봤다. 그런데 여기서 전임자가 시도했던 흔적을 하나 발견했다.

NCP 디스크 사용률 알람 임계값을 재구성한 예시

과거 설정을 보니 디스크 사용률 90%·95%를 기준으로 알람이 걸려 있었다. 짐작건대 전임자도 원인을 특정하기 어려운 지연을 한 번쯤 겪었고, 그때 확인할 수 있었던 유일한 지표인 용량을 기준으로 알람을 걸어 대응해두려 했던 게 아닐까 싶었다. 확인해보니 지금 용량은 3%밖에 안 찬 상태였으니, 설령 그 알람이 그대로 남아 있었더라도 이번 건은 못 잡았을 것이다.

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

6. NCP 콘솔에서 확인할 수 있는 건 용량뿐이었다

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

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

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

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

7. TA도 못 보고, 결국 네이버에 직접 물었다

우리 팀 TA(인프라 담당자)에게 이 볼륨의 성능 데이터를 확인해달라고 요청했다. 그런데 TA도 NCP에서 제공하는 도구만으로는 확인이 안 된다고 했다 — 결국 네이버클라우드 측에 직접 문의를 넣어야 했다.

며칠 뒤 네이버로부터 회신이 왔다.

문의주신 해당 볼륨 인스턴스 점검 결과 특이점은 없습니다. 8/5(수)부터 현재까지 성능적 이슈는 없는 상태로 운영 중이며, 스토리지 H/W 적인 이벤트나 특이점도 없었습니다. NAS 볼륨 인스턴스 사용률(IOPS)도 낮은 수준으로 성능 지연 이슈는 없습니다.

근거로 함께 온 그래프도 이 말을 뒷받침했다. (아래는 실제 볼륨 인스턴스 ID·화면은 노출하지 않고, 패턴만 재구성한 예시 그래프다)

NAS 볼륨 주간 성능 추이를 재구성한 예시 그래프

IOPS는 500 스케일 중 최대 300 정도, Latency는 최대 4ms, Throughput은 최대 1.5MB/s 수준으로, 임계값에 붙어 지속되는 구간은 어디에도 없었다. 스토리지 자체는 그 순간에도 딱히 바쁘지 않았던 것으로 보인다.

다만 이 자료로 모든 게 끝난 건 아니었다. 이 그래프는 주 단위 뷰라, 실제 빌드가 느려졌던 5~10분 구간을 정확히 짚어내진 못한다. 그리고 이건 스토리지 볼륨 자체의 지표일 뿐, Jenkins pod에서 이 NAS까지 가는 네트워크 경로(K8s 노드, CNI 등)는 이 그래프에 안 잡힌다. 스토리지가 그 순간 바빴을 가능성은 낮아졌지만, 정확히 뭐가 원인이었는지는 여전히 답할 수 없었다.

8. 그 사이, 다른 얼굴로 한 번 더

조사가 마무리될 무렵, 다른 빌드에서 비슷한 낌새가 한 번 더 있었다. 빌드 자체(컴파일·패키징) 소요 시간은 평소와 같았는데, 배포가 끝난 뒤 워크스페이스 디렉터리를 통째로 삭제하는 단계가 평소보다 1분가량 더 걸렸다. 삭제도 파일 하나하나를 확인하고 지우는 I/O 작업이라, 앞서 봤던 “자잘한 파일을 대량으로 다루면 느려진다”는 패턴과 결이 비슷했다. 다만 이것도 스토리지 지표상 뚜렷한 이상으로 확인된 건 아니어서, 확정적인 증거로 삼기는 어렵다.

결론

결국 이번 지연의 정확한 원인은 끝내 특정하지 못했다. 소스 문제는 아니었고, 스토리지 볼륨 자체도 네이버 측 확인으로는 특별한 이상이 없었다. 남은 건 “그 순간 어딘가에서 뭔가 있었던 것 같은데, 정확히 뭐였는지는 모른다”는 결말이다.

그런데 이 조사 과정 자체가 하나는 뚜렷하게 보여줬다. 나도, 우리 팀 TA도, NCP 콘솔만으로는 이 질문에 답할 방법이 없었다는 것. 결국 벤더에게 직접 문의를 넣고 며칠을 기다려야 겨우 “문제 없다”는 답을 받을 수 있었다. 전임자가 남겨둔 용량 알람도 결국 “그때 확인할 수 있었던 유일한 지표”였을 뿐, 정작 필요했던 처리 성능 지표는 걸 방법조차 없었다.

AWS EFS였다면 얘기가 달랐을 것이다. PercentIOLimit, BurstCreditBalance 같은 지표를 CloudWatch에서 엔지니어가 직접, 그 자리에서 조회할 수 있다. 벤더에게 티켓을 넣고 답을 기다릴 필요가 없다.

장애가 하나도 안 나는 클라우드는 없다. 다만 장애가 났을 때 그 원인을 스스로, 빠르게 좁혀볼 수 있느냐는 클라우드마다 분명히 차이가 난다. 이번 조사에서 가장 크게 배운 건 그 지점이었다.

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

© noah. Some rights reserved.