InfoGrab DocsInfoGrab Docs

GitLab Shell 개발 가이드라인

요약

GitLab Shell은 GitLab의 Git SSH 세션을 처리하고 인증된 키 목록을 수정합니다. GitLab은 SSH를 통해 Git LFS 인증을 지원합니다. GitLab Shell은 Go로 작성되어 있으며, 빌드하려면 Go 컴파일러가 필요합니다.

GitLab Shell은 GitLab의 Git SSH 세션을 처리하고 인증된 키 목록을 수정합니다. GitLab Shell은 Unix 셸이 아니며 Bash나 Zsh의 대체제도 아닙니다.

GitLab은 SSH를 통해 Git LFS 인증을 지원합니다.

요구 사항#

GitLab Shell은 Go로 작성되어 있으며, 빌드하려면 Go 컴파일러가 필요합니다. 빌드 및 테스트에는 여전히 Ruby가 필요하지만, 실행에는 필요하지 않습니다.

GitLab Shell은 Linux 패키지 설치 시 port 22에서 실행됩니다. 일반 SSH 서비스를 사용하려면 다른 포트로 구성하세요.

현재 버전의 Go를 다운로드하여 설치하세요. Go 릴리즈 정책을 따르며 다음을 지원합니다:

  • 현재 안정 버전.

  • 이전 두 메이저 버전.

버전#

GitLab Shell과 관련된 두 가지 버전 파일:

GitLab 팀 구성원은 #announcements 내부 Slack 채널을 모니터링할 수도 있습니다.

GitLab Shell 작동 방식#

SSH를 통해 GitLab 서버에 접근하면 GitLab Shell은 다음을 수행합니다:

  • 사전 정의된 Git 명령어(git push, git pull, git fetch)로 제한합니다.

  • GitLab Rails API를 호출하여 인가 여부와 리포지터리가 있는 Gitaly 서버를 확인합니다.

  • SSH 클라이언트와 Gitaly 서버 사이에서 데이터를 복사합니다.

HTTP(S)를 통해 GitLab 서버에 접근하면 gitlab-workhorse로 연결됩니다.

SSH를 통한 git pull#

%%{init: { "fontFamily": "GitLab Sans" }}%% graph LR A[Git pull] --> |via SSH| B[gitlab-shell] B -->|API call| C[gitlab-rails
authorization] C -->|accept or decline| D[Gitaly session]

SSH를 통한 git push#

git push 명령어는 gitlab-rails가 푸시를 수락한 이후에 실행됩니다:

%%{init: { "fontFamily": "GitLab Sans" }}%% graph LR subgraph User initiates A[Git push] -->|via SSH| B[gitlab-shell] end subgraph Gitaly B -->|establish Gitaly session| C[gitlab-shell pre-receive hook] C -->|API auth call| D[Gitlab-rails] D --> E[accept or decline push] end

전체 기능 목록

authorized_keys 수정#

GitLab Shell은 클라이언트 머신의 authorized_keys 파일을 수정합니다.

GitLab Shell에 기여하기#

GitLab Shell에 기여하려면:

  • GitLab API 접근 및 내부 API를 통한 Redis에 연결 가능한지 확인합니다: make check

  • gitlab-shell 바이너리를 컴파일하여 bin/에 배치합니다: make compile

  • make install을 실행하여 gitlab-shell 바이너리를 빌드하고 파일 시스템에 설치합니다. 기본 위치는 /usr/local입니다. 변경하려면 PREFIXDESTDIR 환경 변수를 설정하세요.

  • 단일 머신에서 소스로부터 GitLab을 설치하려면 make setup을 실행하세요. GitLab Shell 바이너리를 컴파일하고, 파일 시스템의 여러 경로가 올바른 권한으로 존재하는지 확인합니다. 설치 방법 문서에서 이 명령어를 실행하도록 지시하지 않는 한 실행하지 마세요.

자세한 내용은 CONTRIBUTING.md를 참조하세요.

테스트 실행#

기여 시 테스트를 실행하세요:

bundle installmake test로 테스트를 실행합니다.

Gofmt 실행: make verify

테스트와 검증을 모두 실행합니다(기본 Makefile 타깃):

bundle install
make validate

필요한 경우 Gitaly를 구성합니다.

로컬 테스트를 위한 Gitaly 구성#

