Apache Spark በ Kubernetes ላይ በማሄድ ላይ

ውድ አንባቢዎች ደህና ከሰአት። ዛሬ ስለ Apache Spark እና ስለ ልማት ተስፋዎች ትንሽ እንነጋገራለን.

Apache Spark በ Kubernetes ላይ በማሄድ ላይ

በዘመናዊው የቢግ ዳታ ዓለም ውስጥ፣ Apache Spark የባች ዳታ ማቀናበሪያ ተግባራትን ለማዳበር ትክክለኛው ደረጃ ነው። በተጨማሪም ፣ በማይክሮ ባች ፅንሰ-ሀሳብ ፣ ማቀናበር እና ማጓጓዣ መረጃን በትንሽ ክፍሎች (Spark Structured Streaming) ውስጥ የሚሰሩ የዥረት አፕሊኬሽኖችን ለመፍጠርም ይጠቅማል። እና በተለምዶ YARN (ወይንም በአንዳንድ አጋጣሚዎች Apache Mesos) እንደ የንብረት አስተዳዳሪ በመጠቀም የአጠቃላይ የሃዱፕ ቁልል አካል ነው። እ.ኤ.አ. በ 2020 ፣ በባህላዊው መልክ አጠቃቀሙ በአብዛኛዎቹ ኩባንያዎች ውስጥ ጥሩ የሃዱፕ ስርጭት ባለመኖሩ ጥያቄ ውስጥ ነው - የ HDP እና CDH ልማት ቆሟል ፣ CDH በደንብ ያልዳበረ እና ከፍተኛ ወጪ ያለው ሲሆን የተቀሩት Hadoop አቅራቢዎችም አላቸው ። ወይ ሕልውናው አቁሟል ወይም የወደፊት ተስፋ የለውም። ስለዚህ Kubernetes ን በመጠቀም Apache Spark መጀመሩ በህብረተሰቡ እና በትላልቅ ኩባንያዎች መካከል ያለው ፍላጎት እየጨመረ ነው - በኮንቴይነር ኦርኬስትራ እና በግሉ እና በሕዝብ ደመናዎች ውስጥ በኮንቴይነር ኦርኬስትራ እና በንብረት አስተዳደር ውስጥ መደበኛ መሆን ፣ ችግሩን በ YARN ላይ የስፓርክ ተግባራትን በማይመች መርሐግብር መፍታት እና ያቀርባል ። ብዙ የንግድ እና ክፍት ስርጭቶች በሁሉም መጠኖች እና መስመሮች ላሉ ኩባንያዎች ያለማቋረጥ በማደግ ላይ ያለ መድረክ። በተጨማሪም ፣ በታዋቂነት ወቅት ፣ አብዛኛዎቹ የራሳቸው ሁለት ጭነቶችን ለማግኘት ችለዋል እና በአጠቃቀሙ ላይ ያላቸውን እውቀት ጨምረዋል ፣ ይህም እንቅስቃሴውን ቀላል ያደርገዋል።

ከስሪት 2.3.0 ጀምሮ Apache Spark በ Kubernetes ክላስተር ውስጥ ሥራዎችን ለማስኬድ ኦፊሴላዊ ድጋፍ አግኝቷል እናም ዛሬ ስለዚህ አቀራረብ ወቅታዊ ብስለት ፣ ስለ አጠቃቀሙ የተለያዩ አማራጮች እና በመተግበሩ ወቅት ሊያጋጥሙ ስለሚችሉ ችግሮች እንነጋገራለን ።

በመጀመሪያ ደረጃ በ Apache Spark ላይ ተመስርተው ተግባሮችን እና አፕሊኬሽኖችን የማዘጋጀት ሂደቱን እንይ እና በ Kubernetes ክላስተር ላይ አንድን ተግባር ለማስኬድ የሚያስፈልግዎትን የተለመዱ ጉዳዮችን እናሳይ። ይህን ልጥፍ በማዘጋጀት ላይ፣ OpenShift እንደ ማከፋፈያ ጥቅም ላይ ይውላል እና ከትእዛዝ መስመር መገልገያው (oc) ጋር ተዛማጅነት ያላቸውን ትዕዛዞች ይሰጣል። ለሌሎች የኩበርኔትስ ስርጭቶች፣ ከመደበኛው Kubernetes የትእዛዝ መስመር መገልገያ (kubectl) ወይም አናሎግዎቻቸው (ለምሳሌ፣ ለ oc adm ፖሊሲ) ተጓዳኝ ትዕዛዞችን መጠቀም ይቻላል።

የመጀመሪያ አጠቃቀም መያዣ - ብልጭታ-ማስረከብ

በተግባሮች እና አፕሊኬሽኖች ልማት ወቅት ገንቢው የውሂብ ለውጥን ለማረም ተግባራትን ማካሄድ አለበት። በንድፈ ሀሳቡ፣ ስቱቦስ ለእነዚህ አላማዎች ጥቅም ላይ ሊውል ይችላል፣ ነገር ግን በእውነተኛ (ምንም እንኳን ፈተና ቢሆንም) የፍጻሜ ስርዓቶች ሁኔታዎች ተሳትፎ ያለው እድገት በዚህ የስራ ክፍል ውስጥ ፈጣን እና የተሻለ ሆኖ ተገኝቷል። የፍጻሜ ስርዓቶችን እውነተኛ ሁኔታዎችን ስናስተካክል ሁለት ሁኔታዎች ሊኖሩ ይችላሉ።

  • ገንቢው በብቸኝነት ሁነታ ውስጥ በአካባቢው የስፓርክ ተግባርን ያካሂዳል;

    Apache Spark በ Kubernetes ላይ በማሄድ ላይ

  • አንድ ገንቢ በሙከራ ዑደት ውስጥ በኩበርኔትስ ክላስተር ላይ የስፓርክ ተግባርን ያካሂዳል።

    Apache Spark በ Kubernetes ላይ በማሄድ ላይ

የመጀመሪያው አማራጭ የመኖር መብት አለው ፣ ግን ብዙ ጉዳቶችን ያስከትላል።

  • እያንዳንዱ ገንቢ ከሥራ ቦታ ወደ እሱ የሚያስፈልጋቸው የመጨረሻ ስርዓቶች ሁኔታዎች ሁሉ መድረስ አለበት ።
  • እየተገነባ ያለውን ተግባር ለማስኬድ በሚሠራው ማሽን ላይ በቂ መጠን ያለው ሀብት ያስፈልጋል.

ሁለተኛው አማራጭ እነዚህ ጉዳቶች የሉትም ፣ ምክንያቱም የኩበርኔትስ ክላስተር አጠቃቀም አስፈላጊ የሆነውን የግብዓት ገንዳ ለስራ ስራዎች ለመመደብ እና አስፈላጊውን የፍጻሜ ስርዓት ሁኔታዎችን እንዲያገኝ ስለሚያስችል የኩበርኔትስ አርአያ በመጠቀም በቀላሉ ማግኘት ይቻላል ። ሁሉም የልማት ቡድን አባላት. እንደ መጀመሪያው የአጠቃቀም ጉዳይ እናድመቅ - በሙከራ ወረዳ ውስጥ ባለው የኩበርኔትስ ክላስተር ላይ የስፓርክ ተግባራትን ከአካባቢው ገንቢ ማሽን ማስጀመር።

