파이프라인 효율성
파이프라인 효율성 (Pipeline efficiency)
CI/CD 파이프라인은 GitLab CI/CD의 기본 구성 요소예요. 파이프라인을 더 효율적으로 만들면 개발자 시간을 아낄 수 있고, 이는 다음으로 이어져요.
- DevOps 프로세스 가속화
- 비용 절감
- 개발 피드백 루프 단축
새로운 팀이나 프로젝트가 느리고 비효율적인 파이프라인으로 시작해서 시행착오를 거쳐 구성을 개선하는 경우가 흔해요. 더 나은 프로세스는 효율성을 개선하는 파이프라인 기능을 바로 사용해서, 더 빠른 소프트웨어 개발 수명 주기를 일찍 얻는 거예요.
먼저 GitLab CI/CD 기초에 익숙해지고 빠른 시작 가이드를 이해했는지 확인해요.
출처: 문서
본문
병목과 일반적인 실패 식별하기
비효율적인 파이프라인을 확인하는 가장 쉬운 지표는 잡, 스테이지의 런타임과 파이프라인 자체의 총 런타임이에요. 총 파이프라인 기간은 다음에 크게 영향받아요.
- 저장소 크기
- 스테이지와 잡의 총 수.
- 잡 사이의 의존성.
- 파이프라인의 최소·최대 기간을 나타내는 "임계 경로(critical path)".
GitLab 러너와 관련해 주의해야 할 추가 사항:
- 러너의 가용성과 프로비저닝된 리소스. GitLab 호스팅 러너를 사용한다면 과도하거나 부족하게 프로비저닝하지 말고, 잡에 맞는 머신 유형을 선택해요.
- 빌드 의존성, 설치 시간, 저장 공간 요구 사항.
- 컨테이너 이미지 크기.
- 네트워크 지연과 느린 연결.
불필요하게 자주 실패하는 파이프라인도 개발 수명 주기를 느리게 만들어요. 실패한 잡에서 문제가 되는 패턴을 찾아봐요.
- 무작위로 실패하거나 신뢰할 수 없는 테스트 결과를 내는 플래키(flaky) 단위 테스트.
- 그 동작과 관련된 테스트 커버리지 하락 및 코드 품질.
- 안전하게 무시할 수 있는데도 파이프라인을 중단시키는 실패.
- 긴 파이프라인의 끝에서 실패하지만 더 이른 스테이지에 있을 수 있는 테스트. 피드백이 지연될 수 있어요.
파이프라인 분석
파이프라인 성능을 분석해 효율성을 개선할 방법을 찾아요. 분석은 CI/CD 인프라에서 가능한 블로커를 식별하는 데 도움이 돼요. 여기에는 다음 분석이 포함돼요.
- 잡 워크로드.
- 실행 시간의 병목.
- 전체 파이프라인 아키텍처.
파이프라인 워크플로를 이해하고 문서화하며 가능한 조치와 변경을 논의하는 것이 중요해요. 파이프라인 리팩토링은 DevSecOps 수명 주기에서 팀 간의 신중한 협업이 필요할 수 있어요.
파이프라인 분석은 비용 효율성 문제를 식별하는 데도 도움이 돼요. 예를 들어 유료 클라우드 서비스로 호스팅되는 러너는 다음으로 프로비저닝될 수 있어요.
- CI/CD 파이프라인에 필요한 것보다 많은 리소스로, 돈을 낭비.
- 충분하지 않은 리소스로, 느린 런타임과 시간 낭비를 초래.
파이프라인 인사이트
파이프라인 성공 및 기간 차트는 파이프라인 런타임과 실패한 잡 수에 대한 정보를 제공해요.
단위 테스트, 통합 테스트, 종단 간 테스트, 코드 품질 테스트 등은 CI/CD 파이프라인이 문제를 자동으로 찾도록 보장해요. 관련된 파이프라인 스테이지가 많으면 런타임이 길어질 수 있어요.
같은 스테이지에서 서로 다른 것을 테스트하는 잡을 병렬로 실행하면 전체 런타임을 줄일 수 있어요. 단점은 병렬 잡을 지원하기 위해 동시에 실행되는 러너가 더 필요하다는 거예요.
needs 의존성 시각화
전체 파이프라인 그래프에서 needs 의존성을 보면 파이프라인의 임계 경로를 분석하고 가능한 블로커를 이해하는 데 도움이 돼요.
파이프라인 모니터링
전역 파이프라인 상태는 잡 및 파이프라인 기간과 함께 모니터링해야 할 핵심 지표예요. CI/CD 분석이 파이프라인 상태의 시각적 표현을 제공해요.
인스턴스 관리자는 추가 성능 지표 및 자체 모니터링에 접근할 수 있어요.
API에서 특정 파이프라인 상태 지표를 가져올 수 있어요. 외부 모니터링 도구가 API를 폴링해 파이프라인 상태를 확인하거나 장기 SLA 분석을 위한 지표를 수집할 수 있어요.
예를 들어 Prometheus용 GitLab CI Pipelines Exporter는 API와 파이프라인 이벤트에서 지표를 가져와요. 프로젝트의 브랜치를 자동으로 확인하고 파이프라인 상태와 기간을 얻을 수 있어요. Grafana 대시보드와 결합하면 운영 팀을 위한 실행 가능한 보기를 만드는 데 도움이 돼요. 지표 그래프는 인시던트에 임베드해 문제 해결을 더 쉽게 만들 수도 있어요. 또한 잡과 환경에 대한 지표도 내보낼 수 있어요.
GitLab CI Pipelines Exporter를 사용한다면 예제 구성으로 시작해야 해요.
또는 [check_gitlab](https://gitlab.com/6uellerBpanda/check_gitlab)처럼 스크립트를 실행할 수 있는 모니터링 도구를 사용할 수도 있어요.
러너 모니터링
호스트 시스템이나 Kubernetes 같은 클러스터에서 CI 러너를 모니터링할 수도 있어요. 여기에는 다음 확인이 포함돼요.
- 디스크 및 디스크 IO
- CPU 사용량
- 메모리
- 러너 프로세스 리소스
Prometheus Node Exporter는 Linux 호스트의 러너를 모니터링할 수 있고, [kube-state-metrics](https://github.com/kubernetes/kube-state-metrics)는 Kubernetes 클러스터에서 실행돼요.
클라우드 제공자로 GitLab Runner 자동 확장을 테스트하고, 비용을 줄이기 위해 오프라인 시간을 정의할 수도 있어요.
대시보드와 인시던트 관리
기존 모니터링 도구와 대시보드를 사용해 CI/CD 파이프라인 모니터링을 통합하거나 처음부터 구축해요. 런타임 데이터가 팀 간에 실행 가능하도록 보장해서 운영/SRE가 문제를 충분히 일찍 식별할 수 있게 해요. 인시던트 관리도 임베드된 지표 차트와 문제 분석에 필요한 모든 귀중한 세부 정보로 도움이 될 수 있어요.
저장소 사용량
비용과 효율성을 분석하는 데 도움을 주려면 다음의 저장소 사용을 검토해요.
- 잡 아티팩트와 그
[expire_in](/ci/yaml/#artifactsexpire_in)구성. 너무 오래 보관하면 저장소 사용량이 늘어나고 파이프라인을 느리게 할 수 있어요. - 컨테이너 레지스트리 사용량.
- 패키지 레지스트리 사용량.
파이프라인 구성
파이프라인을 구성할 때 신중한 선택을 하면 파이프라인을 더 빠르게 하고 리소스 사용량을 줄여요. 여기에는 파이프라인을 더 빠르고 효율적으로 실행하게 하는 GitLab CI/CD의 내장 기능을 활용하는 것이 포함돼요.
잡 실행 빈도 줄이기
어떤 상황에서 실행할 필요가 없는 잡을 찾아서 파이프라인 구성으로 실행을 막아요.
[interruptible](/ci/yaml/#interruptible)키워드를 사용해 더 새 파이프라인으로 대체될 때 이전 파이프라인을 중지해요.[rules](/ci/yaml/#rules)를 사용해 필요하지 않은 테스트를 건너뛰어요. 예를 들어 프런트엔드 코드만 변경되었을 때 백엔드 테스트를 건너뛰는 식이에요.- 필수적이지 않은 예약된 파이프라인을 덜 자주 실행해요.
[cron 스케줄](/ci/pipelines/schedules/#distribute-pipeline-schedules-to-prevent-system-load)을 시간에 걸쳐 고르게 분산해요.
빠른 실패 (Fail fast)
CI/CD 파이프라인에서 오류가 일찍 감지되도록 해요. 완료에 매우 오래 걸리는 잡은 그 잡이 완료될 때까지 파이프라인이 실패 상태를 반환하지 못하게 해요.
빠르게 실패할 수 있는 잡이 더 일찍 실행되도록 파이프라인을 설계해요. 예를 들어 초기 스테이지를 추가하고 문법, 스타일 린팅, Git 커밋 메시지 검증 등의 잡을 거기에 넣어요.
더 빠른 잡의 빠른 피드백 전에 긴 잡을 일찍 실행하는 것이 중요한지 결정해요. 초기 실패가 나머지 파이프라인을 실행하면 안 된다는 것을 분명히 할 수 있어서 파이프라인 리소스를 절약해요.
needs 키워드
기본 구성에서 잡은 항상 이전 스테이지의 다른 모든 잡이 완료될 때까지 기다렸다가 실행돼요. 이 구성이 가장 단순하지만 대부분의 경우 가장 느려요. needs 키워드가 있는 파이프라인과 부모/자식 파이프라인은 더 유연하고 효율적일 수 있지만, 파이프라인을 이해하고 분석하기 어렵게 만들 수도 있어요.
CI/CD 컴포넌트로 구성 재사용하기
[include](/ci/yaml/includes/)로 파이프라인 구성을 중복하는 대신, CI/CD 컴포넌트로 테스트되고 버전 관리된 구성을 프로젝트 간에 재사용해요. 게시된 컴포넌트는 CI/CD 카탈로그에서 찾을 수 있어요. 컴포넌트는 중복된 구성을 동기화 상태로 유지하는 유지보수 부담을 줄여줘요.
캐싱
또 다른 최적화 방법은 의존성을 캐시하는 거예요. 의존성이 거의 변하지 않는다면 캐싱으로 파이프라인 실행을 훨씬 빠르게 할 수 있어요. NodeJS, PHP, Python, Ruby, Go에 대한 구성 예시는 의존성 캐시 예시를 참고해요.
잡이 실패해도 다운로드한 의존성을 캐시하려면 [cache:when](/ci/yaml/#cachewhen)을 사용할 수 있어요.
Docker 이미지
Docker 이미지 다운로드와 초기화는 잡의 전체 런타임에서 큰 부분을 차지할 수 있어요.
Docker 이미지가 잡 실행을 느리게 한다면 기본 이미지 크기와 레지스트리에 대한 네트워크 연결을 분석해요. GitLab이 클라우드에서 실행 중이라면 벤더가 제공하는 클라우드 컨테이너 레지스트리를 찾아보세요. 추가로 GitLab 컨테이너 레지스트리를 활용할 수 있는데, 이 레지스트리는 GitLab 인스턴스가 다른 레지스트리보다 빠르게 접근할 수 있어요.
Docker 이미지 최적화
최적화된 Docker 이미지를 빌드해요. 큰 Docker 이미지는 공간을 많이 차지하고 느린 연결 속도로 다운로드하는 데 오래 걸리기 때문이에요. 가능하면 모든 잡에 하나의 큰 이미지를 사용하지 마세요. 각각 특정 작업을 위한 여러 개의 더 작은 이미지를 사용하면 다운로드와 실행이 더 빨라요.
소프트웨어가 미리 설치된 커스텀 Docker 이미지를 사용해 보세요. 더 큰 사전 구성 이미지를 다운로드하는 것이, 일반 이미지를 사용해 매번 소프트웨어를 설치하는 것보다 보통 훨씬 빠르다는 걸 명심해요. 효율적인 Docker 이미지 빌드에 대한 자세한 내용은 Docker의 Dockerfile 작성 모범 사례 문서를 참고해요.
Docker 이미지 크기를 줄이는 방법:
debian-slim같은 작은 기본 이미지를 사용해요.- 애플리케이션과 런타임 의존성만 포함하고, 일반적인 Linux 배포판에서 찾을 수 있는 패키지 매니저, 셸, 기타 프로그램이 없는 distroless 이미지를 사용해요.
- 엄밀히 필요하지 않다면 vim이나 curl 같은 편의 도구를 설치하지 마세요.
- 전용 개발 이미지를 만들어요.
- 패키지가 설치하는 man 페이지와 문서를 비활성화해 공간을 절약해요.
RUN레이어를 줄이고 소프트웨어 설치 단계를 결합해요.- 빌더 패턴을 사용하는 여러 Dockerfile을 하나로 병합하는 multi-stage 빌드를 사용해 이미지 크기를 줄일 수 있어요.
apt를 사용한다면 불필요한 패키지를 피하려고--no-install-recommends를 추가해요.- 끝에 더 이상 필요하지 않은 캐시와 파일을 정리해요. 예: Debian과 Ubuntu는
rm -rf /var/lib/apt/lists/*, RHEL과 CentOS는yum clean all. - dive나 Slim Toolkit 같은 도구로 이미지를 분석하고 줄여요.
Docker 이미지 관리를 단순화하려면 Docker 이미지 관리 전용 그룹을 만들고, CI/CD 파이프라인으로 테스트, 빌드, 게시할 수 있어요.
테스트, 문서화, 학습
파이프라인 개선은 반복적인 프로세스예요. 작은 변경을 하고 효과를 모니터링한 다음 다시 반복해요. 많은 작은 개선이 파이프라인 효율성의 큰 증가로 누적될 수 있어요.
파이프라인 설계와 아키텍처를 문서화하는 것이 도움이 될 수 있어요. GitLab 저장소에서 직접 Markdown의 Mermaid 차트로 할 수 있어요.
수행한 연구와 찾은 해결책을 포함해 CI/CD 파이프라인 문제와 인시던트를 이슈에 문서화해요. 이는 새 팀원의 온보딩을 돕고, CI 파이프라인 효율성의 반복적인 문제를 식별하는 데도 도움이 돼요.
관련 주제
더 알아보기
파이프라인 효율성을 높이는 핵심 구성 요소인 needs와 부모-자식 파이프라인은 파이프라인 아키텍처 문서에서, 의존성 캐싱은 캐싱 문서에서 자세히 볼 수 있어요. 효율성 개선을 시작하기 전에 먼저 GitLab CI/CD 기초를 훑어보는 걸 추천해요.