GitLab 컨테이너 레지스트리 관리

Tier: Free, Premium, Ultimate Offering: Self-Managed
note
차세대 컨테이너 레지스트리가 이제 베타 기능으로 자체 관리 인스턴스에서 업그레이드 및 테스트할 수 있습니다. 이 업그레이드된 레지스트리는 온라인 가비지 수집을 지원하며, 중요한 성능 및 신뢰성 개선이 있습니다.

GitLab 컨테이너 레지스트리를 사용하면 각 프로젝트마다 Docker 이미지를 저장할 수 있는 공간을 지닐 수 있습니다.

배포 레지스트리에 대한 자세한 내용은 다음을 참조하세요:

이 문서는 관리자 가이드입니다. GitLab 컨테이너 레지스트리 사용 방법에 대해 알아보려면 사용자 설명서를 참조하세요.

컨테이너 레지스트리 활성화

컨테이너 레지스트리를 활성화하는 프로세스는 사용하는 설치 유형에 따라 다릅니다.

Linux 패키지 설치

Linux 패키지를 사용하여 GitLab을 설치한 경우, 컨테이너 레지스트리는 기본적으로 사용 가능할 수도 있고 아닐 수도 있습니다.

컨테이너 레지스트리는 내장 Let’s Encrypt 통합을 사용하는 경우 GitLab 도메인의 포트 5050에서 자동으로 활성화되어 사용할 수 있습니다.

그렇지 않으면 컨테이너 레지스트리가 활성화되지 않습니다. 활성화하려면:

컨테이너 레지스트리는 기본적으로 HTTPS에서 작동합니다. HTTP를 사용할 수 있지만 권장되지는 않으며 이 문서의 범위를 벗어납니다.

자체 컴파일 설치

만약 GitLab 설치를 스스로 컴파일했다면:

  1. GitLab 버전에 해당하는 이미지를 사용하여 레지스트리를 배포해야 합니다. (예: registry.gitlab.com/gitlab-org/build/cng/gitlab-container-registry:v3.15.0-gitlab)
  2. 설치가 완료된 후, 활성화하려면 레지스트리의 설정을 gitlab.yml에 구성해야 합니다.
  3. lib/support/nginx/registry-ssl에서 샘플 NGINX 구성 파일을 사용하고 호스트, 포트 및 TLS 인증서 경로와 일치하도록 수정해야 합니다.

gitlab.yml의 내용은 다음과 같습니다.

registry:
  enabled: true
  host: registry.gitlab.example.com
  port: 5005
  api_url: http://localhost:5000/
  key: config/registry.key
  path: shared/registry
  issuer: gitlab-issuer

여기서:

매개변수 설명
enabled true 또는 false. GitLab에서 레지스트리를 활성화합니다. 기본적으로 비활성화되어 있습니다.
host 레지스트리가 실행되고 사용자가 사용할 수 있는 호스트 URL.
port 외부 레지스트리 도메인이 수신 대기하는 포트.
api_url 레지스트리가 노출되는 내부 API URL. 기본값은 http://localhost:5000입니다. 이것은 외부 도커 레지스트리를 설정하는 경우를 제외하고 변경하지 마십시오.
key rootcertbundle 레지스트리의 쌍인 프라이빗 키 위치.
path 이 경로는 레지스트리의 rootdirectory에서 지정한 것과 동일해야 합니다. 이 경로는 GitLab 사용자, 웹 서버 사용자 및 레지스트리 사용자가 읽을 수 있어야 합니다.
issuer 레지스트리의 issuer에서 구성한 값과 동일해야 합니다.

GitLab을 소스에서 설치한 경우에는 레지스트리 init 파일이 함께 제공되지 않습니다. 따라서 GitLab을 다시 시작하더라도 설정을 수정해도 레지스트리가 다시 시작되지 않습니다. 그것을 달성하는 방법에 대한 상위 문서를 읽어보세요.

최소한 레지스트리 구성이 서비스로 container_registry를 사용하고 인증을 위한 https://gitlab.example.com/jwt/auth로 확인되어야 합니다.

auth:
  token:
    realm: https://gitlab.example.com/jwt/auth
    service: container_registry
    issuer: gitlab-issuer
    rootcertbundle: /root/certs/certbundle

경고: 만약 auth가 설정되지 않았다면 사용자는 인증 없이 Docker 이미지를 끌어올 수 있습니다.

컨테이너 레지스트리 도메인 구성

레지스트리의 외부 도메인은 다음 중 하나의 방법으로 구성할 수 있습니다:

컨테이너 레지스트리는 TLS 인증서가 필요하기 때문에 비용이 발생할 수 있습니다.

최초 컨테이너 레지스트리를 구성하기 전에 이 사항을 고려해 보세요.

기존 GitLab 도메인 하에 컨테이너 레지스트리 구성

컨테이너 레지스트리가 기존 GitLab 도메인을 사용하도록 구성된 경우, 컨테이너 레지스트리를 포트에 노출할 수 있습니다. 이렇게 하면 기존 GitLab TLS 인증서를 재사용할 수 있습니다.

만약 GitLab 도메인이 https://gitlab.example.com이고 외부 세계로의 포트가 5050이라면 컨테이너 레지스트리를 구성하려면:

  • Linux 패키지 설치를 사용하는 경우 gitlab.rb를 편집하세요.
  • 소스로 컴파일한 설치를 사용하는 경우 gitlab.yml을 편집하세요.

참고: 호스트와 컨테이너 방화벽 규칙은 registry_external_url 라인에 나열된 포트를 통해 내부 트래픽을 허용하도록 구성되어야 하며, 기본값인 gitlab_rails['registry_port'] (기본값 5000)가 아닌 포트를 사용하도록 합니다.

컨테이너 레지스트리 전체 사이트에서 비활성화

이러한 단계를 따라 레지스트리를 비활성화하면 기존의 Docker 이미지가 삭제되지는 않습니다. Docker 이미지 삭제는 레지스트리 응용 프로그램 자체에서 처리됩니다.

Linux 패키지 (Omnibus)
  1. /etc/gitlab/gitlab.rb를 열고 registry['enable']false로 설정합니다:

    registry['enable'] = false
    
  2. 파일을 저장하고 변경 사항이 적용되도록 GitLab을 재구성합니다.

자체 컴파일 (소스)
  1. /home/git/gitlab/config/gitlab.yml을 열고 registry 항목을 찾아 enabledfalse로 설정합니다:

    registry:
      enabled: false
    
  2. 파일을 저장하고 변경 사항이 적용되도록 GitLab을 다시 시작합니다.

사이트 전체에서 새 프로젝트를 위한 컨테이너 레지스트리 비활성화

컨테이너 레지스트리가 활성화된 경우, 모든 새 프로젝트에서 사용할 수 있어야 합니다. 이 기능을 비활성화하고 프로젝트 소유자가 스스로 컨테이너 레지스트리를 활성화할 수 있도록하려면 다음 단계를 따르세요.

Linux 패키지 (Omnibus)
  1. /etc/gitlab/gitlab.rb를 편집하고 다음 라인을 추가합니다:

    gitlab_rails['gitlab_default_projects_features_container_registry'] = false
    
  2. 파일을 저장하고 변경 사항이 적용되도록 GitLab을 재구성합니다.

자체 컴파일 (소스)
  1. /home/git/gitlab/config/gitlab.yml을 열고 default_projects_features 항목을 찾아 container_registryfalse로 설정합니다:

    ## 기본 프로젝트 기능 설정
    default_projects_features:
      issues: true
      merge_requests: true
      wiki: true
      snippets: false
      builds: true
      container_registry: false
    
  2. 파일을 저장하고 변경 사항이 적용되도록 GitLab을 다시 시작합니다.

토큰 기간 증가

GitLab에서 컨테이너 레지스트리 토큰의 유효 기간은 5분입니다. 토큰 기간을 증가시키려면:

  1. 왼쪽 사이드바에서 관리자 영역을 선택합니다.
  2. 설정 > CI/CD를 선택합니다.
  3. 컨테이너 레지스트리를 확장합니다.
  4. 인가 토큰 기간(분)을 업데이트합니다.
  5. 변경 사항 저장을 선택합니다.

컨테이너 레지스트리용 저장소 구성

참고: 지원하는 저장소 백엔드에서는 모든 버킷에 저장된 비현재 버전 객체를 보존, 검색, 복원하기 위해 객체 버전 관리를 사용할 수 있습니다. 그러나 이로 인해 더 많은 저장소 사용량과 비용이 발생할 수 있습니다. 레지스트리의 작동 방식에 따라 이미지 업로드는 먼저 임시 경로에 저장되고 그런 다음 최종 위치로 전송됩니다. S3 및 GCS와 같은 객체 저장소 백엔드에서는 이 전송이 복사 후 삭제로 이루어집니다. 객체 버전 관리가 활성화되면 삭제된 임시 업로드 아티팩트는 비현재 버전으로 유지되므로 저장소 버킷 크기가 증가합니다. 비현재 버전이 일정 시간이 지난 후 삭제되도록 보장하려면 저장소 제공업체와 객체 라이프사이클 정책을 구성해야 합니다.

경고: 컨테이너 레지스트리에 의해 저장된 파일이나 객체를 직접 수정하지 마십시오. 레지스트리가 이러한 항목을 작성하거나 삭제하는 것 이외의 작업을 수행하면 인스턴스 전체의 데이터 일관성 및 안정성 문제가 발생할 수 있습니다. 이러한 문제로부터 복구할 수 없을 수도 있습니다.

컨테이너 레지스트리를 다양한 저장소 백엔드를 사용하도록 구성하려면 저장소 드라이버를 구성하세요. 기본적으로 GitLab 컨테이너 레지스트리는 파일 시스템 드라이버 구성을 사용합니다.

다음과 같은 다른 지원되는 드라이버가 있습니다:

