Spark를 위한 서버리스 Dataproc로 커스텀 컨테이너 사용

Spark를 위한 서버리스 Dataproc은 Docker 컨테이너 내에서 워크로드를 실행합니다. 컨테이너는 워크로드의 드라이버와 실행자 프로세스를 위한 런타임 환경을 제공합니다. 기본적으로 Spark를 위한 서버리스 Dataproc은 런타임 출시 버전과 연결된 기본 Spark, 자바, Python, R 패키지가 포함된 컨테이너 이미지를 사용합니다. Spark를 위한 서버리스 Dataproc batches API를 사용하면 기본 이미지 대신 커스텀 컨테이너 이미지를 사용할 수 있습니다. 일반적으로 커스텀 컨테이너 이미지는 기본 컨테이너 이미지에서 제공하지 않는 Spark 워크로드 자바 또는 Python 종속 항목을 추가합니다. 중요: 커스텀 컨테이너 이미지에 Spark를 포함하지 마세요. Spark를 위한 서버리스 Dataproc은 런타임 시 Spark를 컨테이너에 마운트합니다.

커스텀 컨테이너 이미지를 사용하여 Spark 배치 워크로드 제출

gcloud

Spark 배치 워크로드를 제출할 때 gcloud dataproc batches submit spark 명령어를 --container-image 플래그와 함께 사용하여 커스텀 컨테이너 이미지를 지정합니다.

gcloud dataproc batches submit spark \
    --container-image=custom-image, for example, "gcr.io/my-project-id/my-image:1.0.1" \
    --region=region \
    --jars=path to user workload jar located in Cloud Storage or included in the custom container \
    --class=The fully qualified name of a class in the jar file, such as org.apache.spark.examples.SparkPi \
    -- add any workload arguments here

참고:

  • Custom-image: {hostname}/{project-id}/{image}:{tag} Container Registry 이미지 이름 지정 형식을 사용하여 커스텀 컨테이너 이미지를 지정합니다(예: 'gcr.io/my-project-id/my-image:1.0.1'). 참고: Container Registry에서 커스텀 컨테이너 이미지를 호스팅해야 합니다(서버리스 Dataproc는 다른 레지스트리에서 컨테이너를 가져올 수 없음).
  • --jars: 커스텀 컨테이너 이미지에 포함되어 있거나 Cloud Storage에 있는 사용자 워크로드의 경로를 지정합니다(예: '/opt/spark/jars/spark-examples.jar' 또는 'gs://my-bucket/spark/jars/spark-examples.jar').
  • 기타 배치 명령어 옵션: 예를 들어 Spark 기록 서버를 사용하는 등 다른 선택적 배치 명령어 플래그를 추가할 수 있습니다. 지원되는 명령어 플래그는 gcloud dataproc batches submit을 참조하세요.
  • 워크로드 인수 명령어 끝에 '--'를 추가하고 워크로드 인수를 추가하여 모든 워크로드 인수를 추가할 수 있습니다.

REST 및 명령줄

커스텀 컨테이너 이미지는 batches.create API 요청의 일부로 RuntimeConfig.containerImage 필드를 통해 제공됩니다.

다음 예시에서는 커스텀 컨테이너로 Spark를 위한 서버리스 Dataproc batches.create API를 사용하여 배치 워크로드를 제출하는 방법을 보여줍니다.

요청 데이터를 사용하기 전에 다음을 바꿉니다.

  • project-id: Google Cloud 프로젝트 ID
  • region: 리전
  • custom-container-image: Container Registry 이미지 이름 지정 형식 {hostname}/{project-id}/{image}:{tag}을 사용하여 커스텀 컨테이너 이미지를 지정합니다(예: 'gcr.io/my-project-id/my-image:1.0'). 참고: Container Registry에서 커스텀 컨테이너를 호스팅해야 합니다(서버리스 Dataproc는 다른 레지스트리에서 컨테이너를 가져올 수 없음).
  • jar-uri: 커스텀 컨테이너 이미지에 포함되어 있거나 Cloud Storage에 있는 워크로드 jar의 경로를 지정합니다. 예를 들면 '/opt/spark/jars/spark-examples.jar' 또는 'gs:///spark/jars/spark-examples.jar'입니다
  • class: jar 파일에 있는 클래스의 정규화된 이름입니다(예: 'org.apache.spark.examples.SparkPi').
  • 기타 옵션: 다른 배치 워크로드 리소스 필드를 사용할 수 있습니다. 예를 들어 sparkBatch.args 필드를 사용하여 워크로드에 인수를 전달할 수 있습니다(자세한 내용은 Batch 리소스 문서 참조). Spark 기록 서버를 사용하려면 영구 기록 서버 설정을 참조하세요.

