GitLab 아키텍처 개요

소프트웨어 배포

GitLab에는 두 가지 소프트웨어 배포가 있습니다:

GitLab은 다양한 구독 아래에서 제공됩니다.

GitLab의 새로운 버전은 안정적인 브랜치에서 릴리즈되며, main 브랜치는 bleeding-edge 개발에 사용됩니다.

자세한 내용은 GitLab 릴리즈 프로세스를 참조하세요.

두 배포 모두 추가 구성 요소가 필요합니다. 이러한 구성 요소는 구성 요소 세부정보 섹션에 설명되어 있으며, 각 구성 요소는 자체 저장소를 가지고 있습니다.

각 의존 구성 요소의 새로운 버전은 일반적으로 태그로 제공되지만, GitLab 코드베이스의 main 브랜치를 사용하면 이러한 구성 요소의 최신 안정 버전을 얻을 수 있습니다. 새로운 버전은 일반적으로 GitLab 릴리즈와 거의 동시에 릴리즈되며, 중요한 비공식 보안 업데이트는 제외됩니다.

구성 요소

GitLab의 일반적인 설치는 GNU/Linux에서 이루어지지만, 점점 더 많은 배포가 Kubernetes 플랫폼을 사용하고 있습니다. 가장 큰 알려진 GitLab 인스턴스는 GitLab.com에 있으며, 이는 우리의 공식 GitLab Helm 차트공식 Linux 패키지를 사용하여 배포되었습니다.

일반적인 설치에서는 NGINX 또는 Apache를 웹 서버로 사용하여 GitLab Workhorse를 통해 프록시를 설정하고 Puma 애플리케이션 서버로 전달합니다. GitLab은 Puma 애플리케이션 서버를 사용하여 웹 페이지와 GitLab API를 제공합니다. Sidekiq를 작업 큐로 사용하며, 이는 다시 Redis를 비영속적인 데이터베이스 백엔드로 사용하여 작업 정보, 메타데이터 및 수신 작업을 처리합니다.

기본적으로 Puma와 Workhorse 간의 통신은 유닉스 도메인 소켓을 통해 이루어지지만, TCP를 통한 요청 전달도 지원됩니다. Workhorse는 gitlab/public 디렉터리에 접근하여 정적 페이지, 업로드(예: 아바타 이미지 또는 첨부 파일) 및 사전 컴파일된 자산을 제공하기 위해 Puma 애플리케이션 서버를 우회합니다.

GitLab 애플리케이션은 PostgreSQL을 지속적인 데이터베이스 정보(예: 사용자, 권한, 이슈 또는 기타 메타데이터)를 위해 사용합니다. GitLab은 구성 파일의 repositories: 섹션에서 정의된 위치에 베어 Git 저장소를 저장합니다. 또한 베어 저장소와 함께 기본 브랜치 및 훅 정보를 유지합니다.

HTTP/HTTPS를 통해 저장소를 제공할 때 GitLab은 GitLab API를 사용하여 인증 및 접근을 확인하고 Git 개체를 제공합니다.

부가 구성 요소인 GitLab Shell은 SSH를 통해 저장소를 제공합니다. GitLab Shell은 구성 파일의 GitLab Shell 섹션에서 정의된 위치 내에서 SSH 키를 관리합니다. 해당 위치의 파일은 수동으로 편집해서는 안 됩니다. GitLab Shell은 Gitaly를 통해 베어 저장소에 접근하여 Git 개체를 제공하고, Redis와 통신하여 GitLab이 처리할 작업을 Sidekiq에 제출합니다. GitLab Shell은 GitLab API를 쿼리하여 인증 및 접근을 확인합니다.

Gitaly는 GitLab Shell 및 GitLab 웹 앱에서의 Git 작업을 실행하며, GitLab 웹 앱에 Git 속성(예: 제목, 브랜치, 태그 또는 기타 메타데이터)을 가져오고 블롭(예: diff, 커밋 또는 파일)을 가져오도록 API를 제공합니다.

GitLab.com의 프로덕션 아키텍처에도 관심이 있을 수 있습니다.

기존 구성 요소 조정 및 새로운 구성 요소 도입

응용 프로그램이 전통적인 리눅스 머신에 설치될 때와 Kubernetes와 같은 컨테이너화된 플랫폼에 설치될 때의 동작 방식에는 근본적인 차이가 있습니다.