드라이버 설명
filesystem 로컬 파일 시스템의 경로 사용
azure Microsoft Azure Blob Storage
gcs Google Cloud Storage
s3 Amazon Simple Storage Service. 올바른 S3 Permission Scopes로 스토리지 버킷을 구성해야 합니다.

거의 모든 S3 호환 서비스(예: MinIO)는 컨테이너 레지스트리와 함께 작동해야 하지만, 우리는 AWS S3에 대해만 지원을 보장합니다. 제 3자 S3 구현의 정확성을 단언할 수 없기 때문에, 문제에 대한 디버깅은 할 수 있지만, AWS S3 버킷에서 문제가 재현되지 않는 한 레지스트리를 패치할 수는 없습니다.

경고: 다음 드라이버에 대한 지원은 GitLab 16.6에서 폐기 예정되었으며 17.0에서 삭제될 예정입니다. 이 변경 사항은 주요 변경 사항입니다.

드라이버 설명
swift OpenStack Swift Object Storage
oss Aliyun OSS

파일 시스템 사용

이미지를 파일 시스템에 저장하려면 컨테이너 레지스트리의 저장 경로를 변경할 수 있습니다. 아래 단계를 따라주세요.

이 경로는 다음과 같이 접근할 수 있습니다:

  • 컨테이너 레지스트리 데몬을 실행하는 사용자
  • GitLab을 실행하는 사용자

모든 GitLab, 레지스트리 및 웹 서버 사용자는 이 디렉터리에 액세스해야 합니다.

Linux 패키지 (Omnibus)

Linux 패키지 설치의 기본 이미지 저장 위치는 /var/opt/gitlab/gitlab-rails/shared/registry입니다. 변경하려면:

  1. /etc/gitlab/gitlab.rb 파일을 편집하세요:

    gitlab_rails['registry_path'] = "/path/to/registry/storage"
    
  2. 파일을 저장하고 변경 사항이 적용되도록 GitLab을 다시 구성하세요.

:::

직접 컴파일 (원본)

자체로 컴파일한 설치의 기본 이미지 저장 위치는 /home/git/gitlab/shared/registry입니다. 변경하려면:

  1. /home/git/gitlab/config/gitlab.yml을 열고 registry 항목을 찾아 path 설정을 변경하세요:

    registry:
      path: shared/registry
    
  2. 파일을 저장하고 변경 사항이 적용되도록 GitLab을 다시 시작하세요.

:::

객체 저장소 사용

이미지를 객체 저장소에 저장하려면 컨테이너 레지스트리의 저장 드라이버를 변경할 수 있습니다.

GitLab에서 객체 저장소 사용에 대해 자세히 알아보기.

경고: 파일 시스템에 저장되지 않은 Docker 이미지는 GitLab에서 백업하지 않습니다. 원하는 경우 객체 저장소 공급 업체와 백업을 활성화하세요.

Linux 패키지 설치용 s3gcs 저장 드라이버 구성

다음 구성 단계는 s3gcs 저장 드라이버를 위한 것입니다. 다른 저장 드라이버도 지원됩니다.

Linux 패키지 설치용 s3 저장 드라이버를 구성하려면:

  1. /etc/gitlab/gitlab.rb 파일을 편집하세요:

    registry['storage'] = {
      's3' => {
        'accesskey' => 's3-access-key',
        'secretkey' => 's3-secret-key-for-access-key',
        'bucket' => 'your-s3-bucket',
        'region' => 'your-s3-region',
        'regionendpoint' => 'your-s3-regionendpoint'
      }
    }
    

    정적 자격 증명을 사용하지 않으려면 IAM 역할을 사용하고 accesskeysecretkey를 생략하세요. IAM 프로필이 Docker에서 문서화된 권한을 따르는지 확인하세요.

    registry['storage'] = {
      's3' => {
        'bucket' => 'your-s3-bucket',
        'region' => 'your-s3-region'
      }
    }
    

    AWS S3 VPC 엔드포인트를 사용하는 경우 regionendpoint를 VPC 엔드포인트 주소로 설정하고 pathstyle을 false로 설정하세요:

    registry['storage'] = {
      's3' => {
        'accesskey' => 's3-access-key',
        'secretkey' => 's3-secret-key-for-access-key',
        'bucket' => 'your-s3-bucket',
        'region' => 'your-s3-region',
        'regionendpoint' => 'your-s3-vpc-endpoint',
        'pathstyle' => false
      }
    }
    
    • regionendpoint는 MinIO와 같은 S3 호환 서비스 구성 또는 AWS S3 VPC 엔드포인트를 구성할 때만 필요합니다.
    • your-s3-bucket은 존재하는 버킷의 이름이어야 하며 하위 디렉터리를 포함할 수 없습니다.
    • pathstylehost/bucket_name/object 스타일 경로 대신 bucket_name.host/object를 사용하려면 false로 설정하세요. AWS S3에서 false로 설정하세요.

    S3 API에서 503 오류를 피하기 위해 S3에 대한 연결 속도 제한을 설정할 수 있습니다. 이를 위해 maxrequestspersecondS3 요청 속도 제한 범위 내의 숫자로 설정하세요:

       registry['storage'] = {
       's3' => {
         'accesskey' => 's3-access-key',
         'secretkey' => 's3-secret-key-for-access-key',
         'bucket' => 'your-s3-bucket',
         'region' => 'your-s3-region',
         'regionendpoint' => 'your-s3-regionendpoint',
         'maxrequestspersecond' => 100
       }
     }
    
  2. 파일을 저장하고 변경 사항이 적용되도록 GitLab을 다시 구성하세요.

Linux 패키지 설치용 gcs 저장 드라이버를 구성하려면:

  1. /etc/gitlab/gitlab.rb 파일을 편집하세요:

       registry['storage'] = {
       'gcs' => {
         'bucket' => 'BUCKET_NAME',
         'keyfile' => 'PATH/TO/KEYFILE',
         # 레지스트리 이외의 다른 앱과 버킷을 공유하는 경우 다음을 주석 처리 해제하세요:
         # 'rootdirectory' => '/gcs/object/name/prefix'
       }
     }
    

    GitLab은 사용 가능한 모든 매개변수를 지원합니다.

  2. 파일을 저장하고 변경 사항이 적용되도록 GitLab을 다시 구성하세요.

자체 컴파일된 설치

저장 드라이버를 구성하는 작업은 Docker 레지스트리를 배포할 때 생성된 레지스트리 구성 YAML 파일에서 수행됩니다.

s3 저장 드라이버 예시:

storage:
  s3:
    accesskey: 's3-access-key'                # IAM 역할을 사용하는 경우 필요하지 않음
    secretkey: 's3-secret-key-for-access-key' # IAM 역할을 사용하는 경우 필요하지 않음
    bucket: 'your-s3-bucket'
    region: 'your-s3-region'
    regionendpoint: 'your-s3-regionendpoint'
  cache:
    blobdescriptor: inmemory
  delete:
    enabled: true

your-s3-bucket은 존재해야 하는 버킷의 이름이어야 하며, 하위 디렉토리를 포함할 수 없습니다.

다운타임 없이 객체 스토리지로 마이그레이션

경고: S3 버킷 간 레지스트리 데이터를 복사하려면 AWS DataSync을 사용하면 버킷에 잘못된 메타데이터 개체가 생성됩니다. 자세한 내용은 이름이 비어있는 태그을 참조하세요. 레지스트리 데이터를 S3 버킷 간에 이동하려면 AWS CLI의 sync 작업을 권장합니다.

컨테이너 레지스트리를 중지하지 않고 스토리지를 마이그레이션하려면 컨테이너 레지스트리를 읽기 전용 모드로 설정하세요. 큰 인스턴스의 경우 컨테이너 레지스트리가 어느 정도의 시간 동안 읽기 전용 모드여야 할 수 있습니다. 이 기간 동안 컨테이너 레지스트리에서 가져올 수는 있지만 푸시할 수는 없습니다.

  1. 선택 사항: 마이그레이션할 데이터 양을 줄이려면 다운타임 없이 가비지 수집 도구를 실행하세요.
  2. 이 예시는 aws CLI를 사용합니다. CLI를 이전에 구성하지 않은 경우 sudo aws configure를 실행하여 자격 증명을 구성해야 합니다. 아마도 관리자가 아닌 사용자는 컨테이너 레지스트리 폴더에 액세스할 수 없을 것이므로 sudo를 사용해야 합니다. 자격 증명 구성을 확인하려면 ls를 실행하여 모든 버킷을 나열하세요.

    sudo aws --endpoint-url https://your-object-storage-backend.com s3 ls
    

    AWS를 백엔드로 사용하는 경우 --endpoint-url이 필요하지 않습니다.

  3. 초기 데이터를 S3 버킷에 복사하려면, 예를 들어 aws CLI의 cp 또는 sync 명령을 사용하세요. 버킷 내에서 docker 폴더를 최상위 폴더로 유지해야 합니다.

    sudo aws --endpoint-url https://your-object-storage-backend.com s3 sync registry s3://mybucket
    

    참고: 많은 양의 데이터가 있는 경우 병렬 동기화 작업을 실행하여 성능을 향상시킬 수 있습니다.

  4. 최종 데이터 동기화를 수행하려면, 컨테이너 레지스트리를 읽기 전용 모드로 설정하고 GitLab을 다시 구성하세요.
  5. 초기 데이터로부터의 변경 사항을 S3 버킷으로 동기화하고 대상 버킷에만 있는 파일을 삭제하세요:

    sudo aws --endpoint-url https://your-object-storage-backend.com s3 sync registry s3://mybucket --delete --dryrun
    

    명령이 예상대로 수행되는지 확인한 후, --dryrun 플래그를 제거하고 명령을 실행하세요.

    경고: --delete 플래그는 대상에만 있는 파일을 삭제합니다. 소스와 대상을 바꾸면 레지스트리의 모든 데이터가 삭제됩니다.

  6. 모든 컨테이너 레지스트리 파일이 객체 스토리지에 업로드되었는지 확인하기 위해 다음 두 명령어로 반환된 파일 수를 확인하세요:

    sudo find registry -type f | wc -l
    
    sudo aws --endpoint-url https://your-object-storage-backend.com s3 ls s3://mybucket --recursive | wc -l
    

    이러한 명령의 출력은 _uploads 디렉토리와 하위 디렉토리를 제외하고 일치해야 합니다.

  7. 레지스트리를 S3 버킷을 사용하도록 구성하세요.
  8. 변경 사항이 적용되려면 레지스트리를 읽기-쓰기 모드로 다시 설정하고 GitLab을 다시 구성하세요.