일부 테스트에는 Gitaly 서버가 필요합니다. docker-compose.yml 파일은 포트 8075에서 Gitaly를 실행합니다. 테스트에 Gitaly 위치를 알려주려면 GITALY_CONNECTION_INFO를 설정하세요:

export GITALY_CONNECTION_INFO='{"address": "tcp://localhost:8075", "storage": "default"}'
make test

GITALY_CONNECTION_INFO가 설정되지 않은 경우 테스트 스위트는 여전히 실행되지만, Gitaly가 필요한 테스트는 건너뜁니다. CI 환경에서는 항상 테스트가 실행됩니다.

속도 제한#

GitLab Shell은 Git 작업에 대해 사용자 계정 및 프로젝트별로 속도 제한을 수행합니다. GitLab Shell은 Git 작업 요청을 수락한 후 Redis로 지원되는 Rails 속도 제한기를 호출합니다. user + project가 속도 제한을 초과하면, GitLab Shell은 해당 user + project에 대한 추가 연결 요청을 차단합니다.

속도 제한기는 Git 명령어(플러밍) 수준에서 적용됩니다. 각 명령어는 분당 600회의 속도 제한이 있습니다. 예를 들어, git push는 분당 600회이고, git pull은 별도로 분당 600회입니다.

동일한 플러밍 명령어인 git-upload-pack을 사용하기 때문에, git pullgit clone은 속도 제한 목적상 실질적으로 동일한 명령어입니다.

Gitaly에도 속도 제한기가 있지만, GitLab Shell(Rails)에서 속도 제한이 초과되면 Gitaly에 대한 호출이 이루어지지 않습니다.

GitLab Shell의 로그#

일반적으로 로그를 검사하면 GitLab Shell 또는 gitlab-sshd 세션의 구조는 파악할 수 있지만 내용은 파악할 수 없습니다. 몇 가지 가이드라인:

  • 로깅에는 gitlab.com/gitlab-org/labkit/log를 사용합니다.

  • 항상 상관 관계 ID를 포함하세요.

  • 로그 메시지는 불변이고 고유해야 합니다. 부수적인 정보는 log.WithField, log.WithFields, 또는 log.WithError를 사용하여 필드에 포함하세요.

  • 성공 케이스와 오류 케이스 모두 로그를 남기세요.

  • 로그가 너무 많은 것이 너무 적은 것보다 낫습니다. 메시지가 너무 장황하다고 느껴지면 메시지를 제거하기 전에 로그 수준을 낮추는 것을 고려하세요.

GitLab.com#

GitLab.com에서 gitlab-shell 흐름 다이어그램:

%%{init: { "fontFamily": "GitLab Sans" }}%% graph LR a2 --> b2 a2 --> b3 a2 --> b4 b2 --> c1 b3 --> c1 b4 --> c1 c2 --> d1 c2 --> d2 c2 --> d3 d1 --> e1 d2 --> e1 d3 --> e1 a1[Cloudflare] --> a2[TCP
load balancer] e1[Git]

subgraph HAProxy Fleet
b2[HAProxy]
b3[HAProxy]
b4[HAProxy]
end

subgraph GKE
c1[Internal TCP<br/> load balancer<br/>port 2222] --> c2[GitLab-shell<br/> pods]
end

subgraph Gitaly
d1[Gitaly]
d2[Gitaly]
d3[Gitaly]
end

GitLab Shell 아키텍처#

%%{init: { "fontFamily": "GitLab Sans" }}%% 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->>&#43;SSH server: ssh git fetch-pack request
SSH server->>&#43;AuthorizedKeysCommand: gitlab-shell-authorized-keys-check git AAAA...
AuthorizedKeysCommand->>&#43;Rails: GET /internal/api/authorized_keys?key=AAAA...
Note right of Rails: Lookup key ID
Rails-->>-AuthorizedKeysCommand: 200 OK, command=&#34;gitlab-shell upload-pack key_id=1&#34;
AuthorizedKeysCommand-->>-SSH server: command=&#34;gitlab-shell upload-pack key_id=1&#34;
SSH server->>&#43;GitLab Shell: gitlab-shell upload-pack key_id=1
GitLab Shell->>&#43;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->>&#43;Gitaly: SSHService.SSHUploadPack request
Gitaly->>&#43;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

관련 항목#

