객체 저장소

Tier: Free, Premium, Ultimate Offering: Self-Managed

GitLab은 다양한 유형의 데이터를 보유하기 위한 객체 저장소 서비스를 지원합니다. 이는 일반적으로 NFS보다 더 우수하며 대규모 설정에서 성능이 우수하고 신뢰성이 있으며 확장 가능하기 때문에 권장됩니다.

객체 저장소를 구성하려면 두 가지 옵션이 있습니다:

데이터를 로컬로 저장하면 객체 저장소로 이관하는 방법을 확인하십시오.

지원되는 객체 저장소 제공업체

GitLab은 Fog 라이브러리와 긴밀히 통합되어 있으므로 GitLab에서 사용할 수있는 제공업체를 확인할 수 있습니다.

구체적으로 GitLab은 다음과 같은 여러 객체 저장소 제공업체에서 고객 및 고객에 의해 테스트되었습니다.

모든 객체 유형을 위한 단일 저장소 연결 구성 (통합된 형식)

CI 아티팩트, LFS 파일 및 업로드 첨부 파일과 같은 대부분의 객체 유형은 여러 버킷에 단일 자격 증명을 지정하여 객체 저장소에 저장할 수 있습니다.

통합된 형식을 사용하여 객체 저장소를 구성하는 것에는 여러 가지 이점이 있습니다:

통합된 형식이 사용될 때, 직접 업로드가 자동적으로 활성화됩니다. 따라서 다음의 제공업체만 사용할 수 있습니다:

통합된 형식 구성은 백업이나 Mattermost에는 사용할 수 없습니다. 백업은 별도로 서버 측 암호화로 구성할 수 있습니다. 지원되는 객체 저장소 유형에 대한 완전한 목록은 테이블에서 확인하십시오.

통합된 형식은 모든 객체 유형에 대한 객체 저장소를 활성화합니다. 모든 버킷이 지정되지 않은 경우 다음과 같은 오류가 표시될 수 있습니다:

<객체 유형>에 대한 객체 저장소에는 버킷을 지정해야합니다

특정 객체 유형에 대해 로컬 저장소를 사용하려는 경우 특정 기능에 대한 객체 저장소 비활성화를 할 수 있습니다.

공통 매개변수 구성

통합된 형식에서 object_store 섹션은 일반적인 매개변수를 정의합니다.

설정 설명
enabled 객체 저장소를 활성화 또는 비활성화합니다.
proxy_download 모든 파일을 프록시하는 것을 활성화하려면 true로 설정합니다. 이 옵션은 클라이언트가 모든 데이터를 프록시하는 대신 원격 저장소에서 직접 다운로드할 수 있도록하여 이직 트래픽을 줄일 수 있습니다.
connection 아래에 설명 된 여러 연결 옵션.
storage_options 서버 측 암호화와 같은 새로운 객체를 저장할 때 사용할 옵션. GitLab 13.3에서 도입되었습니다.
objects 객체별 구성.

예를 들어, 통합된 형식과 Amazon S3를 사용하는 방법을 참조하십시오.

각 객체의 매개변수 구성

각 객체 유형은 저장될 버킷 이름을 적어도 정의해야 합니다.

다음 표는 사용 가능한 유효한 objects를 나열합니다.

유형 설명
artifacts CI artifacts
external_diffs Merge request diffs
uploads User uploads
lfs Git Large File Storage objects
packages Project packages (for example, PyPI, Maven, or NuGet)
dependency_proxy Dependency Proxy
terraform_state Terraform state files
pages Pages

각 객체 유형 내에서 세 가지 매개변수를 정의할 수 있습니다:

설정 필요 여부 설명
bucket Yes* 객체 유형의 버킷 이름. enabledfalse로 설정된 경우 필요하지 않음.
enabled No 공통 매개변수를 재정의합니다.
proxy_download No 공통 매개변수를 재정의합니다.

예를 들어, 통합된 형식 및 Amazon S3 사용 방법을 참조하세요.

특정 기능에 대해 객체 저장 비활성화

위에서 볼 수 있듯이, enabled 플래그를 false로 설정하여 특정 유형에 대한 객체 저장을 비활성화할 수 있습니다. 예를 들어, CI artifacts의 객체 저장을 비활성화하려면:

gitlab_rails['object_store']['objects']['artifacts']['enabled'] = false

기능 전체적으로 비활성화된 경우 버킷은 필요하지 않습니다. 이 설정으로 CI artifacts를 비활성화하면 버킷이 필요하지 않습니다.

gitlab_rails['artifacts_enabled'] = false

각 객체 유형을 정의하기위한 각자의 저장 연결 구성(저장 유형별 형식)

저장 유형별 형식에서는 각 객체가 자체 객체 저장 연결과 구성을 정의합니다. GitLab 13.2 이상을 사용하는 경우 통합된 형식으로 전환해야 합니다.

암호화된 S3 버킷은 비통합된 형식으로는 지원되지 않습니다. 또한, 사용할 경우 ETag 불일치 오류가 발생할 수 있습니다.

