په کوبرنیټس کې د اپاچي سپارک چلول

ګرانو لوستونکو، مازدیګر مو پخیر. نن ورځ موږ به د اپاچي سپارک او د هغې د پراختیا امکاناتو په اړه لږ څه وغږیږو.

په کوبرنیټس کې د اپاچي سپارک چلول

د لوی ډیټا په عصري نړۍ کې، اپاچی سپارک د بیچ ډیټا پروسس کولو دندو د پراختیا لپاره د حقیقت معیار دی. سربیره پردې ، دا د سټیمینګ غوښتنلیکونو رامینځته کولو لپاره هم کارول کیږي چې د مایکرو بیچ مفهوم کې کار کوي ، په کوچنیو برخو کې ډیټا پروسس او لیږدوي (سپارک ساختماني سټریمینګ). او په دودیز ډول دا د عمومي هډوپ سټیک برخه وه ، د سرچینې مدیر په توګه د YARN (یا په ځینو مواردو کې اپاچی میسوس) کارول. تر 2020 پورې ، په دودیز ډول د دې کارول د ډیری شرکتونو لپاره د ښه هاډوپ توزیع نشتوالي له امله تر پوښتنې لاندې دي - د HDP او CDH پراختیا بنده شوې ، CDH ښه وده نه ده کړې او لوړ لګښت لري ، او د هاډوپ پاتې عرضه کونکي لري. یا به شتون ختم کړي یا تیاره راتلونکې ولري. له همدې امله، د کوبرنیټس په کارولو سره د اپاچي سپارک پیل کول د ټولنې او لویو شرکتونو ترمنځ د علاقې زیاتیدونکي دي - په خصوصي او عامه بادلونو کې د کانټینر آرکیسټریشن او سرچینو مدیریت کې معیاري کیدو سره ، دا په YARN کې د سپارک دندو د غیر منظم سرچینې مهالویش سره ستونزه حل کوي او چمتو کوي. د ټولو اندازو او پټو شرکتونو لپاره د ډیری سوداګریزو او خلاص توزیعونو سره په دوامداره توګه وده کونکی پلیټ فارم. برسېره پردې، د شهرت په پایله کې، ډیری یې لا دمخه د خپل ځان یو څو تاسیسات ترلاسه کړي او د هغې په کارولو کې یې خپل مهارت زیات کړی، کوم چې حرکت ساده کوي.

د 2.3.0 نسخه سره پیل کول، اپاچی سپارک د Kubernetes په کلستر کې د دندو د چلولو لپاره رسمي ملاتړ ترلاسه کړ او نن به موږ د دې طریقې د اوسني بشپړتیا په اړه خبرې وکړو، د هغې د کارولو مختلف انتخابونه او د پلي کولو په وخت کې به ورسره مخ شي.

له هرڅه دمخه ، راځئ چې د اپاچي سپارک پراساس د دندو او غوښتنلیکونو رامینځته کولو پروسې ته وګورو او ځانګړي قضیې په ګوته کړو په کوم کې چې تاسو اړتیا لرئ د کبرنیټس کلستر کې دنده پرمخ وړئ. د دې پوسټ په چمتو کولو کې، OpenShift د توزیع په توګه کارول کیږي او د هغې د کمانډ لاین یوټیلیټ (oc) پورې اړوند کمانډونه به ورکړل شي. د نورو Kubernetes توزیع لپاره، د معیاري Kubernetes کمانډ لاین افادیت (kubectl) یا د دوی انلاګونو (د مثال په توګه، د oc adm پالیسۍ لپاره) اړوند کمانډونه کارول کیدی شي.

لومړی د کارولو قضیه - سپارک - سپارل

د دندو او غوښتنلیکونو پراختیا په جریان کې ، پراختیا کونکی اړتیا لري د ډیټا بدلون ډیبګ کولو لپاره دندې پرمخ بوځي. په تیوریکي توګه، سټبونه د دې موخو لپاره کارول کیدی شي، مګر د پای سیسټمونو د اصلي (البته ازموینې) مثالونو کې د ګډون سره پرمختګ د دې ټولګي دندو کې ګړندی او غوره ثابت شوی. په هغه حالت کې کله چې موږ د پای سیسټمونو اصلي مثالونو باندې ډیبګ کوو، دوه سناریوګانې ممکن دي:

  • پراختیا کونکی د سپارک دنده په محلي ډول په سټنډرډ حالت کې پرمخ وړي؛

    په کوبرنیټس کې د اپاچي سپارک چلول

  • یو پراختیا کونکی د ټیسټ لوپ کې د کبرنیټس کلستر کې د سپارک دنده پرمخ وړي.

    په کوبرنیټس کې د اپاچي سپارک چلول