ስፓርክን በአገር ውስጥ ለማስኬድ ስለማዘጋጀት ሂደት የበለጠ እንነጋገር። ስፓርክን መጠቀም ለመጀመር እሱን መጫን ያስፈልግዎታል፡-

mkdir /opt/spark
cd /opt/spark
wget http://mirror.linux-ia64.org/apache/spark/spark-2.4.5/spark-2.4.5.tgz
tar zxvf spark-2.4.5.tgz
rm -f spark-2.4.5.tgz

ከ Kubernetes ጋር ለመስራት አስፈላጊዎቹን ፓኬጆች እንሰበስባለን-

cd spark-2.4.5/
./build/mvn -Pkubernetes -DskipTests clean package

ሙሉ ግንባታ ብዙ ጊዜ ይወስዳል እና የዶከር ምስሎችን ለመፍጠር እና በ Kubernetes ክላስተር ላይ ለማስኬድ ከ"ስብሰባ/" ማውጫ ውስጥ የጃር ፋይሎችን ብቻ ነው የሚያስፈልግህ፣ ስለዚህ ይህን ንዑስ ፕሮጀክት ብቻ መገንባት ትችላለህ፡-

./build/mvn -f ./assembly/pom.xml -Pkubernetes -DskipTests clean package

Spark jobs በ Kubernetes ላይ ለማስኬድ እንደ መሰረታዊ ምስል ለመጠቀም Docker ምስል መፍጠር ያስፈልግዎታል። እዚህ 2 ሊሆኑ የሚችሉ ዘዴዎች አሉ-

  • የመነጨው Docker ምስል የሚተገበረውን የስፓርክ ተግባር ኮድ ያካትታል;
  • የተፈጠረው ምስል ስፓርክን እና አስፈላጊ ጥገኞችን ብቻ ያካትታል፣ የሚፈፀመው ኮድ በርቀት ነው የሚስተናገደው (ለምሳሌ በኤችዲኤፍኤስ)።

በመጀመሪያ፣ የስፓርክ ተግባር የሙከራ ምሳሌ የያዘ Docker ምስል እንገንባ። Docker ምስሎችን ለመፍጠር፣ Spark "docker-image-tool" የሚባል መገልገያ አለው። በእሱ ላይ ያለውን እርዳታ እናጠና፡-

./bin/docker-image-tool.sh --help

በእሱ እርዳታ Docker ምስሎችን መፍጠር እና ወደ የርቀት መዝገቦች መስቀል ይችላሉ, ነገር ግን በነባሪነት በርካታ ጉዳቶች አሉት:

  • ያለምንም ችግር 3 Docker ምስሎችን በአንድ ጊዜ ይፈጥራል - ለ Spark ፣ PySpark እና R;
  • የምስል ስም እንዲገልጹ አይፈቅድልዎትም.

ስለዚህ፣ ከዚህ በታች የተሰጠውን የተሻሻለውን የዚህን መገልገያ ስሪት እንጠቀማለን፡-

vi bin/docker-image-tool-upd.sh

#!/usr/bin/env bash

function error {
  echo "$@" 1>&2
  exit 1
}

if [ -z "${SPARK_HOME}" ]; then
  SPARK_HOME="$(cd "`dirname "$0"`"/..; pwd)"
fi
. "${SPARK_HOME}/bin/load-spark-env.sh"

function image_ref {
  local image="$1"
  local add_repo="${2:-1}"
  if [ $add_repo = 1 ] && [ -n "$REPO" ]; then
    image="$REPO/$image"
  fi
  if [ -n "$TAG" ]; then
    image="$image:$TAG"
  fi
  echo "$image"
}

function build {
  local BUILD_ARGS
  local IMG_PATH

  if [ ! -f "$SPARK_HOME/RELEASE" ]; then
    IMG_PATH=$BASEDOCKERFILE
    BUILD_ARGS=(
      ${BUILD_PARAMS}
      --build-arg
      img_path=$IMG_PATH
      --build-arg
      datagram_jars=datagram/runtimelibs
      --build-arg
      spark_jars=assembly/target/scala-$SPARK_SCALA_VERSION/jars
    )
  else
    IMG_PATH="kubernetes/dockerfiles"
    BUILD_ARGS=(${BUILD_PARAMS})
  fi

  if [ -z "$IMG_PATH" ]; then
    error "Cannot find docker image. This script must be run from a runnable distribution of Apache Spark."
  fi

  if [ -z "$IMAGE_REF" ]; then
    error "Cannot find docker image reference. Please add -i arg."
  fi

  local BINDING_BUILD_ARGS=(
    ${BUILD_PARAMS}
    --build-arg
    base_img=$(image_ref $IMAGE_REF)
  )
  local BASEDOCKERFILE=${BASEDOCKERFILE:-"$IMG_PATH/spark/docker/Dockerfile"}

  docker build $NOCACHEARG "${BUILD_ARGS[@]}" 
    -t $(image_ref $IMAGE_REF) 
    -f "$BASEDOCKERFILE" .
}

function push {
  docker push "$(image_ref $IMAGE_REF)"
}

function usage {
  cat <<EOF
Usage: $0 [options] [command]
Builds or pushes the built-in Spark Docker image.

Commands:
  build       Build image. Requires a repository address to be provided if the image will be
              pushed to a different registry.
  push        Push a pre-built image to a registry. Requires a repository address to be provided.

Options:
  -f file               Dockerfile to build for JVM based Jobs. By default builds the Dockerfile shipped with Spark.
  -p file               Dockerfile to build for PySpark Jobs. Builds Python dependencies and ships with Spark.
  -R file               Dockerfile to build for SparkR Jobs. Builds R dependencies and ships with Spark.
  -r repo               Repository address.
  -i name               Image name to apply to the built image, or to identify the image to be pushed.  
  -t tag                Tag to apply to the built image, or to identify the image to be pushed.
  -m                    Use minikube's Docker daemon.
  -n                    Build docker image with --no-cache
  -b arg      Build arg to build or push the image. For multiple build args, this option needs to
              be used separately for each build arg.

Using minikube when building images will do so directly into minikube's Docker daemon.
There is no need to push the images into minikube in that case, they'll be automatically
available when running applications inside the minikube cluster.

Check the following documentation for more information on using the minikube Docker daemon:

  https://kubernetes.io/docs/getting-started-guides/minikube/#reusing-the-docker-daemon

Examples:
  - Build image in minikube with tag "testing"
    $0 -m -t testing build

  - Build and push image with tag "v2.3.0" to docker.io/myrepo
    $0 -r docker.io/myrepo -t v2.3.0 build
    $0 -r docker.io/myrepo -t v2.3.0 push
EOF
}

if [[ "$@" = *--help ]] || [[ "$@" = *-h ]]; then
  usage
  exit 0
fi

REPO=
TAG=
BASEDOCKERFILE=
NOCACHEARG=
BUILD_PARAMS=
IMAGE_REF=
while getopts f:mr:t:nb:i: option
do
 case "${option}"
 in
 f) BASEDOCKERFILE=${OPTARG};;
 r) REPO=${OPTARG};;
 t) TAG=${OPTARG};;
 n) NOCACHEARG="--no-cache";;
 i) IMAGE_REF=${OPTARG};;
 b) BUILD_PARAMS=${BUILD_PARAMS}" --build-arg "${OPTARG};;
 esac
