This page contains information related to upcoming products, features, and functionality. It is important to note that the information presented is for informational purposes only. Please do not rely on this information for purchasing or planning purposes. As with all projects, the items mentioned on this page are subject to change or delay. The development, release, and timing of any products, features, or functionality remain at the sole discretion of GitLab Inc.
Status Authors Coach DRIs Owning Stage Created
ongoing @vtak @grzesiek @ericschurter @oregand devops create 2022-11-15

원격 개발

요약

원격 개발은 GitLab에서 호스팅된 코드 작성의 더 일관된 사용자 경험을 제공하는 새로운 소프트웨어 서비스 플랫폼 아키텍처입니다. 미래에는 순수한 브라우저 기반 워크스페이스와 이미 실행 중인 VM/컨테이너에 연결하거나 GitLab에서 호스팅된 VM/컨테이너를 사용하는 등 추가 기능을 제공할 수도 있습니다.

Web IDE 및 원격 개발

remote development !== Web IDE임을 명확히 하고자 이 문서에서 강조해야 하는 부분입니다. 새로운 Web IDE는 원격 개발과 별도로 병행되는 별도의 노력입니다.

이 두 가지 별개의 범주는 사용자가 실행 중인 워크스페이스를 Web IDE에 연결할 수 있도록 하는 것을 목표로 하고 있지만, 이는 두 가지가 서로 종속된 것은 아니라는 것을 의미합니다.

웹 브라우저에서 종속성을 설치하거나 저장소를 복제하지 않고도 프로젝트에 대한 변경 사항을 직접 커밋할 수 있는 Web IDE를 사용할 수 있습니다. 그러나 Web IDE에는 코드를 컴파일하거나 테스트를 실행하거나 IDE에서 실시간 피드백을 생성하는 데 사용할 네이티브 런타임 환경이 없습니다. 더 완전한 IDE 환경을 위해 Web IDE를 적절히 구성하여 호스트로 실행되도록 한 원격 개발 워크스페이스와 결합할 수 있습니다.

장기적인 비전

로컬 개발 환경이 없는 새로 온 Sasha와 같은 소프트웨어 개발자가 다음을 할 수 있어야 합니다:

  • GitLab.com 또는 Self-Managed의 저장소로 이동합니다.
  • 이 저장소에 대한 현재 워크스페이스 목록을 제공하는 버튼을 클릭합니다.
  • 새로운 워크스페이스를 생성하거나 목록에서 기존 워크스페이스를 선택하는 버튼을 클릭합니다.
  • 워크스페이스를 위해 다양한 옵션을 선택할 수 있도록 하는 구성 마법사를 사용합니다(메모리/CPU).
  • Web IDE에서 워크스페이스를 시작하고 1분 이내에 완전히 상호 작용하는 터미널 패널을 사용할 수 있습니다.
  • 코드 변경, 테스트 실행, 터미널 출력을 기반으로 문제해결 및 새 변경 사항 커밋을 수행할 수 있습니다.
  • 저장소를 로컬로 복제하거나 로컬 개발 환경을 수동으로 업데이트하지 않고도 어떠한 종류의 MR(Merge Request)를 제출할 수 있어야 합니다.

용어

원격 개발 아키텍처의 구성 요소 및 속성을 설명하는 데 다음 용어를 사용합니다.

원격 개발

원격 개발은 로컬 머신을 통해 웹 브라우저나 클라이언트 기반 솔루션을 통해 클라우드에서 안전한 개발 환경을 사용할 수 있도록 하는 것입니다.

원격 개발 속성

  • 로컬 머신 구성에 영향을 주지 않기 위해 개발 환경을 분리합니다.
  • 새 기여자가 시작하기 쉽게 만들고 모든 사람이 일관된 환경에서 유지할 수 있도록 합니다.
  • 로컬 OS에서 사용할 수 없는 도구 또는 런타임을 사용하거나 그러한 도구 또는 런타임의 여러 버전을 관리합니다.
  • 여러 기계나 위치에서 기존 개발 환경에 액세스합니다.

