지리적 프록시
세컨더리는 거의 모든 HTTP 요청을 Workhorse를 통해 기본(primary)으로 프록시하므로, 사용자들이 세컨더리에서 탐색할 때 읽기-쓰기 UI를 보게 되며, 기본에서 수행할 수 있는 모든 작업을 수행할 수 있습니다.
고수준 구성 요소
GitLab UI 및 API HTTP 요청의 프록시는 gitlab-workhorse
구성 요소에 의해 처리됩니다. Geo 세컨더리 사이트에서 일반적으로 Rails 애플리케이션으로 전송되는 트래픽은 대신 기본 Geo 사이트의 내부 URL로 프록시됩니다.
Git over HTTP 요청의 프록시는 gitlab-workhorse
구성 요소에 의해 처리되지만, 프록시 여부는 Rails 애플리케이션에서 결정되며, 요청이 푸시(push)인지 풀(pull)인지 및 원하는 Git 데이터가 최신인지 고려합니다.
Git over SSH 트래픽의 프록시는 gitlab-shell
구성 요소에 의해 처리되지만, 프록시 여부는 Rails 애플리케이션에서 결정되며, 요청이 푸시(push)인지 풀(pull)인지 및 원하는 Git 데이터가 최신인지 고려합니다.
요청 생명 주기
최고 수준의 개요
프록시 상호작용은 다음 다이어그램을 통해 고수준에서 설명할 수 있습니다:
sequenceDiagram
actor client
participant secondary
participant primary
client->>secondary: GET /explore
secondary-->>primary: GET /explore (proxied)
primary-->>secondary: HTTP/1.1 200 OK [..]
secondary->>client: HTTP/1.1 200 OK [..]
프록시 감지 메커니즘
기본으로 요청을 프록시해야 하는지 여부와 기본의 URL(데이터베이스에 저장됨)을 알기 위해, Workhorse는 Geo가 활성화되었을 때 내부 API를 폴링합니다. 프록싱이 활성화되어야 할 경우, 내부 API는 기본 URL과 부가 데이터를 받아서 매 요청마다 기본에 전달됩니다.
sequenceDiagram
participant W as Workhorse (secondary)
participant API as Internal Rails API
W->API: GET /api/v4/geo/proxy (internal)
loop 10초 마다 폴링
API-->W: {geo_proxy_primary_url, geo_proxy_extra_data}, 구성 업데이트
end
프록시와 비교한 심층 요청 흐름 및 로컬 데이터 가속
구현 세부 사항을 설명하자면, 요청된 사이트의 Workhorse는 데이터를 프록시해야 할지 여부를 결정합니다. 데이터 유형을 “가속화”할 수 있는 경우(즉, 왕복 요청을 절약하기 위해 로컬로 제공할 수 있는 경우), 즉시 데이터를 반환합니다. 그렇지 않으면 트래픽은 기본의 내부 URL로 전송되어, 기본의 Workhorse가 직접 요청처럼 제공하게 됩니다. 응답은 그런 다음, 동일한 연결을 통해 세컨더리 Workhorse를 통해 사용자에게 프록시됩니다.
flowchart LR
A[클라이언트]--->W1["Workhorse (secondary)"]
W1 --> W1C[로컬로 데이터 제공?]
W1C -- "예" ----> W1
W1C -- "아니오 (프록시)" ----> W2["Workhorse (primary)"]
W2 --> W1 ----> A
로그인
권한이 필요한 기본으로 프록시된 요청
sequenceDiagram
autoNumber
participant Client
participant Secondary
participant Primary
Client->>Secondary: `/group/project` 요청
Secondary->>Primary: 프록시 /group/project
opt 기본에 로그인하지 않음
Primary-->>Secondary: 302 리다이렉트
Secondary-->>Client: 프록시 302 리다이렉트
Client->>Secondary: /users/sign_in
Secondary->>Primary: 프록시 /users/sign_in
Note right of Primary: 인증이 발생하며, 같은 URL에 POST 등
Primary-->>Secondary: 302 리다이렉트
Secondary-->>Client: 프록시 302 리다이렉트
Client->>Secondary: /group/project
Secondary->>Primary: 프록시 /group/project
end
Primary-->>Secondary: /group/project에 로그인된 응답 (기본에 세션 생성됨)
Secondary-->>Client: 프록시 전체 응답
Git pull
역사적인 이유로, push_from_secondary
경로가 Git pull을 전달하는 데 사용됩니다. 혼란을 피하기 위해 이 경로의 이름을 변경하자는
문제가 제기되었습니다.
Git pull over HTTP(s)
Accelerated repositories
저장소가 보조에 존재하고 기본과 동기화되어 있음을 감지하면, 프록시 대신 직접 제공합니다.
sequenceDiagram
participant C as Git client
participant Wsec as "Workhorse (secondary)"
participant Rsec as "Rails (secondary)"
participant Gsec as "Gitaly (secondary)"
C->>Wsec: GET /foo/bar.git/info/refs/?service=git-upload-pack
Wsec->>Rsec: <internal API check>
note over Rsec: 저장소가 동기화되고 최신이라는 결정을 내림
Rsec-->>Wsec: 401 Unauthorized
Wsec-->>C: <response>
C->>Wsec: GET /foo/bar.git/info/refs/?service=git-upload-pack
Wsec->>Rsec: <internal API check>
Rsec-->>Wsec: Render Workhorse OK
Wsec-->>C: 200 OK
C->>Wsec: POST /foo/bar.git/git-upload-pack
Wsec->>Rsec: GitHttpController#git_receive_pack
Rsec-->>Wsec: Render Workhorse OK
Wsec->>Gsec: Workhorse가 Rails에서 연결 세부정보를 가져와 Gitaly에 연결: SmartHTTP Service, UploadPack RPC (안전성을 위해 프로토타입을 확인하세요)
Gsec-->>Wsec: Proto 메시지의 스트림 반환
Wsec-->>C: Git 클라이언트로 메시지 전송
Proxied repositories
요청된 저장소가 동기화되어 있지 않거나 최신이 아닌 경우, 요청은 기본으로 프록시되어 변경 사항의 최신 버전을 가져옵니다.
sequenceDiagram
participant C as Git client
participant Wsec as "Workhorse (secondary)"
participant Rsec as "Rails (secondary)"
participant W as "Workhorse (primary)"
participant R as "Rails (primary)"
participant G as "Gitaly (primary)"
C->>Wsec: GET /foo/bar.git/info/refs/?service=git-upload-pack
Wsec->>Rsec: <response>
note over Rsec: 저장소가 구식이라는 결정을 내림
Rsec-->>Wsec: 302 Redirect to /-/push_from_secondary/2/foo/bar.git/info/refs?service=git-upload-pack
Wsec-->>C: <response>
C->>Wsec: GET /-/push_from_secondary/2/foo/bar.git/info/refs/?service=git-upload-pack
Wsec->>W: <proxied request>
W->>R: <data>
R-->>W: 401 Unauthorized
W-->>Wsec: <proxied response>
Wsec-->>C: <response>
C->>Wsec: GET /-/push_from_secondary/2/foo/bar.git/info/refs/?service=git-upload-pack
note over W: 프록시됨
Wsec->>W: <proxied request>
W->>R: <data>
R-->>W: Render Workhorse OK
W-->>Wsec: <proxied response>
Wsec-->>C: <response>
C->>Wsec: POST /-/push_from_secondary/2/foo/bar.git/git-upload-pack
Wsec->>W: <proxied request>
W->>R: GitHttpController#git_receive_pack
R-->>W: Render Workhorse OK
W->>G: Workhorse가 Rails에서 연결 세부정보를 가져와 Gitaly에 연결: SmartHTTP Service, UploadPack RPC (안전성을 위해 프로토타입을 확인하세요)
G-->>W: Proto 메시지의 스트림 반환
W-->>Wsec: Git 클라이언트로 메시지 전송
Wsec-->>C: Git에서 파이프된 메시지 반환
Git pull over SSH
SSH 작업은 Workhorse가 아닌 GitLab Shell을 통해 진행되므로, Workhorse 요청에 사용되는 메커니즘을 통해 프록시되지 않습니다. SSH 작업에서는, 이들은 보조 Rails 내부 API에 의해 Git HTTP 요청으로 기본 사이트에 프록시됩니다.
Accelerated repositories
저장소가 보조에 존재하고 기본과 최신 상태인지 감지되는 경우, 프록시하는 대신 직접 제공됩니다.
sequenceDiagram
participant C as Git client
participant S as GitLab Shell (secondary)
participant I as Internal API (secondary Rails)
participant G as Gitaly (secondary)
C->>S: git pull
S->>I: SSH key validation (api/v4/internal/authorized_keys?key=..)
I-->>S: HTTP/1.1 200 OK
S->>G: InfoRefs:UploadPack RPC
G-->>S: stream Git response back
S-->>C: stream Git response back
C-->>S: stream Git data to push
S->>G: UploadPack RPC
G-->>S: stream Git response back
S-->>C: stream Git response back
Proxied repositories
요청된 저장소가 동기화되지 않거나 최신 상태가 아닌 경우, 요청은 기본으로 프록시되어 최신 변경 사항을 가져옵니다.
sequenceDiagram
participant C as Git client
participant S as GitLab Shell (secondary)
participant I as Internal API (secondary Rails)
participant P as Primary API
C->>S: git pull
S->>I: SSH key validation (api/v4/internal/authorized_keys?key=..)
I-->>S: HTTP/1.1 300 (custom action status) with {endpoint, msg, primary_repo}
S->>I: POST /api/v4/geo/proxy_git_ssh/info_refs_upload_pack
I->>P: POST $PRIMARY/foo/bar.git/info/refs/?service=git-upload-pack
P-->>I: HTTP/1.1 200 OK
I-->>S: <response>
S-->>C: return Git response from primary
C-->>S: stream Git data to push
S->>I: POST /api/v4/geo/proxy_git_ssh/upload_pack
I->>P: POST $PRIMARY/foo/bar.git/git-upload-pack
P-->>I: HTTP/1.1 200 OK
I-->>S: <response>
S-->>C: return Git response from primary
Git push
Git push over SSH
SSH 작업은 Workhorse가 아닌 GitLab Shell을 통해 진행되므로, Workhorse 요청에 사용되는 메커니즘을 통해 프록시되지 않습니다. SSH 작업에서는, 이들은 보조 Rails 내부 API에 의해 Git HTTP 요청으로 기본 사이트에 프록시됩니다.
sequenceDiagram
participant C as Git client
participant S as GitLab Shell (secondary)
participant I as Internal API (secondary Rails)
participant P as Primary API
C->>S: git push
S->>I: SSH key validation (api/v4/internal/authorized_keys?key=..)
I-->>S: HTTP/1.1 300 (custom action status) with {endpoint, msg, primary_repo}
S->>I: POST /api/v4/geo/proxy_git_ssh/info_refs_receive_pack
I->>P: POST $PRIMARY/foo/bar.git/info/refs/?service=git-receive-pack
P-->>I: HTTP/1.1 200 OK
I-->>S: <response>
S-->>C: return Git response from primary
C-->>S: stream Git data to push
S->>I: POST /api/v4/geo/proxy_git_ssh/receive_pack
I->>P: POST $PRIMARY/foo/bar.git/git-receive-pack
P-->>I: HTTP/1.1 200 OK
I-->>S: <response>
S-->>C: return Git response from primary
Git HTTP(S)로 푸시
요청된 리포지토리가 동기화되지 않았거나 최신 상태가 아닌 경우, 요청은 기본(primary)으로 프록시됩니다. 푸시는 /-/push_from_secondary/$SECONDARY_ID/*
형식의 로컬 경로로 리디렉션됩니다.
또한, 이 경로를 통해 요청은 기본(primary)으로 프록시되며, 기본이 푸시를 처리합니다.
sequenceDiagram
participant C as Git 클라이언트
participant Wsec as Workhorse (보조)
participant W as Workhorse (기본)
participant R as Rails (기본)
participant G as Gitaly (기본)
C->>Wsec: GET /foo/bar.git/info/refs/?service=git-receive-pack
Wsec->>C: 302 리디렉션 /-/push_from_secondary/2/foo/bar.git/info/refs?service=git-receive-pack
C->>Wsec: GET /-/push_from_secondary/2/foo/bar.git/info/refs/?service=git-receive-pack
Wsec->>W: <프록시 요청>
W->>R: <데이터>
R-->>W: 401 인증 실패
W-->>Wsec: <프록시 응답>
Wsec-->>C: <응답>
C->>Wsec: GET /-/push_from_secondary/2/foo/bar.git/info/refs/?service=git-receive-pack
Wsec->>W: <프록시 요청>
W->>R: <데이터>
R-->>W: Workhorse OK 렌더링
W-->>Wsec: <프록시 응답>
Wsec-->>C: <응답>
C->>Wsec: POST /-/push_from_secondary/2/foo/bar.git/git-receive-pack
Wsec->>W: <프록시 요청>
W->>R: GitHttpController:git_receive_pack
R-->>W: Workhorse OK 렌더링
W->>G: Rails에서 연결 세부정보를 가져와서 SmartHTTP 서비스에 연결, ReceivePack RPC
G-->>W: 프로토 메시지의 스트림 반환
W-->>Wsec: Git 클라이언트에 메시지 파이프
Wsec-->>C: Git으로부터 파이프된 메시지 반환