Драги читатели, добро попладне. Денес ќе зборуваме малку за Apache Spark и неговите изгледи за развој.
Во современиот свет на големи податоци, Apache Spark е де факто стандард за развој на задачи за сериска обработка на податоци. Дополнително, се користи и за креирање апликации за стриминг кои работат во концептот на микро серија, обработка и испорака на податоци во мали делови (Spark Structured Streaming). И традиционално е дел од целокупниот стек Hadoop, користејќи YARN (или во некои случаи Apache Mesos) како менаџер на ресурси. До 2020 година, неговата употреба во неговата традиционална форма е доведена во прашање за повеќето компании поради недостатокот на пристојни дистрибуции на Hadoop - развојот на HDP и CDH е запрен, CDH не е добро развиен и има висока цена, а преостанатите добавувачи на Hadoop имаат или престана да постои или има мрачна иднина. Затоа, лансирањето на Apache Spark со користење на Kubernetes е од зголемен интерес кај заедницата и големите компании - станувајќи стандард во оркестрацијата на контејнери и управувањето со ресурси во приватни и јавни облаци, го решава проблемот со незгодното закажување ресурси на задачите Spark на YARN и обезбедува платформа која постојано се развива со многу комерцијални и отворени дистрибуции за компании од сите големини и ленти. Покрај тоа, во пресрет на популарноста, повеќето веќе успеаја да стекнат неколку сопствени инсталации и ја зголемија својата експертиза во неговата употреба, што го поедноставува потегот.
Почнувајќи од верзијата 2.3.0, Apache Spark доби официјална поддршка за извршување задачи во кластерот Kubernetes и денес ќе зборуваме за моменталната зрелост на овој пристап, различните опции за негова употреба и замките што ќе се сретнат при имплементацијата.
Пред сè, да го погледнеме процесот на развивање задачи и апликации засновани на Apache Spark и да ги истакнеме типичните случаи во кои треба да извршите задача на кластерот Kubernetes. При подготовката на овој пост, OpenShift се користи како дистрибуција и ќе бидат дадени команди релевантни за неговата алатка за командна линија (oc). За други дистрибуции на Kubernetes, може да се користат соодветните наредби од стандардната алатка за командна линија Kubernetes (kubectl) или нивните аналози (на пример, за oc adm политика).
Случај за прва употреба - искра-поднеси
За време на развојот на задачите и апликациите, развивачот треба да изврши задачи за дебагирање на трансформацијата на податоците. Теоретски, никулците може да се користат за овие цели, но развојот со учество на реални (иако тест) примери на крајните системи се покажа како побрз и подобар во оваа класа на задачи. Во случај кога дебагираме на реални примери на крајни системи, можни се две сценарија:
програмерот извршува задача Spark локално во самостоен режим;
програмер извршува задача Spark на кластерот Kubernetes во тест циклус.
Првата опција има право да постои, но повлекува голем број на недостатоци:
Секој развивач мора да има пристап од работното место до сите случаи на крајните системи што му се потребни;
потребно е доволно количество ресурси на работната машина за извршување на задачата што се развива.
Втората опција ги нема овие недостатоци, бидејќи употребата на кластерот Kubernetes ви овозможува да го распределите потребниот базен на ресурси за извршување задачи и да му го обезбедите потребниот пристап до крајните системски примероци, флексибилно обезбедувајќи пристап до него користејќи го моделот на Kubernetes за сите членови на тимот за развој. Ајде да го истакнеме како прв случај на употреба - започнување задачи на Spark од локална машина за развивачи на кластерот Kubernetes во тест циклус.
Ајде да разговараме повеќе за процесот на поставување на Spark да работи локално. За да започнете со користење на Spark, треба да го инсталирате:
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
Целосната изградба бара многу време, а за да креирате Docker слики и да ги извршите на кластерот Kubernetes, навистина ви требаат само jar-датотеки од директориумот „assembly/“, така што можете да го изградите само овој подпроект:
За да ги извршите Spark работните места на Kubernetes, треба да креирате Docker слика за да ја користите како основна слика. Постојат 2 можни пристапи овде:
Генерираната слика на Docker го вклучува извршниот код за задачата Spark;
Создадената слика вклучува само Spark и потребните зависности, извршниот код е хостиран од далечина (на пример, во HDFS).
Прво, ајде да изградиме слика на Docker што содржи тест пример за задача на Spark. За да креирате 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
Со негова помош, составуваме основна слика на Spark која содржи тест задача за пресметување на Pi со помош на Spark (тука {docker-registry-url} е URL-то на вашиот регистар со слики на Docker, {repo} е името на складиштето во регистарот, што се совпаѓа со проектот во OpenShift , {image-name} — име на сликата (ако се користи раздвојување на слики на три нивоа, на пример, како во интегрираниот регистар на слики од Red Hat OpenShift), {tag} — ознака на оваа верзија на сликата):
Ајде да провериме дали склопената слика е достапна во ОКД. За да го направите ова, отворете го URL-то во прелистувачот со листа на слики од соодветниот проект (тука {project} е името на проектот во кластерот OpenShift, {OKD-WEBUI-URL} е URL-адресата на веб-конзолата OpenShift ) - https://{OKD-WEBUI-URL}/console /project/{project}/browse/images/{image-name}.
За извршување на задачите, мора да се креира сервисна сметка со привилегии да се извршуваат подлоги како root (ќе разговараме за оваа точка подоцна):
Ајде да ја извршиме командата spark-submit за да објавиме задача Spark во кластерот OKD, наведувајќи ја креираната сметка на услугата и сликата на Docker:
—име — името на задачата што ќе учествува во формирањето на името на мешунките Кубернет;
—класа — класа на извршната датотека, повикана кога започнува задачата;
—conf — параметри за конфигурација на Spark;
spark.executor.instances — бројот на Spark извршители што треба да се стартуваат;
spark.kubernetes.authenticate.driver.serviceAccountName - името на сметката на услугата Kubernetes што се користи при стартување на pods (за дефинирање на безбедносниот контекст и можности при интеракција со Kubernetes API);
spark.kubernetes.namespace — именски простор на Kubernetes во кој ќе се активираат подлоги за двигатели и извршители;
spark.submit.deployMode — метод за лансирање на Spark (за стандарден spark-submit се користи „кластер“, за Spark Operator и подоцнежните верзии на Spark „клиент“);
spark.kubernetes.container.image - Докер-слика што се користи за лансирање на подлоги;
spark.master — URL-адреса на Kubernetes API (надворешна е одредена така што пристапот се јавува од локалната машина);
local:// е патеката до извршната датотека Spark во сликата на Docker.
Одиме во соодветниот OKD проект и ги проучуваме креираните подлоги - https://{OKD-WEBUI-URL}/console/project/{project}/browse/pods.
За да се поедностави процесот на развој, може да се користи друга опција, во која се креира заедничка основна слика на Spark, која се користи од сите задачи за извршување, а снимките од извршните датотеки се објавуваат на надворешно складирање (на пример, Hadoop) и се одредуваат при повикување искра-поднеси како врска. Во овој случај, можете да извршите различни верзии на задачите на Spark без да ги обновувате сликите на Docker, користејќи, на пример, 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
Ќе добиете ваков одговор (тука {location} е URL-то што треба да се користи за преземање на датотеката):
Вчитајте ја извршната датотека Spark во HDFS (тука {path-to-local-file} е патеката до извршната датотека Spark на тековниот домаќин):
curl -i -X PUT -T {path-to-local-file} "{location}"
После ова, можеме да направиме spark-submit користејќи ја датотеката Spark поставена на HDFS (тука {class-name} е името на класата што треба да се стартува за да се заврши задачата):
Треба да се забележи дека за да пристапите до HDFS и да се осигурате дека задачата работи, можеби ќе треба да ги промените Dockerfile и скриптата entrypoint.sh - додадете директива во Dockerfile за да ги копирате зависните библиотеки во директориумот /opt/spark/jars и вклучете ја конфигурациската датотека HDFS во SPARK_CLASSPATH во влезната точка.
Случај за втора употреба - Apache Livy
Понатаму, кога задачата се развива и резултатот треба да се тестира, се поставува прашањето за нејзино лансирање како дел од процесот CI/CD и следење на статусот на неговото извршување. Се разбира, можете да го извршите користејќи локален повик за испраќање искра, но ова ја комплицира инфраструктурата CI/CD бидејќи бара инсталирање и конфигурирање на Spark на агентите/трчачите на серверот CI и поставување пристап до Kubernetes API. За овој случај, целната имплементација избра да користи Apache Livy како REST API за извршување задачи на Spark хостирани во кластерот Kubernetes. Со негова помош, можете да извршувате задачи на Spark на кластерот Kubernetes користејќи редовни барања за cURL, што лесно се спроведува врз основа на кое било CI решение, а неговото поставување во кластерот Kubernetes го решава проблемот со автентикацијата при интеракција со Kubernetes API.
Ајде да го истакнеме како втор случај на употреба - извршување задачи на Spark како дел од процесот CI/CD на кластерот Kubernetes во тест циклус.
Малку за Apache Livy - тој работи како HTTP сервер кој обезбедува веб-интерфејс и RESTful API што ви овозможува далечински да го стартувате spark-submit со пренесување на потребните параметри. Традиционално, тој е испорачан како дел од дистрибуција на HDP, но исто така може да се распореди на OKD или која било друга инсталација на Kubernetes користејќи го соодветниот манифест и збир на слики на Docker, како што е оваа - github.com/ttauveron/k8s-big-data-experiments/tree/master/livy-spark-2.3. За нашиот случај, беше изградена слична слика на Docker, вклучително и Spark верзија 2.4.5 од следната Dockerfile:
Генерираната слика може да се изгради и прикачи во вашето постоечко складиште на Docker, како што е внатрешното складиште на OKD. За да го распоредите, користете го следниов манифест ({registry-url} - URL на регистарот на слики на Docker, {image-name} - Docker image name, {tag} - Docker image ознака, {livy-url} - саканиот URL каде што серверот ќе биде достапен Livy; манифестот „Route“ се користи ако Red Hat OpenShift се користи како дистрибуција на Kubernetes, инаку се користи соодветниот Ingress или Service манифест од типот NodePort):
Откако ќе го примените и успешно го стартувате подлогот, графичкиот интерфејс Livy е достапен на врската: http://{livy-url}/ui. Со Livy, можеме да ја објавиме нашата Spark задача користејќи барање REST од, на пример, Postman. Пример за колекција со барања е претставен подолу (конфигурациските аргументи со променливи неопходни за функционирање на започнатата задача може да се пренесат во низата „args“):
Ајде да го извршиме првото барање од колекцијата, да одиме во интерфејсот OKD и да провериме дали задачата е успешно стартувана - https://{OKD-WEBUI-URL}/console/project/{project}/browse/pods. Во исто време, ќе се појави сесија во интерфејсот Livy (http://{livy-url}/ui), во рамките на која, користејќи го Livy API или графичкиот интерфејс, можете да го следите напредокот на задачата и да ја проучувате сесијата трупци.
Сега да покажеме како работи Ливи. За да го направите ова, ајде да ги испитаме дневниците на контејнерот Livy внатре во подлогата со серверот Livy - https://{OKD-WEBUI-URL}/console/project/{project}/browse/pods/{livy-pod-name }?tab=дневници. Од нив можеме да видиме дека при повикување на Livy REST API во контејнер наречен „livy“, се извршува spark-submit, сличен на оној што го користевме погоре (тука {livy-pod-name} е името на креираниот pod со серверот Livy). Колекцијата, исто така, воведува второ барање што ви овозможува да извршувате задачи што од далечина хостираат извршна датотека Spark користејќи сервер Livy.
Случај за трета употреба - Spark Operator
Сега, кога задачата е тестирана, се поставува прашањето за нејзино редовно извршување. Природниот начин за редовно извршување на задачите во кластерот Kubernetes е ентитетот CronJob и можете да го користите, но во моментов употребата на оператори за управување со апликации во Kubernetes е многу популарна и за Spark има прилично зрел оператор, кој исто така е се користи во решенија на ниво на претпријатија (на пример, Lightbend FastData Platform). Препорачуваме да го користите - тековната стабилна верзија на Spark (2.4.5) има прилично ограничени опции за конфигурација за извршување задачи на Spark во Kubernetes, додека следната голема верзија (3.0.0) прогласува целосна поддршка за Kubernetes, но датумот на неговото објавување останува непознат . Spark Operator го компензира овој недостаток со додавање важни опции за конфигурација (на пример, монтирање на ConfigMap со конфигурација за пристап Hadoop на Spark pods) и можност за извршување на редовно закажана задача.
Ајде да го истакнеме како трет случај на употреба - редовно извршување на задачите на Spark на кластерот Kubernetes во производствен циклус.
Користење на манифести од официјалното складиште (https://github.com/GoogleCloudPlatform/spark-on-k8s-operator/tree/master/manifest). Вреди да се забележи следново - Cloudflow вклучува оператор со API верзија v1beta1. Ако се користи овој тип на инсталација, описите на манифестот на апликацијата Spark треба да се засноваат на пример ознаки во Git со соодветна верзија на API, на пример, „v1beta1-0.9.0-2.4.0“. Верзијата на операторот може да се најде во описот на CRD вклучена во операторот во речникот „верзии“:
oc get crd sparkapplications.sparkoperator.k8s.io -o yaml
Ако операторот е правилно инсталиран, во соодветниот проект ќе се појави активен pod со операторот Spark (на пример, cloudflow-fdp-sparkoperator во просторот Cloudflow за инсталацијата Cloudflow) и ќе се појави соодветен тип на ресурс Kubernetes наречен „sparkapplications“ . Можете да ги истражувате достапните апликации Spark со следнава команда:
oc get sparkapplications -n {project}
За да извршите задачи користејќи Spark Operator, треба да направите 3 работи:
креирајте Docker слика која ги вклучува сите потребни библиотеки, како и конфигурациските и извршните датотеки. Во целната слика, ова е слика создадена во фазата CI/CD и тестирана на тест кластер;
објави слика на Docker во регистар достапен од кластерот Kubernetes;
речникот „apiVersion“ мора да ја означи верзијата на API што одговара на верзијата на операторот;
речникот „metadata.namespace“ мора да го означи именскиот простор во кој ќе се активира апликацијата;
речникот „spec.image“ мора да ја содржи адресата на креираната слика на Docker во достапен регистар;
речникот „spec.mainClass“ мора да ја содржи класата на задачи Spark што треба да се изврши кога ќе започне процесот;
патеката до извршната датотека jar мора да биде наведена во речникот „spec.mainApplicationFile“;
речникот „spec.sparkVersion“ мора да ја означи верзијата на Spark што се користи;
речникот „spec.driver.serviceAccount“ мора да ја наведе сметката на услугата во соодветниот именски простор на Kubernetes што ќе се користи за извршување на апликацијата;
речникот „spec.executor“ мора да го означи бројот на ресурси доделени на апликацијата;
речникот „spec.volumeMounts“ мора да го наведе локалниот директориум во кој ќе се креираат локалните датотеки со задачи Spark.
Пример за генерирање на манифест (тука {spark-service-account} е сервисна сметка во кластерот Kubernetes за извршување задачи на Spark):
Овој манифест одредува сервисна сметка за која, пред да го објавите манифестот, мора да ги креирате потребните врски за улоги кои ги обезбедуваат потребните права за пристап за апликацијата Spark да комуницира со Kubernetes API (ако е потребно). Во нашиот случај, на апликацијата и се потребни права за креирање Pods. Ајде да ја создадеме потребната обврзувачка улога:
Исто така, вреди да се напомене дека оваа спецификација на манифестот може да вклучува параметар „hadoopConfigMap“, кој ви овозможува да наведете ConfigMap со конфигурацијата Hadoop без претходно да ја поставите соодветната датотека во сликата на Docker. Погоден е и за редовно извршување на задачите - со помош на параметарот „распоред“, може да се одреди распоред за извршување на дадена задача.
После тоа, го зачувуваме нашиот манифест во датотеката spark-pi.yaml и го применуваме во нашиот кластер Kubernetes:
oc apply -f spark-pi.yaml
Ова ќе создаде објект од типот „sparkapplications“:
oc get sparkapplications -n {project}
> NAME AGE
> spark-pi 22h
Во овој случај, ќе се создаде подлога со апликација, чиј статус ќе се прикаже во креираните „sparkapplications“. Можете да го видите со следнава команда:
oc get sparkapplications spark-pi -o yaml -n {project}
По завршувањето на задачата, POD ќе се пресели во статусот „Завршен“, кој исто така ќе се ажурира во „sparkapplications“. Дневниците на апликациите може да се видат во прелистувачот или со помош на следнава команда (тука {sparkapplications-pod-name} е името на подлогата на тековната задача):
oc logs {sparkapplications-pod-name} -n {project}
Задачите со Spark може да се управуваат и со помош на специјализираната алатка 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
Ајде да ја извршиме опишаната задача користејќи sparkctl:
sparkctl create spark-app.yaml -n {project}
Ајде да го испитаме списокот со задачи на Spark:
sparkctl list -n {project}
Ајде да го испитаме списокот на настани на започнатата задача на Spark:
sparkctl event spark-pi -n {project} -f
Ајде да го испитаме статусот на работната задача Spark:
sparkctl status spark-pi -n {project}
Како заклучок, би сакал да ги разгледам откриените недостатоци за користење на тековната стабилна верзија на Spark (2.4.5) во Kubernetes:
Првиот и, можеби, главниот недостаток е недостатокот на локалитет на податоци. И покрај сите недостатоци на YARN, имаше и предности за користење, на пример, принципот на доставување код до податоци (наместо податоци до код). Благодарение на него, задачите на Spark беа извршени на јазлите каде што се наоѓаа податоците вклучени во пресметките, а времето потребно за доставување податоци преку мрежата беше значително намалено. Кога користиме Kubernetes, се соочуваме со потребата да ги преместиме податоците вклучени во задача низ мрежата. Ако се доволно големи, времето за извршување на задачата може значително да се зголеми, а исто така да бара прилично голема количина на простор на дискот доделен на примероците на задачи Spark за нивно привремено складирање. Овој недостаток може да се ублажи со користење на специјализиран софтвер кој обезбедува локација на податоци во Kubernetes (на пример, Alluxio), но тоа всушност значи потреба да се складира целосна копија од податоците на јазлите на кластерот Kubernetes.
Вториот важен недостаток е безбедноста. Стандардно, функциите поврзани со безбедноста во врска со извршувањето на задачите на Spark се оневозможени, употребата на Kerberos не е опфатена во официјалната документација (иако соодветните опции беа воведени во верзијата 3.0.0, која ќе бара дополнителна работа), а безбедносната документација за користејќи Spark (https ://spark.apache.org/docs/2.4.5/security.html) само YARN, Mesos и самостоен кластер се појавуваат како складишта за клучеви. Во исто време, корисникот под кој се стартуваат задачите на Spark не може директно да се одреди - ние ја одредуваме само сметката на услугата под која ќе работи, а корисникот се избира врз основа на конфигурираните безбедносни политики. Во овој поглед, или се користи root корисникот, кој не е безбеден во продуктивна средина, или корисник со случаен UID, што е незгодно кога се дистрибуираат правата за пристап до податоците (ова може да се реши со креирање PodSecurityPolicies и нивно поврзување со соодветните сметки за услуги). Во моментов, решението е или да ги поставите сите потребни датотеки директно во сликата на Docker или да ја измените скриптата за стартување Spark за да го користите механизмот за складирање и преземање тајни усвоени во вашата организација.
Извршувањето на Spark jobs со користење на Kubernetes е официјално сè уште во експериментален режим и може да има значителни промени во користените артефакти (датотеки за конфигурација, слики од базата на Docker и скрипти за лансирање) во иднина. И навистина, при подготовката на материјалот, беа тестирани верзиите 2.3.0 и 2.4.5, однесувањето беше значително различно.
Да почекаме ажурирања - неодамна беше објавена нова верзија на Spark (3.0.0), која донесе значителни промени во работата на Spark на Kubernetes, но го задржа експерименталниот статус на поддршка за овој менаџер на ресурси. Можеби следните ажурирања навистина ќе овозможат целосно да препорачате напуштање на YARN и извршување на задачите на Spark на Kubernetes без страв за безбедноста на вашиот систем и без потреба од независно менување на функционалните компоненти.