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 @igorwwwwwwwwwwwwwwwwwwww @ggillies @andrewn @marin @fzimmer 2023-07-31

Runway: GitLab을 위한 PaaS

요약

Runway는 GitLab을 위한 내부 Platform as a Service로, 팀이 서비스를 신속하고 안전하게 배포하고 실행할 수 있도록 하는 것을 목표로 합니다.

동기

이 설계안의 명확한 동기, 목표 및 비목표를 명시적으로 나열하기 위한 섹션입니다. 변경 사항이 왜 중요한지, 모든 기회, 사용자들에 대한 이점을 설명하세요.

동기 섹션에서는 광범위한 GitLab 커뮤니티 내에서 해당 설계안에 대한 관심을 나타내는 이슈에 대한 링크를 제공할 수 있습니다. 경쟁 제품 및 서비스에 대한 문서 링크도 격려되며, 여기서 GitLab이 제공하는 기능의 명백한 공백을 보여주는 경우에는 특히 그러합니다.

구체적인 제안에 대한 목표와 비목표를 명시적으로 나열하는 것을 권장하지만, 문제가 명확하게 정의되지 않았거나 디자인 세부 사항이 아직 확립되지 않은 경우, 이 섹션을 문제 설명, 도전 과제 또는 기회로 구성하는 것이 더 적합할 수 있습니다.

이 계획을 통해 나아가고자 하는 목표/기회를 나열하세요.

  • 인프라 관리, 확장, 모니터링과 같은 부분에 너무 많은 걱정 없이 서비스를 배포하려는 개발팀.
  • 상태가 없는 위성 서비스에 중점을 두며 따라서 수요를 충족시키기 위해 자동으로 확장할 수 있습니다.
  • 기존 GitLab 기능 및 도구와 통합하여 원활한 경험을 제공하는 데 초점을 두고 있습니다.

비목표

제한된 목표를 나열하면 토론에 집중하고 진전을 이룰 수 있습니다.

이 섹션은 선택 사항입니다.

이 설계안의 범위를 벗어나는 것은 무엇인가요?

  • GitLab 모놀리스 호스팅: 모놀리스는 매우 특수한 요구 사항을 가진 복잡한 애플리케이션이며, 이에 따라 범위에서 제외됩니다. 모놀리스의 배포는 배포팀이 책임지고 있으며, 이를 위해 Cells와 같은 다른 도구 및 이니셔티브가 있습니다.
  • 임의의 GCP 리소스: 우리는 일반적으로 사용되는 일부 GCP 리소스를 지원할 수 있지만, 지원할 리소스를 선택적으로 제공할 것입니다. 더 많은 유연성이 필요한 경우 GitLab Sandbox 프로젝트를 요청하는 것이 좋습니다.
  • 임의의 Kubernetes 리소스: 관리형 플랫폼으로서, 기본 배포 메커니즘을 너무 많이 노출하지 않는 것을 목표로 합니다. 이는 지원되는 하위 집합을 가지고 있고 제공 업체를 변경할 수 있는 유연성을 제공합니다. 특수한 요구 사항이 있는 경우 자체 Kubernetes 클러스터를 사용하는 것이 더 좋을 수 있습니다.

제안

Runway은 Docker 이미지로 패키징된 서비스를 프로덕션 환경으로 배포하는 수단입니다. 이를 위해 GitLab CI/CD뿐만 아니라 다른 GitLab 제품 기능을 활용합니다.

디자인 및 구현 세부 정보

Runway의 디자인은 각 구성 요소를 시간이 지남에 따라 변경하고 교체할 수 있는 방식으로 분리하는 것을 목표로 하고 있습니다.

아키텍처

Runway 아키텍처

다이어그램 소스

초기 아키텍처 논의

Provisioner

Provisioner는 나머지 시스템에서 필요로 하는 서비스 계정 및 최소 리소스를 생성하는 권한이 있는 코드입니다.

이 프로세스는 “나를 위해 실험 공간을 만들어 주세요”라는 요청을 받아 해당 공간을 위한 최소한의 인프라를 구축합니다. 더 이상 필요하지 않은 공간이면 폐기하는 것도 담당합니다.

  • 현재 Terraform을 기반으로 하고 있습니다.
  • Terraform은 provisioner 프로젝트에서 CI를 통해 실행됩니다.
  • 우리는 Terraform 상태를 GitLab Terraform 상태 백엔드에 저장합니다.