Azure Object Storage로 이동

  • 스토리지 드라이버의 기본 구성은 GitLab 16.0에서 변경 예정입니다.

기존 파일 시스템이나 다른 객체 스토리지 제공업체에서 Azure Object Storage로 이동하는 경우 레지스트리를 표준 루트 디렉토리를 사용하도록 구성해야 합니다. 레지스트리 구성의 Azure 스토리지 드라이버 섹션에 trimlegacyrootprefix: true을 설정하여 구성하세요. 이 구성이 없으면 Azure 스토리지 드라이버는 마이그레이션된 이미지에 액세스할 수 없도록 루트 경로의 첫 번째 섹션으로 /대신 //를 사용합니다.

Linux Package (Omnibus)
registry['storage'] = {
  'azure' => {
    'accountname' => 'accountname',
    'accountkey' => 'base64encodedaccountkey',
    'container' => 'containername',
    'rootdirectory' => '/azure/virtual/container',
    'trimlegacyrootprefix' => true
  }
}
Self-compiled (source)
storage:
  azure:
    accountname: accountname
    accountkey: base64encodedaccountkey
    container: containername
    rootdirectory: /azure/virtual/container
    trimlegacyrootprefix: true

기본적으로 Azure 스토리지 드라이버는 core.windows.net 영역을 사용합니다. azure 섹션에서 realm의 다른 값을 설정할 수 있습니다 (예: Azure Government Cloud를 위해 core.usgovcloudapi.net).

스토리지 드라이버의 리디렉션 비활성화

기본적으로 원격 백엔드로 구성된 레지스트리에 액세스하는 사용자는 스토리지 드라이버의 기본 백엔드로 리디렉션됩니다. 예를 들어, 레지스트리는 원격 S3 버킷으로 요청을 리디렉션하여 GitLab 서버의 부하를 줄일 수 있습니다.

그러나 일반적으로 공개 서버에 액세스할 수 없는 내부 호스트에서 사용되는 레지스트리에 대해 이 동작은 원치 않을 수 있습니다. 리디렉트를 비활성화하고 프록시 다운로드를 설정하려면 다음과 같이 disable 플래그를 true로 설정하세요. 이로 인해 모든 트래픽이 항상 레지스트리 서비스를 통해 전달됩니다. 이로 인해 보안이 향상되지만(스토리지 백엔드에 공개 액세스할 필요가 없음) 성능이 악화됩니다(모든 트래픽이 서비스를 통해 리디렉션됨).

Linux Package (Omnibus)
  1. /etc/gitlab/gitlab.rb을 편집하세요.

    registry['storage'] = {
      's3' => {
        'accesskey' => 's3-access-key',
        'secretkey' => 's3-secret-key-for-access-key',
        'bucket' => 'your-s3-bucket',
        'region' => 'your-s3-region',
        'regionendpoint' => 'your-s3-regionendpoint'
      },
      'redirect' => {
        'disable' => true
      }
    }
    
  2. 파일을 저장하고 변경 사항이 적용되도록 GitLab을 다시 구성하세요.

Self-compiled (source)
  1. 레지스트리 구성 YAML 파일에 redirect 플래그를 추가하세요.

    storage:
      s3:
        accesskey: 'AKIAKIAKI'
        secretkey: 'secret123'
        bucket: 'gitlab-registry-bucket-AKIAKIAKI'
        region: 'your-s3-region'
        regionendpoint: 'your-s3-regionendpoint'
      redirect:
        disable: true
      cache:
        blobdescriptor: inmemory
      delete:
        enabled: true
    
  2. 파일을 저장하고 변경 사항이 적용되도록 GitLab을 다시 시작하세요.

암호화된 S3 버킷

S3 버킷에 AWS KMS를 사용하여 서버 측 암호화를 할 수 있습니다. 이를 사용하려면 기본적으로 SSE-S3 또는 SSE-KMS 암호화가 활성화된 S3 버킷에 대해 encrypt 옵션을 활성화해야 합니다. 고객 마스터 키(CMK) 및 SSE-C 암호화는 모든 요청에 암호화 키를 보내야 하므로 지원되지 않습니다.

SSE-S3를 사용하려면 설치 방법에 따라 GitLab을 설치한 방법과 일치하는 지침에 따라서 레지스트리 설정에서 encrypt 옵션을 활성화해야 합니다.

Linux Package (Omnibus)
  1. /etc/gitlab/gitlab.rb을 편집하세요.

    registry['storage'] = {
      's3' => {
        'accesskey' => 's3-access-key',
        'secretkey' => 's3-secret-key-for-access-key',
        'bucket' => 'your-s3-bucket',
        'region' => 'your-s3-region',
        'regionendpoint' => 'your-s3-regionendpoint',
        'encrypt' => true
      }
    }
    
  2. 파일을 저장하고 변경 사항이 적용되도록 GitLab을 다시 구성하세요.

Self-compiled (source)
  1. 레지스트리 구성 YAML 파일을 편집하세요.

    storage:
      s3:
        accesskey: 'AKIAKIAKI'
        secretkey: 'secret123'
        bucket: 'gitlab-registry-bucket-AKIAKIAKI'
        region: 'your-s3-region'
        regionendpoint: 'your-s3-regionendpoint'
        encrypt: true
    
  2. 파일을 저장하고 변경 사항이 적용되도록 GitLab을 다시 시작하세요.

저장 공간 제한

저장 공간 제한이 없으므로 사용자는 무제한으로 크기가 임의인 Docker 이미지를 업로드할 수 있습니다. 이 설정은 향후 릴리스에서 구성 가능해야 합니다.

레지스트리의 내부 포트 변경

기본적으로 레지스트리 서버는 로컬호스트의 포트 5000에서 수신 대기합니다. 이는 레지스트리 서버가 연결을 수락해야 하는 주소입니다. 아래 예제에서는 레지스트리의 포트를 5010으로 설정합니다.

Linux 패키지 (Omnibus)
  1. /etc/gitlab/gitlab.rb를 열고 registry['registry_http_addr']을 설정합니다:

    registry['registry_http_addr'] = "localhost:5010"
    
  2. 파일을 저장하고 변경 사항이 적용되도록 GitLab을 다시 구성합니다.

직접 컴파일 (소스)
  1. 레지스트리 서버의 구성 파일을 열고 http:addr 값을 편집합니다:

    http:
      addr: localhost:5010
    
  2. 파일을 저장하고 레지스트리 서버를 다시 시작합니다.

프로젝트별 컨테이너 레지스트리 비활성화

GitLab 인스턴스에서 레지스트리가 활성화되어 있지만 프로젝트에서 필요하지 않은 경우, 프로젝트 설정에서 비활성화할 수 있습니다.

GitLab을 인증 엔드포인트로 사용하여 외부 컨테이너 레지스트리 사용

경고: GitLab 15.8에서는 GitLab에서의 제3자 컨테이너 레지스트리 사용이 폐기되었으며, 지원은 GitLab 16.0에서 종료되었습니다. GitLab 컨테이너 레지스트리 대신 제3자 컨테이너 레지스트리를 사용해야 하는 경우 피드백 이슈 958에서 사용 사례를 알려주세요.

외부 컨테이너 레지스트리를 사용하는 경우, 컨테이너 레지스트리와 관련된 일부 기능이 사용할 수 없거나 본질적인 위험을 가질 수 있습니다.

통합이 작동하려면 외부 레지스트리가 GitLab과 인증하기 위해 JSON Web Token을 사용하도록 구성되어 있어야 합니다. 외부 레지스트리의 런타임 구성은 다음 항목을 반드시 포함해야 합니다.

auth:
  token:
    realm: https://gitlab.example.com/jwt/auth
    service: container_registry
    issuer: gitlab-issuer
    rootcertbundle: /root/certs/certbundle

이러한 항목이 없으면 레지스트리 로그인은 GitLab에서 인증할 수 없습니다. 또한 GitLab은 프로젝트 계층 구조 아래의 중첩 이미지 이름을 알 수 없으며, registry.example.com/group/project/image-name:tag 또는 registry.example.com/group/project/my/image-name:tag와 같이 인식하며 registry.example.com/group/project:tag만 인식합니다.

Linux 패키지 설치