GitLab Shell 개발 가이드라인

GitLab v19.1
원문 보기
요약

GitLab Shell은 GitLab의 Git SSH 세션을 처리하고 인증된 키 목록을 수정합니다. GitLab은 SSH를 통해 Git LFS 인증을 지원합니다. GitLab Shell은 Go로 작성되어 있으며, 빌드하려면 Go 컴파일러가 필요합니다.

GitLab Shell은 GitLab의 Git SSH 세션을 처리하고 인증된 키 목록을 수정합니다. GitLab Shell은 Unix 셸이 아니며 Bash나 Zsh의 대체제도 아닙니다.

GitLab은 SSH를 통해 Git LFS 인증을 지원합니다.

요구 사항#

GitLab Shell은 Go로 작성되어 있으며, 빌드하려면 Go 컴파일러가 필요합니다. 빌드 및 테스트에는 여전히 Ruby가 필요하지만, 실행에는 필요하지 않습니다.

GitLab Shell은 Linux 패키지 설치 시 port 22에서 실행됩니다. 일반 SSH 서비스를 사용하려면 다른 포트로 구성하세요.

현재 버전의 Go를 다운로드하여 설치하세요. Go 릴리즈 정책을 따르며 다음을 지원합니다:

  • 현재 안정 버전.

  • 이전 두 메이저 버전.

버전#

GitLab Shell과 관련된 두 가지 버전 파일:

GitLab 팀 구성원은 #announcements 내부 Slack 채널을 모니터링할 수도 있습니다.

GitLab Shell 작동 방식#

SSH를 통해 GitLab 서버에 접근하면 GitLab Shell은 다음을 수행합니다:

  • 사전 정의된 Git 명령어(git push, git pull, git fetch)로 제한합니다.

  • GitLab Rails API를 호출하여 인가 여부와 리포지터리가 있는 Gitaly 서버를 확인합니다.

  • SSH 클라이언트와 Gitaly 서버 사이에서 데이터를 복사합니다.

HTTP(S)를 통해 GitLab 서버에 접근하면 gitlab-workhorse로 연결됩니다.

SSH를 통한 git pull#

%%{init: { "fontFamily": "GitLab Sans" }}%% graph LR A[Git pull] --> |via SSH| B[gitlab-shell] B -->|API call| C[gitlab-rails
authorization] C -->|accept or decline| D[Gitaly session]

SSH를 통한 git push#

git push 명령어는 gitlab-rails가 푸시를 수락한 이후에 실행됩니다:

%%{init: { "fontFamily": "GitLab Sans" }}%% graph LR subgraph User initiates A[Git push] -->|via SSH| B[gitlab-shell] end subgraph Gitaly B -->|establish Gitaly session| C[gitlab-shell pre-receive hook] C -->|API auth call| D[Gitlab-rails] D --> E[accept or decline push] end

전체 기능 목록

authorized_keys 수정#

GitLab Shell은 클라이언트 머신의 authorized_keys 파일을 수정합니다.

GitLab Shell에 기여하기#

GitLab Shell에 기여하려면:

  • GitLab API 접근 및 내부 API를 통한 Redis에 연결 가능한지 확인합니다: make check

  • gitlab-shell 바이너리를 컴파일하여 bin/에 배치합니다: make compile

  • make install을 실행하여 gitlab-shell 바이너리를 빌드하고 파일 시스템에 설치합니다. 기본 위치는 /usr/local입니다. 변경하려면 PREFIXDESTDIR 환경 변수를 설정하세요.

  • 단일 머신에서 소스로부터 GitLab을 설치하려면 make setup을 실행하세요. GitLab Shell 바이너리를 컴파일하고, 파일 시스템의 여러 경로가 올바른 권한으로 존재하는지 확인합니다. 설치 방법 문서에서 이 명령어를 실행하도록 지시하지 않는 한 실행하지 마세요.

자세한 내용은 CONTRIBUTING.md를 참조하세요.

테스트 실행#

기여 시 테스트를 실행하세요:

bundle installmake test로 테스트를 실행합니다.

Gofmt 실행: make verify

테스트와 검증을 모두 실행합니다(기본 Makefile 타깃):

bundle install
make validate

필요한 경우 Gitaly를 구성합니다.

로컬 테스트를 위한 Gitaly 구성#

