GitLab 아키텍처 개요
GitLab v19.4요약
GitLab에는 두 가지 소프트웨어 배포판이 있습니다. EE 리포지터리는 보관 처리되었습니다. GitLab은 다양한 구독으로 제공됩니다. GitLab의 새 버전은 안정 브랜치에서 릴리스되며, main 브랜치는 최신 개발 용도로 사용됩니다.
소프트웨어 배포#
GitLab에는 두 가지 소프트웨어 배포판이 있습니다.
- 오픈 소스 Community Edition(CE).
- 오픈 코어 Enterprise Edition(EE).
EE 리포지터리는 보관 처리되었습니다. GitLab은 이제 단일 코드베이스로 운영됩니다.
GitLab은 다양한 구독으로 제공됩니다.
GitLab의 새 버전은 안정 브랜치에서 릴리스되며, main 브랜치는
최신 개발 용도로 사용됩니다.
자세한 내용은 GitLab 릴리스 프로세스를 참고합니다.
두 배포판 모두 추가 컴포넌트가 필요합니다. 이러한 컴포넌트는
컴포넌트 세부 정보 섹션에서 설명하며, 모두 자체 리포지터리를 가지고 있습니다.
각 의존 컴포넌트의 새 버전은 대개 태그로 제공되지만, GitLab 코드베이스의 main 브랜치를 유지하면
해당 컴포넌트의 최신 안정 버전을 사용할 수 있습니다. 새 버전은
대체로 GitLab 릴리스와 비슷한 시기에 출시되며, 중요하다고 판단되는 비정기 보안
업데이트는 예외입니다.
컴포넌트#
일반적인 GitLab 설치는 GNU/Linux 환경에서 이루어지지만, Kubernetes 플랫폼을 사용하는 배포도 늘고 있습니다. 알려진 가장 큰 GitLab 인스턴스는 GitLab.com이며, GitLab의 공식 GitLab Helm 차트와 공식 Linux 패키지로 배포됩니다.
일반적인 설치에서는 NGINX 또는 Apache를 웹 서버로 사용하여 요청을 GitLab Workhorse를 거쳐 Puma 애플리케이션 서버로 전달합니다. GitLab은 Puma 애플리케이션 서버로 웹 페이지와 GitLab API를 제공합니다. Sidekiq를 job 큐로 사용하며, Sidekiq는 다시 Redis를 job 정보, 메타데이터, 수신 job을 위한 비영구 데이터베이스 백엔드로 사용합니다.
기본적으로 Puma와 Workhorse 사이의 통신은 Unix 도메인 소켓을 통하지만, TCP로 요청을
전달하는 방식도 지원합니다. Workhorse는 gitlab/public 디렉터리에 접근하여 Puma
애플리케이션 서버를 거치지 않고 정적 페이지, 업로드(예: 아바타 이미지 또는 첨부 파일),
사전 컴파일된 에셋을 제공합니다.
GitLab 애플리케이션은 영구 데이터베이스 정보(예: 사용자,
권한, 이슈 또는 기타 메타데이터)에 PostgreSQL을 사용합니다. GitLab은 bare Git 리포지터리를
설정 파일의 repositories: 섹션에 정의된 위치에 저장합니다.
기본 브랜치와 훅 정보도 bare 리포지터리와 함께 보관합니다.
HTTP/HTTPS로 리포지터리를 제공할 때 GitLab은 GitLab API를 사용하여 인가와 접근 권한을 확인하고 Git 객체를 제공합니다.
애드온 컴포넌트인 GitLab Shell은 SSH로 리포지터리를 제공합니다. SSH 키는
설정 파일의 GitLab Shell 섹션에 정의된 위치에서 관리합니다.
해당 위치의 파일은 절대 수동으로 편집하면 안 됩니다. GitLab Shell은 Gitaly를 통해 bare
리포지터리에 접근하여 Git 객체를 제공하고, Redis와 통신하여 GitLab이 처리할 job을
Sidekiq에 제출합니다. GitLab Shell은 GitLab API에 질의하여 인가와 접근 권한을 확인합니다.
Gitaly는 GitLab Shell과 GitLab 웹 앱에서 오는 Git 작업을 실행하며, GitLab 웹 앱에 Git의 속성(예: 제목, 브랜치, 태그 또는 기타 메타데이터)을 가져오는 API와 블롭(예: diff, 커밋 또는 파일)을 가져오는 API를 제공합니다.
GitLab.com의 프로덕션 아키텍처에도 관심이 있을 수 있습니다.
기존 컴포넌트 조정과 새 컴포넌트 도입#
애플리케이션을 기존 Linux 머신에 설치할 때와 Kubernetes 같은 컨테이너화된 플랫폼에 설치할 때는 동작 방식에 근본적인 차이가 있습니다.
공식 설치 방법과 비교했을 때 눈에 띄는 차이점은 다음과 같습니다.
- 공식 Linux 패키지에서는 여러 서비스가 같은 파일 시스템의 파일에 접근할 수 있습니다. 공유 파일은 Kubernetes 플랫폼에서 실행되는 애플리케이션에서는 사용할 수 없는 방식입니다.
- 공식 Linux 패키지는 기본적으로 서비스가 공유 설정과 네트워크에 접근할 수 있습니다. Kubernetes에서 실행되는 서비스는 그렇지 않으며, 서비스가 완전히 격리된 상태로 실행되거나 특정 포트를 통해서만 접근할 수도 있습니다.
즉, 새 기능을 설계하고 새 컴포넌트를 추가할 때는 서비스 간 공유 상태를 신중하게 고려해야 합니다. 같은 파일에 접근해야 하는 서비스는 적절한 API를 통해 정보를 교환할 수 있어야 합니다. 가능하면 파일로 이 작업을 처리하지 않아야 합니다.
API 우선 철학으로 작성된 컴포넌트는 두 방식 모두와 호환되므로, 모든 새 기능과 서비스는 Kubernetes 호환성을 가장 먼저 고려하여 작성해야 합니다.
이를 보장하는 가장 간단한 방법은 기능이나 서비스에 대한 지원을 공식 GitLab Helm 차트에 추가하거나 Distribution 팀에 문의하는 것입니다.
자세한 내용은 새 서비스 컴포넌트 추가 프로세스를 참고합니다.
간략한 컴포넌트 개요#
다음은 GitLab 아키텍처를 이해하는 데 사용할 수 있는 간략한 아키텍처 다이어그램입니다.
전체 아키텍처 다이어그램은 아래의 컴포넌트 다이어그램에서 확인할 수 있습니다.
소스 코드 보기
%%{init: {"flowchart": { "useMaxWidth": false } }}%%
graph TB
%% Component declarations and formatting
HTTP((HTTP/HTTPS))
SSH((SSH))
GitLabPages(GitLab Pages)
GitLabWorkhorse(GitLab Workhorse)
GitLabShell(GitLab Shell)
Gitaly(Gitaly)
Puma("Puma (Gitlab Rails)")
Sidekiq("Sidekiq (GitLab Rails)")
PostgreSQL(PostgreSQL)
Redis(Redis)
HTTP -- TCP 80,443 --> NGINX
SSH -- TCP 22 --> GitLabShell
NGINX -- TCP 8090 --> GitLabPages
NGINX --> GitLabWorkhorse
GitLabShell --> Gitaly
GitLabShell --> GitLabWorkhorse
GitLabWorkhorse --> Gitaly
GitLabWorkhorse --> Puma
GitLabWorkhorse --> Redis
Sidekiq --> PostgreSQL
Sidekiq --> Redis
Puma --> PostgreSQL
Puma --> Redis
Puma --> Gitaly
Gitaly --> GitLabWorkhorse
별도로 명시하지 않는 한 모든 연결은 Unix 소켓을 사용합니다.
컴포넌트 다이어그램#
소스 코드 보기
%%{init: {"flowchart": { "useMaxWidth": false } }}%%
graph LR
%% Anchor items in the appropriate subgraph.
%% Link them where the destination* is.
subgraph Clients
Browser((Browser))
Git((Git))
end
%% External Components / Applications
Geo{{GitLab Geo}} -- TCP 80, 443 --> HTTP
Geo -- TCP 22 --> SSH
Geo -- TCP 5432 --> PostgreSQL
Runner{{GitLab Runner}} -- TCP 443 --> HTTP
K8sAgent{{GitLab agent}} -- TCP 443 --> HTTP
%% GitLab Application Suite
subgraph GitLab
subgraph Ingress
HTTP[[HTTP/HTTPS]]
SSH[[SSH]]
NGINX[NGINX]
GitLabShell[GitLab Shell]
%% inbound/internal
Browser -- TCP 80,443 --> HTTP
Git -- TCP 80,443 --> HTTP
Git -- TCP 22 --> SSH
HTTP -- TCP 80, 443 --> NGINX
SSH -- TCP 22 --> GitLabShell
end
subgraph GitLab Services
%% inbound from NGINX
NGINX --> GitLabWorkhorse
NGINX -- TCP 8090 --> GitLabPages
NGINX -- TCP 8150 --> GitLabKas
NGINX --> Registry
%% inbound from GitLabShell
GitLabShell --> GitLabWorkhorse
%% services
Puma["Puma (GitLab Rails)"]
Puma <--> Registry
GitLabWorkhorse[GitLab Workhorse] <--> Puma
GitLabKas[GitLab agent server] --> GitLabWorkhorse
GitLabPages[GitLab Pages] --> GitLabWorkhorse
Mailroom
Sidekiq
end
subgraph Integrated Services
%% Grafana
Grafana
NGINX --> Grafana
end
subgraph Metadata
%% PostgreSQL
PostgreSQL
PostgreSQL --> Consul
%% Consul and inbound
Consul
Puma ---> Consul
Sidekiq ---> Consul
Migrations --> PostgreSQL
%% PgBouncer and inbound
PgBouncer
PgBouncer --> Consul
PgBouncer --> PostgreSQL
Sidekiq --> PgBouncer
Puma --> PgBouncer
end
subgraph State
%% Redis and inbound
Redis
Puma --> Redis
Sidekiq --> Redis
GitLabWorkhorse --> Redis
Mailroom --> Redis
GitLabKas --> Redis
%% Sentinel and inbound
Sentinel <--> Redis
Puma --> Sentinel
Sidekiq --> Sentinel
GitLabWorkhorse --> Sentinel
Mailroom --> Sentinel
GitLabKas --> Sentinel
end
subgraph Git Repositories
%% Gitaly / Praefect
Praefect --> Gitaly
GitLabKas --> Praefect
GitLabShell --> Praefect
GitLabWorkhorse --> Praefect
Puma --> Praefect
Sidekiq --> Praefect
Praefect <--> PraefectPGSQL[PostgreSQL]
%% Gitaly makes API calls
%% Ordered here to ensure placement.
Gitaly --> GitLabWorkhorse
end
subgraph Storage
%% ObjectStorage and inbound traffic
ObjectStorage["Object storage"]
Puma -- TCP 443 --> ObjectStorage
Sidekiq -- TCP 443 --> ObjectStorage
GitLabWorkhorse -- TCP 443 --> ObjectStorage
Registry -- TCP 443 --> ObjectStorage
GitLabPages -- TCP 443 --> ObjectStorage
%% Gitaly can perform repository backups to object storage.
Gitaly --> ObjectStorage
end
subgraph Monitoring
%% Prometheus
Grafana -- TCP 9090 --> Prometheus[Prometheus]
Prometheus -- TCP 80, 443 --> Puma
RedisExporter[Redis Exporter] --> Redis
Prometheus -- TCP 9121 --> RedisExporter
PostgreSQLExporter[PostgreSQL Exporter] --> PostgreSQL
PgBouncerExporter[PgBouncer Exporter] --> PgBouncer
Prometheus -- TCP 9187 --> PostgreSQLExporter
Prometheus -- TCP 9100 --> NodeExporter[Node Exporter]
Prometheus -- TCP 9168 --> GitLabExporter[GitLab Exporter]
Prometheus -- TCP 9127 --> PgBouncerExporter
Prometheus --> Alertmanager
GitLabExporter --> PostgreSQL
GitLabExporter --> GitLabShell
GitLabExporter --> Sidekiq
%% Alertmanager
Alertmanager -- TCP 25 --> SMTP
end
%% end subgraph GitLab
end
subgraph External
subgraph External Services
SMTP[SMTP Gateway]
LDAP
%% Outbound SMTP
Sidekiq -- TCP 25 --> SMTP
Puma -- TCP 25 --> SMTP
Mailroom -- TCP 25 --> SMTP
%% Outbound LDAP
Puma -- TCP 369 --> LDAP
Sidekiq -- TCP 369 --> LDAP
%% Elasticsearch
Elasticsearch
Puma -- TCP 9200 --> Elasticsearch
Sidekiq -- TCP 9200 --> Elasticsearch
Elasticsearch --> Praefect
%% Zoekt
Zoekt --> Praefect
end
subgraph External Monitoring
%% Sentry
Sidekiq -- TCP 80, 443 --> Sentry
Puma -- TCP 80, 443 --> Sentry
%% Jaeger
Jaeger
Sidekiq -- UDP 6831 --> Jaeger
Puma -- UDP 6831 --> Jaeger
Gitaly -- UDP 6831 --> Jaeger
GitLabShell -- UDP 6831 --> Jaeger
GitLabWorkhorse -- UDP 6831 --> Jaeger
end
%% end subgraph External
end
click Alertmanager "#alertmanager"
click Praefect "#praefect"
click Geo "#gitlab-geo"
click NGINX "#nginx"
click Runner "#gitlab-runner"
click Registry "#registry"
click ObjectStorage "#object-storage"
click Gitaly "#gitaly"
click Jaeger "#jaeger"
click GitLabWorkhorse "#gitlab-workhorse"
click LDAP "#ldap-authentication"
click Puma "#puma"
click GitLabShell "#gitlab-shell"
click SSH "#ssh-request-22"
click Sidekiq "#sidekiq"
click Sentry "#sentry"
click GitLabExporter "#gitlab-exporter"
click Elasticsearch "#elasticsearch"
click Migrations "#database-migrations"
click PostgreSQL "#postgresql"
click Consul "#consul"
click PgBouncer "#pgbouncer"
click PgBouncerExporter "#pgbouncer-exporter"
click RedisExporter "#redis-exporter"
click Redis "#redis"
click Prometheus "#prometheus"
click Grafana "#grafana"
click GitLabPages "#gitlab-pages"
click PostgreSQLExporter "#postgresql-exporter"
click SMTP "#outbound-email"
click NodeExporter "#node-exporter"
컴포넌트 범례#
- ✅ - 기본 설치됨
- ⚙ - 추가 설정 필요
- ⤓ - 수동 설치 필요
- ❌ - 지원되지 않거나 안내가 없음
- N/A - 해당 없음
컴포넌트 상태는 각 컴포넌트의 설정 문서로 연결됩니다.
컴포넌트 목록#
| 컴포넌트 | 설명 | Omnibus GitLab | GitLab Environment Toolkit (GET) | GitLab chart | minikube Minimal | GitLab.com | Source | GDK | CE/EE |
|---|---|---|---|---|---|---|---|---|---|
| AI Gateway | GitLab AI 네이티브 기능 | ⤓ | ❌ | ✅ | ❌ | ✅ | ⤓ | ✅ | EE Only |
| GitLab Duo Workflow Service | GitLab AI 네이티브 기능 | ⤓ | ❌ | ✅ | ❌ | ✅ | ⤓ | ✅ | EE Only |
| Certificate Management | TLS 설정, Let's Encrypt | ✅ | ✅ | ✅ | ⚙ | ✅ | ⚙ | ⚙ | CE & EE |
| Consul | 데이터베이스 노드 검색, 장애 조치 | ⚙ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | EE Only |
| Database Migrations | 데이터베이스 마이그레이션 | ✅ | ✅ | ✅ | ✅ | ✅ | ⚙ | ✅ | CE & EE |
| Elasticsearch | GitLab 내 검색 개선 | ⤓ | ⚙ | ⤓ | ⤓ | ✅ | ⤓ | ⚙ | EE Only |
| Gitaly | GitLab이 수행하는 모든 Git 호출을 처리하는 Git RPC 서비스 | ✅ | ✅ | ✅ | ✅ | ✅ | ⚙ | ✅ | CE & EE |
| GitLab Exporter | 다양한 GitLab 메트릭 생성 | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | CE & EE |
| GitLab Geo | 지리적으로 분산된 GitLab 사이트 | ⚙ | ⚙ | ❌ | ❌ | ✅ | ❌ | ⚙ | EE Only |
| GitLab Pages | 정적 웹사이트 호스팅 | ⚙ | ⚙ | ⚙ | ❌ | ✅ | ⚙ | ⚙ | CE & EE |
| GitLab agent for Kubernetes | 클라우드 네이티브 방식으로 Kubernetes 클러스터 통합 | ⚙ | ⚙ | ⚙ | ❌ | ❌ | ⤓ | ⚙ | EE Only |
| GitLab self-monitoring: Alertmanager | Prometheus의 알림을 중복 제거, 그룹화하고 라우팅 | ⚙ | ⚙ | ✅ | ⚙ | ✅ | ❌ | ❌ | CE & EE |
| GitLab self-monitoring: Grafana | 메트릭 대시보드 | ✅ | ✅ | ⚙ | ⤓ | ✅ | ❌ | ⚙ | CE & EE |
| GitLab self-monitoring: Jaeger | GitLab 인스턴스가 생성한 트레이스 확인 | ❌ | ⚙ | ⚙ | ❌ | ❌ | ⤓ | ⚙ | CE & EE |
| GitLab self-monitoring: Prometheus | 시계열 데이터베이스, 메트릭 수집 및 쿼리 서비스 | ✅ | ✅ | ✅ | ⚙ | ✅ | ❌ | ⚙ | CE & EE |
| GitLab self-monitoring: Sentry | GitLab 인스턴스에서 발생한 오류 추적 | ⤓ | ⤓ | ⤓ | ❌ | ✅ | ⤓ | ⤓ | CE & EE |
| GitLab Shell | SSH 세션을 통한 git 처리 |
✅ | ✅ | ✅ | ✅ | ✅ | ⚙ | ✅ | CE & EE |
| GitLab Workhorse | 스마트 리버스 프록시, 대용량 HTTP 요청 처리 | ✅ | ✅ | ✅ | ✅ | ✅ | ⚙ | ✅ | CE & EE |
| Inbound email (SMTP) | 이슈를 업데이트하는 메시지 수신 | ⤓ | ⤓ | ⚙ | ⤓ | ✅ | ⤓ | ⤓ | CE & EE |
| Jaeger integration | 배포된 앱의 분산 추적 | ⤓ | ⤓ | ⤓ | ⤓ | ⤓ | ⤓ | ⚙ | EE Only |
| LDAP Authentication | 중앙 LDAP 디렉터리를 대상으로 사용자 인증 | ⤓ | ⤓ | ⤓ | ⤓ | ❌ | ⤓ | ⚙ | CE & EE |
| Object storage | S3 호환 오브젝트 스토리지 서비스 | ⤓ | ⤓ | ✅ | ✅ | ✅ | ❌ | ⚙ | CE & EE |
| NGINX | 요청을 적절한 컴포넌트로 라우팅, SSL 종료 | ✅ | ✅ | ✅ | ⚙ | ✅ | ⤓ | ⚙ | CE & EE |
| Node Exporter | 시스템 메트릭을 제공하는 Prometheus 엔드포인트 | ✅ | ✅ | N/A | N/A | ✅ | ❌ | ❌ | CE & EE |
| Outbound email (SMTP) | 사용자에게 이메일 메시지 전송 | ⤓ | ⤓ | ⚙ | ⤓ | ✅ | ⤓ | ⤓ | CE & EE |
| Patroni | PostgreSQL HA 클러스터의 리더 선출 및 복제 관리 | ⚙ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | EE Only |
| PgBouncer Exporter | PgBouncer 메트릭을 제공하는 Prometheus 엔드포인트 | ⚙ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | CE & EE |
| PgBouncer | 데이터베이스 연결 풀링, 장애 조치 | ⚙ | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | EE Only |
| PostgreSQL Exporter | PostgreSQL 메트릭을 제공하는 Prometheus 엔드포인트 | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | CE & EE |
| PostgreSQL | 데이터베이스 | ✅ | ✅ | ✅ | ✅ | ✅ | ⤓ | ✅ | CE & EE |
| Praefect | 모든 Git 클라이언트와 Gitaly 스토리지 노드 사이의 투명한 프록시 | ✅ | ✅ | ⚙ | ❌ | ❌ | ⚙ | ✅ | CE & EE |
| Puma (GitLab Rails) | 웹 인터페이스와 API 요청 처리 | ✅ | ✅ | ✅ | ✅ | ✅ | ⚙ | ✅ | CE & EE |
| Redis Exporter | Redis 메트릭을 제공하는 Prometheus 엔드포인트 | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | CE & EE |
| Redis | 캐싱 서비스 | ✅ | ✅ | ✅ | ✅ | ✅ | ⤓ | ✅ | CE & EE |
| Registry | 컨테이너 레지스트리, 이미지 푸시 및 풀 허용 | ⚙ | ⚙ | ✅ | ✅ | ✅ | ⤓ | ⚙ | CE & EE |
| Runner | GitLab CI/CD job 실행 | ⤓ | ⤓ | ✅ | ⚙ | ✅ | ⚙ | ⚙ | CE & EE |
| Sentry integration | 배포된 앱의 오류 추적 | ⤓ | ⤓ | ⤓ | ⤓ | ⤓ | ⤓ | ⤓ | CE & EE |
| Sidekiq | 백그라운드 job 처리기 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | CE & EE |
| Token Revocation API | 유출된 시크릿 수신 및 폐기 | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | EE Only |
컴포넌트 세부 정보#
이 문서는 GitLab의 내부 구조와 각 부분이 함께 동작하는 방식을 더 자세히 알고자 하는 시스템 관리자와 GitLab 지원 엔지니어를 위해 작성되었습니다.
배포된 GitLab은 아래 프로세스의 집합체로 볼 수 있습니다. 문제를 해결하거나 디버깅할 때는 참조하는 컴포넌트를 가능한 한 구체적으로 밝힙니다. 그러면 명확성이 높아지고 혼란이 줄어듭니다.
레이어
프로세스 관점에서 GitLab은 두 개의 레이어로 볼 수 있습니다.
- 모니터링: 이 레이어의 항목은 애플리케이션으로서의 GitLab을 제공하는 데 필수는 아니지만, 관리자가 인프라와 서비스 전체의 동작을 더 깊이 파악할 수 있게 해 줍니다.
- 코어: GitLab을 플랫폼으로 제공하는 데 필수적인 모든 프로세스입니다. 이 프로세스 중 하나라도 중단되면 GitLab 장애가 발생합니다. 코어 레이어는 다시 다음과 같이 나눌 수 있습니다.
- 프로세서: 실제로 작업을 수행하고 서비스를 제공하는 프로세스입니다.
- 데이터: GitLab 서비스를 위한 구조화된 데이터를 저장하거나 노출하는 서비스입니다.
Alertmanager#
- 프로젝트 페이지
- 설정:
- 레이어: 모니터링
- 프로세스:
alertmanager - GitLab.com: GitLab.com 모니터링
Alert manager는 Prometheus가 제공하는 도구로, "Prometheus 서버와 같은 클라이언트 애플리케이션이 보낸 알림을 처리합니다. 알림의 중복을 제거하고, 그룹화하고, 이메일, PagerDuty, Opsgenie 같은 올바른 수신자 통합으로 라우팅합니다. 또한 알림의 무음 처리와 억제도 담당합니다." 어떤 항목에 알림을 설정하는지는 이슈 #45740에서 더 읽을 수 있습니다.
AI Gateway#
- 프로젝트 페이지:
- 설정:
- GitLab.com: GitLab.com 모니터링
GitLab AI Gateway는 독립 실행형 서비스로, GitLab Self-Managed, GitLab Dedicated, GitLab.com 등 어떤 인스턴스를 사용하든 모든 GitLab 사용자에게 AI 기능에 대한 접근을 제공합니다.
다음 문서에서 더 자세히 알 수 있습니다.
GitLab Duo Workflow Service#
- 프로젝트 페이지:
- 설정:
- GitLab.com: GitLab.com 모니터링
GitLab Duo Workflow Service는 Runway 서비스 내에 배포되는 에이전틱 AI 기능입니다.
다음 문서에서 더 자세히 알 수 있습니다.
인증서 관리#
Consul#
Consul은 서비스 검색과 설정을 위한 도구입니다. Consul은 분산형이며 고가용성을 제공하고 매우 확장성이 뛰어납니다.
데이터베이스 마이그레이션#
Elasticsearch#
- 프로젝트 페이지
- 설정:
- 레이어: 코어 서비스(데이터)
- GitLab.com: GitLab.com에서 고급 검색 작동시키기(Closed) epic.
Elasticsearch는 클라우드를 위해 만들어진 분산형 RESTful 검색 엔진입니다.
Gitaly#
Gitaly는 분산 GitLab 배포(GitLab.com이나 고가용성 배포를 떠올리면 됩니다)에서 Git 스토리지를 위한 NFS의 필요성을 없애려고 GitLab이 설계한 서비스입니다. 11.3.0부터 이 서비스가 GitLab의 모든 Git 수준 접근을 처리합니다. 프로젝트에 대해서는 프로젝트 README에서 더 읽을 수 있습니다.
Praefect#
Praefect는 각 Git 클라이언트와 Gitaly 사이의 투명한 프록시로, 리포지터리 업데이트를 보조 노드로 복제하는 과정을 조율합니다.
GitLab Geo#
Geo는 기본 GitLab 인스턴스의 읽기 전용 미러를 하나 이상 제공하여 분산된 팀의 개발 속도를 높이도록 만든 Premium 기능입니다. 이 미러(Geo 보조 사이트)는 대용량 리포지터리와 프로젝트를 클론하거나 페치하는 시간을 줄여 주며, 재해 복구 솔루션의 일부가 될 수도 있습니다.
GitLab Exporter#
- 프로젝트 페이지
- 설정:
- 레이어: 모니터링
- 프로세스:
gitlab-exporter - GitLab.com: GitLab.com 모니터링
GitLab Exporter는 GitLab 애플리케이션 내부에 대한 메트릭을 Prometheus로 내보낼 수 있도록 자체 개발한 프로세스입니다. 자세한 내용은 프로젝트 README에서 확인할 수 있습니다.
GitLab agent for Kubernetes#
GitLab agent for Kubernetes는 GitLab과 Kubernetes 통합 작업을 안전한 클라우드 네이티브 방식으로 해결하기 위해 클러스터 내부에서 동작하는 능동적인 컴포넌트입니다.
이 에이전트로 Kubernetes 클러스터에 배포를 동기화할 수 있습니다.
GitLab Pages#
- 설정:
- 레이어: 코어 서비스(프로세서)
- GitLab.com: GitLab Pages
GitLab Pages는 GitLab의 리포지터리에서 정적 웹사이트를 바로 게시할 수 있는 기능입니다.
포트폴리오, 문서, 선언문, 비즈니스 프레젠테이션 같은 개인 또는 비즈니스 웹사이트에 사용할 수 있습니다. 콘텐츠에 어떤 라이선스든 지정할 수도 있습니다.
GitLab Runner#
GitLab Runner는 job을 실행하고 결과를 GitLab으로 보냅니다.
GitLab CI/CD는 GitLab에 포함된 오픈 소스 지속적 통합 서비스로, 테스트를 조율합니다. 이 프로젝트의 예전 이름은 GitLab CI Multi Runner였지만, 앞으로는 (CI를 뺀) GitLab Runner를 사용해야 합니다.
GitLab Shell#
GitLab Shell은 SSH 기반 git 세션을 처리하고 승인된 키 목록을 수정하도록 GitLab에서 설계한 프로그램입니다. GitLab Shell은 Unix 셸이 아니며 Bash나 Zsh를 대체하지도 않습니다.
GitLab Workhorse#
GitLab Workhorse는 Puma의 부하를 덜어 주도록 GitLab에서 설계한 프로그램입니다. 개발하게 된 역사적 배경은 여기에서 더 읽을 수 있습니다. 스마트 리버스 프록시로 동작하여 GitLab 전체의 속도를 높이도록 설계되었습니다.
Grafana#
- 프로젝트 페이지
- 설정:
- 레이어: 모니터링
- GitLab.com: GitLab 트리아지 Grafana 대시보드
Grafana는 Graphite, Elasticsearch, OpenTSDB, Prometheus, InfluxDB용의 오픈 소스이며 기능이 풍부한 메트릭 대시보드 및 그래프 편집기입니다.
Jaeger#
Jaeger는 Dapper와 OpenZipkin에서 영감을 받은 분산 트레이싱 시스템입니다. 마이크로서비스 기반 분산 시스템을 모니터링하는 데 사용할 수 있습니다.
Logrotate#
GitLab은 모두 로그를 남기는 다수의 서비스로 구성됩니다. 로그를 책임감 있게 남기도록 자체 Logrotate를 번들로 제공합니다. 이는 널리 쓰이는 오픈 소스 제품을 패키징한 버전일 뿐입니다.
오브젝트 스토리지#
GitLab은 CI 아티팩트, LFS 객체, 업로드, 컨테이너 레지스트리 이미지 같은 데이터를 저장하기 위해 S3 호환 오브젝트 스토리지가 필요합니다. GitLab은 S3 API와 완전히 호환되는 모든 오브젝트 스토리지 공급자와 호환됩니다. 공급자 선택은 사용자의 책임입니다. Amazon S3, Google Cloud Storage, Azure Blob Storage 같은 클라우드 관리형 서비스가 흔히 쓰이며, 자체 호스팅 S3 호환 솔루션도 마찬가지입니다.
NGINX#
NGINX는 모든 HTTP 요청을 받는 인그레스 포트를 제공하며 요청을 GitLab 내의 적절한 하위 시스템으로 라우팅합니다. 널리 쓰이는 오픈 소스 웹 서버를 수정하지 않은 버전으로 번들로 제공합니다.
Node Exporter#
- 프로젝트 페이지
- 설정:
- 레이어: 모니터링
- 프로세스:
node-exporter - GitLab.com: GitLab.com 모니터링
Node Exporter는 기반 머신의 메트릭(CPU/디스크/부하 등)을 제공하는 Prometheus 도구입니다. Prometheus 프로젝트의 널리 쓰이는 오픈 소스 제품을 패키징한 버전일 뿐입니다.
Patroni#
- 프로젝트 페이지
- 설정:
- 레이어: 코어 서비스(데이터)
- 프로세스:
patroni - GitLab.com: 데이터베이스 아키텍처
PgBouncer#
- 프로젝트 페이지
- 설정:
- 레이어: 코어 서비스(데이터)
- GitLab.com: 데이터베이스 아키텍처
PostgreSQL용 경량 연결 풀러입니다.
PgBouncer Exporter#
- 프로젝트 페이지
- 설정:
- 레이어: 모니터링
- GitLab.com: GitLab.com 모니터링
PgBouncer용 Prometheus 익스포터입니다. 9127/metrics에서 메트릭을 내보냅니다.
PostgreSQL#
- 프로젝트 페이지
- 설정:
- 레이어: 코어 서비스(데이터)
- 프로세스:
postgresql - GitLab.com: PostgreSQL
GitLab은 널리 쓰이는 데이터베이스를 패키징하여 애플리케이션 메타데이터와 사용자 정보의 스토리지를 제공합니다.
PostgreSQL Exporter#
- 프로젝트 페이지
- 설정:
- 레이어: 모니터링
- 프로세스:
postgres-exporter - GitLab.com: GitLab.com 모니터링
postgres_exporter는 PostgreSQL에 대한 데이터를 Prometheus로 전달하여 Grafana 대시보드에서 사용할 수 있게 하는, 커뮤니티가 제공하는 Prometheus 익스포터입니다.
Prometheus#
- 프로젝트 페이지
- 설정:
- 레이어: 모니터링
- 프로세스:
prometheus - GitLab.com: Prometheus
Prometheus는 GitLab 관리자가 GitLab 서비스를 제공하는 개별 프로세스에 대한 메트릭을 노출할 수 있게 해 주는 시계열 도구입니다.
Redis#
Redis는 다음을 저장할 공간을 제공하도록 패키징되어 있습니다.
- 세션 데이터
- 임시 캐시 정보
- 백그라운드 job 큐
GitLab이 Redis를 사용하는 방법에 대한 자세한 내용은 Redis 가이드라인을 참고합니다.
Redis Exporter#
- 프로젝트 페이지
- 설정:
- 레이어: 모니터링
- 프로세스:
redis-exporter - GitLab.com: GitLab.com 모니터링
Redis Exporter는 Redis 프로세스에 대한 구체적인 메트릭을 Prometheus에 제공하여 Grafana에서 그래프로 나타낼 수 있게 하도록 설계되었습니다.
Registry#
레지스트리는 사용자가 자신의 Docker 이미지를 저장하는 데 사용하는 서비스입니다. 번들로 제공되는
레지스트리는 NGINX를 로드 밸런서로, GitLab을 인증 관리자로 사용합니다.
클라이언트가 레지스트리에서 이미지를 풀하거나 푸시하도록 요청할 때마다
레지스트리는 401 응답을 반환하며, 인증 토큰을 어디에서 받을 수 있는지(이 경우 GitLab 인스턴스)
알려 주는 헤더를 함께 보냅니다. 그러면 클라이언트는 GitLab에 풀 또는 푸시 인증 토큰을
요청한 뒤 레지스트리에 원래 요청을 다시 시도합니다.
자세한 내용은
토큰 인증을 참고합니다.
외부 레지스트리도 GitLab을 인증 엔드포인트로 사용하도록 설정할 수 있습니다.
Sentry#
Sentry는 근본적으로 충돌을 실시간으로 모니터링하고 수정하도록 돕는 서비스입니다. 서버는 Python으로 작성되었지만, 어떤 언어의 어떤 애플리케이션에서든 이벤트를 보낼 수 있는 전체 API를 포함합니다.
배포된 앱을 모니터링하려면 Sentry 통합 문서를 참고합니다.
Sidekiq#
Sidekiq는 Redis 큐에서 job을 가져와 처리하는 Ruby 백그라운드 job 처리기입니다. 백그라운드 job을 사용하면 작업을 백그라운드로 옮겨 GitLab이 더 빠른 요청/응답 주기를 제공할 수 있습니다.
Puma#
Puma는 기본 웹 서버입니다.
Puma는 GitLab에서 사용자에게 보이는 기능을 제공하는 핵심 Rails 애플리케이션을 실행하는 데 사용되는 Ruby 애플리케이션 서버입니다. GitLab 버전에 따라 프로세스 출력에 bundle 또는 config.ru로 표시되는 경우가 많습니다.
LDAP 인증#
아웃바운드 이메일#
인바운드 이메일#
요청 유형별 GitLab#
GitLab은 최종 사용자가 서비스에 접근하는 두 가지 "인터페이스"를 제공합니다.
- 웹 HTTP 요청(UI/API 보기)
- Git HTTP/SSH 요청(Git 데이터 푸시/풀)
일부 프로세스는 둘 모두에서 사용되고 다른 일부는 특정 요청 유형에서만 사용되므로 이 차이를 이해하는 것이 중요합니다.
GitLab 웹 HTTP 요청 주기#
HTTP 엔드포인트(예: /users/sign_in)에 요청하면 요청은 GitLab 서비스에서 다음 경로를 거칩니다.
- NGINX - 첫 번째 리버스 프록시 역할을 합니다.
- GitLab Workhorse - 요청을 Rails 애플리케이션으로 보낼지 Puma의 부하를 줄이기 위해 다른 곳으로 보낼지 결정합니다.
- Puma - 웹 요청이고 애플리케이션에 접근해야 하므로 Puma로 라우팅됩니다.
- PostgreSQL/Gitaly/Redis - 요청 유형에 따라 데이터를 저장하거나 가져오기 위해 이 서비스에 접근할 수 있습니다.
GitLab Git 요청 주기#
아래에서는 HTTP와 SSH Git 요청이 거치는 서로 다른 경로를 설명합니다. 웹 요청 주기와 겹치는 부분도 있지만 차이점도 있습니다.
웹 요청(80/443)#
HTTP를 통한 Git 작업은 상태 비저장(stateless) "스마트" 프로토콜을 사용하며, 이는 Git 문서에 설명되어 있지만, 이러한 작업의 처리 책임은 여러 GitLab 컴포넌트에 나뉘어 있습니다.
다음은 git fetch의 시퀀스 다이어그램입니다. 모든 요청은
NGINX와 그 밖의 HTTP 로드 밸런서를 거치지만 이들이 요청을 어떤 식으로도
변형하지 않습니다. 모든 경로는 /namespace/project.git URL을 기준으로 한 상대 경로입니다.
소스 코드 보기
sequenceDiagram
participant Git on client
participant NGINX
participant Workhorse
participant Rails
participant Gitaly
participant Git on server
Note left of Git on client: git fetch<br/>info-refs
Git on client->>+Workhorse: GET /info/refs?service=git-upload-pack
Workhorse->>+Rails: GET /info/refs?service=git-upload-pack
Note right of Rails: Auth check
Rails-->>-Workhorse: Gitlab::Workhorse.git_http_ok
Workhorse->>+Gitaly: SmartHTTPService.InfoRefsUploadPack request
Gitaly->>+Git on server: git upload-pack --stateless-rpc --advertise-refs
Git on server-->>-Gitaly: git upload-pack response
Gitaly-->>-Workhorse: SmartHTTPService.InfoRefsUploadPack response
Workhorse-->>-Git on client: 200 OK
Note left of Git on client: git fetch<br/>fetch-pack
Git on client->>+Workhorse: POST /git-upload-pack
Workhorse->>+Rails: POST /git-upload-pack
Note right of Rails: Auth check
Rails-->>-Workhorse: Gitlab::Workhorse.git_http_ok
Workhorse->>+Gitaly: SmartHTTPService.PostUploadPack request
Gitaly->>+Git on server: git upload-pack --stateless-rpc
Git on server-->>-Gitaly: git upload-pack response
Gitaly-->>-Workhorse: SmartHTTPService.PostUploadPack response
Workhorse-->>-Git on client: 200 OK</code></pre></details></div>
git push의 시퀀스도 비슷하지만, git-upload-pack 대신
git-receive-pack을 사용합니다.
SSH 요청(22)#
SSH를 통한 Git 작업은 상태 저장(stateful) 프로토콜을 사용할 수 있으며, 이는
Git 문서에 설명되어 있지만,
이러한 작업의 처리 책임은 여러 GitLab 컴포넌트에 나뉘어 있습니다.
어떤 GitLab 컴포넌트도 SSH를 직접 사용하지 않습니다. 모든 SSH 연결은
클라이언트 머신의 Git과 연결을 종료하는 SSH 서버 사이에서 이루어집니다.
SSH 서버에는 모든 연결이 git 사용자로 인증되며, GitLab
사용자는 클라이언트가 제시하는 SSH 키로 구분됩니다.
다음은 빠른 SSH 키 조회가 활성화되어 있다고 가정한 git fetch의
시퀀스 다이어그램입니다. AuthorizedKeysCommand는
GitLab Shell이 제공하는 실행 파일입니다.
Mermaid 다이어그램 (27줄)소스 코드 보기
sequenceDiagram
participant Git on client
participant SSH server
participant AuthorizedKeysCommand
participant GitLab Shell
participant Rails
participant Gitaly
participant Git on server
Note left of Git on client: git fetch
Git on client->>+SSH server: ssh git fetch-pack request
SSH server->>+AuthorizedKeysCommand: gitlab-shell-authorized-keys-check git AAAA...
AuthorizedKeysCommand->>+Rails: GET /internal/api/authorized_keys?key=AAAA...
Note right of Rails: Lookup key ID
Rails-->>-AuthorizedKeysCommand: 200 OK, command="gitlab-shell upload-pack key_id=1"
AuthorizedKeysCommand-->>-SSH server: command="gitlab-shell upload-pack key_id=1"
SSH server->>+GitLab Shell: gitlab-shell upload-pack key_id=1
GitLab Shell->>+Rails: GET /internal/api/allowed?action=upload_pack&key_id=1
Note right of Rails: Auth check
Rails-->>-GitLab Shell: 200 OK, { gitaly: ... }
GitLab Shell->>+Gitaly: SSHService.SSHUploadPack request
Gitaly->>+Git on server: git upload-pack request
Note over Git on client,Git on server: Bidirectional communication between Git client and server
Git on server-->>-Gitaly: git upload-pack response
Gitaly -->>-GitLab Shell: SSHService.SSHUploadPack response
GitLab Shell-->>-SSH server: gitlab-shell upload-pack response
SSH server-->>-Git on client: ssh git fetch-pack response</code></pre></details></div>
git push 작업도 매우 비슷하지만, git upload-pack 대신
git receive-pack을 사용합니다.
빠른 SSH 키 조회가 활성화되지 않은 경우 SSH 서버는
~git/.ssh/authorized_keys 파일을 읽어 특정
SSH 세션에 대해 실행할 명령을 결정합니다. 이 파일은 Rails의 AuthorizedKeysWorker가
최신 상태로 유지하며, 사용자가 SSH 키를 수정할 때마다 실행되도록 예약됩니다.
키 대신 SSH 인증서를 사용할 수도 있습니다.
이 경우 AuthorizedKeysCommand가
AuthorizedPrincipalsCommand로 대체됩니다. 이 명령은 인증서에서 사용자 이름을 추출하며
Rails 내부 API를 사용하지 않습니다. 이 사용자 이름은 이후
/api/internal/allowed 호출에서 key_id 대신 쓰입니다.
GitLab Shell에는 2단계 인증 코드 재설정처럼
Gitaly가 관여하지 않는 작업도 몇 가지 있습니다. 이러한 작업도 같은 방식으로 처리되지만,
Gitaly로의 왕복은 없습니다. Rails가 내부 API 호출의 일부로
작업을 수행하고, GitLab Shell은
응답을 사용자에게 직접 스트리밍합니다.
시스템 레이아웃#
그림에서 ~git은 Git 사용자의 홈 디렉터리를 뜻하며, 일반적으로 /home/git입니다.
GitLab은 주로 git 사용자로서 /home/git 사용자 홈 디렉터리 안에 설치됩니다. 홈 디렉터리에는 GitLab 서버 소프트웨어와 리포지터리가 있습니다(리포지터리 위치는 설정할 수 있습니다).
bare 리포지터리는 /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과는 다른 시스템 사용자로 실행해야 합니다
(예: git이 아니라 postgres, redis, www-data).
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를 참고합니다.
서비스의 init 스크립트#
GitLab init 스크립트는 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에 설정을 추가할 때는 다음을 수행합니다.
- 설정이 함께
Omnibus에 추가되었는지 확인합니다.
- 필요하면 Charts에 추가되었는지도 확인합니다.
- 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
sudo -i -u git 또는 sudo su - git으로
git 사용자로 로그인하는 것을 권장합니다. GitLab이 제공하는 sudo 명령은 Ubuntu에서는 동작하지만,
RHEL에서는 항상 동작하지는 않습니다.
GitLab.com#
GitLab.com 아키텍처는
참고용으로 자세히 설명되어 있지만, 이 아키텍처는 사용자가 수백만 명인 경우에만
유용합니다.
AI 아키텍처#
SaaS 모델 게이트웨이를 통해 AI 네이티브 기능을 사용할 수 있습니다.