Geo 프록시

Geo 프록시를 사용하면 보조 시스템이 프라이머리를 통해 웹 요청을 프록시하므로, 보조 시스템을 방문하는 사용자는 읽기-쓰기 UI를 보며 프라이머리에서 수행할 수 있는 모든 작업을 수행할 수 있습니다.

요청 수명주기

최상위 수준 보기

프록시 상호작용은 다음 다이어그램을 통해 고수준으로 설명할 수 있습니다.

primarysecondaryprimarysecondaryclientGET /exploreGET /explore (proxied)HTTP/1.1 200 OK [..]HTTP/1.1 200 OK [..]client

프록시 탐지 메커니즘

Geo가 활성화된 경우, 프라이머리로의 프록시 요청 여부와 프라이머리의 URL을 확인하기 위해 Workhorse는 내부 API를 폴링합니다. 프록시가 활성화되어야 하는 경우 내부 API는 프라이머리 URL과 모든 요청에 전달되는 JWT로 서익합니다.

Internal Rails APIWorkhorse (secondary)Internal Rails APIWorkhorse (secondary)loop[10초마다 폴링]GET /api/v4/geo/proxy (internal){geo_proxy_primary_url, geo_proxy_extra_data}, 구성 업데이트

자세한 요청 흐름 및 프록시링을 통한 로컬 데이터 가속

보조(요청된) 사이트의 Workhorse는 데이터 유형을 “가속”할 수 있는지(라운드트립 요청을 저장할 수 있는지) 여부를 결정합니다. 데이터를 즉시 반환할 수 있다면 반환합니다. 그렇지 않으면, 트래픽은 프라이머리의 내부 URL로 보내지며, 프라이머리의 Workhorse에서 직접 요청한 것처럼 처리됩니다. 응답은 결국 보조 Workhorse를 통해 사용자에게 프록시됩니다.

아니오 (프록시)
Client
Workhorse (secondary)
로컬로 데이터 제공?
Workhorse (primary)

로그인

프라이머리에 프록시되는 권한이 필요한 요청

PrimarySecondaryClientPrimarySecondaryClient인증 진행, 동일 URL에 대한 POST 등alt[프라이머리에 로그인되지 않은 경우]`/group/project` 요청1프라이머리에 프록시 /group/project2302 리디렉션3프라이머리에 프록시 302 리디렉션4/users/sign_in5프라이머리에 프록시 /users/sign_in6302 리디렉션7프라이머리에 프록시 302 리디렉션8/group/project9프라이머리에 프록시 /group/project10/group/project 로그인된 응답 (프라이머리에서 세션 생성됨)11전체 응답 프록시12

Git 풀

역사적인 이유로 push_from_secondary 경로를 전달하는 데 Git 풀을 사용합니다. 혼란을 피하기 위해 이 라우트의 이름을 변경하는 문제가 제기되었습니다.

HTTP(s)를 통한 Git 풀

가속된 리포지터리

보조에서 리포지터리가 프라이머리와 동기화되어 있고 최신인 경우, 프록시하지 않고 직접 제공합니다.

"Gitaly (secondary)""Rails (secondary)""Workhorse (secondary)"Git client"Gitaly (secondary)""Rails (secondary)""Workhorse (secondary)"Git client리포지터리가 동기화되어 있고 최신인 것으로 판단GET /foo/bar.git/info/refs/?service=git-upload-pack<내부 API 확인>401 Unauthorized<응답>GET /foo/bar.git/info/refs/?service=git-upload-pack<내부 API 확인>Workhorse OK 렌더링200 OKPOST /foo/bar.git/git-upload-packGitHttpControllerWorkhorse OK 렌더링Workhorse가 Rails로부터 연결 세부 정보를 가져와 Gitaly에 연결: SmartHTTP Service, UploadPack RPC (세부 내용은 프로토를 확인하십시오)프로토 메시지 스트림 반환Git 클라이언트로 메시지 전달

프록시된 리포지터리