비권장하는 동의어: 웹용 VS Code, 원격 개발 확장, 브라우저 전용 WebIDE, 클라이언트 전용 WebIDE

워크스페이스

코드 작성, 빌드, 테스트, 실행, 디버그에 필요한 모든 도구와 종속성을 제공하는 컨테이너/VM 기반의 개발자 머신입니다.

워크스페이스 속성

  • 워크스페이스는 기본적으로 서로 분리되어 있어야 하며 컴포넌트의 라이프사이클을 관리해야 합니다. 이 분리는 다중 레이어 구성될 수 있습니다: 네임스페이스 분리, 네트워크 분리, 리소스 분리, 노드 분리, 컨테이너 검사 등 (참고).
  • 워크스페이스에는 프로젝트 컴포넌트와 편집기 컴포넌트가 포함되어야 합니다.
  • 워크스페이스는 클라우드 기반 개발 환경을 지원하는 리소스의 조합이어야 합니다.
  • 워크스페이스는 제공된 리소스 양에 제약을 받습니다.

Web IDE

VS Code를 웹용으로 대체하는 GitLab 컨텍스트 인식형 Web IDE입니다.

Web IDE 속성

  • Microsoft의 VS Code를 기반으로 구축됩니다. GitLab의 VS Code 프로젝트 포크에서 VS Code 기능을 사용자 정의하고 추가합니다.
  • 웹 IDE가 워크스페이스에 연결되도록 구성될 수 있어야 합니다. 워크스페이스에 연결된 경우 사용자는 웹 IDE에서 다음을 수행할 수 있어야 합니다:
    • 로컬 머신과는 다른 OS에서 편집, 빌드 또는 디버깅을 수행할 수 있어야 합니다.
    • 로컬 머신보다 크거나 더 특수한 하드웨어를 개발에 사용할 수 있어야 합니다.
    • 뭔가의 충돌을 피하고 보안을 강화하며 온보딩 속도를 높이기 위해 개발자 환경을 분리해야 합니다.

데스크톱용 원격 개발 확장

데스크톱 IDE에 연결되어 워크스페이스에 접속하는 기능입니다.

데스크톱용 원격 개발 확장 속성

  • 워크스페이스에서 모든 폴더를 열 수 있어야 합니다.
  • 데스크톱 IDE에 대한 중립적이어야 합니다.
  • 로컬 파일이나 API에 액세스할 수 있어야 합니다.

목표

일관된 경험

조직은 온프레미스 GitLab 인스턴스에서와 동일한 사용자 경험을 가져야 합니다. 사용자의 개발 환경을 추상화하여 로컬 머신 구성에 영향을 주지 않도록 해야 합니다. 또한 배포하는 운영 체제에서 개발할 수 있도록 지원하거나 더 크거나 특수한 하드웨어를 사용할 수 있도록 지원하려 합니다.

주요 목표는 개발 팀의 각 구성원이 특수 로컬 구성을 제외하고 동일한 개발 경험을 갖도록 하는 것입니다. 또한 새 기여자가 시작하기 쉽게 만들고 모든 사람이 일관된 환경에서 유지할 수 있도록 하는 것입니다.

높은 가용성

작업 영역은 단일 또는 다중 팀에서 여러 대의 기기와 위치에서 기존 개발 환경에 액세스할 수 있어야 합니다. 또한 사용자가 로컬 OS에서 사용할 수 없는 도구나 런타임을 사용하거나 그러한 도구의 여러 버전을 관리할 수 있어야 합니다.

또한 원격 개발 작업 영역은 Cells의 기능을 활용할 수 있다면 재해 복구 방안을 제공할 수 있습니다.

확장성

기관이 성장하기 시작하면 복잡한 워크플로우를 필요로 하는 추가 유형의 프로젝트를 지원해야 할 필요성을 빠르게 깨닫게 됩니다. 원격 개발 작업 영역은 복잡한 머신 구성, 의존성 관리, 가능한 데이터 시드 문제의 부담을 추상화하여 이 문제를 해결하고자 합니다.