لومړی اختیار د شتون حق لري، مګر یو شمیر زیانونه لري:

  • هر پراختیا کونکي ته باید د کار ځای څخه د پای سیسټم ټولو مثالونو ته لاسرسی چمتو شي چې ورته اړتیا لري؛
  • په کاري ماشین کې کافي اندازه سرچینې ته اړتیا ده ترڅو د کار پرمخ وړل پرمخ بوځي.

دوهم اختیار دا نیمګړتیاوې نلري، ځکه چې د Kubernetes کلستر کارول تاسو ته اجازه درکوي چې د چلولو دندو لپاره اړین سرچینې حوض تخصیص کړي او د پای سیسټم مثالونو ته اړین لاسرسی چمتو کړي، په انعطاف سره د 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

بشپړ جوړول ډیر وخت نیسي ، او د ډاکر عکسونو رامینځته کولو او د کوبرنیټس کلستر کې د چلولو لپاره ، تاسو واقعیا یوازې د "اسمبلۍ/" لارښود څخه جار فایلونو ته اړتیا لرئ ، نو تاسو یوازې دا فرعي پروژه رامینځته کولی شئ:

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

په کوبرنیټس کې د سپارک دندو چلولو لپاره ، تاسو اړتیا لرئ د بیس عکس په توګه کارولو لپاره د ډاکر عکس رامینځته کړئ. دلته دوه ممکنه لارې شتون لري:

  • تولید شوي ډاکر عکس کې د اجرا وړ سپارک کاري کوډ شامل دی؛
  • جوړ شوي عکس کې یوازې سپارک او اړین انحصارونه شامل دي، د اجرا وړ کوډ په لیرې توګه کوربه شوی (د مثال په توګه، په HDFS کې).

لومړی ، راځئ چې د ډاکر عکس جوړ کړو چې د سپارک ټاسک ازموینې مثال لري. د ډاکر عکسونو رامینځته کولو لپاره ، سپارک د "docker-image-tool" په نوم یو افادیت لري. راځئ چې پدې اړه مرسته مطالعه کړو:

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

د دې په مرسته ، تاسو کولی شئ د ډاکر عکسونه رامینځته کړئ او لرې پرتو راجسټریو ته یې اپلوډ کړئ ، مګر په ډیفالټ سره دا یو شمیر زیانونه لري:

  • پرته له ناکامۍ په یوځل کې 3 ډاکر عکسونه رامینځته کوي - د سپارک ، پی اسپارک او آر لپاره؛
  • تاسو ته اجازه نه ورکوي چې د انځور نوم مشخص کړئ.

له همدې امله، موږ به د دې یوټیلیټ بدله شوې نسخه په لاندې ډول وکاروو:

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