done

case "${@: -1}" in
  build)
    build
    ;;
  push)
    if [ -z "$REPO" ]; then
      usage
      exit 1
    fi
    push
    ;;
  *)
    usage
    exit 1
    ;;
esac

በእሱ እርዳታ ስፓርክን በመጠቀም ፒን ለማስላት የሙከራ ተግባርን የያዘ መሰረታዊ የስፓርክ ምስል እንሰበስባለን (እዚህ {docker-registry-url} የ Docker ምስል መዝገብ ቤትዎ ዩአርኤል ነው፣ {repo} በመዝገቡ ውስጥ ያለው ማከማቻ ስም ነው፣ ከፕሮጀክቱ ጋር የሚዛመደው በ OpenShift , {image-name} — የምስሉ ስም (ባለሶስት-ደረጃ የምስሎች መለያየት ጥቅም ላይ ከዋለ ለምሳሌ እንደ የተቀናጀው የ Red Hat OpenShift ምስሎች መዝገብ ውስጥ)፣ {tag} — የዚህ መለያ መለያ የምስሉ ስሪት):

./bin/docker-image-tool-upd.sh -f resource-managers/kubernetes/docker/src/main/dockerfiles/spark/Dockerfile -r {docker-registry-url}/{repo} -i {image-name} -t {tag} build

የኮንሶል መገልገያውን በመጠቀም ወደ OKD ክላስተር ይግቡ (እዚህ {OKD-API-URL} የOKD ክላስተር API URL ነው)፡

oc login {OKD-API-URL}

በDocker መዝገብ ቤት ውስጥ የአሁኑን ተጠቃሚ ማስመሰያ ለፈቃድ እናግኝ፡

oc whoami -t

ወደ የ OKD ክላስተር የውስጥ Docker መዝገብ ይግቡ (የቀድሞውን ትዕዛዝ በመጠቀም የተገኘውን ማስመሰያ እንደ የይለፍ ቃል እንጠቀማለን)

docker login {docker-registry-url}

የተሰበሰበውን Docker ምስል ወደ Docker Registry OKD እንስቀል፡

./bin/docker-image-tool-upd.sh -r {docker-registry-url}/{repo} -i {image-name} -t {tag} push

የተሰበሰበው ምስል በ OKD ውስጥ መኖሩን እንፈትሽ። ይህንን ለማድረግ ዩአርኤሉን በአሳሹ ውስጥ ከተዛማጅ የፕሮጀክት ምስሎች ዝርዝር ጋር ይክፈቱ (እዚህ {ፕሮጀክት} በOpenShift ክላስተር ውስጥ ያለው የፕሮጀክቱ ስም ነው፣ {OKD-WEBUI-URL} የOpenShift Web console URL ነው ) - https://{OKD-WEBUI-URL}/console /project/{project}/browse/images/{image-name}።

ተግባራትን ለማስኬድ የአገልግሎት መለያ መፈጠር አለበት ፖዶችን እንደ ስር የማሄድ ልዩ መብቶች (ይህን ነጥብ በኋላ እንነጋገራለን)

oc create sa spark -n {project}
oc adm policy add-scc-to-user anyuid -z spark -n {project}

የተፈጠረውን የአገልግሎት መለያ እና የዶከር ምስል በመግለጽ የስፓርክ ተግባርን ወደ OKD ክላስተር ለማተም የ spark-submit ትዕዛዙን እናሂድ።

 /opt/spark/bin/spark-submit --name spark-test --class org.apache.spark.examples.SparkPi --conf spark.executor.instances=3 --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark --conf spark.kubernetes.namespace={project} --conf spark.submit.deployMode=cluster --conf spark.kubernetes.container.image={docker-registry-url}/{repo}/{image-name}:{tag} --conf spark.master=k8s://https://{OKD-API-URL}  local:///opt/spark/examples/target/scala-2.11/jars/spark-examples_2.11-2.4.5.jar

እዚህ:

- ስም - የኩበርኔትስ ፖድዶች ስም በሚፈጠርበት ጊዜ የሚሳተፈው ተግባር ስም;

-ክፍል - የሚፈፀመው ፋይል ክፍል, ስራው ሲጀምር ይባላል;

-conf - የስፓርክ ውቅረት መለኪያዎች;

spark.executor.instances - ለመጀመር የስፓርክ አስፈፃሚዎች ብዛት;

spark.kubernetes.authenticate.driver.serviceAccountName - የኩበርኔትስ አገልግሎት መለያ ስም ፖድሶችን ሲጀምሩ (ከኩበርኔትስ ኤፒአይ ጋር በሚገናኙበት ጊዜ የደህንነት አውድ እና ችሎታዎችን ለመወሰን);

spark.kubernetes.namespace - የኩበርኔትስ ስም ቦታ ሹፌር እና አስፈፃሚ ፓዶች የሚጀምሩበት;

spark.submit.deployMode - ስፓርክን የማስጀመር ዘዴ (ለመደበኛ ስፓርክ አስገባ "ክላስተር" ጥቅም ላይ ይውላል፣ ለስፓርክ ኦፕሬተር እና በኋላ ላይ የስፓርክ "ደንበኛ" ስሪቶች);

spark.kubernetes.container.image - የዶከር ምስል ፖድዎችን ለማስጀመር የሚያገለግል;

spark.master — Kubernetes API URL (ውጫዊው ተገልጿል ስለዚህ መዳረሻ ከአካባቢው ማሽን ይከሰታል);

local:// በ Docker ምስል ውስጥ ወደ Spark executable የሚወስደው መንገድ ነው።

ወደ ተጓዳኝ የ OKD ፕሮጀክት ሄደን የተፈጠሩትን ፖዶች - https://{OKD-WEBUI-URL}/console/project/{project}/browse/pods እናጠናለን።

የዕድገት ሂደቱን ለማቃለል ሌላ አማራጭ መጠቀም ይቻላል፣ ይህም የተለመደው የስፓርክ ምስል የሚፈጠርበት፣ በሁሉም ተግባራት ለማሄድ ጥቅም ላይ የሚውልበት፣ እና ሊተገበሩ የሚችሉ ፋይሎች ቅጽበታዊ ገጽ እይታዎች ወደ ውጫዊ ማከማቻ (ለምሳሌ ሃዱፕ) የሚታተሙ እና በሚደውሉበት ጊዜ ይገለጻሉ። ብልጭታ-አስረክብ እንደ ማገናኛ. በዚህ አጋጣሚ Docker ምስሎችን እንደገና ሳይገነቡ፣ ምስሎችን ለማተም ለምሳሌ WebHDFSን በመጠቀም የተለያዩ የስፓርክ ተግባራትን ስሪቶች ማሄድ ይችላሉ። ፋይል ለመፍጠር ጥያቄ እንልካለን (እዚህ {አስተናጋጅ} የዌብኤችዲኤፍኤስ አገልግሎት አስተናጋጅ ነው፣ {ፖርት} የዌብኤችዲኤፍኤስ አገልግሎት ወደብ ነው፣ {path-to-file-on-hdfs} ወደ ፋይሉ የሚወስደው መንገድ ነው በኤችዲኤፍኤስ ላይ)