다른 프로젝트에서 다른 기능에 작업하는 것을 용이하게 하기 위해 원격 개발은 각 사용자가 여러 개의 작업 영역을 프로비저닝하여 빠른 컨텍스트 전환을 가능하게 해야 합니다.

마침내 사용자가 현재 2 CPU 및 4GB RAM 작업 공간을 사용 중이지만 더 많은 CPU가 필요하다고 깨닫게 되면 작업 영역에서 한 번의 클릭 또는 CLI 명령으로 계산 레이어를 더 적합한 것으로 업그레이드할 수 있어야 합니다.

내장된 보안 및 기업용 준비

원격 개발이 가상 데스크톱 인프라 솔루션의 실질적인 대안이 될 때, 보안 및 기업 요구 사항을 지원하고 안전해야 합니다. 이러한 요구 사항에는 역할 기반의 액세스 제어와 개발자 기기에서 모든 소스 코드를 제거하는 기능이 포함됩니다.

프로젝트 및 개발자 지원의 신속한 적응

브라우저에서 실행되는 설치 없이 개발 환경이므로 원격 개발은 누구나 팀에 가입하고 프로젝트에 기여할 수 있도록 쉽게 만듭니다.

지역

GitLab.com은 미국에서만 호스팅됩니다. 다른 지역에 위치한 기관들은 로컬 SaaS 오퍼링을 요청해왔습니다. BYO 인프라는 사용자의 작업 영역이 서로 다른 지리적 위치에 배포될 수 있기 때문에 GitLab Regions와 함께 작업할 수 있습니다. 다른 지역에 작업 영역을 배포할 수 있는 능력은 데이터 국지화 및 규정 준수 문제를 해결하는 데 도움이 될 수도 있습니다.

시장 분석

우리는 더 넓은 시장을 이해하고 오픈 소스 라이브러리, 통합 또는 파트너십 기회를 통해 다른 사람이 우리에게 제공할 수 있는 것을 이해하기 위해 시장 분석을 수행했습니다. 우리는 각 잠재적인 경쟁사/경로/파트너십을 조사하기 위해 노력을 일련의 이슈로 분해했습니다.

Che vs DevWorkspace Operator vs 사용자 정의 솔루션

원격 개발을 가속화하기 위해 Che를 사용하는 것에 대한 조사를 진행한 뒤, 우리는 궁극적으로 DevWorkspace Operator를 사용하여 사용자 정의 솔루션을 작성하기로 결정했습니다.

우리가 사용자 정의 솔루션을 작성하기로 결정한 몇 가지 장점은 다음과 같습니다:

  • 우리는 여전히 핵심 DevWorkspace Operator를 사용하고 그 위에 덧붙일 수 있습니다.
  • 필요에 따라 미래에 devfile 이외의 다른 구성 지원을 쉽게 추가할 수 있습니다.
  • 우리는 사용할 기술 스택을 선택할 수 있습니다 (예: Che에서 사용되는 traefik 대신에 NGINX 자체를 탐색하거나 Kubernetes용 GitLab Agent를 사용할 수 있습니다).

우리만의 DevWorkspace Operator를 사용하여 사용자 정의 솔루션을 작성한 뒤, 우리는 DevWorkspace Operator의 종속성과 따라서 Cert Manager의 종속성을 제거하기로 결정했습니다.

아키텍처 세부 정보

원격 개발은 GitLab Agent for Kubernetes 프로젝트의 모듈로 제공됩니다. 이 아키텍처의 전반적인 목표는 Kubernetes 클러스터에서 실행 중인 모든 원격 개발 작업 영역의 실제 상태가 사용자가 설정한 원하는 상태와 조화롭게 되도록 하는 것입니다.

이는 다음과 같이 수행됩니다:

  1. 작업 영역의 원하는 상태는 GitLab UI 또는 API에서 사용자의 작업으로부터 얻어지고 Rails 데이터베이스에 저장됩니다.
  2. 에이전트와 Rails 간에 조화력 루프가 있으며, 이는:
    • 에이전트를 통해 Kubernetes 클러스터에서 작업 영역의 실제 상태를 검색하고 Rails에 보내어 저장하도록 합니다.
    • Rails는 실제 상태를 원하는 상태와 비교하여 작업 영역의 실제 상태를 원하는 상태와 조화롭게 만들기 위한 조치를 취하도록 응답합니다.