공식 설치 방법과 비교할 때 몇 가지 주목할 만한 차이점은 다음과 같습니다:

  • 공식 리눅스 패키지는 서로 다른 서비스와 동일한 파일 시스템의 파일에 접근할 수 있습니다.

    공유 파일은 Kubernetes 플랫폼에서 실행되는 애플리케이션의 선택 사항이 아닙니다.

  • 공식 리눅스 패키지는 기본적으로 공유 구성 및 네트워크에 접근할 수 있는 서비스를 가지고 있습니다. 그러나 이는 Kubernetes에서 실행되는 서비스에 해당되지 않으며, 서비스는 완전한 격리 상태에서 실행되거나 특정 포트를 통해서만 접근이 가능할 수 있습니다.

즉, 서비스를 아키텍처할 때 서비스 간의 공유 상태를 신중하게 고려해야 하며, 동일한 파일에 접근해야 하는 서비스는 적절한 API를 통해 정보를 교환할 수 있어야 합니다. 가능하면, 이는 파일을 통해 수행되어서는 안 됩니다.

API 우선 철학으로 작성된 구성 요소는 두 가지 방법과 호환되므로 모든 새로운 기능과 서비스는 Kubernetes 호환성을 먼저 고려하여 작성해야 합니다.

이를 보장하는 가장 간단한 방법은 기능이나 서비스의 지원을 공식 GitLab Helm 차트에 추가하거나 배포 팀과 연락하는 것입니다.

자세한 내용은 새 서비스 구성 요소 추가 프로세스를 참조하십시오.

간소화된 구성 요소 개요

이것은 GitLab 아키텍처를 이해하는 데 사용될 수 있는 간소화된 아키텍처 다이어그램입니다.

전체 아키텍처 다이어그램은 아래의 구성 요소 다이어그램에서 확인하실 수 있습니다.

TCP 80,443
TCP 22
TCP 8090
HTTP/HTTPS
SSH
GitLab Pages
GitLab Workhorse
GitLab Shell
Gitaly
Puma (Gitlab Rails)
Sidekiq (GitLab Rails)
PostgreSQL
Redis
NGINX

모든 연결은 별도로 명시되지 않는 한 유닉스 소켓을 사용합니다.

구성 요소 다이어그램

Syntax error in textmermaid version 10.9.3

시퀀스는 git push에 대해서도 유사하지만, git-receive-pack이 대신 사용됩니다.

SSH 요청 (22)

SSH를 통한 Git 작업은 Git 문서에 설명된 상태 저장 프로토콜을 사용할 수 있지만, 이를 처리하는 책임은 여러 GitLab 구성 요소에 나눠져 있습니다.

GitLab 구성 요소는 SSH를 직접적으로 사용하지 않습니다. 모든 SSH 연결은 클라이언트 머신의 Git과 SSH 서버 간에 이루어지며, SSH 서버가 연결을 종료합니다. SSH 서버에게 모든 연결은 git 사용자로 인증됩니다. GitLab 사용자는 클라이언트가 제시한 SSH 키에 따라 구분됩니다.

여기 git fetch에 대한 시퀀스 다이어그램이 있습니다. Fast SSH key lookup이 활성화되어 있다고 가정합니다. AuthorizedKeysCommandGitLab Shell이 제공하는 실행 파일입니다:

Git on serverGitalyRailsGitLab ShellAuthorizedKeysCommandSSH serverGit on clientGit on serverGitalyRailsGitLab ShellAuthorizedKeysCommandSSH serverGit on clientgit fetch키 ID 조회인증 확인Git 클라이언트와 서버 간의 양방향 통신ssh git fetch-pack requestgitlab-shell-authorized-keys-check git AAAA...GET /internal/api/authorized_keys?key=AAAA...200 OK, command="gitlab-shell upload-pack key_id=1"command="gitlab-shell upload-pack key_id=1"gitlab-shell upload-pack key_id=1GET /internal/api/allowed?action=upload_pack&key_id=1200 OK, { gitaly: ... }SSHService.SSHUploadPack 요청git upload-pack 요청git upload-pack 응답SSHService.SSHUploadPack 응답gitlab-shell upload-pack 응답ssh git fetch-pack 응답