외부 컨테이너 레지스트리를 사용하여 GitLab을 인증 엔드포인트로 사용할 수 있습니다.

  1. /etc/gitlab/gitlab.rb를 열고 필요한 구성을 설정합니다:

    gitlab_rails['registry_enabled'] = true
    gitlab_rails['registry_api_url'] = "https://<external_registry_host>:5000"
    gitlab_rails['registry_issuer'] = "gitlab-issuer"
    
    • gitlab_rails['registry_enabled'] = true은 GitLab 컨테이너 레지스트리 기능과 인증 엔드포인트를 활성화하는 데 필요합니다. 이를 활성화해도 GitLab 번들 된 컨테이너 레지스트리 서비스는 시작되지 않습니다.
    • gitlab_rails['registry_api_url'] = "http://<external_registry_host>:5000"은 레지스트리가 설치된 호스트와 일치하도록 변경해야 합니다. 외부 레지스트리가 TLS를 사용하도록 구성된 경우 https를 지정해야 합니다.
  2. GitLab과 외부 컨테이너 레지스트리가 안전하게 통신하도록 인증서-키 쌍이 필요합니다. 외부 컨테이너 레지스트리에서 공개 인증서(rootcertbundle)로 구성하고 GitLab에서 개인 키로 구성해야 합니다. 이를 위해 /etc/gitlab/gitlab.rb에 다음을 추가합니다:

    # registry['internal_key']에 사용자 지정 키 파일의 내용이 포함되어야 합니다.
    # 키 파일의 줄 바꿈은 `\n` 문자를 사용하여 표시해야 합니다.
    # 예시:
    registry['internal_key'] = "---BEGIN RSA PRIVATE KEY---\nMIIEpQIBAA\n"
    
    # 리눅스 패키지 설치를 위한 사용자 정의 파일을 registry['internal_key']의 내용을 쓰도록 정의할 수 있습니다.
    gitlab_rails['registry_key_path'] = "/custom/path/to/registry-key.key"
    

    구성이 실행될 때마다 registry_key_path에서 지정된 파일에 internal_key로 지정된 내용이 채워집니다. 파일이 지정되지 않으면 리눅스 패키지 설치는 기본적으로 /var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key로 지정하고 채웁니다.

  3. GitLab 컨테이너 레지스트리 페이지에 표시되는 컨테이너 레지스트리 URL을 변경하려면 다음 구성을 설정합니다:

    gitlab_rails['registry_host'] = "registry.gitlab.example.com"
    gitlab_rails['registry_port'] = "5005"
    
  4. 파일을 저장하고 변경 사항이 적용되도록 GitLab을 다시 구성합니다.

Self-compiled installations

  1. /home/git/gitlab/config/gitlab.yml을 열고 registry 아래의 구성 설정을 편집합니다:

    ## Container registry
    
    registry:
      enabled: true
      host: "registry.gitlab.example.com"
      port: "5005"
      api_url: "https://<external_registry_host>:5000"
      path: /var/lib/registry
      key: /path/to/keyfile
      issuer: gitlab-issuer
    

    이러한 매개변수의 의미에 대해 자세히 알아보려면 여기를 참조하세요.

  2. 파일을 저장하고 변경 사항이 적용되려면 GitLab을 다시 시작하세요.

컨테이너 레지스트리 알림 구성

레지스트리를 구성하여 레지스트리에서 발생하는 이벤트에 대한 웹훅 알림을 보낼 수 있습니다.

Docker Registry notifications documentation에서 컨테이너 레지스트리 알림 구성 옵션에 대해 자세히 알아보세요.

컨테이너 레지스트리에 대해 여러 엔드포인트를 구성할 수 있습니다.

Linux package (Omnibus)

Linux 패키지 설치의 알림 엔드포인트를 구성하려면:

  1. /etc/gitlab/gitlab.rb을 편집합니다:

    registry['notifications'] = [
      {
        'name' => 'test_endpoint',
        'url' => 'https://gitlab.example.com/notify',
        'timeout' => '500ms',
        'threshold' => 5,
        'backoff' => '1s',
        'headers' => {
          "Authorization" => ["AUTHORIZATION_EXAMPLE_TOKEN"]
        }
      }
    ]
    
  2. 파일을 저장하고 변경 사항이 적용되려면 GitLab을 다시 구성하세요.

Self-compiled (source)

알림 엔드포인트를 구성하는 것은 Docker 레지스트리를 배포할 때 생성된 레지스트리 구성 YAML 파일에서 수행됩니다.

예시:

notifications:
  endpoints:
    - name: alistener
      disabled: false
      url: https://my.listener.com/event
      headers: <http.Header>
      timeout: 500
      threshold: 5
      backoff: 1000

Cleanup 정책 지금 실행

경고: 분산 아키텍처를 사용하고 Sidekiq가 다른 노드에서 실행 중인 경우 정리 정책이 작동하지 않습니다. 이를 해결하려면:

  1. Sidekiq 노드의 gitlab.rb 파일을 올바른 레지스트리 URL을 가리키도록 구성합니다.
  2. registry.key 파일을 각 Sidekiq 노드에 복사합니다.

자세한 내용은 Sidekiq 구성 페이지를 참조하세요.

특정 프로젝트의 컨테이너 레지스트리 디스크 공간 사용량을 줄이려면, 관리자는 정리 정책을 설정하고 가비지 수집을 실행할 수 있습니다.

프로젝트별 레지스트리 디스크 공간 사용량

각 프로젝트가 사용하는 디스크 공간을 확인하려면 GitLab Rails 콘솔에서 다음을 실행하세요:

projects_and_size = [["project_id", "creator_id", "registry_size_bytes", "프로젝트 경로"]]
# 확인하려는 프로젝트를 지정해야 합니다. 이 정보는 어떤 방식으로든 얻을 수 있습니다.
projects = Project.last(100)

projects.each do |p|
   project_total_size = 0
   container_repositories = p.container_repositories

   container_repositories.each do |c|
       c.tags.each do |t|
          project_total_size = project_total_size + t.total_size unless t.total_size.nil?
       end
   end

   if project_total_size > 0
      projects_and_size << [p.project_id, p.creator&.id, project_total_size, p.full_path]
   end
end

# 쉼표로 구분된 출력으로 표시합니다
projects_and_size.each do |ps|
   puts "%s,%s,%s,%s" % ps
end

정리 정책을 실행하여 이미지 태그를 제거하려면 GitLab Rails 콘솔에서 다음 명령을 실행하세요:

# 컨테이너 레지스트리를 정리해야 하는 프로젝트의 숫자 ID
P = <project_id>

# 프로젝트에 대한 개발자, 관리자 또는 소유자 역할을 가진 사용자의 숫자 ID
U = <user_id>

# 필요한 세부 정보/객체 가져오기
user    = User.find_by_id(U)
project = Project.find_by_id(P)
policy  = ContainerExpirationPolicy.find_by(project_id: P)

# 각 컨테이너 리포지토리를 반복합니다
project.container_repositories.find_each do |repo|
  puts repo.attributes

  # 태그 정리 시작
  puts Projects::ContainerRepository::CleanupTagsService.new(container_repository: repo, current_user: user, params: policy.attributes.except("created_at", "updated_at")).execute
end

또한 일정에 따라 정리를 실행할 수 있습니다.

모든 프로젝트에서 인스턴스 전체에 대해 정리 정책을 활성화하려면, 정리 정책이 비활성화된 레지스트리가 있는 모든 프로젝트를 찾아야 합니다:

# 컨테이너 레지스트리가 활성화되어 있지만 정리 정책이 비활성화된 모든 프로젝트 찾기

projects = Project.find_by_sql ("SELECT * FROM projects WHERE id IN (SELECT project_id FROM container_expiration_policies WHERE enabled=false AND id IN (SELECT project_id FROM container_repositories))")

# 각 프로젝트를 반복합니다
projects.each do |p|

# 프로젝트 ID와 프로젝트 전체 이름을 인쇄합니다
    puts "#{p.id},#{p.full_name}"
end

컨테이너 레지스트리 메타데이터 데이터베이스

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

메타데이터 데이터베이스를 통해 온라인 가비지 수집과 많은 레지스트리 작업의 효율성이 향상되는 등 많은 새로운 레지스트리 기능이 활성화됩니다. 자세한 내용은 컨테이너 레지스트리 메타데이터 데이터베이스 페이지를 참조하세요.

컨테이너 레지스트리 가비지 수집

note

Amazon S3 LifeCycle과 같은 객체 저장 공급자의 유지 보수 정책은 객체가 올바르게 삭제되지 않을 수 있습니다.

컨테이너 레지스트리는 상당량의 저장 공간을 사용할 수 있으며, 저장 공간 사용량을 줄이려면 원할 수 있습니다. 나열된 옵션 중 태그 삭제가 가장 효과적인 옵션입니다. 그러나 태그 삭제만으로는 이미지 레이어를 삭제하지 않고 기본 이미지 매니페스트에만 태그가 지정되지 않은 상태를 만듭니다.

보다 효과적으로 공간을 확보하려면 컨테이너 레지스트리에는 참조되지 않는 레이어 및 (선택 사항으로) 태그가 지정되지 않은 매니페스트를 삭제할 수 있는 가비지 컬렉터가 있습니다.

가비지 수집기를 시작하려면 gitlab-ctl에서 제공하는 registry-garbage-collect 명령을 사용하십시오.

caution

이 명령은 가비지 수집 전에 컨테이너 레지스트리를 종료하고, 가비지 수집이 완료된 후에 다시 시작합니다. 다운타임을 피하려는 경우 수동으로 컨테이너 레지스트리를 읽기 전용 모드로 설정하고 gitlab-ctl을 우회할 수 있습니다.

가비지 수집에 필요한 시간은 컨테이너 레지스트리 데이터 크기에 비례합니다.

사전 요구 사항: - GitLab Helm 차트를 사용하여 Linux 패키지 또는 GitLab을 설치해야 합니다.

컨텐츠 주소 지정 레이어 이해

다음 예시를 고려해 보겠습니다.먼저 이미지를 빌드하는 경우:

# 이 명령어는 sha256:111111의 내용을 가진 이미지를 빌드합니다
docker build -t my.registry.com/my.group/my.project:latest .
docker push my.registry.com/my.group/my.project:latest

이제 새 버전으로 :latest를 덮어 씁니다:

# 이 명령어는 sha256:222222의 내용을 가진 이미지를 빌드합니다
docker build -t my.registry.com/my.group/my.project:latest .
docker push my.registry.com/my.group/my.project:latest