시스템 디자인

레일즈와 에이전트 간의 메시지 유형

에이전트는 다른 유형의 메시지를 레일즈에게 보내어 다양한 정보를 캡처할 수 있습니다. 에이전트가 보내는 메시지의 유형에 따라 레일즈가 그에 따라 응답합니다.

다양한 메시지 유형은 다음과 같습니다:

  • prerequisites (아직 구현되지 않음) - 에이전트가 시작하거나 리스타트한 후 또는 리더 선출 후 레일즈에 보내는 첫 번째 메시지입니다.
    • 에이전트에 의해 수행되는 동작:
      • 쿠버네티스 클러스터에서 사용 가능해야 하는 쿠버네티스 리소스를 가져옴
    • 레일즈에 의해 수행되는 동작:
      • 쿠버네티스 클러스터에 있어야 하는 gitlab-workspaces-proxy의 쿠버네티스 매니페스트를 전송
  • reconcile - 현재 워크스페이스 상태를 지속시키기 위해 레일즈에게 보내는 메시지입니다. update_type 필드로 지정된 두 가지 유형의 업데이트가 있습니다: fullpartial. 페이로드 스키마는 두 업데이트 유형에 대해 동일합니다.
    • full
      • 에이전트에 의해 수행되는 동작:
        • 에이전트가 관리하는 쿠버네티스 클러스터의 모든 워크스페이스의 현재 상태를 전송
        • 에이전트와 레일즈 사이를 일관되게 유지하기 위해, 에이전트는 다음과 같은 완전 조정 주기가 발생할 때마다 이 메시지를 전송합니다
          • 에이전트 시작 또는 다시 시작 시
          • 리더 선출 이후
          • full_sync_interval 설정을 사용하여 주기적으로 (기본값: 1시간마다 한 번)
          • 에이전트 구성이 업데이트될 때
      • 레일즈에 의해 수행되는 동작:
        • Postgres를 업데이트하고, 레일즈가 Postgres에 지속한 에이전트가 관리하는 모든 워크스페이스와 그들의 마지막 리소스 버전을 응답
        • 지속된 리소스 버전을 에이전트에게 반환함으로써, 레일즈에서 해당 워크스페이스의 업데이트가 성공적으로 처리되었음을 확인
        • 이러한 지속된 리소스 버전은 reconcile 메시지의 partial 업데이트 유형에 대해 에이전트로부터 레일즈로 최신 워크스페이스 변경사항만 전송하는 데 도움을 줄 것
    • partial
      • 에이전트에 의해 수행되는 동작:
        • 아직 Postgres에 지속되지 않은 최신 워크스페이스 변경사항을 레일즈로 전송
        • 이 지속된 리소스 버전은 에이전트로부터 레일즈로 최신 워크스페이스 변경사항만 전송하는 데 도움을 줄 것
      • 레일즈에 의해 수행되는 동작:
        • Postgres를 업데이트하고, 레일즈가 Postgres에 지속한 현재 상태와 그들의 마지막 리소스 버전을 응답
        • 생성/업데이트/삭제될 워크스페이스는 desired state updated at >= agent info reported at 필터를 사용하여 계산됨
        • 지속된 리소스 버전을 에이전트에게 반환함으로써, 레일즈에서 해당 워크스페이스의 업데이트가 성공적으로 처리되었음을 확인

