Dependency Proxy

Tier: Free, Premium, Ultimate Offering: GitLab.com, Self-Managed, GitLab Dedicated

GitLab Dependency Proxy는 자주 액세스하는 upstream 이미지를 위해 사용할 수 있는 로컬 프록시입니다.

이 Dependency Proxy는 CI/CD의 경우 요청을 받아 레지스트리에서 upstream 이미지를 반환하여 pull-through 캐시 역할을 수행합니다.

Prerequisites

Dependency Proxy를 사용하려면 GitLab 인스턴스에서 활성화되어 있어야 합니다. 기본적으로 활성화되어 있지만 관리자는 이를 끌 수 있습니다.

지원되는 이미지 및 패키지

다음 이미지 및 패키지가 지원됩니다.

이미지/패키지 GitLab 버전
Docker 14.0+

계획된 추가 사항 디렉터리은 방향 페이지에서 확인하세요.

그룹을 위해 Dependency Proxy 활성화 또는 비활성화

그룹을 위해 Dependency Proxy를 활성화하거나 비활성화하려면:

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 그룹을 찾습니다.
  2. 설정 > 패키지 및 레지스트리를 선택합니다.
  3. Dependency Proxy 섹션을 확장합니다.
  4. 프록시를 활성화하려면 프록시 사용을 켭니다. 끄려면 토글을 끕니다.

이 설정은 그룹을 위한 Dependency Proxy에만 영향을 미칩니다. 전체 GitLab 인스턴스에 대해 Dependency Proxy를 켜거나 끌 수 있는 것은 관리자만 할 수 있습니다.

Dependency Proxy 보기

Dependency Proxy를 보려면:

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 그룹을 찾습니다.
  2. 운영 > Dependency Proxy를 선택합니다.

Dependency Proxy는 프로젝트에서 사용할 수 없습니다.

Docker 이미지를 위한 Dependency Proxy 사용

GitLab을 Docker 이미지의 소스로 사용할 수 있습니다.

필수 컴포넌트:

  • 이미지는 Docker Hub에 저장되어 있어야 합니다.

Dependency Proxy로 인증

Dependency Proxy가 Docker 이미지를 그룹과 관련된 공간에 저장하기 때문에 Dependency Proxy에 대해 인증해야 합니다.

사설 레지스트리에서 이미지를 사용하는 방법 안내를 따르되, registry.example.com:5000 대신 포트 없는 GitLab 도메인 gitlab.example.com을 사용하세요.

예를 들어, 매뉴얼으로 로그인하려면:

docker login gitlab.example.com --username my_username --password my_password

다음 중 하나를 사용하여 인증할 수 있습니다.

개인 액세스 토큰 또는 사용자 이름과 암호로 Dependency Proxy에 접근하는 사용자는 이미지를 가져오는 그룹에 대해 최소한 게스트 역할을 가져야 합니다.

Dependency Proxy는 Docker v2 토큰 인증 흐름을 따르며 클라이언트에게 pull 요청에 사용할 JWT를 제공합니다. 인증을 한 결과로 발급된 JWT는 일정 시간 후에 만료됩니다. 토큰이 만료되면 대부분의 Docker 클라이언트는 자격 증명을 저장하고 추가 조치 없이 새 토큰을 요청합니다.

토큰 만료 시간은 구성 가능한 설정입니다. GitLab.com의 경우 만료 시간은 15분입니다.

SAML SSO

SSO 강제 적용이 활성화되어 있으면 사용자는 Dependency Proxy를 통해 이미지를 가져오기 전에 SSO를 통해 로그인해야 합니다.

CI/CD 내에서 인증

러너(runner)는 자동으로 Dependency Proxy에 로그인합니다. Dependency Proxy를 통해 가져오려면 사전 정의된 변수 중 하나를 사용하세요:

  • CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX: 최상위 그룹을 통해 가져옵니다.
  • CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX: 서브그룹 또는 프로젝트가 있는 직접적인 그룹을 통해 가져옵니다.

