Personaliza el entorno de ejecución del trabajo de Spark con Docker en YARN

La función Docker on YARN de Dataproc te permite crear y usar una imagen de Docker para personalizar el entorno de ejecución del trabajo de Spark. La imagen puede incluir personalizaciones para las dependencias de Java, Python y R, y para tu jar de trabajo.

Limitaciones

La disponibilidad o la asistencia de las funciones no están disponibles en los siguientes dispositivos:

  • Versiones de imágenes de Dataproc anteriores a 2.0.49 (no disponibles en imágenes 1.5)
  • Trabajos de MapReduce (solo compatibles con los trabajos de Spark)
  • Modo de cliente de Spark (solo compatible con el modo de clúster de Spark)
  • Clústeres de Kerberos: La creación de clústeres falla si creas un clúster con Docker en YARN y Kerberos habilitado.
  • Personalización de JDK, Hadoop y Spark: se usan el JDK, Hadoop y Spark del host, no tus personalizaciones.

Crear una imagen de Docker

El primer paso para personalizar el entorno de Spark es compilar una imagen de Docker.

Dockerfile

Puedes usar el siguiente Dockerfile como ejemplo, realizando cambios y adiciones según tus necesidades.

FROM debian:10-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 *.jar "${SPARK_EXTRA_JARS_DIR}"

# Optional: Install and configure Miniconda3.
ENV CONDA_HOME=/opt/miniconda3
ENV PYSPARK_PYTHON=${CONDA_HOME}/bin/python
ENV PYSPARK_DRIVER_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}"

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

Compila y envía la imagen

Los siguientes son comandos para compilar y enviar la imagen de Docker de ejemplo. Puedes realizar cambios según tus personalizaciones.

# Increase the version number when there is a change to avoid referencing
# a cached older image. Avoid reusing the version number, including the default
# `latest` version.
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}"

Crea un clúster de Dataproc

Después de crear una imagen de Docker que personalice tu entorno de Spark, crea un clúster de Dataproc que usará tu imagen de Docker cuando ejecute trabajos de Spark.

gcloud

gcloud dataproc clusters create CLUSTER_NAME \
    --region=REGION \
    --image-version=DP_IMAGE \
    --optional-components=DOCKER \
    --properties=dataproc:yarn.docker.enable=true,dataproc:yarn.docker.image=DOCKER_IMAGE \
    other flags

Reemplaza lo siguiente:

  • CLUSTER_NAME: Es el nombre del clúster.
  • REGION: Es la región del clúster.
  • DP_IMAGE: La versión de la imagen de Dataproc debe ser 2.0.49 o posterior (--image-version=2.0 usará una versión secundaria calificada posterior a 2.0.49).
  • --optional-components=DOCKER: Habilita el componente de Docker en el clúster.
  • Marca --properties:
    • dataproc:yarn.docker.enable=true: Es una propiedad obligatoria para habilitar la función Docker de Dataproc en YARN.
    • dataproc:yarn.docker.image: Es una propiedad opcional que puedes agregar para especificar tu DOCKER_IMAGE con el siguiente formato de nomenclatura de imágenes de Container Registry: {hostname}/{project-id}/{image}:{tag}.

      Ejemplo:

      dataproc:yarn.docker.image=gcr.io/project-id/image:1.0.1
      

      Requisito: Debes alojar tu imagen de Docker en Container Registry o Artifact Registry. (Dataproc no puede recuperar contenedores de otros registros).

      Recomendación: Agrega esta propiedad cuando crees tu clúster para almacenar en caché tu imagen de Docker y evitar que se agote el tiempo de espera de YARN más adelante cuando envíes un trabajo que use la imagen.

Cuando dataproc:yarn.docker.enable se establece en true, Dataproc actualiza la configuración de Hadoop y Spark para habilitar la característica Docker en YARN en el clúster. Por ejemplo, spark.submit.deployMode se configura como cluster, y spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_MOUNTS y spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_MOUNTS se configuran para activar directorios del host en el contenedor.

Envía un trabajo de Spark al clúster

Después de crear un clúster de Dataproc, envía un trabajo de Spark al clúster que usa tu imagen de Docker. En el ejemplo de esta sección, se envía un trabajo de PySpark al clúster.

Configura las propiedades del trabajo:

# Set the Docker image URI.
IMAGE=(e.g., gcr.io/my-project/my-image:1.0.1)

# Required: Use `#` as the delimiter for properties to avoid conflicts.
JOB_PROPERTIES='^#^'

# Required: Set Spark properties with the Docker image.
JOB_PROPERTIES="${JOB_PROPERTIES}#spark.yarn.appMasterEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=${IMAGE}"
JOB_PROPERTIES="${JOB_PROPERTIES}#spark.executorEnv.YARN_CONTAINER_RUNTIME_DOCKER_IMAGE=${IMAGE}"

# Optional: Add custom jars to Spark classpath. Don't set these properties if
# there are no customizations.
JOB_PROPERTIES="${JOB_PROPERTIES}#spark.driver.extraClassPath=/opt/spark/jars/*"
JOB_PROPERTIES="${JOB_PROPERTIES}#spark.executor.extraClassPath=/opt/spark/jars/*"

# Optional: Set custom PySpark Python path only if there are customizations.
JOB_PROPERTIES="${JOB_PROPERTIES}#spark.pyspark.python=/opt/miniconda3/bin/python"
JOB_PROPERTIES="${JOB_PROPERTIES}#spark.pyspark.driver.python=/opt/miniconda3/bin/python"

# Optional: Set custom Python module path only if there are customizations.
# Since the `PYTHONPATH` environment variable defined in the Dockerfile is
# overridden by Spark, it must be set as a job property.
JOB_PROPERTIES="${JOB_PROPERTIES}#spark.yarn.appMasterEnv.PYTHONPATH=/opt/python/packages"
JOB_PROPERTIES="${JOB_PROPERTIES}#spark.executorEnv.PYTHONPATH=/opt/python/packages"

Notas:

gcloud

Envía el trabajo al clúster.

gcloud dataproc jobs submit pyspark PYFILE \
    --cluster=CLUSTER_NAME \
    --region=REGION \
    --properties=${JOB_PROPERTIES}

Reemplaza lo siguiente:

  • PYFILE: Es la ruta de acceso a tu archivo de trabajo de PySpark. Puede ser una ruta de archivo local o el URI del archivo en Cloud Storage (gs://BUCKET_NAME/PySpark filename).
  • CLUSTER_NAME: Es el nombre del clúster.
  • REGION: Es la región del clúster.