오브젝트 스토리지
Offering: GitLab Self-Managed
GitLab은 다양한 유형의 데이터를 저장하기 위해 오브젝트 스토리지 서비스 사용을 지원합니다. 오브젝트 스토리지를 구성하는 두 가지 옵션이 있습니다: 권장됨. 각 오브젝트 유형이 자체 스토리지 연결을 정의하도록 구성: 모든 오브젝트가 자체 오브젝트 스토리지 연결 및 구성을 정의합니다.
GitLab은 다양한 유형의 데이터를 저장하기 위해 오브젝트 스토리지 서비스 사용을 지원합니다. 오브젝트 스토리지는 일반적으로 훨씬 더 성능이 좋고, 안정적이며, 확장 가능하므로 NFS보다 권장되며 대규모 설정에서 더 좋습니다.
오브젝트 스토리지를 구성하는 두 가지 옵션이 있습니다:
-
권장됨. 모든 오브젝트 유형에 대한 단일 스토리지 연결 구성: 단일 자격 증명이 지원되는 모든 오브젝트 유형에서 공유됩니다. 이를 통합 형식이라고 합니다.
-
각 오브젝트 유형이 자체 스토리지 연결을 정의하도록 구성: 모든 오브젝트가 자체 오브젝트 스토리지 연결 및 구성을 정의합니다. 이를 스토리지별 형식이라고 합니다.
이미 스토리지별 형식을 사용하고 있다면, 통합 형식으로 전환하는 방법을 참조하세요.
데이터를 로컬에 저장한다면, 오브젝트 스토리지로 마이그레이션하는 방법을 참조하세요.
오브젝트 스토리지 제공자 지원#
GitLab은 오브젝트 스토리지에 Fog 라이브러리를 사용하며 다음 세 가지 연결 유형을 지원합니다. 다른 Fog 제공자는 지원되지 않습니다.
| 연결 유형 | provider 값 |
사용처 |
|---|---|---|
| S3 호환 | AWS |
Amazon S3 및 모든 S3 호환 서비스 |
| Google Cloud Storage | Google |
Google Cloud Storage |
| Azure Blob Storage | AzureRM |
Azure Blob Storage |
오브젝트 스토리지 서비스가 이러한 연결 유형 중 하나와 호환되면, 아래의 해당 연결 설정을 사용하여 구성합니다. 제공자 선택은 사용자가 결정합니다.
활성 테스트 커버리지가 있는 제공자#
GitLab은 다음 제공자를 적극적으로 테스트합니다:
- Amazon S3 -
AWS연결 유형. Object Lock은 지원되지 않습니다. 자세한 내용은 이슈 335775를 참조하세요. - Google Cloud Storage -
Google연결 유형. - Azure Blob Storage -
AzureRM연결 유형.
커뮤니티 문서화된 제공자#
다음 제공자들은 커뮤니티에 의해 문서화되었습니다. GitLab은 이 제공자들을 테스트하지 않습니다. 편의를 위해 구성 예시가 제공됩니다. 이러한 제공자 중 하나를 사용하다가 문제가 발생하면 GitLab 지원이 도움을 드리지 못할 수 있습니다.
- Digital Ocean Spaces. S3 호환, 제공자별 구성 예시를 참조하세요.
- Oracle Cloud Infrastructure. S3 호환, 제공자별 구성 예시를 참조하세요.
- OpenStack Swift (S3 호환 모드).
- Storj Gateway. S3 호환, 제공자별 구성 예시를 참조하세요.
- Ceph RGW. S3 호환, 제공자별 구성 예시를 참조하세요.
- Hitachi Vantara HCP. S3 호환, 제공자별 구성 예시를 참조하세요.
- S3 호환 API를 노출하는 온프레미스 하드웨어 및 어플라이언스.
모든 오브젝트 유형에 대한 단일 스토리지 연결 구성 (통합 형식)#
CI 아티팩트, LFS 파일, 업로드 첨부 파일 등 대부분의 오브젝트 유형은 여러 버킷과 함께 오브젝트 스토리지에 대한 단일 자격 증명을 지정하여 오브젝트 스토리지에 저장할 수 있습니다.
GitLab Helm Charts의 경우, 통합 형식 구성을 참조하세요.
통합 형식을 사용하여 오브젝트 스토리지를 구성하면 여러 가지 이점이 있습니다:
- 오브젝트 유형 간에 연결 세부 정보가 공유되므로 GitLab 구성을 단순화할 수 있습니다.
- 암호화된 S3 버킷 사용을 가능하게 합니다.
- 적절한
Content-MD5헤더로 S3에 파일을 업로드합니다.
통합 형식을 사용하면 직접 업로드가 자동으로 활성화됩니다. 따라서 다음 제공자만 사용할 수 있습니다:
통합 형식 구성은 백업 또는 Mattermost에 사용할 수 없습니다. 백업은 별도로 서버 측 암호화로 구성할 수 있습니다. 지원되는 오브젝트 스토리지 유형의 전체 목록은 표를 참조하세요.
통합 형식을 활성화하면 모든 오브젝트 유형에 대한 오브젝트 스토리지가 활성화됩니다. 모든 버킷이 지정되지 않으면 다음과 같은 오류가 발생할 수 있습니다:
Object storage for <object type> must have a bucket specified
특정 오브젝트 유형에 로컬 스토리지를 사용하려면 특정 기능에 대한 오브젝트 스토리지를 비활성화할 수 있습니다.
공통 파라미터 구성#
통합 형식에서 object_store 섹션은 공통 파라미터 집합을 정의합니다.
| 설정 | 설명 |
|---|---|
enabled |
오브젝트 스토리지를 활성화하거나 비활성화합니다. |
proxy_download |
모든 제공된 파일을 프록시하는 것을 활성화하려면 true로 설정합니다. 이 옵션을 사용하면 클라이언트가 모든 데이터를 프록시하는 대신 원격 스토리지에서 직접 다운로드할 수 있으므로 이그레스 트래픽을 줄일 수 있습니다. |
connection |
아래에 설명된 다양한 연결 옵션. |
storage_options |
서버 측 암호화와 같이 새 오브젝트를 저장할 때 사용할 옵션. |
objects |
오브젝트별 구성. |
예시는 통합 형식 및 Amazon S3 사용 방법을 참조하세요.
각 오브젝트의 파라미터 구성#
각 오브젝트 유형은 적어도 저장될 버킷 이름을 정의해야 합니다.
다음 표는 사용할 수 있는 유효한 objects를 나열합니다:
| 유형 | 설명 |
|---|---|
artifacts |
CI/CD 작업 아티팩트 |
external_diffs |
머지 리퀘스트 diff |
uploads |
사용자 업로드 |
lfs |
Git Large File Storage 오브젝트 |
packages |
프로젝트 패키지 (예: PyPI, Maven, NuGet) |
dependency_proxy |
Dependency Proxy |
terraform_state |
Terraform 상태 파일 |
pages |
Pages |
ci_secure_files |
Secure files |
각 오브젝트 유형 내에서 세 가지 파라미터를 정의할 수 있습니다:
| 설정 | 필수? | 설명 |
|---|---|---|
bucket |
[check-circle] 예* | 오브젝트 유형의 버킷 이름. enabled가 false로 설정된 경우 필수가 아닙니다. |
enabled |
[dotted-circle] 아니오 | 공통 파라미터를 재정의합니다. |
proxy_download |
[dotted-circle] 아니오 | 공통 파라미터를 재정의합니다. |
예시는 통합 형식 및 Amazon S3 사용 방법을 참조하세요.
특정 기능에 대한 오브젝트 스토리지 비활성화#
앞서 살펴본 것처럼, enabled 플래그를 false로 설정하여 특정 유형에 대해 오브젝트 스토리지를 비활성화할 수 있습니다. 예를 들어, CI 아티팩트에 대한 오브젝트 스토리지를 비활성화하려면:
gitlab_rails['object_store']['objects']['artifacts']['enabled'] = false
기능이 완전히 비활성화된 경우 버킷이 필요하지 않습니다. 예를 들어, 이 설정으로 CI 아티팩트가 비활성화되면 버킷이 필요하지 않습니다:
gitlab_rails['artifacts_enabled'] = false
각 오브젝트 유형이 자체 스토리지 연결을 정의하도록 구성 (스토리지별 형식)#
스토리지별 형식의 경우, 모든 오브젝트가 자체 오브젝트 스토리지 연결 및 구성을 정의합니다. 통합 형식이 지원하지 않는 스토리지 유형을 제외하고는 통합 형식을 사용해야 합니다. GitLab Helm 차트를 사용할 때는 차트가 오브젝트 스토리지의 통합 형식을 처리하는 방법을 참조하세요.
통합 형식이 아닌 형식에서 암호화된 S3 버킷 사용은 지원되지 않습니다. 사용하면 ETag 불일치 오류가 발생할 수 있습니다.
스토리지별 형식의 경우, 공유 폴더가 필요하지 않으므로 직접 업로드가 기본값이 될 수 있습니다.
통합 형식이 지원하지 않는 스토리지 유형의 경우 다음 가이드를 참조하세요:
| 오브젝트 스토리지 유형 | 통합 형식이 지원하는가? |
|---|---|
| 백업 | [dotted-circle] 아니오 |
| 컨테이너 레지스트리 (선택 기능) | [dotted-circle] 아니오 |
| Mattermost | [dotted-circle] 아니오 |
| 오토스케일 런너 캐싱 (성능 향상을 위한 선택 사항) | [dotted-circle] 아니오 |
| Secure Files | [check-circle] 예 |
| 작업 아티팩트 (아카이브된 작업 로그 포함) | [check-circle] 예 |
| LFS 오브젝트 | [check-circle] 예 |
| 업로드 | [check-circle] 예 |
| 머지 리퀘스트 diff | [check-circle] 예 |
| 패키지 (선택 기능) | [check-circle] 예 |
| Dependency Proxy (선택 기능) | [check-circle] 예 |
| Terraform 상태 파일 | [check-circle] 예 |
| Pages 콘텐츠 | [check-circle] 예 |
연결 설정 구성#
통합 형식과 스토리지별 형식 모두 연결을 구성해야 합니다. 다음 섹션은 connection 설정에서 사용할 수 있는 파라미터를 설명합니다.
S3 호환 제공자#
이 설정들은 AWS 연결 유형을 사용하는 Amazon S3 및 모든 S3 호환 서비스에 적용됩니다. AWS를 직접 사용하지 않는 경우 endpoint를 제공자의 URL로 설정합니다.
S3 호환 서비스는 AWS S3 API를 얼마나 밀접하게 구현하는지에 따라 다릅니다. GitLab은 사전 서명된 URL, 멀티파트 업로드, 선택적으로 청크된 서명 스트리밍을 포함한 특정 S3 동작을 사용하며, 모든 S3 호환 구현이 동일하게 지원하는 것은 아닙니다. 다른 도구에서는 작동하지만 GitLab에서는 작동하지 않는 제공자가 있다면, 조정이 가장 필요한 설정은 다음과 같습니다:
aws_signature_version.enable_signature_v4_streaming.
연결 설정은 fog-aws가 제공하는 것과 일치합니다:
| 설정 | 설명 | 기본값 |
|---|---|---|
provider |
호환 호스트의 경우 항상 AWS. |
AWS |
aws_access_key_id |
AWS 자격 증명 또는 호환 자격 증명. | |
aws_secret_access_key |
AWS 자격 증명 또는 호환 자격 증명. | |
aws_signature_version |
사용할 AWS 서명 버전. 2 또는 4가 유효한 옵션입니다. 일부 S3 호환 제공자는 2가 필요할 수 있습니다. |
4 |
enable_signature_v4_streaming |
AWS v4 서명으로 HTTP 청크 전송을 활성화하려면 true로 설정합니다. 일부 S3 호환 제공자는 이것을 false로 설정해야 합니다. GitLab 17.4에서 기본값이 true에서 false로 변경되었습니다. |
false |
region |
AWS 리전. | |
host |
더 이상 사용되지 않음: 대신 endpoint를 사용하세요. AWS를 사용하지 않을 때의 S3 호환 호스트. 예: localhost 또는 storage.example.com. HTTPS와 포트 443이 가정됩니다. |
s3.amazonaws.com |
endpoint |
S3 호환 서비스를 구성할 때 사용할 수 있으며, http://127.0.0.1:9000과 같은 URL을 입력합니다. 이것이 host보다 우선합니다. 통합 형식에는 항상 endpoint를 사용합니다. |
(선택 사항) |
path_style |
bucket_name.host/object 대신 host/bucket_name/object 스타일 경로를 사용하려면 true로 설정합니다. 경로 스타일 주소가 필요한 S3 호환 서비스의 경우 true로 설정합니다. AWS S3의 경우 false로 유지합니다. |
false |
use_iam_profile |
액세스 키 대신 IAM 프로파일을 사용하려면 true로 설정합니다. |
false |
aws_credentials_refresh_threshold_seconds |
IAM에서 임시 자격 증명을 사용할 때 자동 갱신 임계값(초)을 설정합니다. | 15 |
disable_imds_v2 |
X-aws-ec2-metadata-token을 검색하는 IMDS v2 엔드포인트에 대한 액세스를 비활성화하여 IMDS v1 사용을 강제합니다. |
false |
S3 호환성 및 알려진 실패 모드#
S3 호환성을 주장한다고 해서 제공자가 GitLab과 올바르게 작동하는 것은 아닙니다. S3 호환 제공자에서 오류가 발생하면 지원 요청을 제기하기 전에 다음 조정을 시도해 보세요:
- 서명 스트리밍: 일부 제공자는 AWS Signature Version 4 스트리밍이 사용하는 청크 전송 인코딩을 거부합니다.
enable_signature_v4_streaming: false를 설정합니다. - 서명 버전: 일부 제공자는 Signature Version 4를 완전히 지원하지 않습니다.
aws_signature_version: 2를 설정합니다. - 경로 스타일 URL: 일부 제공자는 경로 스타일 버킷 주소 지정이 필요합니다.
path_style: true를 설정합니다. - ETag 유효성 검사: 일부 제공자는 GitLab이 유효성을 검사하는 업로드된 오브젝트의 MD5와 일치하지 않는 ETag를 반환합니다. ETag 불일치를 참조하세요.
GitLab 지원은 구성 문제 해결을 도와드릴 수 있지만, 테스트된 제공자 세트에 없는 제공자에 특정한 문제의 해결을 보장할 수 없습니다.
Amazon 인스턴스 프로파일 사용#
오브젝트 스토리지 구성에서 AWS 액세스 및 비밀 키를 제공하는 대신, GitLab이 Amazon Identity Access and Management (IAM) 역할을 사용하도록 구성하여 Amazon 인스턴스 프로파일을 설정할 수 있습니다. 이를 사용하면 GitLab이 S3 버킷에 액세스할 때마다 임시 자격 증명을 가져오므로 구성에 하드코딩된 값이 필요하지 않습니다.
사전 요구 사항:
- GitLab이 인스턴스 메타데이터 엔드포인트에 연결할 수 있어야 합니다.
- GitLab이 인터넷 프록시를 사용하도록 구성된 경우, 엔드포인트 IP 주소를
no_proxy목록에 추가해야 합니다. - IMDS v2 액세스의 경우, 홉 제한이 충분한지 확인합니다. GitLab이 컨테이너에서 실행 중인 경우 제한을 1에서 2로 높여야 할 수 있습니다.
인스턴스 프로파일을 설정하려면:
-
필요한 권한이 있는 IAM 역할을 생성합니다. 다음 예시는
test-bucket이라는 S3 버킷의 역할입니다:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:DeleteObject" ], "Resource": "arn:aws:s3:::test-bucket/*" }, { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": "arn:aws:s3:::test-bucket" } ] } -
GitLab 인스턴스를 호스팅하는 EC2 인스턴스에 이 역할을 연결합니다.
-
GitLab 구성 옵션
use_iam_profile을true로 설정합니다.
암호화된 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 Resource Name. server_side_encryption에서 aws:kms를 사용할 때만 필요합니다. KMS 암호화 사용에 대한 Amazon 문서를 참조하세요. |
기본 암호화의 경우와 마찬가지로, 이 옵션들은 Workhorse S3 클라이언트가 활성화된 경우에만 작동합니다. 다음 두 가지 조건 중 하나를 충족해야 합니다:
- 연결 설정에서
use_iam_profile이true입니다. - 통합 형식이 사용 중입니다.
Workhorse S3 클라이언트를 활성화하지 않고 서버 측 암호화 헤더를 사용하면 ETag 불일치 오류가 발생합니다.
Google Cloud Storage (GCS)#
히스토리
universe_domain설정이 GitLab 18.9에서 도입되었습니다.
다음은 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로 설정합니다. |
|
universe_domain |
Google Cloud 요청에 사용할 유니버스 도메인. Google Cloud Dedicated 또는 다른 기본이 아닌 유니버스 도메인에 연결하는 데 사용합니다. | googleapis.com |
GitLab은 google_json_key_location, 그 다음 google_json_key_string, 마지막으로 google_application_default 순서로 값을 읽습니다. 값이 있는 이 설정 중 첫 번째 것을 사용합니다.
서비스 계정은 버킷에 액세스할 권한이 있어야 합니다. 자세한 내용은 Cloud Storage 인증 문서를 참조하세요.
Google Cloud Application Default Credentials#
Google Cloud Application Default Credentials (ADC)는 일반적으로 기본 서비스 계정 또는 Workload Identity Federation을 사용하기 위해 GitLab과 함께 사용됩니다. google_application_default를 true로 설정하고 google_json_key_location 및 google_json_key_string을 생략합니다.
ADC를 사용하는 경우:
-
사용하는 서비스 계정에
iam.serviceAccounts.signBlob권한이 있는지 확인합니다. 일반적으로 서비스 계정에Service Account Token Creator역할을 부여하여 수행합니다. -
Google Compute 가상 머신을 사용하는 경우 Google Cloud API에 액세스하기 위한 올바른 액세스 범위가 있는지 확인합니다. 머신에 올바른 범위가 없으면 오류 로그에 다음이 표시될 수 있습니다:
Google::Apis::ClientError (insufficientPermissions: Request had insufficient authentication scopes.)
고객 관리 암호화 키 (CMEK)로 버킷 암호화를 사용하려면 통합 형식을 사용합니다.
-
/etc/gitlab/gitlab.rb를 편집하고 원하는 값으로 다음 줄을 추가합니다:gitlab_rails['object_store']['connection'] = { 'provider' => 'Google', 'google_project' => '', 'google_json_key_location' => '' }ADC를 사용하려면
google_application_default를 대신 사용합니다:gitlab_rails['object_store']['connection'] = { 'provider' => 'Google', 'google_project' => '', 'google_application_default' => true }기본이 아닌 유니버스 도메인을 사용하려면 (예: Google Cloud Dedicated):
gitlab_rails['object_store']['connection'] = { 'provider' => 'Google', 'google_project' => '', 'google_application_default' => true, 'universe_domain' => '' } -
파일을 저장하고 GitLab을 재구성합니다:
sudo gitlab-ctl reconfigure
-
Kubernetes Secret으로 사용할
object_storage.yaml이라는 파일에 다음 콘텐츠를 넣습니다:provider: Google google_project: PROJECT> google_json_key_location: ''ADC를 사용하려면
google_application_default를 대신 사용합니다:provider: Google google_project: PROJECT> google_application_default: true기본이 아닌 유니버스 도메인을 사용하려면 (예: Google Cloud Dedicated):
provider: Google google_project: PROJECT> google_application_default: true universe_domain: DOMAIN> -
Kubernetes Secret을 생성합니다:
kubectl create secret generic -n <namespace> gitlab-object-storage --from-file=connection=object_storage.yaml -
Helm values를 내보냅니다:
helm get values gitlab > gitlab_values.yaml -
gitlab_values.yaml을 편집합니다:global: appConfig: artifacts: bucket: gitlab-artifacts ciSecureFiles: bucket: gitlab-ci-secure-files enabled: true dependencyProxy: bucket: gitlab-dependency-proxy enabled: true externalDiffs: bucket: gitlab-mr-diffs enabled: true lfs: bucket: gitlab-lfs object_store: connection: secret: gitlab-object-storage enabled: true proxy_download: false packages: bucket: gitlab-packages terraformState: bucket: gitlab-terraform-state enabled: true uploads: bucket: gitlab-uploads -
파일을 저장하고 새 값을 적용합니다:
helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
-
docker-compose.yml을 편집합니다:version: "3.6" services: gitlab: environment: GITLAB_OMNIBUS_CONFIG: | # Consolidated object storage configuration gitlab_rails['object_store']['enabled'] = true gitlab_rails['object_store']['proxy_download'] = false gitlab_rails['object_store']['connection'] = { 'provider' => 'Google', 'google_project' => '', 'google_json_key_location' => '' } 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'ADC를 사용하려면
google_application_default를 대신 사용합니다:gitlab_rails['object_store']['connection'] = { 'provider' => 'Google', 'google_project' => '', 'google_application_default' => true }기본이 아닌 유니버스 도메인을 사용하려면 (예: Google Cloud Dedicated):
gitlab_rails['object_store']['connection'] = { 'provider' => 'Google', 'google_project' => '', 'google_application_default' => true, 'universe_domain' => '' } -
파일을 저장하고 GitLab을 재시작합니다:
docker compose up -d
Azure Blob storage#
Azure는 container라는 단어를 사용하여 블롭 컬렉션을 나타내지만, GitLab은 bucket이라는 용어를 표준화합니다. bucket 설정에서 Azure 컨테이너 이름을 구성해야 합니다.
Azure Blob storage는 여러 컨테이너에 액세스하는 데 단일 자격 증명 세트가 사용되므로 통합 형식에서만 사용할 수 있습니다. 스토리지별 형식은 지원되지 않습니다. 자세한 내용은 통합 형식으로 전환하는 방법을 참조하세요.
다음은 Azure의 유효한 연결 파라미터입니다. 자세한 내용은 Azure Blob Storage 문서를 참조하세요.
| 설정 | 설명 | 예시 |
|---|---|---|
provider |
제공자 이름. | AzureRM |
azure_storage_account_name |
스토리지에 액세스하는 데 사용되는 Azure Blob Storage 계정 이름. | azuretest |
azure_storage_access_key |
컨테이너에 액세스하는 데 사용되는 스토리지 계정 액세스 키. 일반적으로 base64로 인코딩된 512비트 암호화 키인 비밀입니다. Azure 워크로드 및 관리 ID에는 선택 사항입니다. | 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 |
-
/etc/gitlab/gitlab.rb를 편집하고 원하는 값으로 다음 줄을 추가합니다:gitlab_rails['object_store']['connection'] = { 'provider' => 'AzureRM', 'azure_storage_account_name' => '', 'azure_storage_access_key' => '', 'azure_storage_domain' => '' } 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'워크로드 ID를 사용하는 경우
azure_storage_access_key를 생략합니다:gitlab_rails['object_store']['connection'] = { 'provider' => 'AzureRM', 'azure_storage_account_name' => '', 'azure_storage_domain' => '' } -
파일을 저장하고 GitLab을 재구성합니다:
sudo gitlab-ctl reconfigure
-
Kubernetes Secret으로 사용할
object_storage.yaml이라는 파일에 다음 콘텐츠를 넣습니다:provider: AzureRM azure_storage_account_name: azure_storage_access_key: azure_storage_domain: blob.core.windows.net워크로드 또는 관리 ID를 사용하는 경우
azure_storage_access_key를 생략합니다:provider: AzureRM azure_storage_account_name: azure_storage_domain: blob.core.windows.net -
Kubernetes Secret을 생성합니다:
kubectl create secret generic -n <namespace> gitlab-object-storage --from-file=connection=object_storage.yaml -
Helm values를 내보냅니다:
helm get values gitlab > gitlab_values.yaml -
gitlab_values.yaml을 편집합니다:global: appConfig: artifacts: bucket: gitlab-artifacts ciSecureFiles: bucket: gitlab-ci-secure-files enabled: true dependencyProxy: bucket: gitlab-dependency-proxy enabled: true externalDiffs: bucket: gitlab-mr-diffs enabled: true lfs: bucket: gitlab-lfs object_store: connection: secret: gitlab-object-storage enabled: true proxy_download: false packages: bucket: gitlab-packages terraformState: bucket: gitlab-terraform-state enabled: true uploads: bucket: gitlab-uploads -
파일을 저장하고 새 값을 적용합니다:
helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
-
docker-compose.yml을 편집합니다:version: "3.6" services: gitlab: environment: GITLAB_OMNIBUS_CONFIG: | # Consolidated object storage configuration gitlab_rails['object_store']['enabled'] = true gitlab_rails['object_store']['proxy_download'] = false gitlab_rails['object_store']['connection'] = { 'provider' => 'AzureRM', 'azure_storage_account_name' => '', 'azure_storage_access_key' => '', 'azure_storage_domain' => '' } 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'관리 ID를 사용하는 경우
azure_storage_access_key를 생략합니다.gitlab_rails['object_store']['connection'] = { 'provider' => 'AzureRM', 'azure_storage_account_name' => '', 'azure_storage_domain' => '' } -
파일을 저장하고 GitLab을 재시작합니다:
docker compose up -d
소스에서 자체 컴파일된 설치의 경우, Workhorse도 Azure 자격 증명으로 구성해야 합니다. Linux 패키지 설치에서는 Workhorse 설정이 이전 설정에서 채워지므로 필요하지 않습니다.
-
/home/git/gitlab/config/gitlab.yml을 편집하고 다음 줄을 추가하거나 수정합니다:production: &base object_store: enabled: true proxy_download: false connection: provider: AzureRM azure_storage_account_name: '' azure_storage_access_key: '' 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 -
/home/git/gitlab-workhorse/config.toml을 편집하고 다음 줄을 추가하거나 수정합니다:[object_storage] provider = "AzureRM" [object_storage.azurerm] azure_storage_account_name = "" azure_storage_access_key = ""커스텀 Azure 스토리지 도메인을 사용하는 경우,
azure_storage_domain은 Workhorse 구성에서 설정할 필요가 없습니다. 이 정보는 GitLab Rails와 Workhorse 사이의 API 호출에서 교환됩니다. -
파일을 저장하고 GitLab을 재시작합니다:
# systemd를 실행하는 시스템의 경우 sudo systemctl restart gitlab.target # SysV init을 실행하는 시스템의 경우 sudo service gitlab restart
Azure 워크로드 및 관리 ID#
히스토리
- GitLab 17.9에서 도입되었습니다.
Azure 워크로드 ID 또는 관리 ID를 사용하려면 구성에서 azure_storage_access_key를 생략합니다. azure_storage_access_key가 비어 있으면 GitLab은 다음을 시도합니다:
- 워크로드 ID로 임시 자격 증명 획득.
AZURE_TENANT_ID,AZURE_CLIENT_ID,AZURE_FEDERATED_TOKEN_FILE이 환경에 있어야 합니다. - 워크로드 ID를 사용할 수 없는 경우 Azure Instance Metadata Service에서 자격 증명 요청.
- 사용자 위임 키 가져오기.
- 해당 키로 SAS 토큰을 생성하여 Storage Account 블롭에 액세스.
ID에 Storage Blob Data Contributor 역할이 할당되어 있는지 확인합니다.
제공자별 구성 예시#
다음 예시는 기본이 아닌 설정이 필요한 특정 S3 호환 제공자에 대한 구성을 보여줍니다. 여기에 나열되지 않은 S3 호환 제공자의 경우, 제공자의 적절한 endpoint와 함께 기본 S3 호환 구성을 사용합니다.
Oracle Cloud Infrastructure#
Oracle Cloud Infrastructure S3에는 다음 설정이 필요합니다:
| 설정 | 값 |
|---|---|
enable_signature_v4_streaming |
false |
path_style |
true |
enable_signature_v4_streaming이 true로 설정되면 production.log에서 다음 오류가 발생할 수 있습니다:
STREAMING-AWS4-HMAC-SHA256-PAYLOAD is not supported
Storj Gateway (SJ)#
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#
HCP 연결 시 SignatureDoesNotMatch - The request signature we calculated does not match the signature you provided. Check your HCP Secret Access key and signing method.라는 오류가 반환될 수 있습니다. 이 경우 endpoint를 네임스페이스가 아닌 테넌트의 URL로 설정하고, 버킷 경로가 <namespace_name>/<bucket_name>으로 구성되어 있는지 확인합니다.
HCP는 S3 호환 API를 제공합니다. 다음 구성 예시를 사용합니다:
gitlab_rails['object_store']['connection'] = {
'provider' => 'AWS',
'endpoint' => 'https://<tenant_endpoint>',
'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'] = '<namespace_name>/<bucket_name>'
Ceph RGW#
Ceph RGW는 Ceph용 S3 호환 API입니다. 다음 구성 예시를 사용합니다:
gitlab_rails['object_store']['connection'] = {
'provider' => 'AWS',
'endpoint' => 'https://rgw-ceph.example.com',
'region' => 'us-west-1',
'aws_access_key_id' => 'ACCESS_KEY',
'aws_secret_access_key' => 'SECRET_KEY',
'path_style': true
}
Ceph RGW로 서버 측 암호화를 활성화하려면 HTTPS를 사용하여 연결해야 합니다. Ceph는 비보안 연결을 통한 암호화 요청을 거부합니다.
통합 형식 및 Amazon S3를 사용하는 전체 예시#
다음 예시는 AWS S3를 사용하여 지원되는 모든 서비스에 대한 오브젝트 스토리지를 활성화합니다:
-
/etc/gitlab/gitlab.rb를 편집하고 원하는 값으로 다음 줄을 추가합니다:# Consolidated object storage configuration gitlab_rails['object_store']['enabled'] = true gitlab_rails['object_store']['proxy_download'] = false gitlab_rails['object_store']['connection'] = { 'provider' => 'AWS', 'region' => 'eu-central-1', 'aws_access_key_id' => '', 'aws_secret_access_key' => '' } # OPTIONAL: 다음 줄은 서버 측 암호화가 필요한 경우에만 필요합니다 gitlab_rails['object_store']['storage_options'] = { 'server_side_encryption' => '', '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 } -
파일을 저장하고 GitLab을 재구성합니다:
sudo gitlab-ctl reconfigure
-
Kubernetes Secret으로 사용할
object_storage.yaml이라는 파일에 다음 콘텐츠를 넣습니다:provider: AWS region: us-east-1 aws_access_key_id: aws_secret_access_key:AWS IAM 프로파일을 사용하는 경우 AWS 액세스 키와 비밀 키/값 쌍을 생략합니다. 예:
provider: AWS region: us-east-1 use_iam_profile: true -
Kubernetes Secret을 생성합니다:
kubectl create secret generic -n <namespace> gitlab-object-storage --from-file=connection=object_storage.yaml -
Helm values를 내보냅니다:
helm get values gitlab > gitlab_values.yaml -
gitlab_values.yaml을 편집합니다:global: appConfig: artifacts: bucket: gitlab-artifacts ciSecureFiles: bucket: gitlab-ci-secure-files enabled: true dependencyProxy: bucket: gitlab-dependency-proxy enabled: true externalDiffs: bucket: gitlab-mr-diffs enabled: true lfs: bucket: gitlab-lfs object_store: connection: secret: gitlab-object-storage enabled: true proxy_download: false packages: bucket: gitlab-packages terraformState: bucket: gitlab-terraform-state enabled: true uploads: bucket: gitlab-uploads -
파일을 저장하고 새 값을 적용합니다:
helm upgrade -f gitlab_values.yaml gitlab gitlab/gitlab
-
docker-compose.yml을 편집합니다:version: "3.6" services: gitlab: environment: GITLAB_OMNIBUS_CONFIG: | # Consolidated object storage configuration gitlab_rails['object_store']['enabled'] = true gitlab_rails['object_store']['proxy_download'] = false gitlab_rails['object_store']['connection'] = { 'provider' => 'AWS', 'region' => 'eu-central-1', 'aws_access_key_id' => '', 'aws_secret_access_key' => '' } # OPTIONAL: 다음 줄은 서버 측 암호화가 필요한 경우에만 필요합니다 gitlab_rails['object_store']['storage_options'] = { 'server_side_encryption' => '', '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 } -
파일을 저장하고 GitLab을 재시작합니다:
docker compose up -d
-
/home/git/gitlab/config/gitlab.yml을 편집하고 다음 줄을 추가하거나 수정합니다:production: &base object_store: enabled: true proxy_download: false connection: provider: AWS aws_access_key_id: aws_secret_access_key: region: eu-central-1 storage_options: server_side_encryption: or 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-pagesAWS IAM 프로파일을 사용하는 경우 AWS 액세스 키와 비밀 키/값 쌍을 생략합니다. 예:
connection: provider: AWS region: eu-central-1 use_iam_profile: true -
/home/git/gitlab-workhorse/config.toml을 편집하고 다음 줄을 추가하거나 수정합니다:[object_storage] provider = "AWS" [object_storage.s3] aws_access_key_id = "" aws_secret_access_key = ""AWS IAM 프로파일을 사용하는 경우 AWS 액세스 키와 비밀 키/값 쌍을 생략합니다. 예:
[object_storage.s3] use_iam_profile = true -
파일을 저장하고 GitLab을 재시작합니다:
# systemd를 실행하는 시스템의 경우 sudo systemctl restart gitlab.target # SysV init을 실행하는 시스템의 경우 sudo service gitlab restart
오브젝트 스토리지로 마이그레이션#
기존 로컬 데이터를 오브젝트 스토리지로 마이그레이션하려면 다음 가이드를 참조하세요:
- 작업 아티팩트 (아카이브된 작업 로그 포함)
- LFS 오브젝트
- 업로드
- 머지 리퀘스트 diff
- 패키지 (선택 기능)
- Dependency Proxy
- Terraform 상태 파일
- Pages 콘텐츠
- 프로젝트 수준 Secure Files
통합 형식으로 전환#
스토리지별 구성에서:
- 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'] = false
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'] = false
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을 실행할 수 있습니다.
-
Rclone을 설치합니다.
-
다음을 실행하여 Rclone을 구성합니다:
rclone config구성 프로세스는 대화형입니다. 최소 두 개의 "remote"를 추가합니다: 데이터가 현재 있는 오브젝트 스토리지 제공자(
old)와 이동할 제공자(new). -
이전 데이터를 읽을 수 있는지 확인합니다. 다음 예시는
uploads버킷을 참조하지만 버킷 이름이 다를 수 있습니다:rclone ls old:uploads | head이는
uploads버킷에 현재 저장된 오브젝트의 일부 목록을 출력해야 합니다. 오류가 발생하거나 목록이 비어 있으면rclone config를 사용하여 Rclone 구성을 업데이트합니다. -
초기 복사를 수행합니다. 이 단계에서 GitLab 서버를 오프라인으로 전환할 필요가 없습니다.
rclone sync -P old:uploads new:uploads -
첫 번째 동기화가 완료된 후, 새 오브젝트 스토리지 제공자의 웹 UI 또는 명령줄 인터페이스를 사용하여 새 버킷에 오브젝트가 있는지 확인합니다. 오브젝트가 없거나
rclone sync를 실행하는 동안 오류가 발생하면 Rclone 구성을 확인하고 다시 시도합니다.
이전 위치에서 새 위치로 적어도 하나의 성공적인 Rclone 복사를 수행한 후, 유지 보수를 예약하고 GitLab 서버를 오프라인으로 전환합니다. 유지 보수 기간 동안 두 가지 작업을 수행해야 합니다:
- 사용자가 새 오브젝트를 추가할 수 없어 이전 버킷에 남겨두지 않도록 최종
rclone sync실행을 수행합니다. - GitLab 서버의 오브젝트 스토리지 구성을 업데이트하여
uploads에 새 제공자를 사용합니다.
파일 시스템 스토리지의 대안#
GitLab 구현을 확장하거나 내결함성 및 중복성을 추가하려는 경우, 블록 또는 네트워크 파일 시스템에 대한 종속성을 제거하려고 할 수 있습니다. 다음 추가 가이드를 참조하세요:
git사용자 홈 디렉토리가 로컬 디스크에 있는지 확인합니다.- 공유
authorized_keys파일의 필요성을 없애기 위해 SSH 키의 데이터베이스 조회를 구성합니다. - 작업 로그에 대한 로컬 디스크 사용 방지.
- Pages 로컬 스토리지 비활성화.
문제 해결#
오브젝트가 GitLab 백업에 포함되지 않음#
백업 문서에 언급된 것처럼, 오브젝트는 GitLab 백업에 포함되지 않습니다. 대신 오브젝트 스토리지 제공자로 백업을 활성화할 수 있습니다.
별도의 버킷 사용#
각 데이터 유형에 별도의 버킷을 사용하는 것이 GitLab에서 권장되는 방식입니다. 이는 GitLab이 저장하는 다양한 데이터 유형 간에 충돌이 없음을 보장합니다. 이슈 292958은 단일 버킷 사용을 활성화하기 위한 제안을 담고 있습니다.
Linux 패키지 및 소스에서 자체 컴파일된 설치에서는 단일 실제 버킷을 여러 가상 버킷으로 분할할 수 있습니다. 오브젝트 스토리지 버킷이 my-gitlab-objects인 경우, 업로드를 my-gitlab-objects/uploads로, 아티팩트를 my-gitlab-objects/artifacts로 구성할 수 있습니다. 애플리케이션은 이것들을 별도의 버킷으로 처리합니다. 버킷 접두사 사용은 Helm 백업에서 올바르게 작동하지 않을 수 있습니다.
Helm 기반 설치는 백업 복원을 처리하기 위해 별도의 버킷이 필요합니다.
S3 API 호환성 문제#
S3 호환 제공자에서 오류가 발생하면 일반적인 원인 및 구성 조정 사항에 대해 S3 호환성 및 알려진 실패 모드를 참조하세요. production.log의 411 Length Required 오류는 일반적으로 서명 스트리밍으로 인해 발생합니다. 이를 해결하려면 enable_signature_v4_streaming: false를 설정합니다.
아티팩트가 항상 download 파일 이름으로 다운로드됨#
다운로드된 아티팩트 파일 이름은 GetObject 요청의 response-content-disposition 헤더로 설정됩니다. S3 제공자가 이 헤더를 지원하지 않으면 다운로드된 파일이 항상 download로 저장됩니다.
Proxy Download#
클라이언트는 사전 서명된 시간 제한 URL을 받거나, GitLab이 오브젝트 스토리지에서 클라이언트로 데이터를 프록시하여 오브젝트 스토리지에서 파일을 다운로드할 수 있습니다. 오브젝트 스토리지에서 직접 파일을 다운로드하면 GitLab이 처리해야 하는 이그레스 트래픽 양을 줄이는 데 도움이 됩니다.
파일이 로컬 블록 스토리지 또는 NFS에 저장된 경우, GitLab은 프록시 역할을 해야 합니다. 이것은 오브젝트 스토리지의 기본 동작이 아닙니다.
proxy_download 설정이 이 동작을 제어합니다: 기본값은 false입니다. 각 사용 사례에 대한 문서에서 이것을 확인합니다.
GitLab이 파일을 프록시하도록 하려면 proxy_download를 true로 설정합니다. proxy_download가 true로 설정되면 GitLab 서버에 큰 성능 영향이 있을 수 있습니다. GitLab의 서버 배포는 proxy_download를 false로 설정합니다.
proxy_download가 false인 경우, GitLab은 사전 서명된 시간 제한 오브젝트 스토리지 URL과 함께 HTTP 302 리디렉션을 반환합니다. 이로 인해 다음과 같은 문제가 발생할 수 있습니다:
-
GitLab이 오브젝트 스토리지에 액세스하는 데 비보안 HTTP를 사용하는 경우, 클라이언트가
https->http다운그레이드 오류를 생성하고 리디렉션 처리를 거부할 수 있습니다. 이에 대한 해결책은 GitLab이 HTTPS를 사용하는 것입니다. 예를 들어, LFS는 다음 오류를 생성합니다:LFS: lfsapi/client: refusing insecure redirect, https->http -
클라이언트는 오브젝트 스토리지 인증서를 발급한 인증 기관을 신뢰해야 하거나 다음과 같은 일반적인 TLS 오류를 반환할 수 있습니다:
x509: certificate signed by unknown authority -
클라이언트는 오브젝트 스토리지에 대한 네트워크 액세스가 필요합니다. 네트워크 방화벽이 액세스를 차단할 수 있습니다. 이 액세스가 없으면 발생할 수 있는 오류는 다음을 포함합니다:
Received status code 403 from server: Forbidden -
오브젝트 스토리지 버킷은 GitLab 인스턴스의 URL로부터 교차 출처 리소스 공유 (CORS) 액세스를 허용해야 합니다. 저장소 페이지에서 PDF를 로드하려고 하면 다음 오류가 표시될 수 있습니다:
An error occurred while loading the file. Please try again later.자세한 내용은 LFS 문서를 참조하세요.
사전 서명된 URL은 시간 제한이 있지만 특정 사용자에 묶여 있지 않습니다. 사전 서명된 URL을 획득한 모든 사용자는 URL 유효 기간 동안 인증 없이 오브젝트에 액세스할 수 있습니다. 직접 다운로드는 오브젝트 스토리지 제공자와 클라이언트 사이에 대역폭 요금이 발생할 수도 있습니다.
ETag 불일치#
기본 GitLab 설정을 사용하면 Alibaba와 같은 일부 S3 호환 오브젝트 스토리지 백엔드가 ETag mismatch 오류를 생성할 수 있습니다.
Amazon S3 암호화#
Amazon Web Services S3에서 ETag 불일치 오류가 발생하는 경우, 이는 버킷의 암호화 설정 때문일 가능성이 높습니다. 이 문제를 해결하려면 두 가지 옵션이 있습니다:
통합 형식은 S3 호환 서비스에 권장됩니다. 일부 서비스는 ETag 불일치 오류를 해결하기 위해 호환성 모드 활성화 등 추가적인 서버 측 구성이 필요할 수 있습니다.
통합 형식이나 인스턴스 프로파일이 활성화되지 않은 경우, GitLab Workhorse는 Content-MD5 HTTP 헤더가 계산되지 않은 사전 서명된 URL을 사용하여 S3에 파일을 업로드합니다. 데이터가 손상되지 않도록 하기 위해 Workhorse는 전송된 데이터의 MD5 해시가 S3 서버에서 반환된 ETag 헤더와 같은지 확인합니다. 암호화가 활성화되면 이것이 해당되지 않아 업로드 중에 Workhorse가 ETag mismatch 오류를 보고합니다.
통합 형식을 사용하는 경우:
- S3 호환 오브젝트 스토리지 또는 인스턴스 프로파일과 함께 사용되면, Workhorse는
Content-MD5헤더를 계산할 수 있도록 S3 자격 증명이 있는 내부 S3 클라이언트를 사용합니다. 이는 S3 서버에서 반환된 ETag 헤더를 비교할 필요성을 제거합니다. - S3 호환 오브젝트 스토리지와 함께 사용되지 않으면, Workhorse는 사전 서명된 URL 사용으로 폴백합니다.
Google Cloud Storage 암호화#
히스토리
- GitLab 16.11에서 도입되었습니다.
고객 관리 암호화 키 (CMEK)로 데이터 암호화를 활성화할 때 Google Cloud Storage (GCS)에서도 ETag 불일치 오류가 발생합니다.
CMEK를 사용하려면 통합 형식을 사용합니다.
멀티스레드 복사#
GitLab은 S3 Upload Part Copy API를 사용하여 버킷 내 파일 복사를 가속화합니다. 이 기능은 일부 S3 호환 제공자에서 지원되지 않으며, 업로드 중에 404 오류를 반환합니다.
멀티스레드 복사를 비활성화하려면 Rails 콘솔 액세스가 있는 GitLab 관리자에게 다음 명령을 실행하도록 요청합니다:
Feature.disable(:s3_multithreaded_uploads)
Rails 콘솔을 통한 수동 테스트#
잘못된 구성이 의심될 때 오브젝트 스토리지 연결을 확인하는 데 이 방법을 사용합니다. 다음 예시는 연결을 테스트하고, 테스트 오브젝트를 작성하고, 다시 읽습니다.
-
Rails 콘솔을 시작합니다.
-
/etc/gitlab/gitlab.rb에서 설정한 것과 동일한 파라미터를 사용하여 오브젝트 스토리지 연결을 설정합니다. 다음 예시 형식을 사용합니다:기존 업로드 구성을 사용하는 예시 연결:
settings = Gitlab.config.uploads.object_store.connection.deep_symbolize_keys connection = Fog::Storage.new(settings)액세스 키를 사용하는 예시 연결:
connection = Fog::Storage.new( { provider: 'AWS', region: 'eu-central-1', aws_access_key_id: '', aws_secret_access_key: '' } )AWS IAM 프로파일을 사용하는 예시 연결:
connection = Fog::Storage.new( { provider: 'AWS', use_iam_profile: true, region: 'us-east-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')
추가 디버깅 활성화#
히스토리
AWS_DEBUG환경 변수 지원이 GitLab 18.3에서 도입되었습니다.
HTTP 요청을 보기 위해 추가 디버깅을 활성화할 수도 있습니다. 로그 파일에 자격 증명이 유출되지 않도록 Rails 콘솔에서 수행해야 합니다. 다음은 다양한 제공자에 대한 요청 디버깅을 활성화하는 방법을 보여줍니다:
EXCON_DEBUG 환경 변수를 설정합니다:
ENV['EXCON_DEBUG'] = "1"
AWS_DEBUG 환경 변수를 1로 설정하여 GitLab Workhorse 로그에서 S3 HTTP 요청 및 응답 헤더 로깅을 활성화할 수도 있습니다. Linux 패키지 (Omnibus)의 경우:
-
/etc/gitlab/gitlab.rb를 편집하고 다음 줄을 추가합니다:gitlab_workhorse['env'] = { 'AWS_DEBUG' => '1' } -
파일을 저장하고 GitLab을 재구성합니다:
sudo gitlab-ctl reconfigureS3 호환 스토리지 요청 및 응답 헤더는
/var/log/gitlab/gitlab-workhorse/current에 기록됩니다.
STDOUT에 로그하도록 로거를 구성합니다:
Google::Apis.logger = Logger::new(STDOUT)
DEBUG 환경 변수를 설정합니다:
ENV['DEBUG'] = "1"
Geo 추적 데이터베이스를 재설정하여 전체 오브젝트 일관성 확인#
다음 Geo 시나리오를 가정합니다:
- 환경이 Geo 기본 및 보조 노드로 구성됩니다.
- 기본에서 오브젝트 스토리지로 마이그레이션했습니다.
- 보조는 별도의 오브젝트 스토리지 버킷을 사용합니다.
- "이 보조 사이트가 오브젝트 스토리지에서 콘텐츠를 복제하도록 허용" 옵션이 활성화되어 있습니다.
이러한 마이그레이션은 오브젝트가 추적 데이터베이스에서 동기화된 것으로 표시되지만 실제로는 오브젝트 스토리지에서 물리적으로 누락될 수 있습니다. 이 경우 Geo 보조 사이트 복제를 재설정하여 마이그레이션 후 오브젝트 상태가 일관성을 유지하도록 합니다.
오브젝트 스토리지로 마이그레이션 후 불일치#
로컬 스토리지에서 오브젝트 스토리지로 마이그레이션할 때 데이터 불일치가 발생할 수 있습니다. 특히 마이그레이션 전에 파일이 수동으로 삭제된 경우 Geo와 함께 사용할 때 특히 그렇습니다.
예를 들어, 인스턴스 관리자가 로컬 파일 시스템에서 여러 아티팩트를 수동으로 삭제합니다. 이러한 변경은 데이터베이스에 제대로 전파되지 않아 불일치를 초래합니다. 오브젝트 스토리지로 마이그레이션한 후 이러한 불일치가 남아 있어 문제를 일으킬 수 있습니다. Geo 보조는 데이터베이스에서 여전히 참조되지만 더 이상 존재하지 않는 파일을 계속 복제하려고 할 수 있습니다.
Geo 사용 시 불일치 식별#
다음 Geo 시나리오를 가정합니다:
- 환경이 Geo 기본 및 보조 노드로 구성됩니다.
- 두 시스템 모두 오브젝트 스토리지로 마이그레이션되었습니다.
- 보조는 기본과 동일한 오브젝트 스토리지를 사용합니다.
Allow this secondary site to replicate content on Object Storage옵션이 비활성화되어 있습니다.
- 오브젝트 스토리지 마이그레이션 전에 여러 업로드가 수동으로 삭제되었습니다.
- 이 예시에서는 이슈에 업로드된 두 이미지
이러한 시나리오에서 보조는 기본과 동일한 오브젝트 스토리지를 사용하므로 더 이상 데이터를 복제할 필요가 없습니다. 불일치로 인해 관리자는 보조가 여전히 데이터를 복제하려고 하는 것을 관찰할 수 있습니다:
기본 사이트에서:
- 오른쪽 상단에서 Admin을 선택합니다.
- 왼쪽 사이드바에서 Geo > Sites를 선택합니다.
- 기본 사이트를 보고 확인 정보를 확인합니다. 모든 업로드가 확인되었습니다:

- 보조 사이트를 보고 확인 정보를 확인합니다. 보조가 동일한 오브젝트 스토리지를 사용함에도 불구하고 두 개의 업로드가 여전히 동기화되고 있습니다. 즉, 업로드를 동기화할 필요가 없습니다:

불일치 정리#
삭제 명령을 실행하기 전에 최근의 작동하는 백업이 있는지 확인합니다.
이전 시나리오를 기반으로 아래 예시로 사용되는 불일치를 유발하는 여러 업로드가 있습니다.
잠재적인 잔여물을 올바르게 삭제하려면 다음 절차를 따릅니다:
-
식별된 불일치를 해당 모델 이름에 매핑합니다. 모델 이름은 다음 단계에서 필요합니다.
오브젝트 스토리지 유형 모델 이름 백업 해당 없음 컨테이너 레지스트리 해당 없음 Mattermost 해당 없음 오토스케일 런너 캐싱 해당 없음 Secure Files Ci::SecureFile작업 아티팩트 Ci::JobArtifact및Ci::PipelineArtifactLFS 오브젝트 LfsObject업로드 Upload머지 리퀘스트 diff MergeRequestDiff패키지 Packages::PackageFileDependency Proxy DependencyProxy::Blob및DependencyProxy::ManifestTerraform 상태 파일 Terraform::StateVersionPages 콘텐츠 PagesDeployment -
Rails 콘솔을 시작합니다.
-
이전 단계의 모델 이름을 기반으로 여전히 로컬에 저장된 모든 "파일"을 쿼리합니다 (오브젝트 스토리지 대신). 이 경우 업로드가 영향을 받으므로 모델 이름
Upload가 사용됩니다.openbao.png가 여전히 로컬에 저장되어 있음을 확인합니다:Upload.with_files_stored_locally#] -
식별된 리소스의
id를 사용하여 올바르게 삭제합니다. 먼저find를 사용하여 올바른 리소스인지 확인한 다음destroy를 실행합니다:Upload.find(108) Upload.find(108).destroy -
선택적으로
find를 다시 실행하여 리소스가 올바르게 삭제되었는지 확인합니다. 더 이상 찾을 수 없어야 합니다:Upload.find(108)ActiveRecord::RecordNotFound: Couldn't find Upload with 'id'=108
모든 영향받은 오브젝트 스토리지 유형에 대해 단계를 반복합니다.
다중 노드 GitLab 인스턴스에서 작업 로그 누락#
하나 이상의 Rails 노드 (웹 서비스 또는 Sidekiq를 실행하는 서버)가 있는 GitLab 인스턴스에서는 작업 로그가 Runner에서 전송된 후 모든 노드에서 사용 가능하게 하는 메커니즘이 필요합니다. 작업 로그는 로컬 디스크 또는 오브젝트 스토리지에 저장할 수 있습니다.
NFS를 사용하지 않고 증분 로깅 기능이 활성화되지 않은 경우, 작업 로그가 손실될 수 있습니다:
- 런너에서 로그를 수신하는 노드가 로컬 디스크에 로그를 씁니다.
- GitLab이 로그를 아카이브하려고 할 때, 종종 해당 로그에 액세스할 수 없는 다른 서버에서 작업이 실행됩니다.
- 오브젝트 스토리지에 업로드가 실패합니다.
다음 오류도 /var/log/gitlab/gitlab-rails/exceptions_json.log에 기록될 수 있습니다:
{
"severity": "ERROR",
"exception.class": "Ci::AppendBuildTraceService::TraceRangeError",
"extra.build_id": 425187,
"extra.body_end": 12955,
"extra.stream_size": 720,
"extra.stream_class": {},
"extra.stream_range": "0-12954"
}
다중 노드 환경에서 CI 아티팩트가 오브젝트 스토리지에 기록되는 경우, 증분 로깅 기능을 활성화해야 합니다.