이제 :latest 태그는 sha256:222222의 매니페스트를 가리킵니다. 레지스트리 아키텍처 때문에 이 데이터는 :latest 태그로 직접 접근할 수는 없지만 이미지 my.registry.com/my.group/my.project@sha256:111111을 끌어올 때에는 여전히 접근할 수 있습니다.

참조되지 않는 레이어 제거

이미지 레이어는 컨테이너 레지스트리 저장 공간의 대부분을 차지합니다. 이미지 매니페스트가 해당 이미지 레이어를 참조하지 않을 때 레이어는 참조되지 않는 것으로 간주됩니다. 참조되지 않는 레이어는 컨테이너 레지스트리 가비지 수집기의 기본 대상입니다.

설정 파일의 기본 위치를 변경하지 않은 경우 다음을 실행하십시오:

sudo gitlab-ctl registry-garbage-collect

컨테이너 레지스트리 config.yml의 위치를 변경한 경우:

sudo gitlab-ctl registry-garbage-collect /path/to/config.yml

또한 모든 태그가 지정되지 않은 매니페스트 및 참조되지 않는 레이어를 제거하여 추가 공간을 회복할 수도 있습니다.

태그가 지정되지 않은 매니페스트 및 참조되지 않는 레이어 제거

컨테이너 레지스트리 가비지 컬렉터는 기본적으로 태그가 지정되지 않은 이미지를 무시하며, 사용자는 소화 해시로 이미지를 계속해서 끌어올 수 있습니다. 사용자는 미래에 이미지에 다시 태그를 지정하여 GitLab UI 및 API에서 다시 표시할 수도 있습니다.

태그가 지정되지 않은 이미지에 대해 걱정하지 않으며, 이러한 이미지만 참조하는 레이어가 있는 경우, 모든 것을 삭제할 수 있습니다. registry-garbage-collect 명령에 -m 플래그를 사용하십시오.

sudo gitlab-ctl registry-garbage-collect -m

태그가 지정되지 않은 이미지를 삭제하는 것과 관련해 확신하지 못하는 경우, 진행하기 전에 레지스트리 데이터를 백업하십시오.

다운타임 없이 가비지 수집 수행

컨테이너 레지스트리를 온라인 상태로 유지하면서 가비지 수집을 수행하려면, 레지스트리를 읽기 전용 모드로 설정하고 기본 gitlab-ctl을 우회하십시오.

컨테이너 레지스트리는 읽기 전용 모드에서는 이미지를 당기지만 밀지는 못합니다. 컨테이너 레지스트리는 가비지 수집 중 전체 기간 동안 읽기 전용으로 유지되어야 합니다.

기본적으로 레지스트리 저장 경로/var/opt/gitlab/gitlab-rails/shared/registry입니다.

읽기 전용 모드를 활성화하려면:

  1. /etc/gitlab/gitlab.rb에서 읽기 전용 모드를 지정하십시오:

      registry['storage'] = {
        'filesystem' => {
          'rootdirectory' => "<your_registry_storage_path>"
        },
        'maintenance' => {
          'readonly' => {
            'enabled' => true
          }
        }
      }
    
  2. 저장하고 GitLab을 재구성하십시오:

    sudo gitlab-ctl reconfigure
    

    이 명령은 컨테이너 레지스트리를 읽기 전용 모드로 설정합니다.

  3. 이제 가비지 수집 중 하나의 명령을 트리거하십시오:

    # 참조되지 않는 레이어 제거
    sudo /opt/gitlab/embedded/bin/registry garbage-collect /var/opt/gitlab/registry/config.yml
    
    # 태그가 지정되지 않은 매니페스트 및 참조되지 않은 레이어 제거
    sudo /opt/gitlab/embedded/bin/registry garbage-collect -m /var/opt/gitlab/registry/config.yml
    

    이 명령은 가비지 수집을 시작합니다. 수행 시간은 레지스트리 데이터 크기에 비례합니다.

  4. 완료되면, /etc/gitlab/gitlab.rb에서 다시 쓰기 모드로 변경하십시오:

     registry['storage'] = {
       'filesystem' => {
         'rootdirectory' => "<your_registry_storage_path>"
       },
       'maintenance' => {
         'readonly' => {
           'enabled' => false
         }
       }
     }
    
  5. 저장하고 GitLab을 재구성하십시오:

    sudo gitlab-ctl reconfigure
    

일정에 따른 가비지 수집 실행

이상적으로는 레지스트리의 가비지 수집을 정기적으로 실행하고, 레지스트리가 사용되지 않는 시간에 매주 한 번씩 실행하는 것이 좋습니다. 가장 간단한 방법은 새로운 크론탭 작업을 추가하여 매주 주기적으로 실행하는 것입니다.

/etc/cron.d/registry-garbage-collect에 파일을 생성하세요:

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# 매주 일요일 04:05am에 실행
5 4 * * 0  root gitlab-ctl registry-garbage-collect

태그되지 않은 매니페스트 및 참조되지 않은 레이어를 제거하기 위해 -m 플래그를 추가할 수 있습니다.

가비지 수집 중지

가비지 수집을 중지할 예정이라면, 다운타임 없이 가비지 수집 실행을 수동으로 실행해야 합니다. 그런 다음 Control+C를 눌러 가비지 수집을 중지할 수 있습니다.

그렇지 않으면 gitlab-ctl 실행을 중지하면 레지스트리 서비스가 다운 상태가 될 수 있습니다. 이 경우 gitlab-ctl 명령을 사용하여 레지스트리 서비스를 다시 시작할 수 있도록 시스템에서 가비지 수집 프로세스를 찾아야 합니다.

또한, 프로세스의 마크 단계 동안 진행 상황이나 결과를 저장할 방법이 없습니다. 실제로 뭔가 영구적으로 처리되는 것은 블롭이 삭제되기 시작할 때뿐입니다.

지속적인 다운타임 없는 가비지 수집

상태: Beta

이제 데이터베이스의 메타데이터로 마이그레이션하면 읽기 전용 모드 없이도 배경에서 가비지 수집을 실행할 수 있습니다.

참고: 이 베타 기능을 사용해보고 싶다면, 알려진 제한 사항을 검토해야 합니다. 피드백이 있다면 피드백 이슈에서 알려주세요.

GitLab 및 레지스트리를 별도의 노드에서 실행하도록 구성하기 (Linux 패키지 설치)

기본적으로 패키지는 두 서비스가 동일한 노드에서 실행 중이라고 가정합니다. GitLab 및 레지스트리를 별도의 노드에서 실행하려면, 레지스트리 및 GitLab에 대해 별도의 구성이 필요합니다.

레지스트리 구성

GitLab과 별도로 실행하도록 레지스트리를 설정하려면 /etc/gitlab/gitlab.rb에서 설정해야 하는 구성 옵션을 아래에서 찾을 수 있습니다:

  • registry['registry_http_addr'], 기본적으로 프로그래밍 방식으로 설정됩니다. 웹 서버(또는 로드 밸런서)에서 접근 가능해야 합니다.
  • registry['token_realm'], 기본적으로 프로그래밍 방식으로 설정됩니다. 인증을 수행하기 위해 사용할 엔드포인트를 지정하는데, 일반적으로 GitLab URL입니다. 이 엔드포인트는 사용자에서 접근 가능해야 합니다.
  • registry['http_secret'], 무작위 문자열입니다. 변조에 대비하여 클라이언트에 저장될 수 있는 상태를 보호하는데 사용되는 무작위 데이터 조각입니다.
  • registry['internal_key'], 기본적으로 자동으로 생성됩니다. 토큰을 서명하는 데 GitLab에서 사용하는 키의 내용입니다. 이 키는 레지스트리 서버에서 생성되지만 거기서는 사용되지 않습니다.
  • gitlab_rails['registry_key_path'], 기본적으로 프로그래밍 방식으로 설정됩니다. 이는 internal_key 내용이 디스크에 쓰여지는 경로입니다.
  • registry['internal_certificate'], 기본적으로 자동으로 생성됩니다. 토큰을 서명하는 데 GitLab에서 사용하는 인증서의 내용입니다.
  • registry['rootcertbundle'], 기본적으로 프로그래밍 방식으로 설정됩니다. 인증서의 경로입니다. 이는 internal_certificate 내용이 디스크에 쓰여지는 경로입니다.
  • registry['health_storagedriver_enabled'], 기본적으로 프로그래밍 방식으로 설정됩니다. 구성된 스토리지 드라이버의 건강 상태 확인이 활성화되는지를 구성합니다.
  • gitlab_rails['registry_issuer'], 기본값입니다. 이 설정은 레지스트리와 GitLab 사이에서 동일하게 설정되어야 합니다.

GitLab 구성

아래에서는 GitLab이 레지스트리에서 독립적으로 실행되도록 /etc/gitlab/gitlab.rb에 설정해야 하는 구성 옵션을 찾을 수 있습니다.

  • gitlab_rails['registry_enabled'], true로 설정되어야 합니다. 이 설정은 GitLab에게 레지스트리 API 요청을 허용해야 함을 나타냅니다.
  • gitlab_rails['registry_api_url'], 기본적으로 프로그래밍 방식으로 설정됨. 사용자가 상호 작용할 필요가 없는 내부적으로 사용되는 레지스트리 URL, registry['registry_http_addr']와 함께 scheme이 있음.
  • gitlab_rails['registry_host'], 예를 들어, registry.gitlab.example. 스키마 없이 표시되는 레지스트리 엔드포인트, 최종 사용자에게 표시되는 주소.
  • gitlab_rails['registry_port']. 레지스트리 엔드포인트 포트, 최종 사용자에게 표시됨.
  • gitlab_rails['registry_issuer']은 레지스트리 구성에 있는 발급자와 일치해야 합니다.
  • gitlab_rails['registry_key_path'], 레지스트리 측의 인증서와 일치하는 키의 경로.
  • gitlab_rails['internal_key'], GitLab이 토큰에 서명하는 데 사용하는 키의 내용.