د دې په مرسته، موږ د سپارک په کارولو سره د Pi محاسبه کولو لپاره د ازموینې دنده لري یو بنسټیز سپارک عکس راټولوو (دلته {docker-registry-url} ستاسو د Docker عکس ثبتولو URL دی، {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}

راځئ چې د ډاکر راجسټری کې د واک لپاره د اوسني کارونکي نښه ترلاسه کړو:

oc whoami -t

د OKD کلستر داخلي ډاکر راجستر ته ننوتل (موږ د پاسورډ په توګه د پخوانۍ کمانډ په کارولو سره ترلاسه شوي ټوکن کاروو):

docker login {docker-registry-url}

راځئ چې راټول شوي ډاکر عکس د ډاکر راجسټری OKD ته اپلوډ کړو:

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

راځئ وګورو چې راټول شوی عکس په OKD کې شتون لري. د دې کولو لپاره، URL په براوزر کې د اړونده پروژې د عکسونو لیست سره خلاص کړئ (دلته {project} د OpenShift کلستر دننه د پروژې نوم دی، {OKD-WEBUI-URL} د OpenShift ویب کنسول 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 کلستر ته د سپارک ټاسک خپرولو لپاره د سپارک - سپارلو کمانډ پرمخ یوسو، د جوړ شوي خدمت حساب او ډاکر عکس مشخص کړئ:

 /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 - د Kubernetes خدماتو حساب نوم چې د پوډونو په لاره اچولو کې کارول کیږي (د امنیتي شرایطو او وړتیاو تعریف کولو لپاره کله چې د Kubernetes API سره اړیکه ونیسئ)؛

spark.kubernetes.namespace — د Kubernetes نوم ځای په کوم کې چې چلوونکي او اجرا کونکي پوډونه به په لاره واچول شي؛

spark.submit.deployMode — د سپارک د پیلولو طریقه (د معیاري سپارک-سبمیټ "کلستر" لپاره کارول کیږي، د سپارک آپریټر او د سپارک "مراجعینو" وروستیو نسخو لپاره)؛

spark.kubernetes.container.image - د ډاکر عکس چې د پوډونو د پیلولو لپاره کارول کیږي؛

spark.master — Kubernetes API URL (بهرنی مشخص شوی نو لاسرسی د ځایی ماشین څخه پیښیږی)؛

local:// د ډاکر عکس کې دننه د اجرا وړ سپارک ته لاره ده.

موږ اړوند OKD پروژې ته ځو او پیدا شوي پوډونه مطالعه کوو - https://{OKD-WEBUI-URL}/console/project/{project}/browse/pods.

د پراختیا پروسې ساده کولو لپاره ، یو بل اختیار کارول کیدی شي ، په کوم کې چې د سپارک یو عام بیس عکس رامینځته شوی ، د چلولو لپاره د ټولو کارونو لخوا کارول کیږي ، او د اجرا وړ فایلونو سنیپ شاټونه بهرني ذخیره (د مثال په توګه ، هډوپ) ته خپاره شوي او د زنګ وهلو پرمهال مشخص شوي. سپارک - د لینک په توګه وسپارئ. پدې حالت کې ، تاسو کولی شئ د ډاکر عکسونو له جوړولو پرته د سپارک دندو مختلف نسخې پرمخ وړئ ، د مثال په توګه د عکسونو خپرولو لپاره WebHDFS کارول. موږ د فایل جوړولو لپاره غوښتنه لیږو (دلته {host} د WebHDFS خدمت کوربه دی، {port} د WebHDFS خدمت بندر دی، {path-to-file-on-hdfs} فایل ته مطلوب لاره ده په HDFS کې):

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

تاسو به د دې په څیر ځواب ترلاسه کړئ (دلته {ځای} هغه URL دی چې د فایل ډاونلوډ کولو لپاره کارول کیږي):

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

د سپارک اجرا وړ فایل په HDFS کې پورته کړئ (دلته {path-to-local-file} په اوسني کوربه کې د سپارک اجرا وړ فایل ته لاره ده):

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

له دې وروسته، موږ کولی شو د سپارک فایل په کارولو سره چې HDFS ته اپلوډ شوی سپارک-سبمیټ وکړو (دلته {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}

دا باید په پام کې ونیول شي چې HDFS ته د لاسرسي لپاره او د دندې کار کولو ډاډ ترلاسه کولو لپاره ، تاسو اړتیا لرئ د Dockerfile او entrypoint.sh سکریپټ بدل کړئ - Dockerfile ته لارښود اضافه کړئ ترڅو انحصاري کتابتونونه /opt/spark/jars ډایرکټر ته کاپي کړي او د HDFS ترتیب فایل په SPARK_CLASSPATH کې د ننوتلو ځای کې شامل کړئ.

د دوهم استعمال قضیه - اپاچی لیوی

برسېره پردې، کله چې یو کار رامینځته کیږي او پایله یې ازمایښت ته اړتیا لري، د CI/CD پروسې د یوې برخې په توګه د پیل کولو او د هغې د اجرا کولو حالت تعقیب کولو پوښتنه راپورته کیږي. البته، تاسو کولی شئ دا د محلي سپارک - سپارلو کال په کارولو سره پرمخ بوځي، مګر دا د CI/CD زیربنا پیچلې کوي ځکه چې دا د CI سرور اجنټانو/رنرونو کې سپارک نصب او تنظیم کولو او د کوبرنیټس API ته د لاسرسي تنظیم کولو ته اړتیا لري. د دې قضیې لپاره، د هدف پلي کول د Apache Livy د REST API په توګه کارول غوره کړي ترڅو د سپارک دندو چلولو لپاره چې د Kubernetes کلستر کې کوربه شوي وي. د دې په مرسته ، تاسو کولی شئ د منظم CURL غوښتنو په کارولو سره د کوبرنیټس کلستر کې د سپارک دندې پرمخ وړئ ، کوم چې په اسانۍ سره د هر ډول CI حل پراساس پلي کیږي ، او د Kubernetes کلستر دننه د دې ځای په ځای کول د تصدیق کولو مسله حل کوي کله چې د Kubernetes API سره متقابل عمل کوي.

په کوبرنیټس کې د اپاچي سپارک چلول

راځئ چې دا د دویمې کارونې قضیې په توګه روښانه کړو - د ټیسټ لوپ کې د کبرنیټس کلستر کې د CI/CD پروسې برخې په توګه د سپارک دندې پرمخ وړل.

د Apache Livy په اړه لږ څه - دا د HTTP سرور په توګه کار کوي چې د ویب انٹرفیس او یو RESTful API چمتو کوي چې تاسو ته اجازه درکوي د اړتیا وړ پیرامیټونو په تیریدو سره له لرې لرې سپارک - سپارل پیل کړئ. په دودیز ډول دا د HDP توزیع د یوې برخې په توګه لیږدول شوی، مګر د مناسب منشور او د ډاکر عکسونو سیټ په کارولو سره OKD یا کوم بل Kubernetes نصب ته هم ګمارل کیدی شي ، لکه دا - github.com/ttauveron/k8s-big-data-experiments/tree/master/livy-spark-2.3. زموږ د قضیې لپاره ، ورته ډاکر عکس جوړ شوی و ، پشمول د لاندې ډاکر فایل څخه د سپارک نسخه 2.4.5:

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"]

تولید شوی عکس ستاسو موجوده ډاکر ذخیره کې جوړ او اپلوډ کیدی شي ، لکه د داخلي OKD ذخیره. د دې ځای په ځای کولو لپاره، لاندې منشور وکاروئ ({رجسټری-url} - د ډاکر عکس ثبتولو URL، {image-name} - د ډاکر عکس نوم، {tag} - د ډاکر عکس ټاګ، {livy-url} - مطلوب URL چیرته چې سرور به د لاسرسي وړ Livy وي؛ د "روټ" منشور کارول کیږي که چیرې د Red Hat OpenShift د Kubernetes توزیع په توګه وکارول شي ، که نه نو د نوډ پورټ ډول اړوند انګریس یا خدمت منشور کارول کیږي):

---
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

د دې پلي کولو او په بریالیتوب سره د پوډ په لاره اچولو وروسته، د Livy ګرافیکي انٹرفیس په لینک کې شتون لري: http://{livy-url}/ui. د لیوی سره، موږ کولی شو د 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. په ورته وخت کې، یوه ناسته به د لیوی انٹرفیس (http://{livy-url}/ui) کې ښکاره شي، په کوم کې چې د Livy API یا ګرافیکي انٹرفیس په کارولو سره، تاسو کولی شئ د دندې پرمختګ تعقیب کړئ او د ناستې مطالعه وکړئ. لوګو

اوس راځئ وښیو چې Livy څنګه کار کوي. د دې کولو لپاره ، راځئ چې د Livy سرور سره د پوډ دننه د لیوی کانټینر لاګ معاینه کړو - https://{OKD-WEBUI-URL}/console/project/{project}/browse/pods/{livy-pod-name }?tab=logs. له دوی څخه موږ لیدلی شو چې کله چې د "livy" په نوم کانټینر کې Livy REST API ته زنګ ووهئ ، نو یو spark-submit اجرا کیږي ، لکه څنګه چې موږ پورته کاروو (دلته {livy-pod-name} د جوړ شوي پوډ نوم دی. د لیوی سرور سره). ټولګه یوه دوهمه پوښتنه هم معرفي کوي چې تاسو ته اجازه درکوي هغه دندې پرمخ بوځي چې د لیوی سرور په کارولو سره د سپارک اجرا وړ لیرې کوربه توب کوي.

دریم استعمال قضیه - سپارک آپریټر

اوس چې دا دنده ازمویل شوې، په منظم ډول د هغې د چلولو پوښتنه راپورته کیږي. د Kubernetes په کلستر کې په منظمه توګه د دندو چلولو اصلي لاره د کرون جاب اداره ده او تاسو یې کارولی شئ، مګر دا مهال په کوبرنیټس کې د غوښتنلیکونو اداره کولو لپاره د آپریټرونو کارول خورا مشهور دي او د سپارک لپاره یو کافي بالغ آپریټر شتون لري، کوم چې دا هم د سوداګرۍ کچې حلونو کې کارول کیږي (د مثال په توګه د Lightbend FastData پلیټ فارم). موږ د دې کارولو وړاندیز کوو - د سپارک اوسنی مستحکم نسخه (2.4.5) په کوبرنیټس کې د سپارک دندو چلولو لپاره د تنظیم کولو محدود اختیارونه لري ، پداسې حال کې چې راتلونکی لوی نسخه (3.0.0) د کوبرنیټس لپاره بشپړ ملاتړ اعلانوي ، مګر د هغې د خپریدو نیټه نامعلومه ده. . د سپارک آپریټر د دې نیمګړتیا لپاره د مهم ترتیب کولو اختیارونو اضافه کولو سره جبران کوي ​​(د مثال په توګه ، سپارک پوډونو ته د هډوپ لاسرسي ترتیب سره د کنفیګ میپ نصب کول) او په منظم ډول ټاکل شوي دندې پرمخ وړلو وړتیا.

په کوبرنیټس کې د اپاچي سپارک چلول
راځئ چې دا د دریمې کارونې قضیې په توګه روښانه کړو - په منظم ډول د تولید لوپ کې د کبرنیټس کلستر کې د سپارک دندې پرمخ وړئ.

سپارک آپریټر خلاص سرچینه ده او د ګوګل کلاوډ پلیټ فارم کې رامینځته شوی - github.com/GoogleCloudPlatform/spark-on-k8s-operator. د دې نصب کول په 3 لارو ترسره کیدی شي:

  1. د لایټ بینډ فاسټ ډیټا پلیټ فارم / کلاوډ فلو نصبولو برخې په توګه؛
  2. د هیلم کارول:
    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 کې د API نسخه v1beta1 سره یو آپریټر شامل دی. که دا ډول انسټالشن کارول کیږي، د سپارک غوښتنلیک ښکاره توضیحات باید د مناسب API نسخه سره په Git کې د مثال ټاګونو پراساس وي، د بیلګې په توګه، "v1beta1-0.9.0-2.4.0". د آپریټر نسخه د CRD په تفصیل کې موندل کیدی شي چې په "نسخه" لغت کې په آپریټر کې شامل دي:
    oc get crd sparkapplications.sparkoperator.k8s.io -o yaml
    	

که چیرې آپریټر په سمه توګه نصب شوی وي، د سپارک آپریټر سره یو فعال پوډ به په اړونده پروژه کې ښکاره شي (د بیلګې په توګه، د کلاوډ فلو نصبولو لپاره د کلاوډ فلو ځای کې کلاوډ فلو-fdp-sparkoperator) او د "sparkapplications" په نوم د اړونده Kubernetes سرچینې ډول به څرګند شي. . تاسو کولی شئ د لاندې کمانډ سره موجود سپارک غوښتنلیکونه وپلټئ:

oc get sparkapplications -n {project}

د سپارک آپریټر په کارولو سره د کارونو ترسره کولو لپاره تاسو اړتیا لرئ درې شیان ترسره کړئ:

  • د ډاکر عکس رامینځته کړئ چې پکې ټول اړین کتابتونونه ، په بیله بیا ترتیب او د اجرا وړ فایلونه شامل دي. په نښه شوي انځور کې، دا یو انځور دی چې د CI/CD په مرحله کې جوړ شوی او د ازموینې کلستر کې ازمول شوی؛
  • د کوبرنیټس کلستر څخه د لاسرسي وړ راجسټری ته د ډاکر عکس خپور کړئ؛
  • د "سپارک اپلیکیشن" ډول او د پیل شوي دندې توضیحاتو سره یو څرګندونه رامینځته کړئ. د مثالونو څرګندونه په رسمي ذخیره کې شتون لري (د مثال په توګه github.com/GoogleCloudPlatform/spark-on-k8s-operator/blob/v1beta1-0.9.0-2.4.0/examples/spark-pi.yaml). د منشور په اړه د پام وړ مهم ټکي شتون لري:
    1. د "apiVersion" قاموس باید د API نسخه په ګوته کړي چې د آپریټر نسخې سره مطابقت لري؛
    2. د "metadata.namespace" لغت باید د نوم ځای په ګوته کړي چیرې چې غوښتنلیک به پیل شي؛
    3. د "spec.image" قاموس باید د لاسرسي وړ راجسټری کې د جوړ شوي ډاکر عکس پته ولري؛
    4. د "spec.mainClass" قاموس باید د سپارک ټاسک ټولګي ولري چې د پروسې پیل کولو پرمهال باید پرمخ وړل شي.
    5. د "spec.mainApplicationFile" قاموس باید د اجرا وړ جار فایل ته لاره ولري؛
    6. د "spec.sparkVersion" لغت باید د سپارک نسخه په ګوته کړي چې کارول کیږي؛
    7. د "spec.driver.serviceAccount" لغت باید د اړونده Kubernetes نوم ځای کې د خدماتو حساب مشخص کړي چې د غوښتنلیک چلولو لپاره به کارول کیږي؛
    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"

دا منشور د خدماتو حساب مشخص کوي د کوم لپاره چې د مینی فیسټ خپرولو دمخه ، تاسو باید د رول لازمي پابندۍ رامینځته کړئ چې د سپارک غوښتنلیک لپاره د لاسرسي حقونه چمتو کوي ترڅو د Kubernetes API سره اړیکه ونیسي (که اړتیا وي). زموږ په قضیه کې، غوښتنلیک د پوډونو جوړولو لپاره حقونو ته اړتیا لري. راځئ چې اړین رول پابند جوړ کړو:

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

دا هم د یادولو وړ ده چې پدې څرګند توضیحات کې ممکن د "hadoopConfigMap" پیرامیټر شامل وي ، کوم چې تاسو ته اجازه درکوي د هډوپ ترتیب سره د ConfigMap مشخص کړئ پرته لدې چې د ډاکر عکس کې ورته فایل لومړی ځای په ځای کړئ. دا په منظم ډول د دندو چلولو لپاره هم مناسب دی - د "شیډول" پیرامیټر په کارولو سره ، د ورکړل شوي دندې چلولو لپاره مهالویش مشخص کیدی شي.

له هغې وروسته، موږ خپل منشور په spark-pi.yaml فایل کې خوندي کوو او زموږ د کبرنیټس کلستر ته یې پلي کوو:

oc apply -f spark-pi.yaml

دا به د "sparkapplications" ډول یو څیز رامینځته کړي:

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}

د سپارک دندې هم د ځانګړي سپارکټل افادیت په کارولو سره اداره کیدی شي. د دې د نصبولو لپاره، ذخیره د دې سرچینې کوډ سره کلون کړئ، 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

راځئ چې د سپارک چلولو دندو لیست معاینه کړو:

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}

راځئ چې د سپارک چلولو دندو لیست معاینه کړو:

sparkctl list -n {project}

راځئ چې د پیل شوي سپارک دندې د پیښو لیست معاینه کړو:

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

راځئ چې د چلولو سپارک دندې وضعیت معاینه کړو:

sparkctl status spark-pi -n {project}

په پایله کې، زه غواړم په Kubernetes کې د سپارک (2.4.5) د اوسني مستحکم نسخې کارولو کشف شوي زیانونه په پام کې ونیسم:

  1. لومړی او، شاید، اصلي زیان د معلوماتو د ځای نشتوالی دی. د YARN د ټولو نیمګړتیاوو سره سره، د دې کارولو ګټې هم شتون درلود، د بیلګې په توګه، ډیټا ته د کوډ رسولو اصول (د کوډ پر ځای ډیټا). د دې څخه مننه، د سپارک دندې په نوډونو کې اجرا شوي چیرې چې په محاسبه کې دخیل معلومات موقعیت لري، او هغه وخت چې په شبکه کې د معلوماتو رسولو لپاره یې اخیستی د پام وړ کم شوی. کله چې Kubernetes کاروئ، موږ د شبکې په اوږدو کې په یوه دنده کې ښکیل ډیټا لیږدولو اړتیا سره مخ یو. که دوی کافي لوی وي ، د دندې اجرا کولو وخت د پام وړ وده کولی شي ، او د دوی لنډمهاله ذخیره کولو لپاره د سپارک ټاسک مثالونو ته ځانګړي شوي کافي لوی ډیسک ځای ته هم اړتیا لري. دا نیمګړتیا د ځانګړي سافټویر په کارولو سره کم کیدی شي چې په کوبرنیټس کې د ډیټا موقعیت تضمینوي (د مثال په توګه ، الکسیو) ، مګر دا واقعیا پدې معنی ده چې د کوبرنیټس کلستر نوډونو کې د معلوماتو بشپړ کاپي ذخیره کولو اړتیا.
  2. دوهم مهم زیان امنیت دی. په ډیفالټ ډول، د سپارک دندو د چلولو په اړه د امنیت اړوند ځانګړتیاوې غیر فعال دي، د کربروس کارول په رسمي اسنادو کې نه پوښل شوي (که څه هم ورته اختیارونه په 3.0.0 نسخه کې معرفي شوي، کوم چې اضافي کار ته اړتیا لري)، او د امنیت اسناد د سپارک کارول (https://spark.apache.org/docs/2.4.5/security.html) یوازې YARN، Mesos او Standalone Cluster د کلیدي پلورنځیو په توګه ښکاري. په ورته وخت کې، هغه کارن چې د سپارک کارونه یې په لاره اچول شوي په مستقیم ډول نشي مشخص کیدی - موږ یوازې د خدماتو حساب مشخص کوو چې دا به کار وکړي، او کارن د ترتیب شوي امنیتي پالیسیو پراساس غوره کیږي. په دې برخه کې، یا د روټ کاروونکي کارول کیږي، کوم چې په تولیدي چاپیریال کې خوندي نه وي، یا د تصادفي UID سره کاروونکي، کوم چې ډیټا ته د لاسرسي حقونو ویشلو په وخت کې ناشونی وي (دا د PodSecurity Policies په جوړولو او د دوی سره د لینک کولو له لارې حل کیدی شي. د اړونده خدماتو حسابونه). اوس مهال، حل دا دی چې یا ټول اړین فایلونه په مستقیم ډول د ډاکر عکس کې ځای په ځای کړئ، یا د سپارک لانچ سکریپټ بدل کړئ ترڅو ستاسو په سازمان کې منل شوي رازونو ذخیره کولو او ترلاسه کولو میکانیزم کارولو لپاره.
  3. د کبرنیټس په کارولو سره د سپارک دندو چلول په رسمي ډول لاهم په تجربه لرونکي حالت کې دي او ممکن په راتلونکي کې کارول شوي اثار (د ترتیب فایلونه ، د ډاکر بیس عکسونه ، او لانچ سکریپټونه) کې د پام وړ بدلونونه راشي. او په حقیقت کې، کله چې د موادو چمتو کول، نسخې 2.3.0 او 2.4.5 ازمول شوي، چلند د پام وړ توپیر درلود.

راځئ چې تازه معلوماتو ته انتظار وباسو - د سپارک نوې نسخه (3.0.0) پدې وروستیو کې خپره شوې ، کوم چې په کوبرنیټس کې د سپارک کار کې د پام وړ بدلونونه راوستي ، مګر د دې سرچینې مدیر لپاره د ملاتړ تجربوي حالت یې ساتلی. شاید راتلونکي تازه معلومات به واقعیا دا امکان رامینځته کړي چې په بشپړ ډول د YARN پریښودو او په کوبرنیټ کې د سپارک دندو چلولو وړاندیز وکړئ پرته له دې چې ستاسو د سیسټم امنیت لپاره ویره ولرئ او پرته له دې چې په خپلواکه توګه د فعال اجزاو ترمیم ته اړتیا ولرئ.

فین.

سرچینه: www.habr.com

Add a comment