최신 alpine 이미지를 가져오는 예시:

# .gitlab-ci.yml
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/alpine:latest

사용할 수 있는 기타 사전 정의 CI/CD 변수도 있습니다:

  • CI_DEPENDENCY_PROXY_USER: Dependency Proxy에 로그인하는 CI/CD 사용자.
  • CI_DEPENDENCY_PROXY_PASSWORD: Dependency Proxy에 로그인하는 CI/CD 암호.
  • CI_DEPENDENCY_PROXY_SERVER: Dependency Proxy에 로그인하는 서버.
  • CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX: 의존성 프록시를 통해 이미지를 가져오는 데 사용되는 이미지 접두사.
  • CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX: 프로젝트가 속한 서브그룹 또는 직접적인 그룹을 통해 이미지를 가져오는 데 사용되는 이미지 접두사.

CI_DEPENDENCY_PROXY_SERVER, CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX, 그리고 CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX 에는 서버 포트가 포함됩니다. 의존성 프록시 경로를 명시적으로 포함하는 경우 포트를 포함해야 합니다. 단, 포트를 포함하지 않고 매뉴얼으로 의존성 프록시에 로그인한 경우:

docker pull gitlab.example.com:443/my-group/dependency_proxy/containers/alpine:latest

의존성 프록시를 사용하여 이미지를 빌드하는 예시:

# Dockerfile
FROM gitlab.example.com:443/my-group/dependency_proxy/containers/alpine:latest
# .gitlab-ci.yml
image: docker:20.10.16

variables:
  DOCKER_HOST: tcp://docker:2375
  DOCKER_TLS_CERTDIR: ""

services:
  - docker:20.10.16-dind

build:
  image: docker:20.10.16
  before_script:
    - docker login -u $CI_DEPENDENCY_PROXY_USER -p $CI_DEPENDENCY_PROXY_PASSWORD $CI_DEPENDENCY_PROXY_SERVER
  script:
    - docker build -t test .

사용자 정의 CI/CD 변수를 사용하여 개인 액세스 토큰 또는 배포 토큰을 저장하고 액세스할 수도 있습니다.

Dependency Proxy 캐시에 Docker 이미지 저장

Dependency Proxy 캐시에 Docker 이미지를 저장하려면:

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 그룹을 찾습니다.
  2. 운영 > Dependency Proxy를 선택합니다.
  3. Dependency Proxy 이미지 접두사를 복사합니다.
  4. 다음 중 하나의 명령을 사용하세요. 이 예시에서 이미지는 alpine:latest입니다.
  5. 정확한 이미지 버전을 지정하려면 digest를 사용하여 이미지를 가져올 수 있습니다.

    • 태그별 이미지 가져오기: 이미지를 사용하여 .gitlab-ci.yml 파일에 추가합니다.

      image: gitlab.example.com/groupname/dependency_proxy/containers/alpine:latest
      
    • Digest로 이미지 가져오기: 이미지를 사용하여 .gitlab-ci.yml 파일에 추가합니다.

      image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/alpine@sha256:c9375e662992791e3f39e919b26f510e5254b42792519c180aad254e6b38f4dc
      
    • Docker 이미지 매뉴얼으로 가져오기:

      docker pull gitlab.example.com/groupname/dependency_proxy/containers/alpine:latest
      
    • Dockerfile에 URL 추가:

      FROM gitlab.example.com/groupname/dependency_proxy/containers/alpine:latest
      

GitLab은 Docker 이미지를 Docker Hub에서 가져와 서버에 있는 blob을 제공하여 Docker 클라이언트에 제공합니다. 동일한 이미지를 다음에 가져올 때 GitLab은 Docker Hub에서 이미지의 최신 정보를 받지만 서버에 있는 blob을 제공합니다.

저장 공간 사용량 줄이기