참고: 저장 유형별 형식에서는 공유 폴더가 필요없기 때문에 직접 업로드가 기본이 될 수 있습니다.

GitLab 13.1 이전에 객체 저장을 구성하거나, 통합된 형식에서 지원되지 않는 저장 유형의 경우 다음 가이드를 참조하세요:

객체 저장 유형 통합된 형식으로 지원됩니까?
Secure Files No
백업 No
컨테이너 레지스트리 (optional feature) No
Mattermost No
자동 확장 러너 캐싱 (optional for improved performance) No
작업 artifacts 포함 아카이브 작업 로그 Yes
LFS objects Yes
업로드 Yes
병합 요청 diffs Yes
패키지 (optional feature) Yes
Dependency Proxy (optional feature) Yes
Terraform 상태 파일 Yes
페이지 콘텐츠 Yes

연결 설정 구성

총괄 및 저장소별 형식은 연결을 구성해야 합니다. 다음 섹션에서는 connection 설정에 사용할 수 있는 매개변수를 설명합니다.

Amazon S3

연결 설정은 fog-aws에서 제공하는 것과 일치합니다:

설정 설명 기본값
provider 호환되는 호스트의 경우 항상 AWS. AWS
aws_access_key_id AWS 자격증명 또는 호환 가능.  
aws_secret_access_key AWS 자격증명 또는 호환 가능.  
aws_signature_version 사용할 AWS 서명 버전. 2 또는 4가 유효한 옵션입니다. Digital Ocean Spaces 및 기타 제공업체는 2가 필요할 수 있습니다. 4
enable_signature_v4_streaming AWS v4 서명을 사용하여 HTTP 청크 전송을 활성화하려면 true로 설정합니다. Oracle Cloud S3는 이 값을 false로 설정해야 합니다. true
region AWS 지역.  
host 사용하지 않을 것: 대신 endpoint를 사용합니다. AWS를 사용하지 않을 때 S3 호환 호스트. 예를 들어 localhost 또는 storage.example.com. HTTPS 및 포트 443이 가정됩니다. s3.amazonaws.com
endpoint http://127.0.0.1:9000과 같은 URL을 입력하여 MinIO와 같은 S3 호환 서비스를 구성하는 경우에 사용할 수 있습니다. host보다 우선합니다. 총괄 형식에는 항상 endpoint를 사용하십시오. (옵션)
path_style bucket_name.host/object 스타일의 경로 대신 host/bucket_name/object 스타일의 경로를 사용하려면 true로 설정합니다. MinIO를 사용하는 경우 true로 설정합니다. AWS S3를 사용하는 경우 false로 유지합니다. false
use_iam_profile 액세스 키 대신 IAM 프로필을 사용하려면 true로 설정합니다. false
aws_credentials_refresh_threshold_seconds 임시 자격증명을 사용할 때 자동 새로 고침 임계값을 초 단위로 설정합니다. 15

Amazon 인스턴스 프로필 사용

객체 저장 구성에서 AWS 액세스 및 비밀 키를 제공하는 대신 GitLab을 구성하여 Amazon Identity Access and Management (IAM) 역할을 설정할 수 있습니다. 이를 사용하면 GitLab이 S3 버킷에 접근할 때마다 임시 자격증명을 가져오므로 구성에 하드코딩된 값이 필요하지 않습니다.

사전 요구 사항:

인스턴스 프로필 설정 방법:

  1. 필요한 권한이 있는 IAM 역할을 만듭니다. 다음 예제는 test-bucket이라는 S3 버킷을 위한 역할입니다:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "VisualEditor0",
                "Effect": "Allow",
                "Action": [
                    "s3:PutObject",
                    "s3:GetObject",
                    "s3:DeleteObject"
                ],
                "Resource": "arn:aws:s3:::test-bucket/*"
            }
        ]
    }
    
  2. 이 역할을 EC2 인스턴스에 연결합니다.
  3. GitLab 구성 옵션 use_iam_profiletrue로 설정합니다.

암호화된 S3 버킷

인스턴스 프로필이나 총괄 형식으로 구성된 경우 GitLab Workhorse는 기본적으로 활성화된 SSE-S3 또는 SSE-KMS 암호화가 설정된 S3 버킷으로 파일을 올바르게 업로드합니다. AWS KMS 키 및 SSE-C 암호화는 모든 요청에 암호화 키를 보내야 하므로 지원되지 않습니다.

서버 측 암호화 헤더

S3 버킷에 기본 암호화를 설정하는 것은 암호화를 활성화하는 가장 쉬운 방법입니다만, 아마도 버킷 정책을 설정하여 암호화된 객체만 업로드되도록 보장하고 싶을 것입니다. 이를 위해 GitLab을 구성하여 storage_options 구성 섹션에서 적절한 암호화 헤더를 보내도록 설정해야 합니다:

설정 설명
server_side_encryption 암호화 모드(AES256 또는 aws:kms).
server_side_encryption_kms_key_id Amazon 리소스 이름. server_side_encryption에서 aws:kms를 사용할 때에만 필요합니다. Amazon KMS 암호화 사용 문서를 참조하세요.