@enduml ```

이벤트 기반 폴링 vs 전체 또는 부분 조정

최초에는 에이전트에게 다음 조정 루프를 기다리지 말고 즉시 폴링하도록 지시할 수 있는 것이 바람직하다고 여겨졌습니다. 이렇게 하면 다음과 같은 이점이 얻어집니다.

  1. 이로써 요청에 의한 전체 조정을 트리거할 수 있는 능력이 주어져 에이전트 내에서 모듈 상태를 요구에 따라 즉시 복구/재설정할 수 있습니다.
  2. 아키텍처를 이벤트 기반 및 실시간으로 만드는 것 외에도, 조정 폴링 간격을 늘려 인프라 부하를 줄일 수 있습니다.

그러나, 전망적인 솔루션이 평가될 때, 비교적 객관적인 옵션들의 복잡성을 고려할 때 특히 이러한 능력이 정당화될 많은/드물게 발생하는 경우가 있다는 결론에 이르렀습니다. 대부분의 경우에는 최종적으로 상태 조정이 대부분 충분하며, 부분적인 조정보다 주기적으로 수행되는 전체 조정을 통해 이를 간단히 달성할 수 있습니다.

자세한 내용은 이슈결론 댓글에서 확인할 수 있습니다.

작업 공간 상태

  • CreationRequested - 작업 공간의 초기 상태; 사용자에 의해 생성 요청되었지만 아직 처리되지 않음
  • Starting - 사용 준비 과정 중
  • Running - 사용 가능한 상태
  • Stopping - 축소하는 과정 중
  • Stopped - 지속적인 저장 공간은 사용 가능하지만 작업 공간은 축소되었습니다
  • Failed - agentk가 쿠버네티스 리소스를 적용했지만 여러 가지 이유(예: 컨테이너 충돌)로 인해 준비되지 않은 상태입니다.
  • Error - agentk에의해 쿠버네티스 리소스가 적용되지 않음
  • RestartRequested - 사용자가 작업 공간 재시작을 요청했지만 아직 성공적으로 발생하지 않음
  • Terminating - 사용자가 작업 공간 종료를 요청했고 작업이 시작되었지만 아직 완료되지 않음
  • Terminated - 지속적인 저장 공간이 삭제되었고 작업 공간이 축소되었습니다
  • Unknown - 작업 공간의 실제 상태를 이해할 수 없음

가능한 actual_state

actual_state 값은 에이전트가 수신 및 레일즈로 전송하는 쿠버네티스 배포 변경의 status 속성에서 결정됩니다.

다음 다이어그램은 작업 공간 레코드의 actual_state 값의 전형적인 흐름을 나타냅니다. status는 다양한 조건에 따라 작업 공간의 actual_state를 파생시키기 위해 구문 분석됩니다.

그러나 에이전트로부터 일부 이유로 (빠른 전환, 이벤트 전송 실패 등) 전이적인 status 업데이트가 수신되지 않은 경우 이러한 상태 중 일부가 건너뛰어질 수 있습니다.

가능한 desired_state

desired_state 값은 레일즈에 대한 사용자의 요청에서 결정되며 레일즈에 의해 에이전트로 전송됩니다.

desired_stateactual_state의 하위 집합으로, Running, Stopped, Terminated, 및 RestartRequested 값만 포함됩니다. 레일즈의 상태 조정 로직은 작업 공간이 복구할 수 없는 상태에 있지 않는 한, 계속해서 actual_statedesired_state 값으로 전환시킵니다.

그리고 RestartRequested라는 추가 지원되는 상태가 있습니다. 이는 desired_state에 대해서만 유효한 값입니다. 이 값은 actual_state에 대해 유효한 값이 아닙니다. 시작된 작업 공간의 재시작을 레일즈가 시작하도록 하기 위해 필요합니다. 이 값은 에이전트로부터 Stopped 상태가 수신되면 자동으로 Running으로 변경됩니다. 만약 작업 공간을 다시 시작하는데 실패하고 Stopped 상태가 받아지지 않으면, desired_stateRestartRequested로 유지되어 새로운 desired_state가 지정될 때까지 유지됩니다.

워크스페이스로 환경 변수 및 파일 주입

CI와 마찬가지로, 워크스페이스로 환경 변수 및 파일을 주입해야 합니다. 이러한 환경 변수 및 파일은 워크스페이스 생성 시간에 동결되어야 합니다. 이를 통해 매번 워크스페이스를 시작/재시작할 때 동일한 값이 주입될 수 있습니다. 따라서 ci_job_variables와 유사한 새로운 데이터베이스 테이블이 필요합니다. 이 테이블에는 다음 열이 포함될 것입니다.

  • key - 환경 변수 또는 파일의 이름을 저장합니다.
  • encrypted_value - 환경 변수 또는 파일의 암호화된 값이 저장됩니다.
  • encrypted_value_iv - 암호화에 사용된 초기화 벡터가 저장됩니다.
  • workspace_id - 환경 변수 또는 파일이 주입될 워크스페이스를 참조합니다.
  • variable_type - 이 데이터가 환경 변수로 주입될지 또는 파일로 주입될지를 저장합니다.

암호화를 수행하기 위해 GitLab 인스턴스 수준의 비밀 키가 사용됩니다. 환경 변수 및 파일에 대한 데이터는 필요할 때만 Agent에게 전송됩니다. 즉,

  • 사용자로부터 새로운 워크스페이스 생성 요청을 받았을 때, 그리고 Agent가 부분 조정 요청을 초기화할 때
  • Agent가 전체 조정 요청을 초기화할 때

암호화된 워크스페이스 변수의 복호화에 대한 잠재적인 성능 문제를 염두에 두어야 하며, 조정 요청의 길이가 허용할 수 없는 시간에 도달하는 규모의 벤치마킹을 수행해야 합니다. 예를 들어, 20개의 암호화된 값이 포함된 100개의 워크스페이스에 대한 조정 요청 == 단일 요청에서 2000개의 복호화가 수행됩니다.

벤치마킹에 대한 자세한 내용은 이 문제에서 찾을 수 있습니다.

프로젝트에서 워크스페이스를 생성하는 경우 그룹/서브그룹/프로젝트 계층 구조 아래 정의된 모든 변수를 상속받을 것입니다. 이 측면은 CI/CD 및 워크스페이스 모두에서 상속될 Variables를 정의할 수 있도록 일반화될 것입니다. 사용자는 또한 그들이 생성한 각 워크스페이스에 주입할 환경 변수 및 파일을 정의할 수 있을 것입니다. 워크스페이스를 생성하는 동안 사용자는 그룹/서브그룹/프로젝트/사용자 계층에서 상속된 환경 변수 또는 파일을 재정의할 수 있을 것입니다.

워크스페이스에서 Git 작업 수행

새로운 워크스페이스가 생성될 때, 해당 워크스페이스를 생성한 사용자와 연결된 새로운 개인 액세스 토큰이 생성될 것입니다. 이 개인 액세스 토큰은 워크스페이스의 수명주기에 묶여 있고, 워크스페이스로 클론할 수 있고 기타 작업을 투명하게 지원하도록 허용하기 위해 파일로 워크스페이스에 주입될 것입니다. 이 작업은 사용자 지정 Git 자격 증명 도우미를 사용하여 이루어질 것입니다.

개인 액세스 토큰 대신 일시적 토큰(JWT/OAuth/OIDC 등)을 사용하는 것에 대한 조사는 GitLab에 대한 공통 JWT 인증/승인 계층이 필요하다는 사실을 밝혀냈습니다. 이러한 기능이 제공되면, 각 워크스페이스에 대한 개인 액세스 토큰은 JWT 토큰으로 대체될 것입니다.

워크스페이스 사용자 트래픽 인증 및 승인

워크스페이스에 액세스하는 것은 특정 사용자만 허용해야 합니다. 현재, 이를 워크스페이스를 만든 사용자/소유자로 제한하고 있습니다. 워크스페이스가 만들어진 후, 사용자가 연결할 수 있도록 네트워크에 노출되어야 합니다. 따라서 워크스페이스로 들어오는 모든 트래픽은 인증 및 승인되어야 합니다. gitlab-workspaces-proxy는 Kubernetes 클러스터에서 실행 중인 워크스페이스의 발견, 인증 및 승인을 처리할 것입니다.

이 프록시는 HTTP 및 WebSocket 호출을 모두 워크스페이스로 중계할 것입니다. 이 프록시는 다음 작업을 수행할 것입니다.

  1. 워크스페이스 발견 - 프록시는 Kubernetes 서비스 리소스의 라벨을 기반으로 자동 워크스페이스를 발견합니다. 프록시는 Kubernetes API를 감시하여 Kubernetes 서비스 리소스의 생성/업데이트/삭제를 감지합니다. 서비스 리소스가 생성되면 해당 서비스를 상위 업스트림으로 사용하도록 자동으로 구성할 것입니다. 따라서 이 작업을 수행하려면 Kubernetes 서비스 계정 및 감시, 목록 및 서비스 리소스 가져오기를 허용하는 역할이 필요합니다.
  2. 인증 - GitLab과 함께 OAuth 2.0 플로우를 사용하여 사용자를 인증합니다. GitLab이 식별 공급자로 작동할 것입니다. 고객이 GitLab에 로그인하기 위해 타사 SSO 서비스를 사용하는 경우, 해당 플로우는 자동으로 해당 공급자로 인증을 위임할 것입니다. 인증의 복잡성 중 하나는 각 워크스페이스가 자체 도메인에서 제공되기 때문에 GitLab 앱에서 특정 워크스페이스로 리디렉션 URI를 설정할 수 없다는 사실입니다. 따라서 OAuth 2.0 플로우에 상태를 설정하여 올바른 워크스페이스로 리디렉션할 수 있어야 합니다.
  3. 승인 - 프록시는 사용자의 자격 증명을 사용하여 GitLab GraphQL 엔드포인트에 호출을 수행할 것입니다. 엔드포인트는 사용자가 워크스페이스에 액세스할 수 있는지 유효성을 검사하고, 이에 따라 404 또는 200을 반환할 것입니다.
  4. 세션 관리 - 프록시는 상태가 없으며 캐시 또는 데이터베이스와 같은 추가 타사 소프트웨어 없이 배포될 것이므로, 세션을 관리하기 위해 서명된 JWT를 사용할 것입니다. JWT는 시작 중에 프록시에 제공된 키를 사용하여 서명됩니다.

주어진 도메인의 Kubernetes 클러스터로 들어오는 모든 트래픽은 gitlab-workspaces-proxy로 전달되며, 프록시는 해당 트래픽을 어떻게 제공할지 결정할 것입니다.

고려된 다른 옵션

Sidecar proxy

사이드카는 각 워크스페이스에 주입되며 해당 워크스페이스로의 모든 트래픽이 사이드카를 통해 흐를 것입니다. 사이드카는 단일 워크스페이스의 트래픽만 처리할 것입니다. 두 개의 네트워크 네임스페이스를 공유하기 때문에 사이드카는 루프백 인터페이스(localhost)를 통해 워크스페이스와 통신할 수 있습니다.

flowchart TB 사용자_워크스페이스_트래픽[사용자 워크스페이스 트래픽] --> Ingress subgraph 워크스페이스_클러스터[워크스페이스 클러스터] Ingress --> 워크스페이스1_프록시 Ingress --> 워크스페이스2_프록시 Ingress --> 워크스페이스3_프록시 subgraph workspace1[워크스페이스 1] 워크스페이스1_프록시[워크스페이스 사이드카 프록시] --프록시--> 워크스페이스1[워크스페이스 1] end subgraph workspace2[워크스페이스 2] 워크스페이스2_프록시[워크스페이스 사이드카 프록시] --프록시--> 워크스페이스2[워크스페이스 2] end subgraph workspace3[워크스페이스 3] 워크스페이스3_프록시[워크스페이스 사이드카 프록시] --프록시--> 워크스페이스3[워크스페이스 3] end end 워크스페이스3_프록시 --OAuth 2--> GitLab GitLab --리디렉트--> 워크스페이스3_프록시 워크스페이스3_프록시 --인증 API--> GitLab
  • 장점
    • 대량의 트래픽을 처리할 필요가 없음
    • 사이드카가 작동을 중지해도 다른 워크스페이스의 작동에 영향을 주지 않음
  • 단점
    • 각 워크스페이스마다 사이드카를 배포해야 하므로 리소스를 비효율적으로 사용함
    • 추가 프록시 요소로 인해 워크스페이스가 약간 느리게 동작할 수 있음

Ingress 리소스에 있는 Auth 주석

Ingress 리소스에 있는 Auth 주석을 사용하여 Ingress 컨트롤러(예: ingress-nginx)가 인증 및 허가를 별도의 프로세스에 위임할 수 있도록 합니다. 이 주석들은 표준화되지 않았으며(즉, Ingress 명세의 일부가 아님) 다른 Ingress 컨트롤러에서 지원되지 않을 수 있습니다. 우리는 각 Ingress 컨트롤러에 대해 Auth 공급자를 설정하는 절차를 문서화해야 할 것입니다. 그러나 이러한 요소들이 새로운 게이트웨이 API의 일부가 된다면 이 결정을 재고할 것입니다.

ingress-nginx의 경우, Auth 주석은 다음과 같을 것입니다:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
    nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri"
  name: example-ingress
  namespace: example-namespace
spec:
  ingressClassName: nginx
  rules:
  - host: "*.workspaces.example.dev"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: example-workspace
            port:
              number: 80

traefik의 경우, Auth 주석은 다음과 같을 것입니다:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: example-namespace
  annotations:
    kubernetes.io/ingress.class: traefik
    ingress.kubernetes.io/auth-type: forward
    ingress.kubernetes.io/auth-url: http://traefik-forward-auth:4181
    ingress.kubernetes.io/auth-response-headers: X-Forwarded-User
spec:
  ingressClassName: traefik
  rules:
  - host: "*.workspaces.example.dev"
    http:
      paths:
      - backend:
          name: example-workspace
          servicePort: http

Google Cloud Load Balancer를 사용하는 IAP의 경우, Auth 주석은 다음과 같을 것입니다:

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: example-backend-config
  namespace: example-namespace
spec:
  iap:
    enabled: true
    oauthclientCredentials:
      secretName: example-secret

워크스페이스에서 웹 IDE에 액세스

현재, 런타임 중에 워크스페이스 내에 주입되는 편집기로 GitLab의 VS Code 포크만 지원합니다. 편집기 인젝터는 GitLab의 VS Code 서버를 포함하는 컨테이너 이미지입니다. 편집기 인젝터에는 워크스페이스로 서버를 복사하고 서버를 시작하는 스크립트가 들어 있습니다.

편집기 인젝터는 WebUI와 익스텐션 호스트(VS Code 백엔드)를 함께 패키징합니다. 현재로서는, 우리는 워크스페이스에도 WebUI를 패키징합니다. 즉, GitLab의 VS Code 편집기는 두 가지 방식으로 사용할 수 있습니다:

  • 직접 워크스페이스 URL에 액세스하여 패키지된 WebUI를 사용합니다.
  • WebIDE를 통해 워크스페이스에 액세스하여 패키지된 WebUI를 무시합니다.

Workspaces용 컨테이너 이미지 빌드

우리는 컨테이너 내의 모든 파일을 수정하고 실행할 수 있도록 파일 그룹 권한에 의존합니다. 따라서 워크스페이스를 생성할 때, 임의의 Linux 사용자를 사용하여 컨테이너를 실행합니다. 사용하려는 컨테이너 이미지가 임의 사용자 ID를 지원하지 않는 경우 아래의 코드 조각을 사용하여 직접 빌드할 수 있습니다. 이 코드 조각은 참고용으로만 제공됩니다. 컨테이너 내에서 컨테이너를 실행하는 Linux 사용자에게 쓰기 액세스가 필요한 다른 위치가 있다면, 해당 파일과 폴더가 우리가 의존하는 원하는 루트 Linux 그룹 권한을 갖도록 해야 합니다.

FROM IMAGE_OF_YOUR_CHOICE

RUN useradd -l -u 33333 -G sudo -md /home/gitlab-workspaces -s /bin/bash -p gitlab-workspaces gitlab-workspaces

ENV HOME=/home/gitlab-workspaces

WORKDIR $HOME

RUN mkdir -p /home/gitlab-workspaces && chgrp -R 0 /home && chmod -R g=u /etc/passwd /etc/group /home

USER gitlab-workspaces

이 결정에 대해 더 읽어보려면 이 링크를 참조하세요.

링크