요청된 리포지터리가 동기화되지 않거나 최신이 아닌 경우, 요청은 최신 변경 사항을 가져오기 위해 프라이머리에 프록시됩니다.

"Gitaly (primary)""Rails (primary)""Workhorse (primary)""Rails (secondary)""Workhorse (secondary)"Git client"Gitaly (primary)""Rails (primary)""Workhorse (primary)""Rails (secondary)""Workhorse (secondary)"Git client리포지터리가 최신이 아닌 것으로 판단프록시됨GET /foo/bar.git/info/refs/?service=git-upload-pack<응답>302 /-/push_from_secondary/2/foo/bar.git/info/refs?service=git-upload-pack로 리디렉션<응답>GET /-/push_from_secondary/2/foo/bar.git/info/refs/?service=git-upload-pack<프록시 요청><데이터>401 Unauthorized<프록시 응답><응답>GET /-/push_from_secondary/2/foo/bar.git/info/refs/?service=git-upload-pack<프록시 요청><데이터>Render Workhorse OK<프록시 응답><응답>POST /-/push_from_secondary/2/foo/bar.git/git-upload-pack<프록시 요청>GitHttpControllerRender Workhorse OKWorkhorse가 Rails로부터 연결 세부 정보를 가져와 Gitaly에 연결: SmartHTTP Service, UploadPack RPC (세부 내용은 프로토를 확인하십시오)프로토 메시지 스트림 반환Git 클라이언트로부터 메시지를 전달Git로부터 전달된 메시지 반환

Git pull over SSH

SSH 작업은 Workhorse 대신에 GitLab Shell을 거쳐 가기 때문에, Workhorse 요청에 사용되는 메커니즘을 통해 프록시되지 않습니다. SSH 작업의 경우, 이는 보조 Rails 내부 API에 의해 Git HTTP 요청으로 프록시됩니다.

가속화된 리포지터리

보조에 리포지터리가 있고 주요 리포지터리와 동기화되어 있는 것으로 감지되면, 프록시하는 대신에 바로 제공됩니다.

Gitaly (secondary)Internal API (secondary Rails)GitLab Shell (secondary)Git clientGitaly (secondary)Internal API (secondary Rails)GitLab Shell (secondary)Git clientgit pullSSH 키 인증 (api/v4/internal/authorized_keys?key=..)HTTP/1.1 200 OKInfoRefs:UploadPack RPCGit 응답을 스트리밍으로 다시 보냄Git 응답을 스트리밍으로 다시 보냄푸시할 Git 데이터 스트리밍UploadPack RPCGit 응답을 스트리밍으로 다시 보냄Git 응답을 스트리밍으로 다시 보냄

프록시된 리포지터리

요청된 리포지터리가 동기화되지 않았거나 주요 리포지터리에서 최신 버전을 가져오기 위해 업데이트가 필요한 경우, 요청은 주요 리포지터리로 프록시됩니다.

Primary APIInternal API (secondary Rails)GitLab Shell (secondary)Git clientPrimary APIInternal API (secondary Rails)GitLab Shell (secondary)Git clientgit pullSSH 키 인증 (api/v4/internal/authorized_keys?key=..)HTTP/1.1 300 (custom action status) with {endpoint, msg, primary_repo}POST /api/v4/geo/proxy_git_ssh/info_refs_upload_packPOST $PRIMARY/foo/bar.git/info/refs/?service=git-upload-packHTTP/1.1 200 OK<response>주요 리포지터리에서 반환된 Git 응답푸시할 Git 데이터 스트리밍POST /api/v4/geo/proxy_git_ssh/upload_packPOST $PRIMARY/foo/bar.git/git-upload-packHTTP/1.1 200 OK<response>주요 리포지터리에서 반환된 Git 응답

Git push

SSH로 Git push

SSH 작업은 Workhorse 대신에 GitLab Shell을 거쳐 가기 때문에, Workhorse 요청에 사용되는 메커니즘을 통해 프록시되지 않습니다. SSH 작업의 경우, 이는 보조 Rails 내부 API에 의해 Git HTTP 요청으로 프록시됩니다.

