Create Resource 에서 Python Environment 를 고르면 입력란은 PyPI mirror URL 하나뿐이고 업로드할 수 있는 파일은 requirements.txt 뿐이다. 내부 동작은 다음과 같다.
requirements.txt 업로드
→ CDE 가 컨테이너에서 pip install --index-url <mirror> -r requirements.txt 실행
→ 결과 이미지를 CDE 내부 레지스트리로 push
→ Job 실행 시 해당 이미지를 자동 사용
사용자는 레지스트리를 신경 쓸 필요가 없다. 대신 mirror URL 에 --no-index --find-links=/local/path 같은 옵션을 끼워 넣는 방식은 통하지 않는다. URL 형식 검증에 걸리거나, 통과하더라도 CDE 가 값을 따옴표로 묶어 --index-url 의 값으로 통째로 전달하므로 명령이 깨진다. 업로드한 whl 파일이 빌드 컨텍스트 어디에 놓이는지도 알 수 없다.
폐쇄망에서는 사내 PyPI 미러(Nexus · Artifactory 등)를 mirror URL 로 지정하는 것이 정석이다. 미러를 둘 수 없으면 Custom Runtime Image 로 간다.
사용자가 이미지를 직접 만들어 레지스트리에 올리고, CDE 에 "이 레지스트리의 이 이미지를 쓰라"고 명시하는 구조다. CDE 가 알아서 찾아 주지 않는다.
베이스 이미지는 DEX 버전과 Virtual Cluster 의 Spark 버전에 맞는 dex-spark-runtime 을 써야 한다. 버전이 어긋나면 Job 이 뜨지 않는다.
FROM container.repository.cloudera.com/cloudera/dex/dex-spark-runtime-3.2.3-7.2.15.8:1.20.0-b15
USER root
COPY my_package.whl /tmp/
RUN pip install --no-index /tmp/my_package.whl pandas numpy
USER 1000
docker build -t harbor.internal.example.com/cde/my-custom-runtime:v1 .
docker push harbor.internal.example.com/cde/my-custom-runtime:v1
cde credential create \
--name docker-creds \
--type docker-basic \
--docker-server harbor.internal.example.com \
--docker-username ${REGISTRY_USER}
cde resource create \
--name my-custom-runtime \
--type custom-runtime-image \
--image harbor.internal.example.com/cde/my-custom-runtime:v1 \
--image-engine spark3 \
--image-credential docker-creds
cde job create \
--name my-spark-job \
--type spark \
--mount-1-resource my-files \
--application-file main.py \
--runtime-image-resource-name my-custom-runtime