지오 프록시
세컨더리(Secondary)는 대부분의 HTTP 요청을 주 서버(primary)를 통해 Workhorse를 통해 프록시 처리하기 때문에, 세컨더리로 이동하는 사용자들은 읽기-쓰기 UI를 볼 수 있으며, 주 서버에서 할 수 있는 모든 작업을 수행할 수 있습니다.
고수준 구성 요소
GitLab UI 및 API HTTP 요청의 프록시 처리는 gitlab-workhorse
구성 요소에서 처리됩니다. 보통 Geo 세컨더리 사이트의 Rails 애플리케이션에 보내는 트래픽은 주 Geo 사이트의 내부 URL로 프록시됩니다.
Git을 통한 HTTP 요청의 프록시 처리는 gitlab-workhorse
구성 요소에서 처리하지만, 프록시 여부는 레일즈 애플리케이션에서 결정되며, 요청이 푸시(push)인지 또는 풀(pull)인지, 그리고 원하는 Git 데이터가 최신 상태인지를 고려합니다.
Git을 통한 SSH 트래픽의 프록시 처리는 gitlab-shell
구성 요소에서 처리하지만, 프록시 여부는 레일즈 애플리케이션에서 결정되며, 요청이 푸시(push)인지 또는 풀(pull)인지, 그리고 원하는 Git 데이터가 최신 상태인지를 고려합니다.
요청 수명 주기
최상위 수준 뷰
프록시 처리 상호 작용은 다음 다이어그램을 통해 고수준으로 설명할 수 있습니다:
sequenceDiagram
actor client
participant secondary
participant primary
client->>secondary: GET /explore
secondary-->>primary: GET /explore (프록시 처리됨)
primary-->>secondary: HTTP/1.1 200 OK [..]
secondary->>client: HTTP/1.1 200 OK [..]
프록시 검출 메커니즘
지오가 활성화되어 있는 경우에 프록시 처리 여부와 주 서버의 URL(데이터베이스에 저장된 내용)를 알기 위해 Workhorse는 내부 API를 폴링합니다. 프록시 처리가 활성화되어야 하는 경우, 내부 API는 주 서버 URL 및 JWT로 서명된 데이터를 응답하여 각 요청에 대해 주 서버로 전달합니다.
sequenceDiagram
participant W as Workhorse (secondary)
participant API as Internal Rails API
W->API: GET /api/v4/geo/proxy (내부)
loop 10초마다 폴링
API-->W: {geo_proxy_primary_url, geo_proxy_extra_data}, 구성 업데이트
end
프록시 처리와 지역 데이터 가속화에 대한 심층적인 요청 흐름
구현 세부 정보는 요청된 세컨더리(secondary)의 Workhorse에서 데이터를 프록시 처리할지 여부를 결정합니다. 데이터 유형을 “가속화”할 수 있는 경우(즉, 라운드트립 요청을 저장할 수 있는 경우)에는 데이터를 즉시 반환합니다. 그렇지 않은 경우, 트래픽은 주 서버의 내부 URL로 전송되어, 주 서버의 Workhorse에서 직접적인 요청과 동일하게 처리됩니다. 그 후 응답은 동일한 연결을 통해 세컨더리의 Workhorse를 통해 사용자에게 프록시 처리됩니다.
flowchart LR
A[Client]--->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 풀을 전달합니다. 이 경로의 이름을 변경하는 것을 제안하는 이슈가 있습니다.
HTTP(s)를 통한 Git 풀
가속화된 저장소
세컨더리에 저장소가 있고, 해당 저장소가 주 서버와 동기화되어 있다고 감지되는 경우, 프록시 처리하는 대신 직접 제공합니다.
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: <내부 API 확인>
note over Rsec: 저장소가 동기화되어 있고 최신 상태임을 결정
Rsec-->>Wsec: 401 권한 없음
Wsec-->>C: <응답>
C->>Wsec: GET /foo/bar.git/info/refs/?service=git-upload-pack
Wsec->>Rsec: <내부 API 확인>
Rsec-->>Wsec: Workhorse OK로 렌더링
Wsec-->>C: 200 OK
C->>Wsec: POST /foo/bar.git/git-upload-pack
Wsec->>Rsec: GitHttpController#git_receive_pack
Rsec-->>Wsec: Workhorse OK로 렌더링
Wsec->>Gsec: Workhorse는 연결 세부 정보를 Rails로부터 가져와 Gitaly에 연결합니다: SmartHTTP Service, UploadPack RPC (세부 사항은 프로토를 확인하세요)
Gsec-->>Wsec: 프로토 메시지의 스트림 반환
Wsec-->>C: Git 클라이언트로 메시지 파이프
프록시된 저장소
요청된 저장소가 동기화되지 않은 경우 또는 최신 상태가 아닌 경우, 변경 사항의 최신 버전을 얻기 위해 요청은 주 서버로 프록시됩니다.
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: <응답>
note over Rsec: 저장소가 최신 상태가 아님을 결정
Rsec-->>Wsec: 302 /-/push_from_secondary/2/foo/bar.git/info/refs?service=git-upload-pack로 리디렉트
Wsec-->>C: <응답>
C->>Wsec: GET /-/push_from_secondary/2/foo/bar.git/info/refs/?service=git-upload-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-upload-pack
note over W: 프록시됨
Wsec->>W: <프록시된 요청>
W->>R: <데이터>
R-->>W: Workhorse OK로 렌더링
W-->>Wsec: <프록시된 응답>
Wsec-->>C: <응답>
C->>Wsec: POST /-/push_from_secondary/2/foo/bar.git/git-upload-pack
Wsec->>W: <프록시된 요청>
W->>R: GitHttpController#git_receive_pack
R-->>W: Workhorse OK로 렌더링
W->>G: Workhorse는 연결 세부 정보를 Rails로부터 가져와 Gitaly에 연결합니다: SmartHTTP Service, UploadPack RPC (세부 사항은 프로토를 확인하세요)
G-->>W: 프로토 메시지의 스트림 반환
W-->>Wsec: Git 클라이언트로부터 파이프된 메시지 반환
Wsec-->>C: Git에서 파이프된 메시지를 반환
SSH를 통한 Git pull
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 G as Gitaly (secondary)
C->>S: git pull
S->>I: SSH 키 유효성 검사 (api/v4/internal/authorized_keys?key=..)
I-->>S: HTTP/1.1 200 OK
S->>G: InfoRefs:UploadPack RPC
G-->>S: Git 응답 스트림 전송
S-->>C: Git 응답 스트림 전송
C-->>S: 푸시할 Git 데이터 스트림
S->>G: UploadPack RPC
G-->>S: Git 응답 스트림 전송
S-->>C: Git 응답 스트림 전송
프록시된 저장소
요청된 저장소가 동기화되지 않았거나 최신 상태가 아닌 경우, 변경 사항의 최신 버전을 가져오기 위해 주요 부분에 프록시됩니다.
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 키 유효성 검사 (api/v4/internal/authorized_keys?key=..)
I-->>S: HTTP/1.1 300 (사용자 지정 액션 상태) 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: <응답>
S-->>C: 기본 사이트의 Git 응답 반환
C-->>S: 푸시할 Git 데이터 스트림
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: <응답>
S-->>C: 기본 사이트의 Git 응답 반환
Git push
SSH를 통한 Git push
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 키 유효성 검사 (api/v4/internal/authorized_keys?key=..)
I-->>S: HTTP/1.1 300 (사용자 지정 액션 상태) 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: <응답>
S-->>C: 기본 사이트의 Git 응답 반환
C-->>S: 푸시할 Git 데이터 스트림
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: <응답>
S-->>C: 기본 사이트의 Git 응답 반환
HTTP(S)를 통한 Git push
요청한 저장소가 동기화되지 않았거나 최신 상태가 아닌 경우, 해당 요청은 기본으로 프록시되며, 푸시는 /-/push_from_secondary/$SECONDARY_ID/*
로 형식화된 로컬 경로로 리디렉트됩니다.
이 경로를 통한 추가 요청은 기본 사이트로 프록시되어 처리됩니다.
```mermaid
sequenceDiagram
participant C as Git client
participant Wsec as Workhorse (secondary)
participant W as Workhorse (primary)
participant R as Rails (primary)
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 Unauthorized
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: Proto 메시지의 스트림 반환
W-->>Wsec: Git 클라이언트에 메시지 전달
Wsec-->>C: Git으로부터 전달된 메시지 반환프록시된>응답>프록시>데이터>프록시된>응답>프록시>데이터>프록시된>