기본 암호화와 마찬가지로, 이러한 옵션은 Workhorse S3 클라이언트가 활성화된 경우에만 작동합니다. 다음 두 조건 중 하나를 충족해야 합니다:

  • 연결 설정에서 use_iam_profiletrue로 설정되어 있어야 합니다.
  • 통합 형태가 사용 중이어야 합니다.

서버 측 암호화 헤더를 활성화하지 않고 작업할 경우 ETag 불일치 오류가 발생합니다.

Oracle Cloud S3

Oracle Cloud S3에서 다음 설정을 사용해야 합니다:

설정
enable_signature_v4_streaming false
path_style true

enable_signature_v4_streamingtrue로 설정된 경우 production.log에서 다음과 같은 오류가 발생할 수 있습니다:

STREAMING-AWS4-HMAC-SHA256-PAYLOAD을(를) 지원하지 않습니다

Google Cloud Storage (GCS)

GCS에 대한 유효한 연결 매개변수는 다음과 같습니다:

설정 설명 예시
provider 제공자 이름. Google
google_project GCP 프로젝트 이름. gcp-project-12345
google_json_key_location JSON 키 경로. /path/to/gcp-project-12345-abcde.json
google_json_key_string JSON 키 문자열. { "type": "service_account", "project_id": "example-project-382839", ... }
google_application_default Google Cloud Application Default Credentials를 사용하여 서비스 계정 자격 증명을 찾으려면 true로 설정하세요.  

GitLab은 google_json_key_location, 그런 다음 google_json_key_string, 마지막으로 google_application_default의 값을 읽습니다. 이러한 설정 중 가장 먼저 값이 있는 것을 사용합니다.

서비스 계정은 버킷에 액세스할 수 있어야 합니다. 자세한 내용은 Cloud Storage 인증 문서를 참조하세요.

참고: Cloud Key Management Service (KMS)를 사용하여 버킷 암호화는 지원되지 않으며 ETag 불일치 오류가 발생합니다.

GCS 예시

Linux 패키지 설치의 경우, 통합 형태의 connection 설정의 예시는 다음과 같습니다:

gitlab_rails['object_store']['connection'] = {
  'provider' => 'Google',
  'google_project' => '<GOOGLE PROJECT>',
  'google_json_key_location' => '<FILENAME>'
}

ADC를 사용한 GCS 예시

Google Cloud Application Default Credentials (ADC)는 일반적으로 기본 서비스 계정을 사용하기 위한 GitLab과 함께 사용됩니다. 이를 통해 인스턴스에 자격 증명을 제공할 필요가 없어집니다. 예를 들어, 통합 형태에서:

gitlab_rails['object_store']['connection'] = {
  'provider' => 'Google',
  'google_project' => '<GOOGLE PROJECT>',
  'google_application_default' => true
}

ADC를 사용하는 경우:

  • 사용하는 서비스 계정에 iam.serviceAccounts.signBlob 권한이 있어야 합니다. 일반적으로 이 작업은 서비스 계정에 Service Account Token Creator 역할을 부여함으로써 수행됩니다.
  • 가상 머신이 Google Cloud API에 액세스할 수 있도록 올바른 액세스 범위를 가지고 있어야 합니다. 머신에 올바른 범위가 없는 경우 오류 로그에 다음과 같이 나타날 수 있습니다:

    Google::Apis::ClientError (insufficientPermissions: Request had insufficient authentication scopes.)
    

Azure Blob storage

  • 소개 : GitLab 13.4에서 소개되었습니다.

Azure는 blob의 모음을 나타내는 데에 컨테이너라는 용어를 사용하지만, GitLab은 버킷이라는 용어를 표준화합니다. Azure 컨테이너 이름을 버킷 설정에 구성해야 합니다.

Azure Blob storage는 하나의 자격 증명 세트를 사용하여 여러 컨테이너에 액세스하기 때문에 통합된 형식으로만 사용할 수 있습니다. 저장소별 형식은 지원되지 않습니다. 자세한 내용은 통합된 형식으로의 전환 방법을 참조하십시오.

다음은 Azure의 유효한 연결 매개변수입니다. 자세한 내용은 Azure Blob Storage 문서를 참조하십시오.