Reconciler

Reconciler는 이 시스템의 핵심입니다. 서비스 정의와 현재 버전을 기반으로 원하는 세계를 만드는 책임이 있으며, 실제 상태와의 차이를 찾아 그 차이를 적용하는 것을 담당합니다.

새 버전의 서비스를 배포하는 것은 Reconciler를 호출하는 것입니다.

이 프로세스는 서비스 개발자로부터 아티팩트(예: Docker 이미지)를 가져와 런타임에 넣는 것을 담당합니다. 롤아웃 전략, 롤백, 카나리 배포, 다중 환경 프로모션 및 실패한 배포에 대한 진단 도구도 포함됩니다. 이러한 기능 중 일부는 런타임에 위임될 수도 있습니다. 또한 기존 코드 베이스를 배포에 연결하는 표준 방법이 있어야 합니다.

  • 현재 Terraform을 기반으로 하고 있습니다.
  • Terraform은 배포 프로젝트에서 CI를 통해 실행되며, 서비스 프로젝트에서 다운스트림 파이프라인으로 트리거됩니다.
  • 우리는 배포 프로젝트의 GitLab Terraform 상태 백엔드에 Terraform 상태를 저장합니다.

사용자가 Reconciler와의 상호 작용은 서비스 프로젝트의 CI 설정에 포함된 버전 잠금 CI 작업인 ci-tasks/service-project/runway.yml을 통해 중재됩니다.

런타임

런타임은 실제로 서비스 워크로드를 예약하고 실행하는 것에 책임이 있습니다. Reconciler는 런타임을 대상으로 삼습니다. 런타임은 일정한 수준의 테넌트 격리를 갖춘 자동 확장되는 컴퓨팅 리소스를 제공할 것입니다. 선택적으로 워크로드에 도달할 수 있는 엔드포인트를 노출할 수도 있을 것입니다. 이 엔드포인트는 DNS 이름을 가지고 TLS 암호화될 것입니다.

  • 현재 Cloud Run을 기반으로 하고 있습니다.
  • 더 큰 유연성이 필요하다면 Knative이 가능한 마이그레이션 대상입니다.

서비스는 HTTP 포트를 노출해야 하며, 상태를 유지하지 않아야 합니다(인스턴스를 자동으로 확장할 수 있어야 함). 다른 실행 모델(예: 예약된 작업)도 향후 지원될 수 있습니다.

런타임에서 사용되는 이미지

Runway에서 배포된 이미지는 해당 서비스를 담당하는 팀이 빌드합니다. 그들은 원하는 방식으로 이미지를 빌드하고 서비스 프로젝트의 GitLab 컨테이너 레지스트리에 보관합니다. Runway 배포 프로세스의 일환으로 해당 이미지는 Cloud Run에서 사용되기 전에 GCP Artifact Registry로 미러링됩니다. 이는 두 가지 이유 때문입니다.

  1. Cloud Run은 GCP Artifact Registry에서만 이미지를 사용할 수 있습니다.
  2. 나중에(실수로) 이미지 태그가 변경되더라도 Runway 내에서 실행 중인 이미지에는 영향을 주지 않도록 합니다.

GCP 프로젝트 레이아웃

Runway은 현재 세 가지 환경(dev, staging, production)을 기반으로 한 공유 GCP 프로젝트를 사용합니다. 이러한 GCP 프로젝트는 다음과 같습니다.

  • Dev: runway-dev-527768b3 (IT HackyStack에서 관리)
  • Staging: gitlab-runway-staging (reliability에서 관리)
  • Production: gitlab-runway-production (reliability에서 관리)

Runway에서 사용하는 문서 및 스키마