git push 작업은 git upload-pack 대신 git receive-pack이 사용된다는 점을 제외하면 매우 유사합니다.

빠른 SSH 키 조회가 활성화되지 않은 경우, SSH 서버는 ~git/.ssh/authorized_keys 파일을 읽어 주어진 SSH 세션에 대해 실행할 명령을 결정합니다. 이는 사용자가 SSH 키를 수정할 때마다 실행되도록 Rails에서 AuthorizedKeysWorker에 의해 업데이트됩니다.

SSH 인증서는 키 대신에 사용할 수 있습니다. 이 경우, AuthorizedKeysCommandAuthorizedPrincipalsCommand로 대체됩니다. 이는 Rails 내부 API를 사용하지 않고 인증서에서 사용자 이름을 추출하며, 나중에 /api/internal/allowed 호출에서 key_id 대신 사용됩니다.

GitLab Shell은 Gitaly와 관련이 없는 몇 가지 작업도 수행합니다. 예를 들어, 이중 인증 코드 리셋과 같은 작업이 이에 해당합니다. 이러한 작업은 동일한 방식으로 처리되지만, Gitaly로의 왕복이 없고 Rails가 내부 API 호출의 일환으로 작업을 수행하며, GitLab Shell이 사용자의 응답을 직접 스트리밍합니다.

시스템 레이아웃

사진에서 ~git을 언급할 때는 일반적으로 /home/git인 Git 사용자의 홈 디렉토리를 의미합니다.

GitLab은 주로 /home/git 사용자 홈 디렉토리에 git 사용자로 설치됩니다. 홈 디렉토리 내에는 GitLab 서버 소프트웨어와 리포지토리가 있으며(리포지토리 위치는 구성 가능), 여기서 귀하의 리포지토리를 찾을 수 있습니다.

베어 리포지토리는 /home/git/repositories에 위치합니다. GitLab은 Ruby on Rails 애플리케이션이므로 내부 작업의 세부 사항은 Ruby on Rails 애플리케이션이 작동하는 방식을 연구하여 배울 수 있습니다.

SSH를 통해 리포지토리를 제공하기 위해 /home/git/gitlab-shell에 설치된 GitLab Shell이라는 추가 애플리케이션이 있습니다.

설치 폴더 요약

요약하자면, git 사용자 홈 디렉토리의 디렉토리 구조는 다음과 같습니다.

프로세스

ps aux | grep '^git'

GitLab은 운영을 위해 여러 구성 요소가 필요합니다. 지속적인 데이터베이스(PostgreSQL)와 Redis 데이터베이스가 필요하며, Apache httpd 또는 NGINX를 사용하여 Puma에 proxypass를 설정합니다. 이러한 모든 구성 요소는 GitLab과 다른 시스템 사용자로 실행되어야 합니다(예: postgres, redis, www-data, git이 아님).

git 사용자로 Sidekiq과 Puma(기본적으로 포트 8080에서 실행되는 간단한 Ruby HTTP 서버)를 시작합니다. GitLab 사용자 하에는 일반적으로 4개의 프로세스가 있습니다: puma master (1 프로세스), puma cluster worker (2 프로세스), sidekiq (1 프로세스).

리포지토리 접근

리포지토리는 HTTP 또는 SSH를 통해 접근됩니다. HTTP 클론/푸시/풀은 GitLab API를 사용하고, SSH 클로닝은 GitLab Shell에 의해 처리됩니다(이전에 설명된).

문제 해결

자세한 내용은 README를 참조하십시오.

서비스의 초기화 스크립트

GitLab 초기화 스크립트는 Puma와 Sidekiq를 시작하고 중지합니다:

/etc/init.d/gitlab
Usage: service gitlab {start|stop|restart|reload|status}

Redis (키-값 저장소/비지속적 데이터베이스):

/etc/init.d/redis
Usage: /etc/init.d/redis {start|stop|status|restart|condrestart|try-restart}

SSH 데몬:

/etc/init.d/sshd
Usage: /etc/init.d/sshd {start|stop|restart|reload|force-reload|condrestart|try-restart|status}

웹 서버 (다음 중 하나):

/etc/init.d/httpd
Usage: httpd {start|stop|restart|condrestart|try-restart|force-reload|reload|status|fullstatus|graceful|help|configtest}