curl -i -X PUT "http://{host}:{port}/webhdfs/v1/{path-to-file-on-hdfs}?op=CREATE

እንደዚህ አይነት ምላሽ ይደርስዎታል (እዚህ {ቦታ} ፋይሉን ለማውረድ ስራ ላይ መዋል ያለበት ዩአርኤል ነው)፡-

HTTP/1.1 307 TEMPORARY_REDIRECT
Location: {location}
Content-Length: 0

የ Spark executable ፋይልን ወደ ኤችዲኤፍኤስ ጫን (እዚህ {ዱካ-ወደ-አካባቢ-ፋይል} አሁን ባለው አስተናጋጅ ላይ ወደ ስፓርክ ፈጻሚ ፋይል የሚወስደው መንገድ ነው)።

curl -i -X PUT -T {path-to-local-file} "{location}"

ከዚህ በኋላ፣ ወደ ኤችዲኤፍኤስ የተሰቀለውን የስፓርክ ፋይል በመጠቀም spark-submit ማድረግ እንችላለን (እዚህ ላይ {class-name} ተግባሩን ለማጠናቀቅ መጀመር ያለበት የክፍል ስም ነው)።

/opt/spark/bin/spark-submit --name spark-test --class {class-name} --conf spark.executor.instances=3 --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark --conf spark.kubernetes.namespace={project} --conf spark.submit.deployMode=cluster --conf spark.kubernetes.container.image={docker-registry-url}/{repo}/{image-name}:{tag} --conf spark.master=k8s://https://{OKD-API-URL}  hdfs://{host}:{port}/{path-to-file-on-hdfs}

ኤችዲኤፍኤስን ለማግኘት እና ስራው መስራቱን ለማረጋገጥ Dockerfile እና የመግቢያ ነጥብ.sh ስክሪፕት መቀየር ሊኖርብዎ እንደሚችል ልብ ሊባል የሚገባው - ጥገኛ ቤተ-መጻሕፍትን ወደ /opt/spark/jars ማውጫ ለመቅዳት በ Dockerfile ላይ መመሪያ ይጨምሩ እና የኤችዲኤፍኤስ ማዋቀሪያ ፋይልን በSPARK_CLASSPATH መግቢያ ነጥብ ውስጥ ያካትቱ። sh.

ሁለተኛ የአጠቃቀም ጉዳይ - Apache Livy

በተጨማሪም አንድ ተግባር ሲዘጋጅ እና ውጤቱን መሞከር ሲያስፈልግ, እንደ CI/CD ሂደት አካል ሆኖ ማስጀመር እና የአፈፃፀሙን ሁኔታ መከታተል ጥያቄው ይነሳል. እርግጥ ነው፣ በአካባቢያዊ ስፓርክ-ማስረከቢያ ጥሪ አማካኝነት ማሄድ ይችላሉ፣ ነገር ግን ይህ የCI/CD መሠረተ ልማትን ያወሳስበዋል ምክንያቱም በCI አገልጋይ ወኪሎች/ሯጮች ላይ ስፓርክን መጫን እና ማዋቀር እና የ Kubernetes ኤፒአይ መዳረሻን ማቀናበር ስለሚፈልግ። ለዚህ አጋጣሚ፣ የታለመው ትግበራ Apache Livyን እንደ REST API ለመጠቀም በKubernetes ክላስተር ውስጥ የሚስተናገዱትን የስፓርክ ተግባራትን መርጧል። በእሱ እገዛ የCURL ጥያቄዎችን በመጠቀም የ Spark ተግባሮችን በ Kubernetes ክላስተር ላይ ማሄድ ይችላሉ፣ ይህም በማንኛውም የሲአይኤ መፍትሄ ላይ በመመስረት በቀላሉ ይተገበራል፣ እና በ Kubernetes ክላስተር ውስጥ ያለው ምደባ ከKubernetes API ጋር በሚገናኝበት ጊዜ የማረጋገጫ ጉዳይን ይፈታል።

Apache Spark በ Kubernetes ላይ በማሄድ ላይ

እንደ ሁለተኛ የአጠቃቀም ጉዳይ እናድምቀው - Spark ተግባሮችን እንደ የCI/ሲዲ ሂደት አካል በ Kubernetes ክላስተር በሙከራ ሉፕ ላይ።

ስለ Apache Livy ትንሽ - እንደ ኤችቲቲፒ አገልጋይ ሆኖ ይሰራል የድር በይነገጽ እና አስፈላጊ የሆኑትን መለኪያዎች በማለፍ በርቀት ስፓርክ አስገባን ለማስጀመር የሚያስችል RESTful API። በተለምዶ እንደ ኤችዲፒ ስርጭት አካል ተልኳል፣ ነገር ግን ወደ OKD ወይም ወደ ሌላ የኩበርኔትስ መጫኛ ማሰማራትም ይቻላል ተገቢውን አንጸባራቂ እና የዶከር ምስሎች ስብስብ፣ እንደዚህኛው - github.com/ttauveron/k8s-big-data-experiments/tree/master/livy-spark-2.3. ለጉዳያችን፣ ከሚከተለው Dockerfile የስፓርክ ስሪት 2.4.5ን ጨምሮ ተመሳሳይ Docker ምስል ተገንብቷል።

FROM java:8-alpine

ENV SPARK_HOME=/opt/spark
ENV LIVY_HOME=/opt/livy
ENV HADOOP_CONF_DIR=/etc/hadoop/conf
ENV SPARK_USER=spark

WORKDIR /opt

RUN apk add --update openssl wget bash && 
    wget -P /opt https://downloads.apache.org/spark/spark-2.4.5/spark-2.4.5-bin-hadoop2.7.tgz && 
    tar xvzf spark-2.4.5-bin-hadoop2.7.tgz && 
    rm spark-2.4.5-bin-hadoop2.7.tgz && 
    ln -s /opt/spark-2.4.5-bin-hadoop2.7 /opt/spark

RUN wget http://mirror.its.dal.ca/apache/incubator/livy/0.7.0-incubating/apache-livy-0.7.0-incubating-bin.zip && 
    unzip apache-livy-0.7.0-incubating-bin.zip && 
    rm apache-livy-0.7.0-incubating-bin.zip && 
    ln -s /opt/apache-livy-0.7.0-incubating-bin /opt/livy && 
    mkdir /var/log/livy && 
    ln -s /var/log/livy /opt/livy/logs && 
    cp /opt/livy/conf/log4j.properties.template /opt/livy/conf/log4j.properties

ADD livy.conf /opt/livy/conf
ADD spark-defaults.conf /opt/spark/conf/spark-defaults.conf
ADD entrypoint.sh /entrypoint.sh

ENV PATH="/opt/livy/bin:${PATH}"

EXPOSE 8998

ENTRYPOINT ["/entrypoint.sh"]
CMD ["livy-server"]