Runway가 작동하려면 두 가지 JSON/YAML 문서가 사용됩니다.

  1. Runway Inventory Model. 이 문서는 현재 Runway에 온보딩된 서비스 프로젝트를 다룹니다. 여기에서 찾을 수 있습니다. 문서를 검증하는 데 사용된 스키마는 여기에 있습니다. 이 문서 스키마에 대한 하위 호환성은 보장되지 않습니다. 이는 Runway 팀 내부에서만 사용되기 때문에 하나의 문서만 실제로 Runway를 위해 사용됩니다.

  2. Runway 서비스 모델. 이는 사용자가 Runway에 필요한 구성을 전달하는 데 사용됩니다. 이는 사용자의 서비스 프로젝트 내에 .runway/runway.yml에 위치합니다. 여기에서 예가 있습니다. 문서를 검증하는 데 사용된 스키마는 여기에 있습니다. 모델에 대한 변경 및 개선을 계속 진행할 예정이지만, 동일한 kind/apiVersion 내에서 모델에 대한 모든 변경은 하위 호환성이 있어야 합니다. 파괴적인 변경을 하기 위해서는 새로운 apiVersion의 스키마가 출시될 것입니다. 전반적인 목표는 Kubernetes 모델에서 API 변경을 수행하는 방법을 따르는 것입니다.

또한 Runway 사용자가 GitLab CI를 통해 자동화된 배포를 위해 사용하는 GitLab CI 템플릿이 있습니다. 사용자들은 Renovate bot과 같은 도구를 사용하여 CI 템플릿 및 사용 중인 Runway 버전이 최신 상태인지 확인할 수 있습니다. Runway 팀은 모든 릴리스 된 Runway 버전을 지원할 것이며, 보안 문제가 식별되었을 때에는 예외로 처리됩니다. 이럴 경우 Runway 사용자는 수정 사항을 포함한 Runway 버전으로 가능한 빨리 업데이트해야 합니다(알림을 받은 후로 가능한 빨리).

시크릿 관리

시크릿 관리를 위해 우리는 기존 HashiCorp Vault 설정과 통합을 목표로 합니다. 우리는 Vault에서 시크릿을 Runtime이 가장 잘 통합되는 시크릿 저장소로 동기화할 것입니다. Cloud Run의 경우 Google 시크릿 매니저를 사용할 것이고, Kubernetes의 경우 외부 시크릿을 사용하여 Kubernetes 시크릿 오브젝트로 동기화할 것입니다.

다음은 Vault 내의 시크릿이 Runway를 통해 사용되기 위한 제안된 설정을 보여주는 고수준 다이어그램입니다. 일반 아이디어는 Vault 내에 최상위 네임스페이스 (/runway)가 만들어지며, 여기에는 다음과 같은 롤 및 정책이 적용될 것입니다:

  • Runway 팀 멤버는 해당 네임스페이스에 대한 완전한 권한을 갖습니다.
  • CI에서 실행되는 runway 프로비저너는 runway/env/$environment/service에서 새로운 서비스 네임스페이스를 생성/수정/삭제할 수 있습니다. 현재 필요한 환경은 dev, staging, production입니다.
  • Runway reconciler 서비스 어카운트 및 GitLab 팀 멤버는 배포를 위해 시크릿을 읽기 위해 runway/env/$environment/service/$runway_service_id에 대한 읽기 전용 액세스 권한이 필요합니다.
  • Runway reconciler는 Vault의 시크릿을 Google 시크릿 매니저로 미러링하여 Cloud Run에서 네이티브 시크릿 통합을 통해 사용될 수 있도록 합니다.

Runway Vault 아키텍처

다이어그램 출처

Identity Management, Authentication, Authorization across Runway Components

Runway의 목표는 Runway 구성 요소 내에서 장기간 사용되는 시크릿 또는 토큰에 의존하지 않는 것입니다. 이를 위해 Runway의 모든 부분이 서로 다음과 같은 방법으로 인증됩니다.

서비스 프로젝트에서 runway 배포 프로젝트로

이는 GitLab 하류 파이프라인 트리거에 의해 처리됩니다. 따라서 모든 권한은 GitLab 자체에서 처리됩니다(GitLab API 호출은 단명한 CI_JOB_TOKEN을 사용). 배포 프로젝트와 서비스 프로젝트 간의 API 호출에서 권한이 모두 GitLab 내에서 처리됩니다 (CI_JOB_TOKEN 허용 목록을 사용하여 API 호출에서 환경을 업데이트하는 것과 같은 작업을 허용).

배포 프로젝트에서 GCP 클라우드로

배포 프로젝트의 GitLab CI 파이프라인은 Runway 서비스의 GCP 클라우드 자원을 프로비저닝하고 변경하는 역할을 맡습니다. 이 작업은 Runway 프로비저너에서 수행한 설정을 활용하여 OpenID Connnect를 통해 수행되며, 배포 프로젝트가 제한된 권한을 갖는 GCP 서비스 어카운트로 인증되도록 합니다.