GitLab 컨테이너 레지스트리 아키텍처

GitLab 레지스트리는 사용자가 자체 Docker 이미지를 저장하는 데 사용합니다. 그래서 레지스트리는 클라이언트를 대상으로 한다는 의미로, 웹 서버(또는 로드 밸런서, LB로 약칭함)에서 직접 노출됩니다.

GitLab 레지스트리 다이어그램

위 다이어그램에 설명된 흐름:

  1. 사용자가 클라이언트에서 docker login registry.gitlab.example을 실행합니다. 이것은 443번 포트로 웹 서버(또는 LB)에 도달합니다.
  2. 웹 서버가 레지스트리 백엔드 풀에 연결합니다(기본적으로 5000번 포트를 사용함). 사용자가 유효한 토큰을 제공하지 않았기 때문에 레지스트리는 401 HTTP 코드와 토큰을 얻을 수 있는 URL(레지스트리 구성의 token_realm)을 반환합니다. 이것은 GitLab API를 가리킵니다.
  3. 그럼 Docker 클라이언트는 GitLab API에 연결하여 토큰을 획들합니다.
  4. API는 토큰을 레지스트리 키로 서명하고 Docker 클라이언트에 전달합니다.
  5. Docker 클라이언트는 이제 API에서 받은 토큰으로 다시 로그인합니다. 이제 Docker 이미지를 push하고 pull할 수 있습니다.

참조: https://distribution.github.io/distribution/spec/auth/token/

GitLab과 레지스트리 간 통신

레지스트리에는 내부적으로 사용자를 인증하는 방법이 없기 때문에 자격 증명을 유효화하는 데 GitLab을 의존합니다. 레지스트리와 GitLab 간의 연결은 TLS로 암호화됩니다. 키는 GitLab이 토큰에 서명하는 데 사용되며, 인증서는 레지스트리가 서명을 검증하는 데 사용됩니다. 기본적으로 모든 설치에 대해 자체 서명된 인증서 키 쌍이 생성됩니다. 이는 필요에 따라 재정의할 수 있습니다.

GitLab은 레지스트리와의 상호 작용에 레지스트리 개인 키를 사용합니다. 레지스트리 요청을 보낼 때 새로운 단기 (10분) 지속 기간이 제한된 토큰이 생성되고 사적 키로 서명됩니다. 레지스트리는 그런 다음 서명이 자신의 구성에서 지정된 레지스트리 인증서와 일치하는지 확인하고 작업을 허용합니다. GitLab 백그라운드 작업 처리(Sidekiq을 통해)도 레지스트리와 상호 작용합니다. 이러한 작업은 이미지 삭제를 처리하기 위해 레지스트리에 직접 대화합니다.

서드파티 레지스트리에서의 마이그레이션

GitLab에서 외부 컨테이너 레지스트리의 사용은 GitLab 15.8에서 폐기되었으며 지원 종료는 GitLab 16.0에서 발생했습니다. 자세한 내용은 폐기 공지를 참조하세요.

GitLab 16.0에서 통합은 비활성화되지 않았지만 디버깅과 문제 해결에 대한 지원은 더 이상 제공되지 않습니다. 게다가 이 통합은 더 이상 개발되거나 새로운 기능으로 향상되지 않습니다. 새로운 GitLab 컨테이너 레지스트리 버전이 자체 관리형으로 사용 가능해진 후에는 완전히 외부 레지스트리 기능이 제거될 수 있습니다(에픽 5521을 참조).

이 섹션에는 서드파티 레지스트리에서 GitLab 컨테이너 레지스트리로 마이그레이션하는 관리자를 위한 안내가 포함되어 있습니다. 사용 중인 서드파티 컨테이너 레지스트리가 여기에 나와 있지 않으면 피드백 이슈에 사용 사례를 설명할 수 있습니다.

아래 제공된 모든 지침에 대해 먼저 테스트 환경에서 시도해 보아야 합니다. 모든 것이 의도한 대로 계속 작동하는지 확인한 후에 본사 환경에서 복제하기 전에 보장해 주세요.

Docker Distribution Registry

Docker Distribution Registry는 CNCF에 기증되어 Distribution Registry로 알려지게 되었습니다. 이 레지스트리는 GitLab 컨테이너 레지스트리가 기반으로 하는 오픈 소스 구현체입니다. GitLab 컨테이너 레지스트리는 Distribution 레지스트리에서 제공하는 기본 기능과 모든 지원되는 저장 백엔드를 포함한 기능과 호환됩니다. GitLab 컨테이너 레지스트리로 마이그레이션하려면 이 페이지의 지침을 따르고, Distribution 레지스트리와 동일한 저장 백엔드를 사용해야 합니다. GitLab 컨테이너 레지스트리는 Distribution 레지스트리에 사용 중인 것과 동일한 구성을 받아들여야 합니다.

문제 해결

다음 섹션에 들어가기 전에 기본 문제 해결 방법을 확인하세요:

  1. Docker 클라이언트와 GitLab 서버의 시스템 시계가 동기화되었는지 확인하세요(NTP 등을 통해).

  2. S3 지원 레지스트리를 사용하는 경우, IAM 권한과 S3 자격 증명(지역 포함)이 올바른지 다시 한번 확인하세요. 자세한 내용은 샘플 IAM 정책을 참조하세요.

  3. 레지스트리 로그(예: /var/log/gitlab/registry/current)와 GitLab 프로덕션 로그(예: /var/log/gitlab/gitlab-rails/production.log)에서 오류를 확인하세요. 거기에서 단서를 찾을 수 있을 겁니다.

컨테이너 레지스트리에서 자체 서명 인증서 사용

컨테이너 레지스트리에서 자체 서명 인증서를 사용하는 경우, 다음과 같은 CI 작업 중 문제가 발생할 수 있습니다:

Error response from daemon: Get registry.example.com/v1/users/: x509: certificate signed by unknown authority

명령을 실행하는 Docker 데몬은 인증서를 인증 기관에서 서명된 것으로 기대하므로 위와 같은 오류가 발생합니다.

GitLab은 컨테이너 레지스트리에서 자체 서명 인증서를 기본적으로 지원하지는 않지만, Docker 데몬에 자체 서명 인증서를 신뢰하도록 지시하고, GitLab 러너 config.toml 파일에서 privileged = false를 설정함으로써 작동시킬 수 있습니다. privileged = true로 설정하는 것이 Docker 데몬보다 우선합니다.

  [runners.docker]
    image = "ruby:2.6"
    privileged = false
    volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]

이에 대한 추가 정보: issue 18239.

‘token signed by untrusted key’로 인해 Docker 로그인 시도 실패

레지스트리는 GitLab이 자격 증명을 검증하기를 의존합니다 레지스트리가 유효한 로그인 시도를 인증하지 못하면 다음 오류 메시지가 표시됩니다:

# docker login gitlab.company.com:4567
Username: user
Password:
Error response from daemon: login attempt to https://gitlab.company.com:4567/v2/ failed with status: 401 Unauthorized

그리고 구체적으로는 /var/log/gitlab/registry/current 로그 파일에 다음 내용이 나타납니다:

level=info msg="token signed by untrusted key with ID: "TOKE:NL6Q:7PW6:EXAM:PLET:OKEN:BG27:RCIB:D2S3:EXAM:PLET:OKEN""
level=warning msg="error authorizing context: invalid token" go.version=go1.12.7 http.request.host="gitlab.company.com:4567" http.request.id=74613829-2655-4f96-8991-1c9fe33869b8 http.request.method=GET http.request.remoteaddr=10.72.11.20 http.request.uri="/v2/" http.request.useragent="docker/19.03.2 go/go1.12.8 git-commit/6a30dfc kernel/3.10.0-693.2.2.el7.x86_64 os/linux arch/amd64 UpstreamClient(Docker-Client/19.03.2 \(linux\))"

GitLab은 레지스트리의 인증 토큰을 암호화하기 위해 인증서 키 쌍의 두 측의 내용을 사용합니다. 이 메시지는 이러한 내용이 일치하지 않음을 의미합니다.

사용 중인 파일을 확인하세요:

  • /var/opt/gitlab/registry/config.yml에서 auth:를 찾아 다음을 확인하세요.

    ## Container registry certificate
       auth:
         token:
           realm: https://gitlab.my.net/jwt/auth
           service: container_registry
           issuer: omnibus-gitlab-issuer
      -->  rootcertbundle: /var/opt/gitlab/registry/gitlab-registry.crt
           autoredirect: false
    
  • /var/opt/gitlab/gitlab-rails/etc/gitlab.yml에서 Container Registry를 찾아 다음을 확인하세요.

    ## Container registry key
       registry:
         enabled: true
         host: gitlab.company.com
         port: 4567
         api_url: http://127.0.0.1:5000 # 내부 주소로 레지스트리에 직접 통신하기 위해 GitLab이 사용
         path: /var/opt/gitlab/gitlab-rails/shared/registry
    -->  key: /var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key
         issuer: omnibus-gitlab-issuer
         notification_secret:
    

이러한 openssl 명령어의 출력이 일치하는지 확인하여 인증서 키 쌍이 일치하는지 확인하세요:

/opt/gitlab/embedded/bin/openssl x509 -noout -modulus -in /var/opt/gitlab/registry/gitlab-registry.crt | /opt/gitlab/embedded/bin/openssl sha256
/opt/gitlab/embedded/bin/openssl rsa -noout -modulus -in /var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key | /opt/gitlab/embedded/bin/openssl sha256