የመነጨው ምስል መገንባት እና ወደ ነባር የዶከር ማከማቻዎ ሊሰቀል ይችላል፣ ለምሳሌ እንደ ውስጣዊ የኦኬዲ ማከማቻ። እሱን ለማሰማራት፣ የሚከተለውን አንጸባራቂ ተጠቀም ({registry-url} - የዶከር ምስል መዝገብ ቤት ዩአርኤል፣ {image-name} - Docker image name፣ {tag} - Docker image tag፣ {livy-url} - የተፈለገውን URL አገልጋዩ ሊቪ ተደራሽ ይሆናል፣ የ"Route" መግለጫው ጥቅም ላይ የሚውለው Red Hat OpenShift እንደ Kubernetes ስርጭት ጥቅም ላይ ከዋለ ነው፣ ይህ ካልሆነ ግን NodePort አይነት የመግቢያ ወይም የአገልግሎት መግለጫ ጥቅም ላይ ይውላል፡

---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    component: livy
  name: livy
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      component: livy
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        component: livy
    spec:
      containers:
        - command:
            - livy-server
          env:
            - name: K8S_API_HOST
              value: localhost
            - name: SPARK_KUBERNETES_IMAGE
              value: 'gnut3ll4/spark:v1.0.14'
          image: '{registry-url}/{image-name}:{tag}'
          imagePullPolicy: Always
          name: livy
          ports:
            - containerPort: 8998
              name: livy-rest
              protocol: TCP
          resources: {}
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          volumeMounts:
            - mountPath: /var/log/livy
              name: livy-log
            - mountPath: /opt/.livy-sessions/
              name: livy-sessions
            - mountPath: /opt/livy/conf/livy.conf
              name: livy-config
              subPath: livy.conf
            - mountPath: /opt/spark/conf/spark-defaults.conf
              name: spark-config
              subPath: spark-defaults.conf
        - command:
            - /usr/local/bin/kubectl
            - proxy
            - '--port'
            - '8443'
          image: 'gnut3ll4/kubectl-sidecar:latest'
          imagePullPolicy: Always
          name: kubectl
          ports:
            - containerPort: 8443
              name: k8s-api
              protocol: TCP
          resources: {}
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      serviceAccount: spark
      serviceAccountName: spark
      terminationGracePeriodSeconds: 30
      volumes:
        - emptyDir: {}
          name: livy-log
        - emptyDir: {}
          name: livy-sessions
        - configMap:
            defaultMode: 420
            items:
              - key: livy.conf
                path: livy.conf
            name: livy-config
          name: livy-config
        - configMap:
            defaultMode: 420
            items:
              - key: spark-defaults.conf
                path: spark-defaults.conf
            name: livy-config
          name: spark-config
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: livy-config
data:
  livy.conf: |-
    livy.spark.deploy-mode=cluster
    livy.file.local-dir-whitelist=/opt/.livy-sessions/
    livy.spark.master=k8s://http://localhost:8443
    livy.server.session.state-retain.sec = 8h
  spark-defaults.conf: 'spark.kubernetes.container.image        "gnut3ll4/spark:v1.0.14"'
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: livy
  name: livy
spec:
  ports:
    - name: livy-rest
      port: 8998
      protocol: TCP
      targetPort: 8998
  selector:
    component: livy
  sessionAffinity: None
  type: ClusterIP
---
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  labels:
    app: livy
  name: livy
spec:
  host: {livy-url}
  port:
    targetPort: livy-rest
  to:
    kind: Service
    name: livy
    weight: 100
  wildcardPolicy: None

እሱን ተግባራዊ ካደረጉ በኋላ እና ፖዱን በተሳካ ሁኔታ ካስጀመሩት በኋላ የሊቪ ግራፊክ በይነገጽ በ http://{livy-url}/ui ላይ ይገኛል። ከLivy ጋር፣ የREST ጥያቄን ለምሳሌ የፖስታ ሰውን በመጠቀም የስፓርክ ተግባራችንን ማተም እንችላለን። የጥያቄዎች ስብስብ ምሳሌ ከዚህ በታች ቀርቧል (ለተጀመረው ተግባር አስፈላጊ ከሆኑ ተለዋዋጮች ጋር የማዋቀር ክርክር በ “args” ድርድር ውስጥ ሊተላለፍ ይችላል)

{
    "info": {
        "_postman_id": "be135198-d2ff-47b6-a33e-0d27b9dba4c8",
        "name": "Spark Livy",
        "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
    },
    "item": [
        {
            "name": "1 Submit job with jar",
            "request": {
                "method": "POST",
                "header": [
                    {
                        "key": "Content-Type",
                        "value": "application/json"
                    }
                ],
                "body": {
                    "mode": "raw",
                    "raw": "{nt"file": "local:///opt/spark/examples/target/scala-2.11/jars/spark-examples_2.11-2.4.5.jar", nt"className": "org.apache.spark.examples.SparkPi",nt"numExecutors":1,nt"name": "spark-test-1",nt"conf": {ntt"spark.jars.ivy": "/tmp/.ivy",ntt"spark.kubernetes.authenticate.driver.serviceAccountName": "spark",ntt"spark.kubernetes.namespace": "{project}",ntt"spark.kubernetes.container.image": "{docker-registry-url}/{repo}/{image-name}:{tag}"nt}n}"
                },
                "url": {
                    "raw": "http://{livy-url}/batches",
                    "protocol": "http",
                    "host": [
                        "{livy-url}"
                    ],
                    "path": [
                        "batches"
                    ]
                }
            },
            "response": []
        },
        {
            "name": "2 Submit job without jar",
            "request": {
                "method": "POST",
                "header": [
                    {
                        "key": "Content-Type",
                        "value": "application/json"
                    }
                ],
                "body": {
                    "mode": "raw",
                    "raw": "{nt"file": "hdfs://{host}:{port}/{path-to-file-on-hdfs}", nt"className": "{class-name}",nt"numExecutors":1,nt"name": "spark-test-2",nt"proxyUser": "0",nt"conf": {ntt"spark.jars.ivy": "/tmp/.ivy",ntt"spark.kubernetes.authenticate.driver.serviceAccountName": "spark",ntt"spark.kubernetes.namespace": "{project}",ntt"spark.kubernetes.container.image": "{docker-registry-url}/{repo}/{image-name}:{tag}"nt},nt"args": [ntt"HADOOP_CONF_DIR=/opt/spark/hadoop-conf",ntt"MASTER=k8s://https://kubernetes.default.svc:8443"nt]n}"
                },
                "url": {
                    "raw": "http://{livy-url}/batches",
                    "protocol": "http",
                    "host": [
                        "{livy-url}"
                    ],
                    "path": [
                        "batches"
                    ]
                }
            },
            "response": []
        }
    ],
    "event": [
        {
            "listen": "prerequest",
            "script": {
                "id": "41bea1d0-278c-40c9-ad42-bf2e6268897d",
                "type": "text/javascript",
                "exec": [
                    ""
                ]
            }
        },
        {
            "listen": "test",
            "script": {
                "id": "3cdd7736-a885-4a2d-9668-bd75798f4560",
                "type": "text/javascript",
                "exec": [
                    ""
                ]
            }
        }
    ],
    "protocolProfileBehavior": {}
}

ከስብስቡ የመጀመሪያውን ጥያቄ እናስፈጽም ፣ ወደ OKD በይነገጽ እንሂድ እና ተግባሩ በተሳካ ሁኔታ መጀመሩን እንፈትሽ - https://{OKD-WEBUI-URL}/console/project/{project}/browse/pods። በተመሳሳይ ጊዜ አንድ ክፍለ-ጊዜ በ Livy በይነገጽ (http://{livy-url}/ui) ውስጥ ይታያል, በዚህ ውስጥ, Livy API ወይም graphical interface በመጠቀም, የተግባሩን ሂደት መከታተል እና ክፍለ ጊዜውን ማጥናት ይችላሉ. መዝገቦች.

አሁን ሊቪ እንዴት እንደሚሰራ እናሳይ። ይህንን ለማድረግ በፖድ ውስጥ ያለውን የሊቪ መያዣ ምዝግብ ማስታወሻዎች ከሊቪ አገልጋይ ጋር እንመርምር - https://{OKD-WEBUI-URL}/console/project/{project}/browse/pods/{livy-pod-name }?tab=ምዝግብ ማስታወሻዎች። ከነሱ እንደምንረዳው የ Livy REST API በኮንቴይነር ውስጥ “ሊቪ” ተብሎ በሚጠራው ጊዜ፣ ከላይ ከተጠቀምንበት ጋር ተመሳሳይ የሆነ ስፓርክ-ማስረከቢያ ይፈጸማል (እዚህ ላይ {livy-pod-name} የተፈጠረው ፖድ ስም ነው። ከሊቪ አገልጋይ ጋር)። ስብስቡ የሊቪ አገልጋይን በመጠቀም ስፓርክ ፈጻሚን በርቀት የሚያስተናግዱ ስራዎችን እንዲያከናውኑ የሚያስችልዎትን ሁለተኛ መጠይቅ ያስተዋውቃል።

ሦስተኛው የአጠቃቀም ጉዳይ - ስፓርክ ኦፕሬተር

አሁን ተግባሩ ተፈትኗል, በመደበኛነት የማሄድ ጥያቄ ይነሳል. በ Kubernetes ክላስተር ውስጥ ስራዎችን በመደበኛነት ለማስኬድ ቤተኛ መንገድ የ CronJob አካል ነው እና እሱን መጠቀም ይችላሉ ፣ ግን በአሁኑ ጊዜ በ Kubernetes ውስጥ ኦፕሬተሮችን ለማስተዳደር ኦፕሬተሮችን መጠቀም በጣም ታዋቂ ነው እና ለስፓርክ በትክክል የበሰለ ኦፕሬተር አለ ፣ እሱም እንዲሁ ነው። በድርጅት ደረጃ መፍትሄዎች (ለምሳሌ Lightbend FastData Platform) ጥቅም ላይ ይውላል። እንዲጠቀሙበት እንመክራለን - የአሁኑ የተረጋጋው የስፓርክ ስሪት (2.4.5) በ Kubernetes ውስጥ Spark ተግባራትን ለማስኬድ የተገደበ የውቅር አማራጮች አሉት ፣ የሚቀጥለው ዋና ስሪት (3.0.0) ለ Kubernetes ሙሉ ድጋፍ ይሰጣል ፣ ግን የሚለቀቅበት ቀን አይታወቅም . ስፓርክ ኦፕሬተር ለዚህ ጉድለት አስፈላጊ የሆኑ የማዋቀር አማራጮችን በማከል (ለምሳሌ ConfigMap with Hadoop access ውቅር ወደ Spark pods መጫን) እና በመደበኛነት የተያዘለትን ተግባር ማካካስ ይችላል።

Apache Spark በ Kubernetes ላይ በማሄድ ላይ
እንደ ሶስተኛ የአጠቃቀም ጉዳይ እናድመቅ - ስፓርክ ስራዎችን በ Kubernetes ክላስተር ላይ በመደበኛነት በማምረት ዑደት ውስጥ ማስኬድ።

ስፓርክ ኦፕሬተር ክፍት ምንጭ እና በGoogle ክላውድ ፕላትፎርም ውስጥ የተገነባ ነው - github.com/GoogleCloudPlatform/spark-on-k8s-operator. መጫኑ በ 3 መንገዶች ሊከናወን ይችላል-

  1. እንደ Lightbend FastData Platform/Cloudflow መጫኛ አካል;
  2. Helmን መጠቀም፡-
    helm repo add incubator http://storage.googleapis.com/kubernetes-charts-incubator
    helm install incubator/sparkoperator --namespace spark-operator
    	

  3. መግለጫዎችን ከኦፊሴላዊው ማከማቻ (https://github.com/GoogleCloudPlatform/spark-on-k8s-operator/tree/master/manifest) መጠቀም። የሚከተለውን ልብ ሊባል የሚገባው ነው - Cloudflow ኤፒአይ ስሪት v1beta1 ያለው ኦፕሬተርን ያካትታል። የዚህ አይነት ተከላ ጥቅም ላይ ከዋለ የስፓርክ አፕሊኬሽን አንጸባራቂ መግለጫዎች በጊት ውስጥ ከሚገባው ኤፒአይ ስሪት ጋር በምሳሌ መለያዎች ላይ የተመሰረቱ መሆን አለባቸው ለምሳሌ "v1beta1-0.9.0-2.4.0"። የኦፕሬተሩ ሥሪት በ “ስሪቶች” መዝገበ-ቃላት ውስጥ በኦፕሬተሩ ውስጥ በተካተተው የ CRD መግለጫ ውስጥ ይገኛል-
    oc get crd sparkapplications.sparkoperator.k8s.io -o yaml
    	

ኦፕሬተሩ በትክክል ከተጫነ ከስፓርክ ኦፕሬተር ጋር ንቁ የሆነ ፖድ በሚዛመደው ፕሮጀክት ውስጥ ይታያል (ለምሳሌ ፣Cloudflow-fdp-sparkoperator in the Cloudflow space for Cloudflow installation) እና “ስፓርክፕሊኬሽንስ” የሚባል ተዛማጅ የኩበርኔትስ የመረጃ ምንጭ ይመጣል። . የሚገኙትን የስፓርክ አፕሊኬሽኖች በሚከተለው ትዕዛዝ ማሰስ ይችላሉ።

oc get sparkapplications -n {project}

ስፓርክ ኦፕሬተርን በመጠቀም ስራዎችን ለመስራት 3 ነገሮችን ማድረግ ያስፈልግዎታል፡-

  • ሁሉንም አስፈላጊ ቤተ-መጻሕፍት፣ እንዲሁም ማዋቀር እና ሊተገበሩ የሚችሉ ፋይሎችን የሚያካትት የዶከር ምስል ይፍጠሩ። በዒላማው ምስል, ይህ በ CI / CD ደረጃ ላይ የተፈጠረ እና በሙከራ ክላስተር ላይ የተሞከረ ምስል ነው;
  • የዶከር ምስል ከኩበርኔትስ ክላስተር ተደራሽ ወዳለው መዝገብ ቤት ማተም;
  • በ"SparkApplication" አይነት እና የሚጀምረውን ተግባር መግለጫ የያዘ አንጸባራቂ ማመንጨት። የምሳሌ መግለጫዎች በይፋዊው ማከማቻ ውስጥ ይገኛሉ (ለምሳሌ፡. github.com/GoogleCloudPlatform/spark-on-k8s-operator/blob/v1beta1-0.9.0-2.4.0/examples/spark-pi.yaml). ሾለ ማኒፌስቶው ልብ ሊባል የሚገባው አስፈላጊ ነጥቦች አሉ-
    1. የ "apiVersion" መዝገበ-ቃላት ከኦፕሬተር ስሪት ጋር የሚዛመደውን የኤፒአይ ስሪት ማመልከት አለበት;
    2. የ "metadata.namespace" መዝገበ ቃላት አፕሊኬሽኑ የሚጀመርበትን የስም ቦታ መጠቆም አለበት፤
    3. የ "spec.image" መዝገበ ቃላት በተደራሽ መዝገብ ውስጥ የተፈጠረውን የዶከር ምስል አድራሻ መያዝ አለበት;
    4. የ"spec.mainClass" መዝገበ ቃላት ሂደቱ ሲጀመር መካሄድ ያለበት የስፓርክ ተግባር ክፍል መያዝ አለበት፤
    5. የ"spec.mainApplicationFile" መዝገበ ቃላት ወደ ተፈጻሚው የጃር ፋይል የሚወስደውን መንገድ መያዝ አለበት.
    6. የ"spec.sparkVersion" መዝገበ ቃላት ጥቅም ላይ የሚውለውን የስፓርክ ስሪት መጠቆም አለበት፤
    7. የ "spec.driver.serviceAccount" መዝገበ ቃላት አፕሊኬሽኑን ለማስኬድ የሚያገለግለውን የአገልግሎቱን መለያ በተዛማጅ የኩበርኔትስ ስም ቦታ መግለጽ አለበት፤
    8. የ "spec.executor" መዝገበ-ቃላት ለመተግበሪያው የተመደቡትን ሀብቶች ቁጥር ማመልከት አለበት;
    9. የ"spec.volumeMounts" መዝገበ ቃላት የአካባቢያዊ የስፓርክ ተግባር ፋይሎች የሚፈጠሩበትን የአካባቢ ማውጫ መግለጽ አለበት።

አንጸባራቂ የማመንጨት ምሳሌ (እዚህ {spark-service-account} በ Kubernetes ክላስተር ውስጥ የስፓርክ ተግባራትን ለማካሄድ የአገልግሎት መለያ ነው)

apiVersion: "sparkoperator.k8s.io/v1beta1"
kind: SparkApplication
metadata:
  name: spark-pi
  namespace: {project}
spec:
  type: Scala
  mode: cluster
  image: "gcr.io/spark-operator/spark:v2.4.0"
  imagePullPolicy: Always
  mainClass: org.apache.spark.examples.SparkPi
  mainApplicationFile: "local:///opt/spark/examples/jars/spark-examples_2.11-2.4.0.jar"
  sparkVersion: "2.4.0"
  restartPolicy:
    type: Never
  volumes:
    - name: "test-volume"
      hostPath:
        path: "/tmp"
        type: Directory
  driver:
    cores: 0.1
    coreLimit: "200m"
    memory: "512m"
    labels:
      version: 2.4.0
    serviceAccount: {spark-service-account}
    volumeMounts:
      - name: "test-volume"
        mountPath: "/tmp"
  executor:
    cores: 1
    instances: 1
    memory: "512m"
    labels:
      version: 2.4.0
    volumeMounts:
      - name: "test-volume"
        mountPath: "/tmp"

ይህ አንጸባራቂ የአገልግሎት መለያን ይገልጻል ለዚህም መግለጫውን ከማተምዎ በፊት ለ Spark መተግበሪያ ከ Kubernetes API (አስፈላጊ ከሆነ) ጋር መስተጋብር ለመፍጠር አስፈላጊውን የመዳረሻ መብቶችን የሚያቀርቡ አስፈላጊ የሚና ማሰሪያዎችን መፍጠር አለብዎት። በእኛ ሁኔታ, አፕሊኬሽኑ ፖድስን ለመፍጠር መብቶችን ይፈልጋል. አስፈላጊውን ሚና ትስስር እንፍጠር፡-

oc adm policy add-role-to-user edit system:serviceaccount:{project}:{spark-service-account} -n {project}

በተጨማሪም ይህ አንጸባራቂ ዝርዝር የ"hadoopConfigMap" መለኪያን ሊያካትት እንደሚችል ልብ ሊባል የሚገባው ሲሆን ይህም መጀመሪያ የሚዛመደውን ፋይል በ Docker ምስል ላይ ሳያስቀምጡ ConfigMapን ከሃዱፕ ውቅረት ጋር እንዲገልጹ ያስችልዎታል። እንዲሁም በመደበኛነት ስራዎችን ለመስራት ተስማሚ ነው - የ "መርሃግብር" መለኪያን በመጠቀም, የተሰጠውን ተግባር ለማካሄድ መርሃ ግብር ሊገለጽ ይችላል.

ከዚያ በኋላ የኛን መግለጫ ወደ spark-pi.yaml ፋይል እናስቀምጠዋለን እና ወደ ኩበርኔትስ ክላስተር እንተገብረው፡

oc apply -f spark-pi.yaml

ይህ “ስፓርክፕሊኬሽን” አይነት ነገር ይፈጥራል፡-

oc get sparkapplications -n {project}
> NAME       AGE
> spark-pi   22h

በዚህ ሁኔታ, አፕሊኬሽኑ ያለው ፖድ ይፈጠራል, ሁኔታው ​​በተፈጠረው "ስፓርክፕፕሊኬሽን" ውስጥ ይታያል. በሚከተለው ትዕዛዝ ሊመለከቱት ይችላሉ:

oc get sparkapplications spark-pi -o yaml -n {project}

ስራው ከተጠናቀቀ በኋላ, POD ወደ "የተጠናቀቀ" ሁኔታ ይንቀሳቀሳል, እሱም በ "ስፓርክፕፕስ" ውስጥም ይዘምናል. የመተግበሪያ ምዝግብ ማስታወሻዎች በአሳሹ ውስጥ ሊታዩ ወይም በሚከተለው ትዕዛዝ ሊታዩ ይችላሉ (እዚህ {sparkapplications-pod-name} የሩጫ ተግባር ስም ነው)

oc logs {sparkapplications-pod-name} -n {project}

የስፓርክ ተግባራትን ልዩ የ sparkctl አገልግሎትን በመጠቀም ማስተዳደር ይቻላል። እሱን ለመጫን ማከማቻውን ከምንጩ ኮድ ጋር ይዝጉ ፣ Go ን ይጫኑ እና ይህንን መገልገያ ይገንቡ፡

git clone https://github.com/GoogleCloudPlatform/spark-on-k8s-operator.git
cd spark-on-k8s-operator/
wget https://dl.google.com/go/go1.13.3.linux-amd64.tar.gz
tar -xzf go1.13.3.linux-amd64.tar.gz
sudo mv go /usr/local
mkdir $HOME/Projects
export GOROOT=/usr/local/go
export GOPATH=$HOME/Projects
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
go -version
cd sparkctl
go build -o sparkctl
sudo mv sparkctl /usr/local/bin

የ Spark ተግባራትን ዝርዝር እንመርምር፡-

sparkctl list -n {project}

ለስፓርክ ተግባር መግለጫ እንፍጠር፡-

vi spark-app.yaml

apiVersion: "sparkoperator.k8s.io/v1beta1"
kind: SparkApplication
metadata:
  name: spark-pi
  namespace: {project}
spec:
  type: Scala
  mode: cluster
  image: "gcr.io/spark-operator/spark:v2.4.0"
  imagePullPolicy: Always
  mainClass: org.apache.spark.examples.SparkPi
  mainApplicationFile: "local:///opt/spark/examples/jars/spark-examples_2.11-2.4.0.jar"
  sparkVersion: "2.4.0"
  restartPolicy:
    type: Never
  volumes:
    - name: "test-volume"
      hostPath:
        path: "/tmp"
        type: Directory
  driver:
    cores: 1
    coreLimit: "1000m"
    memory: "512m"
    labels:
      version: 2.4.0
    serviceAccount: spark
    volumeMounts:
      - name: "test-volume"
        mountPath: "/tmp"
  executor:
    cores: 1
    instances: 1
    memory: "512m"
    labels:
      version: 2.4.0
    volumeMounts:
      - name: "test-volume"
        mountPath: "/tmp"

sparkctl ን በመጠቀም የተገለጸውን ተግባር እናካሂድ፡-

sparkctl create spark-app.yaml -n {project}

የ Spark ተግባራትን ዝርዝር እንመርምር፡-

sparkctl list -n {project}

የተጀመረ ስፓርክ ተግባር የክስተቶችን ዝርዝር እንመርምር፡-

sparkctl event spark-pi -n {project} -f

የ Spark ተግባርን ሁኔታ እንመርምር፡-

sparkctl status spark-pi -n {project}

ለማጠቃለል ፣ አሁን ያለውን የተረጋጋ የስፓርክ ስሪት (2.4.5) በኩበርኔትስ የመጠቀም የተገኙ ጉዳቶችን ግምት ውስጥ ማስገባት እፈልጋለሁ።

  1. የመጀመሪያው እና ምናልባትም ዋናው ጉዳቱ የውሂብ አከባቢ አለመኖር ነው. የYARN ድክመቶች ሁሉ ቢኖሩትም እሱን ለመጠቀምም ጥቅማጥቅሞች ነበሩት ለምሳሌ ኮድ ወደ መረጃ የማድረስ መርህ (ከመረጃ ወደ ኮድ)። ለእሱ ምስጋና ይግባውና በስሌቶቹ ውስጥ የተካተቱት መረጃዎች በሚገኙባቸው ኖዶች ላይ የስፓርክ ተግባራት ተፈጽመዋል, እና በአውታረ መረቡ ላይ መረጃን ለማድረስ የሚወስደው ጊዜ በእጅጉ ቀንሷል. Kubernetes ስንጠቀም በአውታረ መረቡ ውስጥ በአንድ ተግባር ውስጥ የተሳተፈ ውሂብን የማንቀሳቀስ አስፈላጊነት አጋጥሞናል። በቂ መጠን ካላቸው፣ የተግባር ማስፈጸሚያ ጊዜ በከፍተኛ ሁኔታ ሊጨምር ይችላል፣ እና ለጊዜያዊ ማከማቻቸው ለስፓርክ ተግባር አጋጣሚዎች የተመደበ በቂ መጠን ያለው የዲስክ ቦታ ይፈልጋል። ይህንን ጉዳቱን በኩበርኔትስ (ለምሳሌ Alluxio) ውስጥ ያለውን የውሂብ አካባቢ የሚያረጋግጥ ልዩ ሶፍትዌሮችን በመጠቀም ሊቀንስ ይችላል ነገር ግን ይህ ማለት በ Kubernetes ክላስተር አንጓዎች ላይ የተሟላ የውሂብ ቅጂ ማከማቸት አስፈላጊ ነው ማለት ነው ።
  2. ሁለተኛው ጠቃሚ ጉዳት ደህንነት ነው. በነባሪነት የስፓርክ ተግባራትን ማሄድን በተመለከተ ከደህንነት ጋር የተገናኙ ባህሪያት ተሰናክለዋል፣ የከርቤሮስ አጠቃቀም በይፋዊ ሰነዶች ውስጥ አልተካተተም (ምንም እንኳን ተጓዳኝ አማራጮች በስሪት 3.0.0 ውስጥ ቢገቡም ተጨማሪ ስራ የሚፈልግ) እና የደህንነት ሰነዶች ለ ስፓርክን በመጠቀም (https://spark.apache.org/docs/2.4.5/security.html) YARN፣ Mesos እና Standalone Cluster ብቻ እንደ ቁልፍ መደብሮች ይታያሉ። በተመሳሳይ ጊዜ ስፓርክ ተግባራት የጀመሩበት ተጠቃሚ በቀጥታ ሊገለጽ አይችልም - የሚሰራበትን የአገልግሎት መለያ ብቻ እንገልፃለን እና ተጠቃሚው በተዋቀሩ የደህንነት ፖሊሲዎች መሰረት ይመረጣል። በዚህ ረገድ ስርወ ተጠቃሚው ጥቅም ላይ ይውላል፣ ምርታማ በሆነ አካባቢ ላይ ደህንነቱ ያልተጠበቀ፣ ወይም በዘፈቀደ ዩአይዲ ያለው ተጠቃሚ፣ ይህም የውሂብ የመዳረሻ መብቶችን ሲያሰራጭ የማይመች ነው (ይህ PodSecurityPolicies በመፍጠር እና እነሱን በማገናኘት ሊፈታ ይችላል) ተዛማጅ የአገልግሎት መለያዎች). በአሁኑ ጊዜ መፍትሄው ሁሉንም አስፈላጊ ፋይሎች በቀጥታ ወደ ዶከር ምስል ማስቀመጥ ወይም በድርጅትዎ ውስጥ የተቀበሉትን ምስጢሮች ለማከማቸት እና ለማውጣት ዘዴን ለመጠቀም የስፓርክ ማስጀመሪያ ስክሪፕትን ማሻሻል ነው።
  3. Kubernetes ን በመጠቀም የስፓርክ ስራዎችን ማስኬድ በይፋ አሁንም በሙከራ ሁነታ ላይ ነው እና ለወደፊቱ ጥቅም ላይ በሚውሉ ቅርሶች ላይ ጉልህ ለውጦች ሊኖሩ ይችላሉ (የማዋቀር ፋይሎች ፣ የዶከር ቤዝ ምስሎች እና የማስጀመሪያ ስክሪፕቶች)። እና በእርግጥ, ቁሳቁሱን ሲያዘጋጁ, ስሪቶች 2.3.0 እና 2.4.5 ተፈትነዋል, ባህሪው በጣም የተለየ ነበር.

ለዝማኔዎች እንጠብቅ - አዲስ የ Spark (3.0.0) እትም በቅርቡ ተለቋል፣ ይህም በስፓርክ በኩበርኔትስ ስራ ላይ ከፍተኛ ለውጦችን አምጥቷል፣ ነገር ግን ለዚህ የንብረት አስተዳዳሪ የድጋፍ የሙከራ ደረጃን ይዞ ቆይቷል። ምናልባት የሚቀጥሉት ዝማኔዎች የ YARN ን መተው እና የSpark ተግባራትን በ Kubernetes ላይ ያለ ፍርሃት ለስርዓትዎ ደህንነት ሳይፈሩ እና የተግባር ክፍሎችን በራስ መተያየት ሳያስፈልግ ሙሉ በሙሉ ለመምከር ያስችላሉ።

ማብቂያ

ምንጭ: hab.com

አስተያየት ያክሉ