Geo프록시

Geo프록시를 사용하면 이제 보조 시스템에서 웹 요청을 주 프라이머리(primary)를 통해 Workhorse를 경유하여 프록시하므로, 보조 시스템으로 이동하는 사용자는 읽기-쓰기 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 등opt[프라이머리가 로그인되어 있지 않음]`/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 pull

역사적인 이유로 push_from_secondary 경로를 통해 Git pull을 전달하는 데 사용됩니다. 혼란을 피하기 위해 이 경로의 이름을 바꾸는 문제가 있습니다.

HTTP(s)를 통한 Git pull

가속된 리포지터리

보조 시스템에서 리포지터리가 존재하고 주 프라이머리와 동기화되었다고 감지되면, 프록시하는 대신 해당 리포지터리를 직접 제공합니다.

"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<응답>/-/push_from_secondary/2/foo/bar.git/info/refs?service=git-upload-pack로 302 리디렉트<응답>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<프록시된 요청><데이터>Workhorse OK 렌더링<프록시된 응답><응답>POST /-/push_from_secondary/2/foo/bar.git/git-upload-pack<프록시된 요청>GitHttpControllerWorkhorse OK 렌더링Workhorse가 Rails로부터 연결 세부 정보를 받아 Gitaly에 연결: SmartHTTP Service, UploadPack RPC (세부 내용은 프로토를 확인하세요)프로토 메시지의 스트림 반환Git 클라이언트로부터 메시지를 전달Git로부터의 파이프 메시지 반환

SSH를 통한 Git pull

SSH 작업은 Workhorse 요청을 위한 메커니즘을 통해 프록시되지 않고, GitLab Shell을 통해 SSH 작업이 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 응답 스트림 반환Push할 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 푸시

SSH를 통한 Git 푸시

SSH 작업은 Workhorse 대신 GitLab Shell을 통해 수행되므로 Workhorse 요청에 사용되는 메커니즘을 통해 프록시되지 않습니다. SSH 작업의 경우, 2차 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_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<프록시된 응답><response>GET /-/push_from_secondary/2/foo/bar.git/info/refs/?service=git-receive-pack<프록시된 요청><데이터>Render Workhorse OK<프록시된 응답><response>POST /-/push_from_secondary/2/foo/bar.git/git-receive-pack<프록시된 요청>GitHttpController:git_receive_packRender Workhorse OKRails에서 연결 세부 정보 가져와 SmartHTTP 서비스에 연결, ReceivePack RPC프로토 메시지의 스트림 반환Git 클라이언트로부터의 메시지 전달Git으로부터의 메시지 반환