Bitbucket 파이프라인에서 CNCF Buildpacks 사용 장애

BitBucket 파이프라인에서 CNCF Buildpacks의 pack 도구를 사용해 컨테이너 이미지를 생성하려고 실험 중인데, 다음과 같은 오류가 발생하고 있습니다:

ERROR: failed to build: failed to create 'creator' container: Error response from daemon: authorization denied by plugin pipelines: -v only supports $BITBUCKET_CLONE_DIR and its subdirectories"

Buildpacks는 일부 마운트 지점에 대해 특정 마운트 디렉토리를 정의할 수 있는 기능을 제공하며, 이들을 BitBucket의 clone 디렉토리로 설정할 수는 있지만, 일부 마운트 지점은 설정할 수 없는 것 같습니다.

Using build cache dir '/opt/atlassian/pipelines/agent/build/build-cache'
Build cache '/opt/atlassian/pipelines/agent/build/build-cache' cleared
Created ephemeral bridge network pack.local-network-<id> with ID <id>
Running the 'creator' on OS 'linux' from image 'pack.local/builder/<id>:latest' with:
Container Settings:
  Args: '/cnb/lifecycle/creator -daemon -launch-cache /launch-cache -log-level debug -app //opt/atlassian/pipelines/agent/build -cache-dir /cache -run-image index.docker.io/paketobuildpacks/run-jammy-base:latest -skip-restore <project>'
  System Envs: 'CNB_PLATFORM_API=0.13'
  Image: 'pack.local/builder/<id>:latest'
  User: 'root'
  Labels: 'map[author:pack]'
Host Settings:
  Binds: '/opt/atlassian/pipelines/agent/build/build-cache:/cache /var/run/docker.sock:/var/run/docker.sock /opt/atlassian/pipelines/agent/build/launch-cache/launch-cache:/launch-cache pack-layers-<id>:/layers pack-app-<id>://opt/atlassian/pipelines/agent/build'
  Network Mode: 'pack.local-network-<id>'
ERROR: failed to build: executing lifecycle: failed to create 'creator' container: Error response from daemon: authorization denied by plugin pipelines: -v only supports $BITBUCKET_CLONE_DIR and its subdirectories

/layers로 마운트된 layers-가 BitBucket의 clone 디렉토리 밖이어서 문제가 발생한 것으로 보입니다. 혼란스러운 점은, maven 빌드에서는 pack을 사용할 때 이 문제가 발생하지 않는다는 점이며, 실행 명령 구성이 유사하다고 느껴집니다. /var/run/docker.sock:/var/run/docker.sock 마운트가 허용되는지도 확실하지 않습니다.

다양한 buildpack을 사용해보고, 실행 시점에 사용할 buildpack을 정의하고, 캐시 위치를 명시하는 등의 시도를 했지만 모두 동일한 오류가 발생했습니다.

로컬 머신에서는 빌드가 정상적으로 작동합니다.

더 이상 시도해볼 아이디어가 없어서 도움을 부탁드립니다.

저는 Bitbucket을 직접 사용하진 않지만, 말씀하신 내용을 보면 CI 작업이 컨테이너 내에서 실행되고 있는 것 같습니다. 이는 Cloud-Native Buildpacks 도구인 pack을 사용할 때 다소 까다로울 수 있습니다. pack의 일부 기능은 Docker 데몬을 필요로 하는데, CI가 이미 컨테이너 환경에서 실행 중인 경우 Docker 데몬을 사용하는 것은 어렵거나 느리거나 아예 불가능할 수 있습니다.

pack 도구는 "플랫폼(platform)"이라고 불리며, CNB 빌드를 실행할 수 있도록 환경을 준비하는 역할을 합니다. 즉, base 이미지와 run 이미지를 가져오고, buildpack 이미지를 다운로드하며, 빌드를 실행할 깨끗한 컨테이너 환경을 구성합니다. 다른 플랫폼으로는 kpack, Spring Boot의 Build Tools 등이 있으며, 간단한 스크립트를 사용하여 직접 플랫폼 역할을 할 수도 있습니다. 이러한 플랫폼들은 실제로 buildpack을 실행하지 않고, CNB lifecycle이라는 도구에 위임합니다.

이처럼 CI 작업이 이미 컨테이너에서 실행되고 있는 상황에서는 일반적으로 CI 컨테이너를 빌드 환경으로 취급하고 pack을 생략한 채 직접 Cloud-Native Buildpacks를 실행하는 방식을 많이 사용합니다.

CI 빌드 작업에서의 절차는 다음과 같습니다:

  1. CI 환경의 base image로 CNB Builder 이미지를 사용합니다. 이렇게 하면 해당 컨테이너에는 기본적인 buildpack들이 이미 설치되어 있습니다.
  2. CNB lifecycle을 다운로드합니다: Releases · buildpacks/lifecycle · GitHub
  3. 애플리케이션 코드를 다운로드하거나 체크아웃합니다. 이전 단계에서 앱을 빌드했다면, 컴파일된 바이너리나 JAR 파일 등 최종 산출물을 사용할 수도 있습니다. 꼭 소스 코드일 필요는 없으며, buildpack이 이미지로 변환할 앱 산출물이면 됩니다.
  4. lifecycle의 creator를 실행합니다. 이 명령은 전체 build 단계를 한 번에 수행하며, 개별 단계로 나누어 실행할 수도 있지만 보통은 필요하지 않습니다.
  5. lifecycle이 buildpack을 실행하고 이미지를 export합니다. 이때 Docker 데몬이 없으므로, export는 레지스트리로 직접 업로드하도록 설정해야 합니다.

이것이 요약된 절차이며, CNB 공식 문서블로그 포스트에서 더 많은 세부 사항과 예시를 확인할 수 있습니다.

감사합니다.