JetBrains는 IntelliJ IDEA, PyCharm 및 WebStorm을 포함하여 전 세계적으로 가장 인기 있는 몇 가지 IDE를 개발합니다. 그리고 전담 인프라 팀은 그 뒤에서 수백 명의 개발자가 이러한 제품을 효율적으로 빌드하고 테스트하여 릴리스할 수 있도록 돕습니다.
이 프로세스의 핵심은 JetBrains의 자체 CI/CD 솔루션인 TeamCity입니다. TeamCity는 빌드 및 테스트 자동화와 확장 가능한 인프라 관리를 지원합니다.
IntelliJ Infrastructure 팀과의 인터뷰를 통해 팀이 TeamCity를 사용하여 700~800명의 개발자를 위한 CI/CD 파이프라인을 관리하고, 매일 수천 개의 빌드를 조정하며, 워크플로를 최적화하여 빠르고 안정적인 릴리스를 보장하는 방법에 대해 알아보았습니다.
대규모 개발자 팀이 지속적으로 변경 사항을 푸시하는 상황에서 빠르고 안정적이며 확장 가능한 CI/CD 파이프라인을 유지하는 일은 간단하지 않습니다. IntelliJ Infrastructure 팀은 사용 가능한 리소스에 부담을 주지 않으면서 하루에 수천 개의 빌드를 실행하는 대규모 처리 능력을 가진 솔루션이 필요합니다. 또한 수동 개입을 최소화하고 고품질 코드 제공을 보장하기 위한 스마트 자동화도 필요합니다.
또한 온프레미스, AWS, macOS, Linux 및 Windows 에이전트를 포함한 다양한 인프라 환경에 대한 지원이 중요합니다. 코드 품질을 높게 유지하기 위해 팀은 수십만 개의 자동화된 테스트를 관리하는 동시에 불안정한 테스트 실패를 최소화해야 합니다.
JetBrains가 개발한 강력한 CI/CD 솔루션인 TeamCity는 이러한 과제를 정면으로 돌파하는 완벽한 솔루션임을 입증했습니다.
"저희는 TeamCity에서 IDE 및 이와 관련된 모든 부분, 이를 테면 내부 서비스, 통계 서비스 등을 빌드합니다. TeamCity에 매우 익숙해지니 손에 망치를 든 것 같더군요. 무엇이든 할 수 있죠."
— Dmitrii Panov, IntelliJ Infrastructure 기술 책임자
대규모 IntelliJ 팀은 현재, 모든 변경 사항을 한 브랜치에 쌓아두고 함께 테스트될 때까지 기다리는 대신 준비되는 즉시 개발자가 코드를 푸시하는 프로세스를 이용합니다.
이 워크플로를 지원하기 위해 IntelliJ Infrastructure 팀은 기본적으로 TeamCity의 복합 빌드 구성 세트인 Safe Push 메커니즘을 구현했습니다. 프로세스가 매우 간단하여 사용자가 IDE를 통해 변경 사항을 푸시하면 됩니다.
백그라운드에서 전용 내부 서비스가 Safe Push 변경 세트를 분석하고 TeamCity REST API를 사용하여 변경 사항을 테스트하는 데 필요한 빌드를 트리거합니다. 또한 실패한 빌드를 다시 시작하여 불안정한 테스트를 다시 시도합니다.
TeamCity는 잘 만들어진 빌드를 재사용할 수 있게 해주어 Safe Push 속도를 상당히 높이고 비용을 줄이는 효과를 가져다줍니다. Safe Push 테스트 빌드에 최대 700,000개의 테스트를 포함할 수 있기 때문에 가능한 일입니다. 빌드 재사용 기능으로 모든 부분을 처음부터 빌드하는 대신 아티팩트, 종속성 및 테스트 결과를 재사용할 수 있습니다. 이를 통해 빌드 효율성이 향상되고 CI/CD 파이프라인이 가속화되며 리소스 소비가 줄어듭니다.
빌드 재사용은 팀이 특히 유용하다고 생각하는 TeamCity 기능 중 하나입니다. 일반적인 TeamCity 빌드 체인은 다음과 같습니다.
TeamCity의 빌드 체인을 보여주는 예
테스트 체인이 첫 번째 시도에서 통과하지 못하면 Safe Push 메커니즘이 실제로 문제가 있는지 확인하기 위해 이를 두 번 더 시도합니다.
빌드 재사용으로 어떻게 반복적 시도가 최적화되는지 알아보기 위해 일반적인 푸시를 생각해 보겠습니다. 첫 번째 시도에서 체인에 있는 329개 빌드가 모두 실행됩니다. 여기서 319개는 통과하지만 10개는 실패하므로 체인이 다시 실행됩니다. 이번에는 실패한 10개 빌드만 실행하고 나머지는 재사용됩니다. 이제 6개가 더 통과하고 일부는 남습니다. 따라서 세 번째 시도에서는 나머지 4개를 실행하고 325개는 재사용됩니다.
그러면 빌드 에이전트의 부하가 크게 줄어들고 재시도 시간이 상당히 단축됩니다. 각각 약 3시간이 걸리는 전체 시도를 3번 실행하는 대신, 빌드 재사용을 통해 실행 시간을 약 30% 단축할 수 있습니다.
IntelliJ 팀은 하루에 180명 이상의 고유한 사용자를 위해 158,000개 이상의 빌드를 실행하므로 효율성이 매우 중요합니다. TeamCity의 빌드 재사용 기능은 다음과 같은 이점을 제공합니다.
TeamCity Grafana dashboard
IntelliJ Infrastructure 팀은 Kotlin DSL을 통해 TeamCity를 관리합니다. Kotlin DSL을 사용하면 완전한 프로그래밍 언어의 모든 이점과 코드로 파이프라인을 빌드하도록 설계된 DSL의 강점을 모두 얻을 수 있습니다.
현재 TeamCity 인스턴스에는 2,000개 이상의 프로젝트, 15,000개의 빌드 구성, 거의 300개의 VCS 루트가 포함되어 있습니다. Kotlin DSL이 아닌 다른 언어를 사용하여 이렇게 거대한 인스턴스를 관리한다는 것은 상상하기가 어렵습니다.
"Kotlin 설정 자체에 대한 유닛 테스트만 약 350개 있습니다. YAML에서도 똑같은 상황을 겪고 싶지는 않아요."
— Dmitrii Panov, IntelliJ Infrastructure 기술 책임자
TeamCity의 강력한 에이전트 관리 기능은 CI/CD 파이프라인을 쉽고 효율적으로 확장할 수 있게 해줍니다. 앵커, go-to 문, 수동 재시도 논리와 같은 복잡한 해결 방법이 필요한 YAML 기반 CI/CD 시스템과 달리 TeamCity는 기본 제공되는 에이전트 오케스트레이션으로 이 프로세스를 간소화합니다.
AWS를 사용하는 팀의 경우 TeamCity는 클라우드 인프라와 완벽하게 통합되어 에이전트를 수요에 따라 자동으로 시작하고 관리할 수 있습니다. 예를 들어 주어진 상황에서 필요한 정확한 수의 에이전트를 만들고 유휴 상태일 때는 종료하도록 TeamCity를 구성하여 리소스 활용을 최적화할 수 있습니다.
이러한 수준의 정밀한 에이전트 제어는 다른 솔루션과 비교할 때 훨씬 더 직관적입니다. 다른 솔루션에서는 외부 플러그인의 사용으로 호환성 문제가 발생하고 추가적인 문제 해결이 필요할 수 있습니다.
TeamCity는 10,000개 이상의 빌드 대기열을 지원하고 최대 5,000개의 빌드 에이전트를 동적으로 관리하는 등 방대한 워크로드를 대규모로 처리합니다. 두드러지는 기능 중 하나는 TeamCity에서 선점 가능한 AWS 인스턴스로 작업할 수 있다는 것입니다. AWS에서 인스턴스를 회수하면 TeamCity가 다른 에이전트에서 빌드를 자동으로 다시 시작하여 중단을 방지하고 원활한 실행을 보장합니다.
하루에 수만 개의 빌드를 쏟아내는 수백 명의 개발자를 위해 CI/CD 플랫폼을 관리할 때는 주요 메트릭을 추적하는 것이 중요합니다. TeamCity는 다양한 진단 도구와 메트릭을 즉시 제공합니다. TeamCity는 Prometheus 형식으로 메트릭을 내보낼 수도 있으므로 보다 고급 사용을 위한 맞춤형 대시보드를 빌드할 수 있습니다.
"TeamCity는 빌드나 테스트에 대한 통계 같은 기본적인 빌딩 블록을 제공합니다. 이 기본적 구조를 토대로 하면 더 정교한 것을 구축할 수 있습니다."
— Aleksei Smirnov, .NET Infrastructure 팀 소프트웨어 개발자
TeamCity를 사용하여 CI/CD 프로세스를 최적화하기 위해 IntelliJ Infrastructure 팀이 주의 깊게 살펴보는 주요 메트릭은 다음과 같습니다.
팀은 워크로드와 성능을 파악하기 위해 매일 약 158,000개의 빌드를 모니터링합니다. 빌드 수 자체는 팀이 매우 주의 깊게 살펴보는 부분이 아니지만, 그래도 빌드 에이전트의 워크로드를 예측하는 데는 중요한 메트릭입니다.
어떤 시점에서든 80~90개의 Safe Push 검사가 동시에 실행됩니다. 이 검사가 더 신속하게 진행될수록 빌드가 더 빨라지므로 각 Safe Push 검사에 걸리는 시간을 추적하는 것이 중요합니다.
팀은 재시도 중에 얼마나 많은 빌드가 재사용되는지 분석하여 중복 실행의 필요성을 줄이고 리소스를 절약합니다.
IntelliJ TeamCity 프로젝트에는 하나의 복합 빌드 내에 거의 700,000개의 테스트가 있습니다.
TeamCity의 단일 복합 빌드 내에서 성공적인 테스트 실행
팀은 Safe Push 체인당 700,000개 이상의 테스트를 추적하여 실패한 테스트를 확인합니다. 또한 팀은 테스트 불안정성을 측정하여 실패한 테스트를 자동으로 재시도하고 불안정한 테스트는 추가 조사를 위해 중단합니다.
팀이 개선하려고 하는 메트릭 중 하나는 성공적인 실행에 필요한 시도 횟수입니다. 이를 통해 각 실행을 위한 리소스와 시간을 절약할 수 있습니다.
팀은 5,000개가 넘는 AWS 및 물리적 빌드 에이전트를 모니터링하고 빌드 재사용과 같은 기능으로 리소스 할당을 최적화하는데, 이를 통해 빌드 시간을 약 30%까지 단축할 수 있습니다.
IntelliJ Infrastructure 팀은 TeamCity를 매일 다양한 작업에 활용하고 이를 통해 많은 문제를 해결하고 있지만 TeamCity에 추가하고 싶은 기능이 몇 가지 있다고 말합니다.
TeamCity는 조직 내의 모든 빌드 체인과 프로젝트에 대한 액세스를 제공하지만, 개발자는 관련 빌드만을 보다 집중적으로 보고 싶은 경우가 많습니다. 예를 들어, PyCharm에서 작업하는 개발자는 관련이 없는 프로젝트는 살펴볼 필요 없이 PyCharm 관련 빌드, 테스트 및 구성만 볼 수 있어야 합니다.
관련 빌드 구성, 테스트 및 중단된 테스트만 표시하는 간소화된 대시보드는 사용 편의성을 크게 개선합니다. 팀은 Grafana 기반 솔루션을 만들어 이 문제를 해결하려고 했지만 TeamCity 내에서 보다 통합적이고 사용자 친화적인 접근 방식을 시도하는 것이 이상적입니다.
팀은 TeamCity가 중단 관리 시스템에서 큰 이점을 얻을 것이라고 생각합니다. 자동화된 테스트의 양이 많기 때문에 일부 테스트는 불가피하게 중단되어야 합니다. TeamCity가 테스트 중단 기능을 제공하지만 테스트를 중단하고 잊어버리기가 여전히 매우 쉽기 때문에 이를 사용해야 하는 다른 동료들의 작업이 복잡해질 수 있습니다.
팀이 프로젝트와 관련된 중단 테스트를 쉽게 확인하고 관리 및 추적할 수 있는 전용 중단 관리 시스템이 있으면 더 나은 소유권과 투명성을 보장하는 데 도움이 됩니다.
IntelliJ Infrastructure 팀은 TeamCity를 사용하여 대규모의 CI/CD 효율성을 실현하여 빌드를 간소화하고 리소스 사용을 최적화하며 실행 시간을 크게 단축했습니다. Safe Push, 빌드 재사용 및 자동화된 테스트 재시도를 활용하여 빌드 실행 시간을 30% 단축하고 700~800명의 개발자가 변경 사항을 원활하게 푸시할 수 있었습니다.
IntelliJ Infrastructure 팀의 사례는 TeamCity가 단순한 CI/CD 도구가 아니라 대규모 소프트웨어 개발의 중추라는 사실을 잘 보여줍니다.