인증서의 두 부분이 일치하지 않으면, 파일을 제거하고 gitlab-ctl reconfigure를 실행하여 쌍을 다시 생성하세요. 쌍은 기존 값 /etc/gitlab/gitlab-secrets.json이 있다면 그 값을 사용하여 다시 생성됩니다. 새로운 쌍을 생성하려면 gitlab-ctl reconfigure를 실행하기 전에 /etc/gitlab/gitlab-secrets.json에서 registry 섹션을 삭제하세요.

자체 서명된 쌍을 자동으로 생성된 쌍으로 덮어썼고 내용이 일치한다면, /etc/gitlab/gitlab-secrets.json에서 ‘registry’ 섹션을 삭제하고 gitlab-ctl reconfigure를 실행하세요.

AWS S3 및 GitLab 레지스트리 에러

AWS S3를 GitLab 레지스트리와 함께 사용할 때, 큰 이미지를 푸시할 때 오류가 발생할 수 있습니다. 다음과 같은 오류를 확인하려면 레지스트리 로그를 확인하세요:

level=error msg="response completed with error" err.code=unknown err.detail="unexpected EOF" err.message="unknown error"

이 오류를 해결하려면 레지스트리 구성에서 chunksize 값을 지정하세요. 먼저 25000000 (25 MB)에서 50000000 (50 MB) 사이의 값을 사용해보세요.

Linux package (Omnibus)
  1. /etc/gitlab/gitlab.rb 파일 편집:

    registry['storage'] = {
      's3' => {
        'accesskey' => 'AKIAKIAKI',
        'secretkey' => 'secret123',
        'bucket'    => 'gitlab-registry-bucket-AKIAKIAKI',
        'chunksize' => 25000000
      }
    }
    
  2. 파일을 저장하고 변경 사항을 적용하려면 GitLab 재구성을 실행하세요.

Self-compiled (source)
  1. config/gitlab.yml 파일 편집:

    storage:
      s3:
        accesskey: 'AKIAKIAKI'
        secretkey: 'secret123'
        bucket: 'gitlab-registry-bucket-AKIAKIAKI'
        chunksize: 25000000
    
  2. 파일을 저장하고 변경 사항을 적용하려면 GitLab 재시작을 실행하세요.

오래된 Docker 클라이언트 지원

GitLab과 함께 제공되는 Docker 컨테이너 레지스트리는 기본적으로 schema1 매니페스트를 비활성화합니다. 따라서 오래된 Docker 클라이언트(1.9 버전 이하)를 계속 사용 중이라면 이미지 푸시 중에 오류가 발생할 수 있습니다. 자세한 내용은 이슈 4145를 참조하세요.

호환성을 유지하기 위해 구성 옵션을 추가할 수 있습니다.

Linux package (Omnibus)
  1. /etc/gitlab/gitlab.rb 파일 편집:

    registry['compatibility_schema1_enabled'] = true
    
  2. 파일을 저장하고 변경 사항을 적용하려면 GitLab 재구성을 실행하세요.

Self-compiled (source)
  1. 레지스트리를 배포할 때 생성한 YAML 구성 파일을 편집하고 다음 스니펫을 추가하세요:

    compatibility:
        schema1:
            enabled: true
    
  2. 변경 사항을 적용하려면 레지스트리를 다시 시작하세요.

Docker 연결 오류

그룹, 프로젝트 또는 브랜치 이름에 특수 문자가 포함되어 있을 때 Docker 연결 오류가 발생할 수 있습니다. 특수 문자로는 다음이 포함됩니다:

  • 선행 언더스코어
  • 마지막 하이픈/대시
  • 이중 하이픈/대시

이를 해결하기 위해 그룹 경로를 변경, 프로젝트 경로를 변경하거나 브랜치 이름을 변경할 수 있습니다. 또한 인스턴스 레벨에서 이를 방지하기 위해 푸시 규칙을 생성할 수 있습니다.

이미지 푸시 오류

이미지를 푸시하려고 시도하면 오류가 발생하거나 “재시도” 루프가 발생할 수 있지만 docker login은 정상 작동하는 경우, 이는 NGINX에 의해 레지스트리로 전달된 헤더에 문제가 있을 수 있음을 의미합니다. 기본 권장 NGINX 구성에서는 이를 처리해야 하지만 SSL을 타사 역방향 프록시로 오프로드하는 사용자 정의 설정에서 발생할 수 있습니다.

이 문제는 Docker 프로젝트 이슈에서 논의되었으며, Registry에서 상대적 URL을 활성화하는 것이 해결책일 수 있습니다.

Linux package (Omnibus)
  1. /etc/gitlab/gitlab.rb 파일 편집:

    registry['env'] = {
      "REGISTRY_HTTP_RELATIVEURLS" => true
    }
    
  2. 파일을 저장하고 변경 사항을 적용하려면 GitLab 재구성을 실행하세요.

Self-compiled (source)
  1. 레지스트리를 배포할 때 생성한 YAML 구성 파일을 편집하고 다음 스니펫을 추가하세요:

    http:
        relativeurls: true
    
  2. 변경 사항을 적용하려면 GitLab을 다시 시작하세요.

레지스트리 디버그 서버 활성화

컨테이너 레지스트리 디버깅 서버를 사용하여 문제를 진단할 수 있습니다. 디버그 엔드포인트를 통해 메트릭 및 상태 확인, 프로파일링 등이 가능합니다.

경고: 디버그 엔드포인트에서는 민감한 정보가 제공될 수 있습니다. 실제 운영 환경에서 디버그 엔드포인트에 대한 접근 권한을 제한해야 합니다.

레지스트리 디버그 주소를 gitlab.rb 구성에서 설정하여 디버그 서버를 활성화할 수 있습니다.

registry['debug_addr'] = "localhost:5001"

설정을 추가한 후 GitLab 재구성하여 변경 사항을 적용하세요.

curl을 사용하여 디버그 서버에서 디버그 출력을 요청하세요:

curl "localhost:5001/debug/health"
curl "localhost:5001/debug/vars"

이전 스키마 v1 도커 이미지에 액세스하기

Docker 레지스트리 API V1에 대한 지원으로, 스키마 V1 이미지 매니페스트는 다음과 같습니다.

GitLab 컨테이너 레지스트리에서 더는 v1 이미지를 푸시하거나 끌어올릴 수 없습니다.

GitLab 컨테이너 레지스트리에 v1 이미지가 있지만 GitLab 13.9 업그레이드 전에 도커가 권장하는 단계를 따라 업그레이드하지 않은 경우 이러한 이미지에 더 이상 액세스할 수 없습니다. 이러한 이미지를 끌어오려고 하면 다음 오류가 표시됩니다.

  • Error response from daemon: manifest invalid: Schema 1 manifest not supported

자체 관리 GitLab 인스턴스의 경우 이러한 이미지에 다시 액세스하려면 GitLab 컨테이너 레지스트리를 일시적으로 v3.0.0-gitlab보다 낮은 버전으로 다운그레이드하면 됩니다. 이러한 이미지에 다시 액세스하려면 다음 단계를 따르세요.

  1. 컨테이너 레지스트리를 v2.13.1-gitlab로 다운그레이드합니다.
  2. v1 이미지를 업그레이드합니다.
  3. 컨테이너 레지스트리 다운그레이드를 복원합니다.

이미지 업그레이드 프로세스 중에 레지스트리를 읽기 전용 모드로 설정할 필요는 없습니다. 업그레이드 프로세스 중에 v3.0.0-gitlab 이후에 도입된 새로운 기능에 의존하지 않도록 해야 합니다. 이러한 기능은 업그레이드 프로세스 중에 사용할 수 없습니다. 자세한 정보는 완전한 레지스트리 변경 로그를 참조하세요.

다음 섹션에서 각 설치 방법에 대해 자세한 정보를 제공합니다.

Helm 차트 (Kubernetes)

Helm 차트 설치에 대해:

  1. image.tag 구성 매개변수를 v2.13.1-gitlab로 재정의합니다.
  2. 재시작합니다.
  3. 이미지 업그레이드 단계를 수행합니다.
  4. image.tag 매개변수를 이전 값으로 복원합니다.

기타 레지스트리 구성 변경이 필요하지 않습니다.

Linux 패키지 (Omnibus)

Linux 패키지 설치에 대해:

  1. GitLab 13.9+와 함께 제공되는 레지스트리 이진 파일을 v3.0.0-gitlab 이전의 버전으로 일시적으로 교체합니다. 이를 위해 GitLab 컨테이너 레지스트리의 이전 버전인 v2.13.1-gitlab과 같은 Docker 이미지의 이전 버전을 끌어옵니다. 그런 다음 이 이미지 내부의 /bin/registry 위치에 있는 registry 이진 파일을 가져올 수 있습니다.

    id=$(docker create registry.gitlab.com/gitlab-org/build/cng/gitlab-container-registry:v2.13.1-gitlab)
    docker cp $id:/bin/registry registry-2.13.1-gitlab
    docker rm $id
    
  2. Linux 패키지 설치에 포함된 이진 파일인 /opt/gitlab/embedded/bin/registryregistry-2.13.1-gitlab로 교체합니다. Linux 패키지에 포함된 원본 이진 파일을 먼저 백업하고, 이미지 업그레이드 단계를 수행한 후에 복원해야 합니다. 이진 파일을 교체하기 전에 레지스트리 서비스를 중지하고, 이진 파일을 교체한 후에 바로 시작해야 합니다. 레지스트리 구성 변경이 필요하지 않습니다.

자체 컴파일 (소스)

v3.0.0-gitlab에서 얻은 것과 같이 registry 이진 파일을 찾아서 Linux 패키지 설치와 같이 이진 파일을 일시적으로 교체합니다. 이진 파일을 교체하기 전에 원본 레지스트리 이진 파일을 백업하고, 이미지 업그레이드 단계를 수행한 후에 복원해야 합니다.

이미지 업그레이드