일부 테스트에는 Gitaly 서버가 필요합니다. docker-compose.yml 파일은 포트 8075에서 Gitaly를 실행합니다. 테스트에 Gitaly 위치를 알려주려면 GITALY_CONNECTION_INFO를 설정하세요:

export GITALY_CONNECTION_INFO='{"address": "tcp://localhost:8075", "storage": "default"}'
make test

GITALY_CONNECTION_INFO가 설정되지 않은 경우 테스트 스위트는 여전히 실행되지만, Gitaly가 필요한 테스트는 건너뜁니다. CI 환경에서는 항상 테스트가 실행됩니다.

속도 제한#

GitLab Shell은 Git 작업에 대해 사용자 계정 및 프로젝트별로 속도 제한을 수행합니다. GitLab Shell은 Git 작업 요청을 수락한 후 Redis로 지원되는 Rails 속도 제한기를 호출합니다. user + project가 속도 제한을 초과하면, GitLab Shell은 해당 user + project에 대한 추가 연결 요청을 차단합니다.

속도 제한기는 Git 명령어(플러밍) 수준에서 적용됩니다. 각 명령어는 분당 600회의 속도 제한이 있습니다. 예를 들어, git push는 분당 600회이고, git pull은 별도로 분당 600회입니다.

동일한 플러밍 명령어인 git-upload-pack을 사용하기 때문에, git pullgit clone은 속도 제한 목적상 실질적으로 동일한 명령어입니다.

Gitaly에도 속도 제한기가 있지만, GitLab Shell(Rails)에서 속도 제한이 초과되면 Gitaly에 대한 호출이 이루어지지 않습니다.

GitLab Shell의 로그#

일반적으로 로그를 검사하면 GitLab Shell 또는 gitlab-sshd 세션의 구조는 파악할 수 있지만 내용은 파악할 수 없습니다. 몇 가지 가이드라인:

  • 로깅에는 gitlab.com/gitlab-org/labkit/log를 사용합니다.

  • 항상 상관 관계 ID를 포함하세요.

  • 로그 메시지는 불변이고 고유해야 합니다. 부수적인 정보는 log.WithField, log.WithFields, 또는 log.WithError를 사용하여 필드에 포함하세요.

  • 성공 케이스와 오류 케이스 모두 로그를 남기세요.

  • 로그가 너무 많은 것이 너무 적은 것보다 낫습니다. 메시지가 너무 장황하다고 느껴지면 메시지를 제거하기 전에 로그 수준을 낮추는 것을 고려하세요.

GitLab.com#

GitLab.com에서 gitlab-shell 흐름 다이어그램:

%%{init: { "fontFamily": "GitLab Sans" }}%% graph LR a2 --> b2 a2 --> b3 a2 --> b4 b2 --> c1 b3 --> c1 b4 --> c1 c2 --> d1 c2 --> d2 c2 --> d3 d1 --> e1 d2 --> e1 d3 --> e1 a1[Cloudflare] --> a2[TCP
load balancer] e1[Git]

subgraph HAProxy Fleet
b2[HAProxy]
b3[HAProxy]
b4[HAProxy]
end

subgraph GKE
c1[Internal TCP<br/> load balancer<br/>port 2222] --> c2[GitLab-shell<br/> pods]
end

subgraph Gitaly
d1[Gitaly]
d2[Gitaly]
d3[Gitaly]
end

GitLab Shell 아키텍처#

%%{init: { "fontFamily": "GitLab Sans" }}%% 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->>&#43;SSH server: ssh git fetch-pack request
SSH server->>&#43;AuthorizedKeysCommand: gitlab-shell-authorized-keys-check git AAAA...
AuthorizedKeysCommand->>&#43;Rails: GET /internal/api/authorized_keys?key=AAAA...
Note right of Rails: Lookup key ID
Rails-->>-AuthorizedKeysCommand: 200 OK, command=&#34;gitlab-shell upload-pack key_id=1&#34;
AuthorizedKeysCommand-->>-SSH server: command=&#34;gitlab-shell upload-pack key_id=1&#34;
SSH server->>&#43;GitLab Shell: gitlab-shell upload-pack key_id=1
GitLab Shell->>&#43;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->>&#43;Gitaly: SSHService.SSHUploadPack request
Gitaly->>&#43;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

관련 항목#