설정 설명 예시
provider 제공자 이름 AzureRM
azure_storage_account_name 저장소에 액세스하는 데 사용되는 Azure Blob Storage 계정의 이름 azuretest
azure_storage_access_key 컨테이너에 액세스하는 데 사용되는 저장소 계정 액세스 키. 일반적으로 base64로 인코딩된 512비트 암호화 키인 비밀입니다. czV2OHkvQj9FKEgrTWJRZVRoV21ZcTN0Nnc5eiRDJkYpSkBOY1JmVWpYbjJy\nNHU3eCFBJUQqRy1LYVBkU2dWaw==\n
azure_storage_domain Azure Blob Storage API에 연락하는 데 사용되는 도메인 이름(옵션). 기본값은 blob.core.windows.net입니다. Azure China, Azure Germany, Azure US Government 또는 사용자 정의 Azure 도메인을 사용하는 경우 이를 설정하십시오. blob.core.windows.net
  • Linux 패키지 설치의 경우, 다음은 통합된 형식의 connection 설정의 예입니다.

    gitlab_rails['object_store']['connection'] = {
      'provider' => 'AzureRM',
      'azure_storage_account_name' => '<AZURE STORAGE ACCOUNT NAME>',
      'azure_storage_access_key' => '<AZURE STORAGE ACCESS KEY>',
      'azure_storage_domain' => '<AZURE STORAGE DOMAIN>'
    }
    
  • 직접 컴파일한 설치의 경우 Workhorse도 Azure 자격 증명으로 구성해야 합니다. Linux 패키지 설치의 경우 이 작업은 이전 설정에서 자동으로 이루어지기 때문에 필요하지 않습니다.

    1. /home/git/gitlab-workhorse/config.toml 파일을 편집하고 다음을 추가하거나 수정하십시오.

      [object_storage]
        provider = "AzureRM"
           
      [object_storage.azurerm]
        azure_storage_account_name = "<AZURE STORAGE ACCOUNT NAME>"
        azure_storage_access_key = "<AZURE STORAGE ACCESS KEY>"
      

    사용자 지정 Azure 저장소 도메인을 사용하는 경우 Workhorse 구성에서 azure_storage_domain반드시 설정할 필요가 없습니다. 이 정보는 GitLab Rails와 Workhorse 간의 API 호출에서 교환됩니다.

Storj Gateway (SJ)

note
Storj Gateway는 멀티스레드 복사를 지원하지 않습니다 (UploadPartCopy 참조). 구현이 계획되어 있으나, 완료될 때까지 멀티스레드 복사를 비활성화해야 합니다.

Storj Network는 S3 호환 API 게이트웨이를 제공합니다. 다음은 구성 예입니다.

gitlab_rails['object_store']['connection'] = {
  'provider' => 'AWS',
  'endpoint' => 'https://gateway.storjshare.io',
  'path_style' => true,
  'region' => 'eu1',
  'aws_access_key_id' => 'ACCESS_KEY',
  'aws_secret_access_key' => 'SECRET_KEY',
  'aws_signature_version' => 2,
  'enable_signature_v4_streaming' => false
}

서명 버전은 반드시 2여야 합니다. v4를 사용하면 HTTP 411 Length Required 오류가 발생합니다. 자세한 내용은 이슈 #4419를 참조하십시오.

Hitachi Vantara HCP

note
HCP에 대한 연결은 테넌트 URL 대신 네임스페이스로 설정된 버킷 경로에 대한 SigntureDoesNotMatch - The request signature we calculated does not match the signature you provided. Check your HCP Secret Access key and signing method. 오류가 반환될 수 있습니다.

HCP는 S3 호환 API를 제공합니다. 다음은 구성 예입니다.

gitlab_rails['object_store']['connection'] = {
  'provider' => 'AWS',
  'endpoint' => 'https://<테넌트_엔드포인트>',
  'path_style' => true,
  'region' => 'eu1',
  'aws_access_key_id' => 'ACCESS_KEY',
  'aws_secret_access_key' => 'SECRET_KEY',
  'aws_signature_version' => 4,
  'enable_signature_v4_streaming' => false
}

# <namespace_name/bucket_name> 형식 예시
gitlab_rails['object_store']['objects']['artifacts']['bucket'] = '<네임스페이스_이름>/<버킷_이름>'

통합 형식 및 Amazon S3 사용 예시

다음 예시는 AWS S3를 사용하여 모든 지원되는 서비스에 대한 객체 저장을 활성화합니다.

Linux package (Omnibus)
  1. /etc/gitlab/gitlab.rb를 편집하고 원하는 값으로 대체하여 다음 줄을 추가합니다.

    # 통합 객체 저장 구성
    gitlab_rails['object_store']['enabled'] = true
    gitlab_rails['object_store']['proxy_download'] = true
    gitlab_rails['object_store']['connection'] = {
      'provider' => 'AWS',
      'region' => 'eu-central-1',
      'aws_access_key_id' => '<AWS_ACCESS_KEY_ID>',
      'aws_secret_access_key' => '<AWS_SECRET_ACCESS_KEY>'
    }
    # 선택 사항: 서버 측 암호화가 필요한 경우에만 다음 줄이 필요합니다.
    gitlab_rails['object_store']['storage_options'] = {
      'server_side_encryption' => '<AES256 또는 aws:kms>',
      'server_side_encryption_kms_key_id' => '<arn:aws:kms:xxx>'
    }
    gitlab_rails['object_store']['objects']['artifacts']['bucket'] = 'gitlab-artifacts'
    gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = 'gitlab-mr-diffs'
    gitlab_rails['object_store']['objects']['lfs']['bucket'] = 'gitlab-lfs'
    gitlab_rails['object_store']['objects']['uploads']['bucket'] = 'gitlab-uploads'
    gitlab_rails['object_store']['objects']['packages']['bucket'] = 'gitlab-packages'
    gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = 'gitlab-dependency-proxy'
    gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = 'gitlab-terraform-state'
    gitlab_rails['object_store']['objects']['pages']['bucket'] = 'gitlab-pages'
    

    AWS IAM 프로필을 사용하는 경우 AWS 액세스 키 및 비밀 액세스 키/값 쌍을 생략합니다. 예:

    gitlab_rails['object_store']['connection'] = {
      'provider' => 'AWS',
      'region' => 'eu-central-1',
      'use_iam_profile' => true
    }
    
  2. 파일을 저장하고 GitLab을 재구성합니다.

    sudo gitlab-ctl reconfigure
    