HTTP 메서드 및 URL:

POST https://dataproc.googleapis.com/v1/projects/project-id/locations/region/batches

JSON 요청 본문:

{
  "runtimeConfig":{
    "containerImage":"custom-container-image
  },
  "sparkBatch":{
    "jarFileUris":[
      "jar-uri"
    ],
    "mainClass":"class"
  }
}

요청을 보내려면 다음 옵션 중 하나를 펼칩니다.

다음과 비슷한 JSON 응답이 표시됩니다.

{
"name":"projects/project-id/locations/region/batches/batch-id",
  "uuid":",uuid",
  "createTime":"2021-07-22T17:03:46.393957Z",
  "runtimeConfig":{
    "containerImage":"gcr.io/my-project/my-image:1.0.1"
  },
  "sparkBatch":{
    "mainClass":"org.apache.spark.examples.SparkPi",
    "jarFileUris":[
      "/opt/spark/jars/spark-examples.jar"
    ]
  },
  "runtimeInfo":{
    "outputUri":"gs://dataproc-.../driveroutput"
  },
  "state":"SUCCEEDED",
  "stateTime":"2021-07-22T17:06:30.301789Z",
  "creator":"account-email-address",
  "runtimeConfig":{
    "properties":{
      "spark:spark.executor.instances":"2",
      "spark:spark.driver.cores":"2",
      "spark:spark.executor.cores":"2",
      "spark:spark.app.name":"projects/project-id/locations/region/batches/batch-id"
    }
  },
  "environmentConfig":{
    "peripheralsConfig":{
      "sparkHistoryServerConfig":{
      }
    }
  },
  "operation":"projects/project-id/regions/region/operation-id"
}

커스텀 컨테이너 이미지 빌드

Spark를 위한 서버리스 Dataproc 커스텀 컨테이너 이미지는 Docker 이미지입니다. Docker 이미지 빌드 도구를 사용하여 커스텀 컨테이너 이미지를 빌드할 수 있지만 이미지가 Spark를 위한 서버리스 Dataproc과 호환되어야 합니다. 다음 섹션에서는 이러한 조건을 설명합니다.

운영체제

모든 운영체제 이미지를 커스텀 컨테이너 이미지의 기본 이미지로 선택할 수 있습니다. 권장사항: 호환성 문제를 방지하기 위해 테스트를 수신했으므로 기본 Debian 11 이미지가 권장됩니다(예: debian:11-slim).

유틸리티

Spark를 실행하는 데 필요한 다음 유틸리티 패키지를 커스텀 컨테이너 이미지에 포함해야 합니다.

  • procps
  • tini

컨테이너 사용자

Spark를 위한 서버리스 Dataproc은 1099 UID 및 1099 GID를 사용하여 컨테이너를 spark Linux 사용자로 실행합니다. 커스텀 컨테이너 이미지 Dockerfile에 설정된 USER 지시문은 런타임 시 무시됩니다. 파일 시스템 권한에 UID 및 GID를 사용합니다. 예를 들어 /opt/spark/jars/my-lib.jar의 jar 파일을 워크로드 종속 항목으로 이미지에 추가하면 spark 사용자에게 파일에 대한 읽기 권한을 부여해야 합니다.

Spark

