[Gitlab] 온프레미스 환경 구축하기 – 분석편

Gitlab은 다음으로 구성 되어 있다.

  • puma
  • workhorse
  • sidekiq
  • nginx
  • gitaly
  • gitlab-shell
  • redis
  • postgresql

puma

Ruby on Rails 기반으로 만들어진 애플리케이션을 구동시키는 WAS(Web Application Server) 이다. Spring 기반을 Tomcat으로 구동시키는 것과 같이 puma가 Tomcat의 위치에 있다. puma는 gitlab 코어 코드를 작동시키는 앱이지만, 이 포스팅에서는 puma를 gitlab 코어 서버라는 의미로 사용할 것이다.

workhorse

gitlab에서 개발한 reverse proxy 이다. gitlab을 위해서 개발된 놈이다. 다음과 같은 일을 한다.

  • 파일 다운로드
  • 파일 업로드
  • git push/pull
  • git 아카이브 다운로드

sidekiq

비동기 백그라운드 서버이다. Rails가 job을 sidekiq으로 던지면, sidekiq이 실행시켜 준다고 생각하면 된다. job은 Redis를 사용해서 주고 받는다.

nginx

개발자라면 한번은 들어본 그 reverse proxy 이다. gitlab 패키지에 번들되어 함께 설치된다. workhorse 와는 다르게 범용적인 기능을 제공한다.

gitaly

gitlab에서 개발한 git 관리 서버이다. 여러 기능이 추가된 상위 호환 git이다. 클러스터링이 지원된다.

gitlab-shell

shell 기반 작업을 담당하는 gitlab 서버라고 생각하면 된다. ssh 프로토콜의 git 요청을 처리한다.

redis

메모리 기반 DB이다. 다양한 용도로 쓰일거 같다.

postgresql

디스크 기반 RDBMS이다. 당연 메인 저장소 일듯.

서버 구성도

각 구성요소를 전부 찢어서 정리해보았다. 화살표는 업스트림 트래픽을 의미한다.

이용자가 웹으로 접속하게 되면, 가장 먼저 nginx가 트래픽을 받는다. nginx는 reverse proxy 기능을 사용해 트래픽을 workhorse로 넘겨준다.

workhorse는 이용자의 요청을 파악하고 상황에 맞게 static 자원을 serve 하거나 large http 요청을 처리하거나 puma로 트래픽을 넘겨준다.

puma는 gitlab의 웹 코어이다. 저장소에 직접 접근하여 정보를 가져온다. 필요한 background job이 있으면, redis에 작업 목록을 남겨둔다.

sidekiq은 puma가 남긴 작업 목록을 redis에서 읽어와서 다양한 background job을 빠르게 실행한다. 저장소에 직접 접근하여 작업을 처리한다.

gitlab-shell은 이용자가 ssh 프로토콜로 접속할 때 활용된다. ssh 프로토콜의 요청을 gitlab api에 맞게 번역해준다.

스케일 아웃 가능성

gitlab은 모든 부분이 적절한 설정을 통해서 스케일 아웃이 가능하다. 자세한 구성도가 궁금하다면 아래 ‘각 구성도 보기’를 참고해주세요.

각 구성도 보기

puma & workhorse

puma는 stateless 하게 만들어져 있다. 따라서

workhorse는 load balance 기능이 없다. 따라서 여러 puma 서버에 붙을 수 없다. puma의 스케일 아웃을 위해서는 workhorse와 1대1로 가야한다. 아니면 workhorse 위에 nginx를 두던가

sidekiq

sidekiq은 redis에서 작업을 받아와 기능을 수행하기 때문에 stateless 하다. 스케일 아웃이 가능하다.

gitaly

gitaly는 gitlab에 의해 클러스터링이 가능하게 설계되었다. puma 설정에 다수의 gitaly 서버를 등록해 놓으면 알아서 동기화 / 로드밸런싱이 된다.

gitlab-shell

마찬가지로 stateless 하기 때문에 여러 서버가 있어도 된다. 다만 tcp 로드밸런서를 사용해야 한다.

postgresql & redis

태생적으로 스케일 아웃이 가능하다.

이제 설치하러 가봅시다.

댓글 남기기

이메일 주소는 게시되지 않습니다. 필수 필드는 *로 표시됩니다.