Renovate로 의존성 관리

MSA에서 의존성 관리

MSA에서 라이브러리 업데이트는 꼭 해야 하지만 잊기 쉬운 특성을 가진다. 이는 손씻기나 양치질등과 닮아 있다. 열심히 해도 티가 안난다. 문제가 생기기 전까진!

백엔드 개발자의 백미는 자동화를 통해 적은 리소스로 많은 사용자들을 대상으로 한 서비스에서 발생하는 문제를 해결하는데 있다. Renovate는 버전업 프로세스를 사용자가 원하는 만큼 자동화 시켜준다.

주기적인 버전업은 잠재적인 기술부채를 줄이고 서비스를 더욱 안정적으로 쓸 수 있게 해준다. 최근에는 보안 관련 패치가 버전 업그레이드를 통해 자주 일어난다.

때문에 주기적으로 라이브러리를 업데이트 하지 않으면 기술 부채를 조금씩 저축하는 것과 같다. 지금 팀에서는 매 빌드시마다 SourceClear 를 사용해 소스코드와 라이브러리의 취약점을 분석한다.

작성한 코드에서 취약점이 발견 되는 경우 직접 수정을 하면 되지만 Spring이나 Jackson과 같이 사용중인 라이브러리 취약점이 발생하면 라이브러이 버전 업그레이드로 필요하다. 문제는 이 취약점이 꽤나 빈번하게 발견된다는 점이다. SourceClear와 연동하고 나서 버전 업그레이드가 팀내의 잡일처럼 되어버렸다.

그와중에 Renovate는 가뭄에 단비같은 존재, 사용자 설정한 내용대로 버전 업그레이드를 위한 풀리퀘스트를 생성해준다. 자동으로 master머지도 가능하며 시간당 생성하는 풀리퀘스트의 수 등 아주 다양한 설정이 가능하다.

팀에서는 kotlin + spring + gradle + docker 플러그인을 사용하고 있는데 이외에도 아주 다양한 플러그인을 지원한다. 아래 스크린샷에서도 확인할 수 있듯이 change log까지 전부 첨부해준다. 이건 개발자가 PR을 생성할떄 잘 안해주는 부분인데, Renovate는 세심하다.

Github에서는 App으로 제공되고 있으며 Gitlab이나 기타 설치형 저장소에서는 Renovate Bot을 직접 호스팅 하는 것도 가능하다. 아래는 팀의 일부 저장소에서 사용중인 renovate.json 설정 파일이다. 원하는 만큼 세세하게 설정이 가능하다. https://docs.renovatebot.com/self-hosted-configuration/

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "schedule": [
    "after 10am and before 5pm every weekday"
  ],
  "timezone": "Australia/Sydney",
  "prConcurrentLimit": 20,
  "prHourlyLimit": 1,
  "automerge": true,
  "dockerfile": {
    "enabled": true
  },
  "maven": {
    "enabled": true
  },
  "terraform": {
    "enabled": true
  },
  "extends": [
    "config:base"
  ]
}

Bitbucket에서 혼자서 열심히 버전 업중인 Renovate
Pull Request 템플릿

문제점

하지만 소프트웨어 문제가 언제나 그렇듯이, 항상 좋기만 한 건 없다. 그렇지 않아도 몇일전에 관련된 장애가 한 건 있었다. reactor-netty 에서 중대한 메모리 누수가 발견되서 부랴부랴 전부 롤백해야했다.

사실 Renovate의 문제라기 보다 시스템적으로 버전업시의 충격을 흡수 할 수 있는 쿠션이나 버퍼가 존재했어야 한다. 배포가 잦지 않다면 스테이징 서버가 이런 역할을 할 수 도 있겠지만 문제가 일어난 서비스는 배포가 아주 빈번하게 일어나서 버전 업그레이드가 문제인지 개발자가 머지한 PR이 문제인지 판단하기 힘들었다. 

그래서 우리는 모든 스프링기반 프로젝트의 베이스가 되는 프로젝트를  만들고 해당 프로젝트는 자동적으로 의존성을 갱신하고 배포되도록 했다. 

이글을 읽는 분들도 저장소에 Renovate를 적용해 보고 어느정도 자동화가 가능할지 테스트 해보길 권한다.