커스텀 컨테이너 이미지에 Spark를 포함하지 마세요. 런타임 시 Spark를 위한 서버리스 Dataproc은 호스트의 Spark 바이너리와 구성을 컨테이너에 마운트합니다. 바이너리는 /usr/lib/spark 디렉터리에 마운트되고 구성은 /etc/spark/conf 디렉터리에 마운트됩니다. 이러한 디렉터리의 기존 파일은 런타임 시 Spark를 위한 서버리스 Dataproc에서 재정의됩니다.

자바 런타임 환경

커스텀 컨테이너 이미지에 자체 자바 런타임 환경(JRE)을 포함하지 마세요. 런타임 시 Spark를 위한 서버리스 Dataproc은 호스트의 OpenJDK11을 컨테이너에 마운트합니다. 커스텀 컨테이너 이미지에 JRE를 포함하면 무시됩니다.

자바 패키지

jar 파일을 Spark 워크로드 종속 항목으로 커스텀 컨테이너 이미지에 포함할 수 있으며 jar가 포함되도록 SPARK_EXTRA_CLASSPATH 환경 변수를 설정할 수 있습니다. Spark를 위한 서버리스 Dataproc은 Spark JVM 프로세스의 클래스 경로에 환경 변수 값을 추가합니다. 권장사항: jar를 /opt/spark/jars 디렉터리에 배치하고 SPARK_EXTRA_CLASSPATH/opt/spark/jars/*로 설정합니다.

커스텀 컨테이너 이미지에 워크로드 jar을 포함한 다음 워크로드를 제출할 때 로컬 경로로 참조할 수 있습니다(예: file:///opt/spark/jars/my-spark-job.jar). 커스텀 컨테이너 이미지를 사용하여 Spark 배치 워크로드 제출 예시를 참조하세요.

Python 패키지

기본적으로 Spark를 위한 Dataproc 서버리스는 호스트의 Conda를 런타임에 컨테이너의 /opt/dataproc/conda 디렉터리에 마운트합니다. PYSPARK_PYTHON/opt/dataproc/conda/bin/python으로 설정되어 있습니다. 기본 디렉터리인 /opt/dataproc/conda/binPATH에 포함됩니다.

커스텀 컨테이너 이미지의 다른 디렉터리(예: /opt/conda)에 패키지가 있는 Python 환경을 포함하고 PYSPARK_PYTHON 환경 변수를 /opt/conda/bin/python으로 설정할 수 있습니다.

커스텀 컨테이너 이미지에는 Python 환경에 속하지 않는 다른 Python 모듈(예: 유틸리티 함수가 포함된 Python 스크립트)이 포함될 수 있습니다. 모듈이 있는 디렉터리가 포함되도록 PYTHONPATH 환경 변수를 설정합니다.

R 환경

다음 옵션 중 하나를 사용하여 커스텀 컨테이너 이미지에서 R 환경을 맞춤설정할 수 있습니다. - Conda를 사용하여 conda-forge 채널에서 R 패키지를 관리 및 설치 - 컨테이너 이미지 Linux OS용 R 저장소를 추가하고, Linux OS 패키지 관리자를 통해 R 패키지 설치(R 소프트웨어 패키지 색인 참조)

두 옵션 중 하나를 사용하는 경우 R_HOME 환경 변수가 커스텀 R 환경을 가리키도록 설정해야 합니다. 예외: Conda를 사용하여 R 환경을 관리하고 Python 환경을 맞춤설정하는 경우 R_HOME 환경 변수를 설정할 필요가 없습니다. PYSPARK_PYTHON 환경 변수에 따라 자동으로 설정됩니다.

커스텀 컨테이너 이미지 빌드 예시

Dockerfile

# Debian 11 is recommended.
FROM debian:11-slim

# Suppress interactive prompts
ENV DEBIAN_FRONTEND=noninteractive

# (Required) Install utilities required by Spark scripts.
RUN apt update && apt install -y procps tini

# (Optional) Add extra jars.
ENV SPARK_EXTRA_JARS_DIR=/opt/spark/jars/
ENV SPARK_EXTRA_CLASSPATH='/opt/spark/jars/*'
RUN mkdir -p "${SPARK_EXTRA_JARS_DIR}"
COPY spark-bigquery-with-dependencies_2.12-0.22.2.jar "${SPARK_EXTRA_JARS_DIR}"

# (Optional) Install and configure Miniconda3.
ENV CONDA_HOME=/opt/miniconda3
ENV PYSPARK_PYTHON=${CONDA_HOME}/bin/python
ENV PATH=${CONDA_HOME}/bin:${PATH}
COPY Miniconda3-py39_4.10.3-Linux-x86_64.sh .
RUN bash Miniconda3-py39_4.10.3-Linux-x86_64.sh -b -p /opt/miniconda3 \
  && ${CONDA_HOME}/bin/conda config --system --set always_yes True \
  && ${CONDA_HOME}/bin/conda config --system --set auto_update_conda False \
  && ${CONDA_HOME}/bin/conda config --system --prepend channels conda-forge \
  && ${CONDA_HOME}/bin/conda config --system --set channel_priority strict

# (Optional) Install Conda packages.
#
# The following packages are installed in the default image, it is strongly
# recommended to include all of them.
#
# Use mamba to install packages quickly.
RUN ${CONDA_HOME}/bin/conda install mamba -n base -c conda-forge \
    && ${CONDA_HOME}/bin/mamba install \
      conda \
      cython \
      fastavro \
      fastparquet \
      gcsfs \
      google-cloud-bigquery-storage \
      google-cloud-bigquery[pandas] \
      google-cloud-bigtable \
      google-cloud-container \
      google-cloud-datacatalog \
      google-cloud-dataproc \
      google-cloud-datastore \
      google-cloud-language \
      google-cloud-logging \
      google-cloud-monitoring \
      google-cloud-pubsub \
      google-cloud-redis \
      google-cloud-spanner \
      google-cloud-speech \
      google-cloud-storage \
      google-cloud-texttospeech \
      google-cloud-translate \
      google-cloud-vision \
      koalas \
      matplotlib \
      nltk \
      numba \
      numpy \
      openblas \
      orc \
      pandas \
      pyarrow \
      pysal \
      pytables \
      python \
      regex \
      requests \
      rtree \
      scikit-image \
      scikit-learn \
      scipy \
      seaborn \
      sqlalchemy \
      sympy \
      virtualenv

# (Optional) Add extra Python modules.
ENV PYTHONPATH=/opt/python/packages
RUN mkdir -p "${PYTHONPATH}"
COPY test_util.py "${PYTHONPATH}"

# (Optional) Install R and R libraries.
RUN apt update \
  && apt install -y gnupg \
  && apt-key adv --no-tty \
      --keyserver "hkp://keyserver.ubuntu.com:80" \
      --recv-keys E19F5F87128899B192B1A2C2AD5F960A256A04AF \
  && echo "deb http://cloud.r-project.org/bin/linux/debian bullseye-cran40/" \
      >/etc/apt/sources.list.d/cran-r.list \
  && apt update \
  && apt install -y \
      libopenblas-base \
      libssl-dev \
      r-base \
      r-base-dev \
      r-recommended \
      r-cran-blob

ENV R_HOME=/usr/lib/R

# (Required) Create the 'spark' group/user.
# The GID and UID must be 1099. Home directory is required.
RUN groupadd -g 1099 spark
RUN useradd -u 1099 -g 1099 -d /home/spark -m spark
USER spark

빌드 명령어

Dockerfile 디렉터리에서 실행합니다.

IMAGE=gcr.io/my-project/my-image:1.0.1

# Download the BigQuery connector.
gsutil cp \
  gs://spark-lib/bigquery/spark-bigquery-with-dependencies_2.12-0.22.2.jar .

# Download the Miniconda3 installer.
wget https://repo.anaconda.com/miniconda/Miniconda3-py39_4.10.3-Linux-x86_64.sh

# Python module example
cat >test_util.py <<EOF
def hello(name):
  print("hello {}".format(name))

def read_lines(path):
  with open(path) as f:
    return f.readlines()
EOF

# Build and push the image.
docker build -t "${IMAGE}" .
docker push "${IMAGE}"