Primary APIInternal API (secondary Rails)GitLab Shell (secondary)Git clientPrimary APIInternal API (secondary Rails)GitLab Shell (secondary)Git clientgit pushSSH 키 인증 (api/v4/internal/authorized_keys?key=..)HTTP/1.1 300 (custom action status) with {endpoint, msg, primary_repo}POST /api/v4/geo/proxy_git_ssh/info_refs_receive_packPOST $PRIMARY/foo/bar.git/info/refs/?service=git-receive-packHTTP/1.1 200 OK<response>주요 리포지터리에서 반환된 Git 응답푸시할 Git 데이터 스트리밍POST /api/v4/geo/proxy_git_ssh/receive_packPOST $PRIMARY/foo/bar.git/git-receive-packHTTP/1.1 200 OK<response>주요 리포지터리에서 반환된 Git 응답

HTTP(S)로 Git push

통합된 URL을 사용한 HTTP(S)로 Git push

통합된 URL을 사용하면, 푸시가 /-/push_from_secondary/$SECONDARY_ID/*로 형식화된 로컬 경로로 리디렉션되어, 이 경로를 통해 추가 요청은 주요 리포지터리로 프록시되어 처리됩니다.

Gitaly (primary)Rails (primary)Workhorse (primary)Workhorse (secondary)Git clientGitaly (primary)Rails (primary)Workhorse (primary)Workhorse (secondary)Git clientGET /foo/bar.git/info/refs/?service=git-receive-pack302 Redirect to /-/push_from_secondary/2/foo/bar.git/info/refs?service=git-receive-packGET /-/push_from_secondary/2/foo/bar.git/info/refs/?service=git-receive-pack<프록시된 요청><데이터>401 Unauthorized<프록시된 응답><응답>GET /-/push_from_secondary/2/foo/bar.git/info/refs/?service=git-receive-pack<프록시된 요청><데이터>Workhorse OK로 렌더링<프록시된 응답><응답>POST /-/push_from_secondary/2/foo/bar.git/git-receive-pack<프록시된 요청>GitHttpController:git_receive_packWorkhorse OK로 렌더링Rails로부터 연결 세부 정보를 받아 SmartHTTP Service에 연결, ReceivePack RPCProto 메시지의 스트림 반환Git 클라이언트로 메시지 파이프Git으로부터 파이프된 메시지 반환

별도의 URL을 사용한 HTTP(S)로 Git push

별도의 URL을 사용하면, 보조는 $PRIMARY/-/push_from_secondary/$SECONDARY_ID/*로 형식화된 URL로 리디렉션합니다.

```mermaid sequenceDiagram participant Wsec as Workhorse (secondary) participant C as Git client participant W as Workhorse (primary) participant R as Rails (primary) participant G as Gitaly (primary) C-»Wsec: GET $SECONDARY/foo/bar.git/info/refs/?service=git-receive-pack Wsec-»C: 302 Redirect to $PRIMARY/-/push_from_secondary/2/foo/bar.git/info/refs?service=git-receive-pack C-»W: GET $PRIMARY/-/push_from_secondary/2/foo/bar.git/info/refs/?service=git-receive-pack W-»R: <데이터> R-->>W: 401 Unauthorized W-->>C: <응답> C->>W: GET /-/push_from_secondary/2/foo/bar.git/info/refs/?service=git-receive-pack W->>R: <데이터> R-->>W: Workhorse OK로 렌더링 W-->>C: <응답> C->>W: POST /-/push_from_secondary/2/foo/bar.git/git-receive-pack W->>R: GitHttpController:git_receive_pack R-->>W: Workhorse OK로 렌더링 W->>G: Rails로부터 연결 세부 정보를 받아 SmartHTTP Service에 연결, ReceivePack RPC G-->>W: Proto 메시지의 스트림 반환 W-->>C: Git 클라이언트로 메시지 파이프응답>데이터>응답>데이터>