리포지터리 Proxy에서 저장 공간 사용량을 줄이는 방법에 대한 정보는 의존성 Proxy 저장 공간 사용량 줄이기를 참조하세요.

Docker Hub 속도 제한 및 의존성 Proxy

의존성 Proxy를 사용하여 Docker Hub 속도 제한을 피하는 방법은 여기에서 확인할 수 있습니다.

2020년 11월, Docker는 Docker Hub에서의 풀 요청에 대한 속도 제한을 도입했습니다. GitLab CI/CD 구성이 Docker Hub에서 이미지를 사용하는 경우 작업을 실행할 때마다 풀 요청으로 계산될 수 있습니다. 이 제한을 피하려면 의존성 Proxy 캐시에서 이미지를 가져올 수 있습니다.

이미지를 가져올 때 (예: docker pull 명령 또는 .gitlab-ci.yml 파일에서 image: foo:latest와 같은) Docker 클라이언트는 요청의 모음을 만듭니다:

  1. 이미지 매니페스트를 요청합니다. 매니페스트에는 이미지를 빌드하는 방법에 대한 정보가 포함되어 있습니다.
  2. 매니페스트를 사용하여 Docker 클라이언트는 하나씩 알려진 레이어 또는 블롭의 모음을 요청합니다.

Docker Hub 속도 제한은 매니페스트에 대한 GET 요청의 수에 기반합니다. 의존성 Proxy는 특정 이미지의 매니페스트와 블롭 모두를 캐시하므로 다시 요청할 때 Docker Hub에 연락할 필요가 없습니다.

GitLab은 캐시된 태그 달린 이미지가 유효하지 않은지 어떻게 알까요?

alpine:latest와 같은 이미지 태그를 사용하는 경우 이미지는 시간이 지남에 따라 변경됩니다. 이미지가 변경될 때마다 매니페스트에는 요청할 블롭에 대한 다른 정보가 포함됩니다. 의존성 Proxy는 매니페스트가 변경될 때만 새 이미지를 가져오지며 매니페스트가 유효하지 않은지를만 확인합니다.

Docker는 이미지 매니페스트에 대한 HEAD 요청을 속도 제한으로 계산하지 않습니다. alpine:latest에 대해 HEAD 요청을 수행하여 헤더에서 반환된 다이제스트(체크섬) 값을 볼 수 있으며 매니페스트가 변경되었는지 확인할 수 있습니다.

의존성 Proxy는 모든 요청을 HEAD 요청으로 시작합니다. 매니페스트가 유효하지 않아지면 새 이미지가 가져와집니다.

예를 들어, 파이프라인에서 node:latest를 매 5분마다 가져오는 경우 의존성 Proxy는 전체 이미지를 캐시하며 node:latest가 변경될 때만 업데이트합니다. 따라서 6시간 동안 이미지에 대해 360번의 요청을 하는 대신 매니페스트가 해당 시간에 변경되지 않는 한 하나의 풀 요청만 있습니다.

Docker Hub 속도 제한 확인

Docker Hub에 몇 개의 요청을 보냈는지와 남은 요청의 수에 대해 궁금하다면 Runner에서 이러한 명령을 실행하거나 심지어 CI/CD 스크립트에서 실행할 수 있습니다:

# 참고: 이 명령을 실행하려면 jq가 설치되어 있어야 합니다
TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq --raw-output .token) && curl --head --header "Authorization: Bearer $TOKEN" "https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest" 2>&1 | grep --ignore-case RateLimit
...

출력은 다음과 유사합니다:

RateLimit-Limit: 100;w=21600
RateLimit-Remaining: 98;w=21600

이 예제에서는 6시간 동안 총 100개의 풀을 할 수 있으며, 98개의 풀 요청이 남아 있는 것을 보여줍니다.

CI/CD 작업에서 속도 제한 확인

이 예제는 jqcurl이 설치된 GitLab CI/CD 작업을 보여줍니다:

hub_docker_quota_check:
    stage: build
    image: alpine:latest
    tags:
        - <optional_runner_tag>
    before_script: apk add curl jq
    script:
      - |
        TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq --raw-output .token) && curl --head --header "Authorization: Bearer $TOKEN" "https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest" 2>&1

문제 해결

인증 오류: “HTTP Basic: Access Denied”

의존성 Proxy에 대해 특정 이미지를 인증할 때 HTTP Basic: Access denied 오류 메시지를 받으면 이중 인증 문제 해결 가이드를 참조하세요.

의존성 Proxy 연결 실패

서비스 별칭이 설정되어 있지 않으면 docker:20.10.16 이미지는 dind 서비스를 찾을 수 없으며 다음과 같은 오류가 발생합니다:

error during connect: Get http://docker:2376/v1.39/info: dial tcp: lookup docker on 192.168.0.1:53: no such host

다음과 같이 Docker 서비스에 서비스 별칭을 설정하여 문제를 해결할 수 있습니다:

services:
    - name: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/docker:18.09.7-dind
      alias: docker

CI/CD 작업에서 의존성 Proxy에 대한 인증 문제

GitLab Runner는 의존성 Proxy에 자동으로 인증됩니다. 그러나 기본 Docker 엔진은 인증 해결 프로세스에 따라 여전히 영향을 받을 수 있습니다.

인증 메커니즘의 잘못된 구성으로 HTTP Basic: Access denied403: Access forbidden와 같은 오류가 발생할 수 있습니다.

작업 로그를 사용하여 의존성 Proxy에 대한 인증 메커니즘을 확인할 수 있습니다:

Authenticating with credentials from $DOCKER_AUTH_CONFIG
Authenticating with credentials from /root/.docker/config.json
Authenticating with credentials from job payload (GitLab Registry)

사용 중인 인증 메커니즘을 확인하세요.

이미지를 가져올 때 Not Found 또는 404 오류

이러한 오류는 작업을 실행하는 사용자가 의존성 Proxy 그룹에서 최소한의 게스트 역할을 할당받지 못한 경우를 나타낼 수 있습니다:

  • ERROR: gitlab.example.com:443/group1/dependency_proxy/containers/alpine:latest: not found
      
    failed to solve with frontend dockerfile.v0: failed to create LLB definition: gitlab.example.com:443/group1/dependency_proxy/containers/alpine:latest: not found
    
  • ERROR: Job failed: failed to pull image "gitlab.example.com:443/group1/dependency_proxy/containers/alpine:latest" with specified policies [always]:
    Error response from daemon: error parsing HTTP 404 response body: unexpected end of JSON input: "" (manager.go:237:1s)
    

Access denied와 유사한 경우에 대한 오류 메시지를 개선할 작업에 대한 자세한 내용은 이슈 354826을 참조하세요.

의존성 Proxy에서 이미지를 실행할 때 exec format error

note
이 문제는 GitLab 16.3에서 해결되었습니다. 16.2 또는 그 이전의 Self-Managed형 인스턴스의 경우 인스턴스를 16.3으로 업데이트하거나 아래에 문서화된 우회 방법을 사용할 수 있습니다.

이 오류는 GitLab 16.2 이전의 ARM 기반 Docker 설치에서 의존성 Proxy를 사용하려고 시도할 때 발생합니다. 의존성 Proxy는 특정 태그로 이미지를 가져올 때 x86_64 아키텍처만 지원합니다.

대체 아키텍처를 가져오도록 의존성 Proxy를 강제로 지정하려면 이미지의 SHA256를 지정할 수 있습니다:

docker pull ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/library/docker:20.10.3@sha256:bc9dcf5c8e5908845acc6d34ab8824bca496d6d47d1b08af3baf4b3adb1bd8fe

이 예에서 bc9dcf5c8e5908845acc6d34ab8824bca496d6d47d1b08af3baf4b3adb1bd8fe는 ARM 기반 이미지의 SHA256입니다.