Reconciler에서 GCP 클라우드로

Reconciler(runwayctlterraform을 감싸고 실행)는 배포 프로젝트의 GitLab CI 내에서 실행됩니다. 이 작업은 각 Runway 서비스를 위해 설정된 특정 서비스 어카운트를 사용하며, 해당 작업에 필요한 권한만을 갖습니다. 이 인증은 앞서 설명한 대로 GitLab CI에서 처리됩니다.

관측성

관측성은 별도의 청사진에서 다루어질 것입니다.

대체 솔루션

Unmanaged GCP 프로젝트

관리되지 않는 플랫폼을 구축하는 대신 팀에게 GCP 프로젝트를 제공하고 그들이 자유롭게 사용하도록 할 수 있습니다. 실제로 몇 가지 서비스에 대해서는 이미 이러한 접근을 채택했습니다. 이 접근 방식에는 몇 가지 문제점이 있습니다:

  • 인프라스트럭처-애스코드(IaC) 부재: 기존 구조가 없으면 팀은 Terraform 또는 유사한 IaC 도구를 사용하지 않고 UI를 통해 클라우드 자원을 생성할 가능성이 있습니다. 이로 인해 변경 사항을 감사하고 여러 환경에 인프라를 다시 프로비저닝하기가 매우 어려워집니다.
  • 확산: 합리적이고 안전한 기본값이 없으면 각 서비스마다 자체의 배포 방법을 개발해야 합니다. 또한, 누구든 해당 서비스에 기여하기가 매우 어려워집니다.
  • 비확장성 설계: 임의의 VM을 만들 수 있기 때문에 수평 확장에 대한 고려 없이 단일 장비에 서비스를 함께 두는 유혹이 생길 수 있습니다.

관리되지 않는 Kubernetes 클러스터 또는 네임스페이스

사용자 정의 플랫폼을 구축하는 대신 Kubernetes를 플랫폼으로 삼고, 팀에게 자체 클러스터 또는 공유 클러스터의 자체 네임스페이스를 사용할 수 있도록 할 수 있습니다.

이러한 접근 방식에는 몇 가지 도전 과제가 있습니다:

  • GKE의 기본 비용: 관리비용은 월별 $70입니다. 여러 환경에서 많은 서비스를 운영하려는 경우, 특정 서비스별로 별도의 클러스터를 사용하는 것은 비효율적일 수 있습니다. 이는 공유 클러스터를 사용하고자 하는 것을 시사합니다.
  • 개발자 친화성: Kubernetes는 인기를 얻고 있지만, 가장 개발자 친화적인 인터페이스는 아닙니다. 다루어야 할 개념과 추상화가 많습니다. 좀 더 좁은 인터페이스인 “이 컨테이너를 배포하고 포트를 제공해주세요”는 유연성은 적지만 진입 장벽이 훨씬 낮습니다.

Runway가 더 많은 이 방향으로 진화할 수 있다고 생각됩니다.

서비스 당 GCP 프로젝트

GCP 프로젝트는 리소스 격리와 비용 할당에 대한 매우 견고한 기반을 제공합니다. 이상적으로는 그러한 모델을 활용할 것입니다. 그러나 공유 리소스의 부족은 각 서비스 당 상당한 기본 비용으로 이어집니다.

만약 우리가 GKE를 활용하려 한다면, 월 70달러의 클러스터 당 관리 비용은 서비스의 최소 비용이 140달러가 될 것으로 예상됩니다. 소규모 서비스에 대해선 이는 비용 효율적이지 않습니다.

고려할 대안은 GKE 없이 Kubernetes를 실행하는 것입니다. 이 경우에는 Kubernetes 배포를 직접 관리해야 하며, GKE와의 차이점을 계속해서 파악해야 합니다.

또 다른 고려할 대안은 작은 서비스에는 Cloud Run을 사용하고, 큰 서비스에는 GKE를 사용하는 것입니다. 그러나 이는 Cloud Run과의 호환성 유지가 필요하며, 기능 면에서는 최소한의 공통 분모로 제한될 수 있습니다.

어느 정도 혼합 방식도 가능합니다(예: Runway 서비스에는 별도의 프로젝트를 할당), 하지만 공유 리소스가 있는 한, 우리는 리소스 당 사용 권한 제어를 구현해야 합니다.