Docker가 업그레이드하는 데 권장하는 단계를 따릅니다. 가장 간단한 옵션은 해당 이미지를 끌어와 레지스트리에 다시 푸시하는 것으로, Docker 클라이언트 버전이 v1.12 이상이면 이미지를 자동으로 변환하여 레지스트리에 푸시합니다. 완료되면 모든 v1 이미지가 이제 v2 이미지로 사용 가능해집니다.

이름이 비어있는 태그

AWS DataSync를 사용하여 레지스트리 데이터를 S3 버킷으로 복사하는 경우, 목적지 버킷의 각 컨테이너 저장소의 루트 경로에 빈 메타데이터 객체가 생성됩니다. 이로 인해 레지스트리는 GitLab UI 및 API에서 이름이 없는 태그로 나타나는 이러한 파일을 해석합니다. 자세한 내용은 이슈를 참조하세요.

이를 해결하기 위해 두 가지 중 하나를 수행할 수 있습니다:

  • 빈 객체를 각 영향을 받는 저장소의 루트에서 제거하려면 AWS CLI의 rm 명령을 사용합니다. 맨 뒤의 /에 특별한 주의를 기울이며 --recursive 옵션을 사용하지 않도록 주의합니다:

    aws s3 rm s3://<bucket>/docker/registry/v2/repositories/<path to repository>/
    
  • 레지스트리 데이터를 새 버킷으로 복사하고 레지스트리가 이를 사용하도록 구성하려면 AWS CLI의 sync 명령을 사용합니다. 이렇게 하면 빈 객체가 남게 됩니다.

고급 문제 해결

S3 설정의 문제를 진단하는 방법을 보여주기 위해 구체적인 예제를 사용합니다.

정리 정책 조사

정리 정책이 태그를 삭제하거나 삭제하지 않은 이유에 대해 확신이 없으면 레일즈 콘솔에서 아래 스크립트를 실행하여 정책을 라인별로 실행합니다. 이는 정책과 관련된 문제를 진단하는 데 도움이 될 수 있습니다.

repo = ContainerRepository.find(<project_id>)
policy = repo.project.container_expiration_policy

tags = repo.tags
tags.map(&:name)

tags.reject!(&:latest?)
tags.map(&:name)

regex_delete = ::Gitlab::UntrustedRegexp.new("\\A#{policy.name_regex}\\z")
regex_retain = ::Gitlab::UntrustedRegexp.new("\\A#{policy.name_regex_keep}\\z")

tags.select! { |tag| regex_delete.match?(tag.name) && !regex_retain.match?(tag.name) }

tags.map(&:name)

now = DateTime.current
tags.sort_by! { |tag| tag.created_at || now }.reverse! # 긴 작업입니다.

tags = tags.drop(policy.keep_n)
tags.map(&:name)

older_than_timestamp = ChronicDuration.parse(policy.older_than).seconds.ago

tags.select! { |tag| tag.created_at && tag.created_at < older_than_timestamp }

tags.map(&:name)
  • 이 스크립트는 삭제할 태그 목록(tags)을 작성합니다.
  • tags.map(&:name)은 제거할 태그 목록을 출력합니다. 이 작업은 시간이 걸릴 수 있습니다.
  • 각 필터링 후 의도한 삭제할 태그를 포함하고 있는지 tags 목록을 확인하세요.

푸시 중 예상치 못한 403 오류

사용자가 S3 백엔드 레지스트리를 활성화하려고 시도했습니다. docker login 단계는 문제없이 진행되었습니다. 그러나 이미지를 푸시하려 할 때 다음 출력이 나타났습니다.

The push refers to a repository [s3-testing.myregistry.com:5050/root/docker-test/docker-image]
dc5e59c14160: Pushing [==================================================>] 14.85 kB
03c20c1a019a: Pushing [==================================================>] 2.048 kB
a08f14ef632e: Pushing [==================================================>] 2.048 kB
228950524c88: Pushing 2.048 kB
6a8ecde4cc03: Pushing [==>                                                ] 9.901 MB/205.7 MB
5f70bf18a086: Pushing 1.024 kB
737f40e80b7f: Waiting
82b57dbc5385: Waiting
19429b698a22: Waiting
9436069b92a3: Waiting
error parsing HTTP 403 response body: unexpected end of JSON input: ""

이 오류는 모호합니다. 403이 GitLab Rails 애플리케이션에서 오는지, Docker 레지스트리에서 오는지 또는 다른 곳에서 오는지 명확하지 않습니다. 이 경우에는 로그인이 성공했기 때문에 클라이언트와 레지스트리 간의 통신을 살펴봐야 할 것으로 생각됩니다.

Docker 클라이언트와 레지스트리 간의 REST API는 Docker 문서에 설명되어 있습니다. 보통은 Wireshark나 tcpdump를 사용하여 트래픽을 캡처하고 잘못된 부분을 확인할 수 있습니다. 그러나 Docker 클라이언트와 서버 간의 모든 통신이 HTTPS로 이루어지기 때문에 실제 키를 알고 있더라도 트래픽을 신속하게 해독하는 것은 약간 어려울 수 있습니다. 대신 어떻게 해야 할까요?

하나의 방법은 보안 상의 이유로 비추천되는 충분한 테스트를 위해서 보안 인증서를 설정하여 HTTPS를 비활성화하는 것입니다. 제품 시스템을 운영 중이고 이 작업을 수행할 수 없거나 원치 않는 경우에는 mitmproxy(Man-in-the-Middle Proxy)를 사용하는 방법이 있습니다.

mitmproxy

mitmproxy를 사용하면 클라이언트와 서버 사이에 프락시를 놓고 모든 트래픽을 검사할 수 있습니다. 하지만 시스템이 이를 작동하기 위해 mitmproxy SSL 인증서를 신뢰해야 합니다.

다음 설치 지침은 Ubuntu에서 실행하는 것을 가정합니다:

  1. mitmproxy 설치.
  2. mitmproxy --port 9000을 실행하여 해당하는 인증서를 생성합니다. 종료하려면 CTRL-C를 누릅니다.
  3. ~/.mitmproxy에서 인증서를 시스템으로 설치합니다.

    sudo cp ~/.mitmproxy/mitmproxy-ca-cert.pem /usr/local/share/ca-certificates/mitmproxy-ca-cert.crt
    sudo update-ca-certificates
    

성공적으로 실행되면 다음과 같은 메시지가 표시됩니다.

/etc/ssl/certs에 인증서 업데이트 중... 1개 추가, 0개 제거; 완료.
..

인증서가 올바르게 설치되었는지 확인하려면 다음을 실행합니다:

mitmproxy --port 9000

이 명령은 mitmproxy를 9000 포트에서 실행합니다. 다른 창에서 다음을 실행합니다:

curl --proxy "http://localhost:9000" "https://httpbin.org/status/200"

모든 것이 올바르게 설정되어 있다면 mitmproxy 창에 정보가 표시되고 curl 명령에서 오류가 발생하지 않습니다.

프록시를 사용하여 Docker 데몬 실행

Docker가 프록시를 통해 연결하려면 Docker 데몬을 올바른 환경 변수로 시작해야 합니다. 가장 간단한 방법은 Docker를 종료하고(예: sudo initctl stop docker) 그런 다음 Docker를 직접 실행하는 것입니다. root로 다음과 같이 실행하세요.

export HTTP_PROXY="http://localhost:9000"
export HTTPS_PROXY="https://localhost:9000"
docker daemon --debug

이 명령은 Docker 데몬을 실행하고 모든 연결을 mitmproxy를 통해 프록시합니다.

Docker 클라이언트 실행

이제 mitmproxy와 Docker가 실행 중이므로 컨테이너 이미지에 로그인하고 푸시할 수 있습니다. 이 작업을 하려면 root로 실행해야 할 수도 있습니다. 예를 들어:

docker login s3-testing.myregistry.com:5050
docker push s3-testing.myregistry.com:5050/root/docker-test/docker-image

위 예에서 mitmproxy 창에 다음 추적을 볼 수 있습니다:

Docker에서의 mitmproxy 출력

위 이미지에서 확인할 수 있는 내용은 다음과 같습니다:

  • 초기 PUT 요청은 201 상태 코드로 정상적으로 전송되었습니다.
  • 201은 클라이언트를 S3 버킷으로 리디렉션했습니다.
  • AWS 버킷에 대한 HEAD 요청은 403 Unauthorized를 보고했습니다.

이것은 무엇을 의미합니까? 이는 S3 사용자가 HEAD 요청을 수행할 권한이 없음을 강력히 시사합니다. 해결 방법은 IAM 권한을 다시 확인하는 것입니다. 올바른 권한이 설정되면 오류가 사라집니다.

gitlab-registry.key 파일을 찾을 수 없어 컨테이너 저장소를 삭제할 수 없음

GitLab 인스턴스의 컨테이너 레지스트리를 비활성화하고 컨테이너 저장소가 있는 프로젝트를 삭제하려고 하면 다음 오류가 발생합니다:

Errno::ENOENT: No such file or directory @ rb_sysopen - /var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key

이 경우, 다음 단계를 따르세요:

  1. gitlab.rb에서 인스턴스 전역 설정으로 컨테이너 레지스트리를 일시적으로 활성화합니다:

    gitlab_rails['registry_enabled'] = true
    
  2. 파일을 저장하고 변경 사항이 적용되도록 GitLab을 다시 구성하세요.
  3. 삭제를 다시 시도하세요.

일반적인 방법을 사용하여 저장소를 삭제할 수 없는 경우 GitLab Rails 콘솔을 사용하여 프로젝트를 강제로 삭제할 수 있습니다:

# 삭제하려는 프로젝트의 경로
prj = Project.find_by_full_path(<project_path>)

# 위 명령은 프로젝트의 컨테이너 레지스트리를 삭제하므로 경로를 반드시 다시 확인하세요!
if prj.has_container_registry_tags?
  prj.container_repositories.each { |p| p.destroy }
end