Helm chart (Kubernetes)
  1. Kubernetes Secret로 사용될 object_storage.yaml 파일에 다음 내용을 추가합니다.

    provider: AWS
    region: us-east-1
    aws_access_key_id: <AWS_ACCESS_KEY_ID>
    aws_secret_access_key: <AWS_SECRET_ACCESS_KEY>
    

    AWS IAM 프로필을 사용하는 경우 AWS 액세스 키 및 비밀 액세스 키/값 쌍을 생략합니다. 예:

    provider: AWS
    region: us-east-1
    use_iam_profile: true
    
  2. Kubernetes Secret를 생성합니다.

    kubectl create secret generic -n <namespace> gitlab-object-storage --from-file=connection=object_storage.yaml
    
  3. Helm 값들을 내보냅니다.

    helm get values gitlab > gitlab_values.yaml
    
  4. gitlab_values.yaml 파일을 편집합니다.

    global:
      appConfig:
        object_store:
          enabled: false
          proxy_download: true
          storage_options: {}
            # server_side_encryption:
            # server_side_encryption_kms_key_id
          connection:
            secret: gitlab-object-storage
        lfs:
          enabled: true
          proxy_download: true
          bucket: gitlab-lfs
          connection: {}
            # secret:
            # key:
        artifacts:
          enabled: true
          proxy_download: true
          bucket: gitlab-artifacts
          connection: {}
            # secret:
            # key:
        uploads:
          enabled: true
          proxy_download: true
          bucket: gitlab-uploads
          connection: {}
            # secret:
            # key:
        packages:
          enabled: true
          proxy_download: true
          bucket: gitlab-packages
          connection: {}
        externalDiffs:
          enabled: true
          when:
          proxy_download: true
          bucket: gitlab-mr-diffs
          connection: {}
        terraformState:
          enabled: true
          bucket: gitlab-terraform-state
          connection: {}
        ciSecureFiles:
          enabled: true
          bucket: gitlab-ci-secure-files
          connection: {}
        dependencyProxy:
          enabled: true
          proxy_download: true
          bucket: gitlab-dependency-proxy
          connection: {}
    
  5. 파일을 저장하고 새로운 값을 적용합니다.

    helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
    
Docker
  1. docker-compose.yml을 편집합니다.

    version: "3.6"
    services:
      gitlab:
        environment:
          GITLAB_OMNIBUS_CONFIG: |
            # 통합 객체 저장 구성
            gitlab_rails['object_store']['enabled'] = true
            gitlab_rails['object_store']['proxy_download'] = true
            gitlab_rails['object_store']['connection'] = {
              'provider' => 'AWS',
              'region' => 'eu-central-1',
              'aws_access_key_id' => '<AWS_ACCESS_KEY_ID>',
              'aws_secret_access_key' => '<AWS_SECRET_ACCESS_KEY>'
            }
            # 선택 사항: 서버 측 암호화가 필요한 경우에만 다음 줄이 필요합니다.
            gitlab_rails['object_store']['storage_options'] = {
              'server_side_encryption' => '<AES256 또는 aws:kms>',
              'server_side_encryption_kms_key_id' => '<arn:aws:kms:xxx>'
            }
            gitlab_rails['object_store']['objects']['artifacts']['bucket'] = 'gitlab-artifacts'
            gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = 'gitlab-mr-diffs'
            gitlab_rails['object_store']['objects']['lfs']['bucket'] = 'gitlab-lfs'
            gitlab_rails['object_store']['objects']['uploads']['bucket'] = 'gitlab-uploads'
            gitlab_rails['object_store']['objects']['packages']['bucket'] = 'gitlab-packages'
            gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = 'gitlab-dependency-proxy'
            gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = 'gitlab-terraform-state'
            gitlab_rails['object_store']['objects']['ci_secure_files']['bucket'] = 'gitlab-ci-secure-files'
            gitlab_rails['object_store']['objects']['pages']['bucket'] = 'gitlab-pages'
    

    AWS IAM 프로필을 사용하는 경우 AWS 액세스 키 및 비밀 액세스 키/값 쌍을 생략합니다. 예:

    gitlab_rails['object_store']['connection'] = {
      'provider' => 'AWS',
      'region' => 'eu-central-1',
      'use_iam_profile' => true
    }
    
  2. 파일을 저장하고 GitLab을 재시작합니다.

    docker compose up -d
    