$ /etc/init.d/nginx
Usage: nginx {start|stop|restart|reload|force-reload|status|configtest}

지속적인 데이터베이스:

$ /etc/init.d/postgresql
Usage: /etc/init.d/postgresql {start|stop|restart|reload|force-reload|status} [version ..]

서비스의 로그 위치

GitLab(여기에는 Puma 및 Sidekiq 로그 포함):

  • /home/git/gitlab/log/에는 일반적으로 application.log, production.log, sidekiq.log, puma.stdout.log, git_json.log, puma.stderr.log가 포함됩니다.

GitLab Shell:

  • /home/git/gitlab-shell/gitlab-shell.log

SSH:

  • /var/log/auth.log 인증 로그 (Ubuntu에서).
  • /var/log/secure 인증 로그 (RHEL에서).

NGINX:

  • /var/log/nginx/에는 오류 및 접근 로그가 포함됩니다.

Apache httpd:

  • Apache 로그 설명.
  • /var/log/apache2/에는 오류 및 출력 로그가 포함됩니다 (Ubuntu에서).
  • /var/log/httpd/에는 오류 및 출력 로그가 포함됩니다 (RHEL에서).

Redis:

  • /var/log/redis/redis.log 여기에도 로그 회전된 로그가 있습니다.

PostgreSQL:

  • /var/log/postgresql/*

GitLab 특정 구성 파일

GitLab에는 /home/git/gitlab/config/*에 위치한 구성 파일이 있습니다. 일반적으로 참조되는 구성 파일은 다음과 같습니다:

  • gitlab.yml: GitLab Rails 구성
  • puma.rb: Puma 웹 서버 설정
  • database.yml: 데이터베이스 연결 설정

GitLab Shell에는 /home/git/gitlab-shell/config.yml에 구성 파일이 있습니다.

GitLab Rails에 새 설정 추가하기

gitlab.yml에 포함되어야 하는 설정은 다음과 같습니다:

  • 여러 서비스에 걸쳐 애플리케이션이 어떻게 연결되는지에 대한 정보. 예를 들어, Gitaly 주소, Redis 주소, Postgres 주소 및 Consul 주소.
  • 분산 추적 구성 및 일부 관측 가능성 구성. 예를 들어, 히스토그램 버킷 경계.
  • Rails 초기화 중에 구성해야 할 모든 것, Postgres 연결이 설정되기 전에 필요할 수 있습니다.

대부분의 다른 설정은 애플리케이션 자체인 ApplicationSetting에 배치하는 것이 더 좋습니다. UI에서 설정을 관리하는 것이 구성 파일을 관리하는 것보다 일반적으로 더 나은 사용자 경험을 제공합니다. 개발 비용과 관련하여, gitlab.yml을 수정하는 것이 종종 더 빠른 반복처럼 보이지만, 아래의 모든 배포 방법을 고려할 때 이는 불리한 거래일 수 있습니다.

gitlab.yml에 설정을 추가할 때:

  1. Omnibus에 추가되었는지 확인 해야 합니다.
  2. 필요하다면 Charts에 추가되었는지 확인 해야 합니다.
  3. GDK에 추가되었는지 확인 해야 합니다.

유지 관리 작업

GitLab은 버전 정보를 보고 구성에서 빠른 검사를 실행하여 애플리케이션 내에서 올바르게 구성되었는지 확인할 수 있는 Rake 작업을 제공합니다. 유지 관리 Rake 작업을 참조하세요.

요약하자면, 다음을 수행하세요:

sudo -i -u git
cd gitlab
bundle exec rake gitlab:env:info RAILS_ENV=production
bundle exec rake gitlab:check RAILS_ENV=production

git 사용자로 로그인할 때는 sudo -i -u git 또는 sudo su - git을 사용하는 것이 좋습니다. GitLab이 제공하는 sudo 명령은 Ubuntu에서 작동하지만, RHEL에서는 항상 작동하지 않을 수 있습니다.

GitLab.com

GitLab.com 아키텍처는 참조를 위해 자세히 설명되어 있지만, 이 아키텍처는 수백만 명의 사용자가 있는 경우에만 유용합니다.

AI 아키텍처

AI 기반 기능을 활성화하기 위한 SaaS 모델 게이트웨이가 제공됩니다.