컨테이너 레지스트리 데이터 전송량 줄이기

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

이미지나 태그를 컨테이너 레지스트리에서 다운로드하는 빈도에 따라 데이터 전송량이 상당히 높아질 수 있습니다. 이 페이지에서는 컨테이너 레지스트리의 전송 데이터 양을 줄이는 다양한 권고 사항과 팁을 제공합니다.

데이터 전송 사용량 확인

전송 사용량은 GitLab UI 내에서 사용할 수 없습니다. GitLab-#350905는 이 정보를 나타내는 작업을 추적하는 epic입니다.

이미지 크기 결정

이러한 도구와 기술을 사용하여 이미지 크기를 결정하세요:

  • Skopeo: Skopeo inspect 명령을 사용하여 API 호출을 통해 레이어 수와 크기를 검사할 수 있습니다. 따라서 docker pull IMAGE를 실행하기 전에 이 데이터를 검사할 수 있습니다.

  • CI에서 Docker: Docker를 사용할 때 GitLab CI를 사용하여 이미지 크기를 검사 및 기록할 수 있습니다. 예를 들어:

    docker inspect "$CI_REGISTRY_IMAGE:$IMAGE_TAG" \
          | awk '/"Size": ([0-9]+)[,]?/{ printf "Final Image Size: %d\n", $2 }'
    
  • Dive Docker 이미지, 레이어 내용을 탐색하고 크기를 줄이는 방법을 발견할 수 있는 도구입니다.

이미지 크기 줄이기

더 작은 기본 이미지 사용

Alpine Linux와 같이 더 작은 기본 이미지를 사용하는 것을 고려하세요. Alpine 이미지는 약 5MB이며, Debian과 같은 인기있는 기본 이미지보다 훨씬 작습니다. 응용 프로그램이 독자적인 정적 이진 파일로 배포되는 경우(Go 애플리케이션 등), Docker scratch 기본 이미지를 사용하는 것도 고려할 수 있습니다.

특정 기본 이미지 OS를 사용해야 하는 경우 -slim 또는 -minimal 변형을 찾아보세요. 이렇게 하면 이미지 크기가 줄어듭니다.

또한 기본 이미지 위에 설치하는 운영 체제 패키지를 신중하게 고려해야 합니다. 이로 인해 수백 메가바이트가 더해질 수 있습니다. 빌드 의존성을 일시적으로 제거하는 데 다단계 빌드(multi-stage builds)가 강력한 도구가 될 수 있습니다.

이 외에도 다음과 같은 도구를 사용할 수 있습니다:

  • DockerSlim 컨테이너 이미지 크기를 줄이기 위한 일련의 명령을 제공합니다.
  • Distroless 이미지는 애플리케이션과 해당 런타임 종속성만 포함합니다. 패키지 관리자, 셸 또는 표준 Linux 배포에 기대할 수 있는 다른 프로그램은 포함되어 있지 않습니다.

레이어 최소화

Dockerfile에서 각 명령은 새 레이어를 생성하며, 해당 명령을 통해 적용된 파일 시스템 변경 사항이 기록됩니다. 일반적으로, 더 많거나 큰 레이어는 더 큰 이미지로 이어집니다. Dockerfile에서 패키지를 설치하기 위한 레이어 수를 최소화하기 위해 최선을 다하세요. 그렇지 않으면 각 단계마다 이미지 크기가 증가할 수 있습니다.

레이어 수와 크기를 줄이기 위한 여러 가지 전략이 있습니다. 예를 들어, 패키지 당 RUN 명령을 사용하는 대신(패키지당 레이어를 만들 수 있음), 빌드 프로세스의 단계 수를 줄이고 이미지 크기를 줄이기 위해 모든 패키지를 하나의 RUN 명령으로 설치할 수 있습니다.

유용한 다른 전략은 일시적 빌드 의존성을 모두 제거하고, 패키지를 설치하기 전후에 운영 체제 패키지 관리자 캐시를 비활성화하거나 비워두는 것입니다.

이미지를 빌드할 때 관련 파일만 복사하도록 해야 합니다. Docker의 경우, .dockerignore를 사용하여 빌드 프로세스가 관련 없는 파일을 무시하도록 해야 합니다.

DockerSlim과 같은 타사 도구를 사용하여 이미지 크기를 줄일 수 있습니다. 그러나 이러한 도구를 부적절하게 사용하면 애플리케이션이 특정 조건에서 작동하는 데 필요한 종속성을 제거할 수 있습니다. 따라서 이미지를 줄이기 위해 피상적으로 수정하는 대신 빌드 프로세스 중에 작은 이미지를 만들도록 노력하는 것이 좋습니다.

다단계 빌드 사용

다단계 빌드(multi-stage builds)를 사용하면 Dockerfile에서 여러 FROM 문을 사용합니다. 각 FROM 명령은 다른 기본을 사용하며, 각각은 새 빌드 단계를 시작합니다. 원하는 것만 최종 이미지에 남기고 다른 단계에서 필요하지 않은 빌드 종속성을 설치해야 하는 경우 특히 유용합니다.

이미지 풀 정책 사용

docker 또는 docker+machine executor를 사용할 때 runner config.toml에서 pull_policy 매개변수를 설정하여 Docker 이미지를 끌어올 때 runner가 작동하는 방식을 정의할 수 있습니다. 큰 크기의 이미지를 사용하고 드물게 업데이트하는 이미지를 끌어올 때 데이터 전송량을 줄이기 위해 if-not-present 풀 정책을 사용하는 것을 고려해보세요.

Docker 레이어 캐싱 사용

docker build를 실행할 때 Dockerfile의 각 명령은 레이어로 저장됩니다. 이러한 레이어는 캐시로 유지되어 변경 사항이 없는 경우 재사용할 수 있습니다. --cache-from 인수를 사용하여 docker build 명령에 캐시 소스로 태그가 지정된 이미지를 지정할 수 있습니다. 여러 개의 --cache-from 인수를 사용하여 여러 이미지를 캐시 소스로 지정할 수 있습니다. 이렇게 하면 빌드 시간을 단축하고 전송 데이터 양을 줄일 수 있습니다. 자세한 내용은 Docker 레이어 캐싱 설명서를 참조하세요.

자동화 빈도 확인

우리는 종종 특정 간격으로 정기적인 작업을 수행하기 위한 자동화 스크립트를 컨테이너 이미지에 묶어둡니다. GitLab Registry에서 컨테이너 이미지를 가져와 GitLab.com 외부의 서비스에 사용하는 자동화 간격을 줄일 수 있습니다.

관련 이슈

  • 기본 도커 이미지가 업데이트될 때 이미지를 다시 빌드하고 싶을 수 있습니다. 그러나 파이프라인 구독 한도가 이 기능을 활용하기에는 너무 낮습니다. 해결책으로 매일 또는 하루에 여러 번 이미지를 다시 빌드할 수 있습니다. GitLab-#225278에서는 이 워크플로우를 돕기 위해 한도를 높이는 제안이 됐습니다.