Self-compiled (source)
  1. /home/git/gitlab/config/gitlab.yml을 편집하고 다음 줄을 추가하거나 수정합니다.

    production: &base
      object_store:
        enabled: true
        proxy_download: true
        connection:
          provider: AWS
          aws_access_key_id: <AWS_ACCESS_KEY_ID>
          aws_secret_access_key: <AWS_SECRET_ACCESS_KEY>
          region: eu-central-1
        storage_options:
          server_side_encryption: <AES256 또는 aws:kms>
          server_side_encryption_key_kms_id: <arn:aws:kms:xxx>
        objects:
          artifacts:
            bucket: gitlab-artifacts
          external_diffs:
            bucket: gitlab-mr-diffs
          lfs:
            bucket: gitlab-lfs
          uploads:
            bucket: gitlab-uploads
          packages:
            bucket: gitlab-packages
          dependency_proxy:
            bucket: gitlab-dependency-proxy
          terraform_state:
            bucket: gitlab-terraform-state
          ci_secure_files:
            bucket: gitlab-ci-secure-files
          pages:
            bucket: gitlab-pages
    

    AWS IAM 프로필을 사용하는 경우 AWS 액세스 키 및 비밀 액세스 키/값 쌍을 생략합니다. 예:

    connection:
      provider: AWS
      region: eu-central-1
      use_iam_profile: true
    
  2. /home/git/gitlab-workhorse/config.toml을 편집하고 다음 줄을 추가하거나 수정합니다.

    [object_storage]
      provider = "AWS"
    
    [object_storage.s3]
      aws_access_key_id = "<AWS_ACCESS_KEY_ID>"
      aws_secret_access_key = "<AWS_SECRET_ACCESS_KEY>"
    

    AWS IAM 프로필을 사용하는 경우 AWS 액세스 키 및 비밀 액세스 키/값 쌍을 생략합니다. 예:

    [object_storage.s3]
      use_iam_profile = true
    
  3. 파일을 저장하고 GitLab을 재시작합니다.

    # systemd를 실행 중인 시스템의 경우
    sudo systemctl restart gitlab.target
    
    # SysV init를 실행 중인 시스템의 경우
    sudo service gitlab restart
    

객체 스토리지로 이전

기존 로컬 데이터를 객체 스토리지로 이전하려면 다음 가이드를 참조하세요:

통합 형태로 전환

GitLab 13.2 이전:

  • CI/CD 아티팩트, LFS 파일, 그리고 업로드 첨부 파일과 같은 모든 유형의 객체에 대한 객체 스토리지 구성을 독립적으로 설정해야 했습니다.
  • 암호 및 엔드포인트 URL과 같은 객체 저장소 연결 매개변수를 각 유형마다 중복으로 설정해야 했습니다.

예를 들어, Linux 패키지 설치에는 다음과 같은 구성이 있을 수 있습니다:

# 원본 객체 스토리지 구성
gitlab_rails['artifacts_object_store_enabled'] = true
gitlab_rails['artifacts_object_store_direct_upload'] = true
gitlab_rails['artifacts_object_store_proxy_download'] = true
gitlab_rails['artifacts_object_store_remote_directory'] = 'artifacts'
gitlab_rails['artifacts_object_store_connection'] = { 'provider' => 'AWS', 'aws_access_key_id' => 'access_key', 'aws_secret_access_key' => 'secret' }
gitlab_rails['uploads_object_store_enabled'] = true
gitlab_rails['uploads_object_store_direct_upload'] = true
gitlab_rails['uploads_object_store_proxy_download'] = true
gitlab_rails['uploads_object_store_remote_directory'] = 'uploads'
gitlab_rails['uploads_object_store_connection'] = { 'provider' => 'AWS', 'aws_access_key_id' => 'access_key', 'aws_secret_access_key' => 'secret' }

이는 GitLab에서 객체를 서로 다른 클라우드 제공자에 걸쳐 저장할 수 있게 해주어 유연성을 제공하지만, 추가 복잡성과 불필요한 중복을 유발합니다. GitLab Rails와 Workhorse 구성 요소가 모두 객체 스토리지에 액세스해야 하는 것을 고려하면, 통합 형태는 자격 증명의 과도한 중복을 피합니다.

통합 형태는 원래 형태의 모든 라인이 제거된 경우에만 사용됩니다. 통합 형태로 이동하려면 원본 구성(예: artifacts_object_store_enabled 또는 uploads_object_store_connection)을 제거하세요.

개체를 다른 객체 스토리지 제공자로 이전

객체 스토리지에 저장된 GitLab 데이터를 다른 객체 스토리지 제공자로 이전해야 할 수 있습니다. 다음 단계는 Rclone을 사용하여 이 작업을 수행하는 방법을 보여줍니다.

이 단계들은 uploads 버킷을 옮기는 것을 전제로 하지만, 같은 프로세스가 다른 버킷에 대해서도 작동합니다.

