지오 프록시

세컨더리(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으로부터 전달된 메시지 반환프록시된>응답>프록시>데이터>프록시된>응답>프록시>데이터>프록시된>