준비 사항:

  • Rclone을 실행할 컴퓨터를 선택하세요. 이전하는 데이터의 양에 따라 Rclone이 오랜 시간 실행될 수 있으므로 절전 모드로 들어갈 수 있는 랩톱이나 데스크탑 컴퓨터를 사용하지 않는 것이 좋습니다. GitLab 서버를 사용하여 Rclone을 실행할 수 있습니다.
  1. 다운로드를 통해 Rclone을 설치하세요.
  2. 다음을 실행하여 Rclone을 구성하세요:

    rclone config
    

    구성 프로세스는 대화형입니다. 현재 데이터가 있는 객체 스토리지 제공자(old)와 이동할 제공자(new)를 적어도 두 개의 “원격”을 추가하세요.

  3. 이전 데이터를 읽을 수 있는지 확인하세요. 다음 예시는 uploads 버킷을 참조하지만, 사용 중인 버킷 이름이 다를 수 있습니다:

    rclone ls old:uploads | head
    

    이 명령은 현재 uploads 버킷에 저장된 개체들의 일부 목록을 출력해야 합니다. 에러가 발생하거나 목록이 비어 있다면 rclone config를 사용하여 Rclone 구성을 업데이트하세요.

  4. 초기 복사를 수행하세요. 이 단계에서는 GitLab 서버를 오프라인으로 두지 않아도 됩니다.

    rclone sync -P old:uploads new:uploads
    
  5. 처음 동기화가 완료되면, 새로운 객체 스토리지 제공자의 웹 UI나 명령줄 인터페이스를 사용하여 새 버킷에 객체가 있는지 확인하세요. 객체가 없거나 rclone sync 실행 중에 오류가 발생한다면 Rclone 구성을 확인하고 다시 시도하세요.

이전 위치에서 새 위치로 최소한 한 번의 성공적인 Rclone 복사를 완료한 후, 유지 보수 일정을 예약하고 GitLab 서버를 오프라인 상태로 전환하세요. 유지 보수 창을 통해 다음 작업을 수행해야 합니다:

  1. 사용자가 새 개체를 추가하지 못하도록 하는 것을 감안하여 최종 rclone sync를 수행하세요.
  2. GitLab 서버의 객체 스토리지 구성을 uploads에 대해 새 제공자를 사용하도록 업데이트하세요.

파일 시스템 저장소의 대안

만약 GitLab 구현을 확장하거나, 내고장성과 장애탈퇴용량을 추가하려 한다면, 블록이나 네트워크 파일 시스템에 대한 의존성을 제거해야 할 수 있습니다. 아래 추가 가이드를 참조하세요:

  1. git 사용자 홈 디렉터리가 로컬 디스크에 있는지 확인하세요.
  2. SSH 키의 데이터베이스 조회를 구성하여 공유 authorized_keys 파일이 필요 없도록 하세요.
  3. 작업 로그를 위한 로컬 디스크 사용을 방지하세요(job_logs.md#prevent-local-disk-usage).
  4. 로컬 저장소 사용 비활성화.

문제 해결

객체가 GitLab 백업에 포함되지 않음

백업 설명서에 언급된 대로 객체는 GitLab 백업에 포함되지 않습니다. 대신, 객체 스토리지 제공업체와 함께 백업을 활성화할 수 있습니다.

별도의 버킷 사용

각 데이터 유형에 대해 별도의 버킷 사용이 GitLab에서 권장하는 방법입니다. 이것은 GitLab이 저장하는 다양한 유형의 데이터 간에 충돌이 없도록 보장합니다. 이슈 292958에서는 단일 버킷 사용을 활성화하는 것을 제안합니다.

리눅스 패키지 및 자체 컴파일 설치에서는 단일 실제 버킷을 여러 가상 버킷으로 분할할 수 있습니다. 만약 객체 스토리지 버킷이 my-gitlab-objects라면, 업로드를 my-gitlab-objects/uploads, 아티팩트를 my-gitlab-objects/artifacts 등으로 설정할 수 있습니다. 이러한 애플리케이션은 이들이 별개의 버킷인 것처럼 작동합니다. 버킷 접두어의 사용은 Helm 백업과 올바르게 작동하지 않을 수 있습니다.

Helm 기반 설치에서는 복원을 다루기 위해 별도의 버킷이 필요합니다.

S3 API 호환성 문제

모든 S3 제공업체가 GitLab이 사용하는 Fog 라이브러리와 완전히 호환되지는 않습니다. 증상으로는 production.log에서 오류가 발생합니다.

411 Length Required

프록시 다운로드

클라이언트는 사전에 서명된 제한 시간 URL을 받거나, GitLab이 객체 스토리지에서 데이터를 클라이언트로 프록시하는 방법으로 객체 스토리지에서 파일을 다운로드할 수 있습니다. 객체 스토리지에서 직접 파일을 다운로드하는 것은 GitLab이 처리해야 하는 egress 트래픽 양을 줄이는 데 도움이 됩니다.

파일이 로컬 블록 저장소나 NFS에 저장된 경우, GitLab은 프록시로 작동해야 합니다. 이것은 객체 스토리지와는 기본적으로 다른 동작입니다.

proxy_download 설정은 이 동작을 제어합니다: 일반적으로 기본 값은 false입니다. 각 사용 사례의 설명서에서 확인하세요. 만약 파일을 프록시로 변환하고 싶다면 true로 설정하세요.

파일을 프록시로 변환하지 않을 때, GitLab은 사전에 서명된, 제한 시간이 있는 객체 스토리지 URL의 HTTP 302 리디렉션을 반환합니다. 이것은 다음과 같은 문제를 일으킬 수 있습니다:

  • GitLab이 객체 스토리지에 비안전한 HTTP로 액세스하는 경우, 클라이언트는 https->http 다운그레이드 오류를 생성하고 리디렉션을 처리하지 않을 수 있습니다. 예를 들어, LFS는 이 오류를 생성합니다:

    LFS: lfsapi/client: refusing insecure redirect, https->http
    
  • 클라이언트는 객체 스토리지 인증서를 발급한 CA를 신뢰해야 하거나, 다음과 같은 일반적인 TLS 오류를 반환할 수 있습니다:

    x509: certificate signed by unknown authority
    
  • 클라이언트는 객체 스토리지에 네트워크 액세스해야 합니다. 네트워크 방화벽이 액세스를 차단할 수 있습니다. 이 액세스가 없다면 발생할 수 있는 오류는 다음과 같습니다:

    Received status code 403 from server: Forbidden
    
  • 객체 스토리지 버킷이 GitLab 인스턴스의 URL에서 Cross-Origin Resource Sharing (CORS) 액세스를 허용해야 합니다. 저장소 페이지에서 PDF를 로드하려고 하면 다음과 같은 오류가 표시될 수 있습니다:

    An error occurred while loading the file. Please try again later.
    

이 외에도 사용자는 잠깐 동안 다른 사람에게 인증 없이 사전 서명된, 제한 시간이 있는 객체 스토리지 URL을 공유할 수 있습니다. 객체 스토리지 제공업체와 클라이언트 간에 대역폭 요금이 발생할 수 있습니다.

ETag 불일치

기본 GitLab 설정을 사용하는 경우, MinIO와 같은 일부 객체 스토리지 백엔드는 ETag mismatch 오류를 생성할 수 있습니다.

Amazon Web Services S3에서 이러한 ETag 불일치 오류가 발생한다면, 아마도 버킷의 암호화 설정 때문입니다. 이 문제를 해결하기 위해 두 가지 옵션이 있습니다:

첫 번째 옵션은 MinIO에게 권장됩니다. 그렇지 않으면, MinIO에 대한 해결책은 서버에서 --compat 매개변수를 사용하는 것입니다.

통합된 형식이:

  • S3 호환 객체 스토리지 또는 인스턴스 프로필을 사용할 때, Workhorse는 내부 S3 클라이언트를 사용하여 S3 자격 증명을 사용하여 Content-MD5 헤더를 계산할 수 있습니다. 이렇게 하면 S3 서버에서 반환된 ETag 헤더를 비교할 필요가 없어집니다.
  • S3 호환 객체 스토리지에 통합된 형식을 사용하지 않으면, Workhorse는 사전에 서명된 URL을 사용하여 S3로 파일을 업로드합니다.

GCS Cloud Key Management Service (KMS)로 버킷을 암호화하는 것은 지원되지 않으며 ETag 불일치 오류를 발생시킵니다.

Multi-threaded copying

GitLab은 버킷 내 파일 복사를 가속화하기 위해 S3 업로드 파트 복사 API를 사용합니다. Ceph S3는 Kraken 11.0.2 이전에는 이를 지원하지 않아 업로드 프로세스 중 파일을 복사할 때 404 오류가 발생합니다.

이 기능은 :s3_multithreaded_uploads 플래그를 사용하여 비활성화할 수 있습니다. 기능을 비활성화하려면 GitLab 관리자에게 Rails 콘솔 액세스를 요청하여 다음 명령을 실행하도록 하세요:

Feature.disable(:s3_multithreaded_uploads)

레일즈 콘솔을 통한 수동 테스트

일부 상황에서는 Rails 콘솔을 사용하여 객체 저장 설정을 테스트하는 것이 도움이 될 수 있습니다. 다음 예제는 주어진 연결 설정 세트를 테스트하고 테스트 객체를 쓰고 최종적으로 읽는 방법을 보여줍니다.

  1. 레일즈 콘솔을 시작합니다.
  2. 다음 예제 형식에 따라 ‘/etc/gitlab/gitlab.rb’에서 설정한 것과 동일한 매개변수를 사용하여 객체 저장 연결을 설정합니다.

접근 키를 사용한 연결의 예:

connection = Fog::Storage.new(
  {
    provider: 'AWS',
    region: `eu-central-1`,
    aws_access_key_id: '<AWS_ACCESS_KEY_ID>',
    aws_secret_access_key: '<AWS_SECRET_ACCESS_KEY>'
  }
)

AWS IAM 프로필을 사용한 연결의 예:

connection = Fog::Storage.new(
  {
    provider: 'AWS',
    use_iam_profile: true,
    region: 'us-east-1'
  }
)
  1. 테스트할 버킷 이름을 지정하고, 테스트 파일을 작성한 후 읽어보세요.
dir = connection.directories.new(key: '<bucket-name-here>')
f = dir.files.create(key: 'test.txt', body: 'test')
pp f
pp dir.files.head('test.txt')