Hyvät lukijat, hyvää iltapäivää. Tänään puhumme hieman Apache Sparkista ja sen kehitysnäkymistä.
Modernissa Big Datan maailmassa Apache Spark on de facto standardi erätietojen käsittelytehtävien kehittämiseen. Lisäksi sitä käytetään myös suoratoistosovellusten luomiseen, jotka toimivat mikroeräkonseptissa, prosessoivat ja lähettävät tietoja pieninä erinä (Spark Structured Streaming). Ja perinteisesti se on ollut osa yleistä Hadoop-pinoa, jossa on käytetty YARN:ia (tai joissain tapauksissa Apache Mesosia) resurssienhallintana. Vuoteen 2020 mennessä sen käyttö perinteisessä muodossa on kyseenalainen useimmille yrityksille kunnollisten Hadoop-jakelujen puutteen vuoksi - HDP:n ja CDH:n kehitys on pysähtynyt, CDH ei ole hyvin kehittynyt ja sen hinta on korkea, ja loput Hadoop-toimittajat ovat joko lakannut olemasta tai niillä on hämärä tulevaisuus. Siksi Apache Sparkin lanseeraus Kubernetesia käyttämällä on yhä kiinnostavampaa yhteisön ja suurten yritysten keskuudessa - siitä tulee standardi konttien orkestroinnissa ja resurssienhallinnassa yksityisissä ja julkisissa pilvissä, se ratkaisee ongelman, joka liittyy Spark-tehtävien epämukavaan resurssien ajoitukseen YARN:ssa ja tarjoaa tasaisesti kehittyvä alusta, jossa on monia kaupallisia ja avoimia jakeluja kaikenkokoisille ja -maisille yrityksille. Lisäksi useimmat ovat suosion perässä jo onnistuneet hankkimaan pari omaa asennusta ja lisänneet asiantuntemustaan sen käytössä, mikä helpottaa muuttoa.
Versiosta 2.3.0 alkaen Apache Spark hankki virallisen tuen tehtävien suorittamiseen Kubernetes-klusterissa, ja tänään puhumme tämän lähestymistavan kypsyydestä, sen erilaisista käyttövaihtoehdoista ja käyttöönoton aikana kohdattavista sudenkuomista.
Ensinnäkin tarkastellaan Apache Sparkiin perustuvien tehtävien ja sovellusten kehittämisprosessia ja korostetaan tyypillisiä tapauksia, joissa sinun on suoritettava tehtävä Kubernetes-klusterissa. Tätä viestiä valmisteltaessa käytetään OpenShiftiä jakeluna ja sen komentorivityökaluun (oc) liittyvät komennot annetaan. Muissa Kubernetes-jakeluissa voidaan käyttää vastaavia komentoja tavallisesta Kubernetes-komentorivityökalusta (kubectl) tai niiden analogeista (esimerkiksi oc adm -käytäntöä varten).
Ensimmäinen käyttötapaus - kipinä-submit
Tehtävien ja sovellusten kehittämisen aikana kehittäjän on suoritettava tehtäviä tietojen muuntamisen virheenkorjausta varten. Teoriassa tyngejä voidaan käyttää näihin tarkoituksiin, mutta kehitys todellisten (vaikkakin testi) loppujärjestelmien esiintymien kanssa on osoittautunut nopeammaksi ja paremmaksi tässä tehtäväluokassa. Jos suoritamme virheenkorjauksen loppujärjestelmien todellisissa esiintymissä, kaksi skenaariota on mahdollista:
kehittäjä suorittaa Spark-tehtävän paikallisesti itsenäisessä tilassa;
kehittäjä suorittaa Spark-tehtävän Kubernetes-klusterissa testisilmukassa.
Ensimmäisellä vaihtoehdolla on oikeus olemassaoloon, mutta siihen liittyy useita haittoja:
Jokaiselle kehittäjälle on annettava pääsy työpaikalta kaikkiin hänen tarvitsemiinsa loppujärjestelmiin.
Työkoneelta vaaditaan riittävä määrä resursseja kehitettävän tehtävän suorittamiseen.
Toisella vaihtoehdolla ei ole näitä haittoja, koska Kubernetes-klusterin käytön avulla voit varata tarvittavan resurssivarannon suoritettaviin tehtäviin ja antaa sille tarvittavan pääsyn loppujärjestelmän ilmentymiin, mikä tarjoaa joustavasti pääsyn siihen Kubernetes-roolimallin avulla. kaikki kehitystiimin jäsenet. Korostetaan se ensimmäisenä käyttötapauksena - Spark-tehtävien käynnistäminen paikalliselta kehittäjäkoneelta Kubernetes-klusterissa testipiirissä.
Puhutaanpa lisää prosessista, jolla Spark määritetään toimimaan paikallisesti. Aloita Sparkin käyttö asentamalla se:
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
Keräämme Kuberneteksen kanssa työskentelyyn tarvittavat paketit:
cd spark-2.4.5/
./build/mvn -Pkubernetes -DskipTests clean package
Täysi rakentaminen vie paljon aikaa, ja Docker-kuvien luomiseen ja niiden suorittamiseen Kubernetes-klusterissa tarvitset vain jar-tiedostoja "assembly/"-hakemistosta, joten voit rakentaa vain tämän aliprojektin:
Jotta voit suorittaa Spark-töitä Kubernetesissa, sinun on luotava Docker-kuva, jota käytetään peruskuvana. Tässä on 2 mahdollista lähestymistapaa:
Luotu Docker-kuva sisältää suoritettavan Spark-tehtäväkoodin;
Luotu kuva sisältää vain Sparkin ja tarvittavat riippuvuudet, suoritettavaa koodia isännöidään etänä (esimerkiksi HDFS:ssä).
Rakennataan ensin Docker-kuva, joka sisältää testiesimerkin Spark-tehtävästä. Docker-kuvien luomiseen Sparkilla on apuohjelma nimeltä "docker-image-tool". Tutustutaanpa siihen liittyvään ohjeeseen:
./bin/docker-image-tool.sh --help
Sen avulla voit luoda Docker-kuvia ja ladata ne etärekistereihin, mutta oletuksena sillä on useita haittoja:
luo epäonnistumatta 3 Docker-kuvaa kerralla - Sparkille, PySparkille ja R:lle;
ei salli kuvan nimen määrittämistä.
Siksi käytämme tämän apuohjelman muokattua versiota, joka on annettu alla:
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
Sen avulla kokoamme Spark-peruskuvan, joka sisältää testitehtävän Pi:n laskemiseen Sparkilla (tässä {docker-registry-url} on Docker-kuvarekisterisi URL-osoite, {repo} on rekisterin sisällä olevan arkiston nimi, joka vastaa projektia OpenShiftissä , {image-name} - kuvan nimi (jos käytetään kuvien kolmitasoista erottelua, kuten esimerkiksi Red Hat OpenShift -kuvien integroidussa rekisterissä), {tag} - tämän tunniste versio kuvasta):
Tarkistetaan, että koottu kuva on saatavilla OKD:ssä. Voit tehdä tämän avaamalla selaimessa URL-osoitteen, jossa on luettelo vastaavan projektin kuvista (tässä {projekti} on projektin nimi OpenShift-klusterin sisällä, {OKD-WEBUI-URL} on OpenShift-verkkokonsolin URL-osoite ) - https://{OKD-WEBUI-URL}/console /project/{project}/browse/images/{image-name}.
Tehtävien suorittamiseksi on luotava palvelutili, jolla on oikeudet suorittaa podeja pääkäyttäjänä (käsittelemme tätä kohtaa myöhemmin):
spark.kubernetes.authenticate.driver.serviceAccountName - Kubernetes-palvelutilin nimi, jota käytetään podeja käynnistettäessä (suojauskontekstin ja -ominaisuuksien määrittäminen Kubernetes API:n kanssa vuorovaikutuksessa);
spark.kubernetes.namespace — Kubernetes-nimiavaruus, jossa ohjain- ja suoritinkotelot käynnistetään;
spark.submit.deployMode — tapa käynnistää Spark (tavalliseen spark-submit -ryhmään käytetään "klusteria", Spark Operatorille ja uudemmille Spark "asiakasversioille");
spark.kubernetes.container.kuva Docker-kuva, jota käytetään koteloiden käynnistämiseen;
spark.master - Kubernetes API URL (ulkoinen on määritetty, jotta pääsy tapahtuu paikalliselta koneelta);
local:// on polku Spark-suoritettavaan tiedostoon Docker-kuvan sisällä.
Siirrymme vastaavaan OKD-projektiin ja tutkimme luotuja podeja - https://{OKD-WEBUI-URL}/console/project/{project}/browse/pods.
Kehitysprosessin yksinkertaistamiseksi voidaan käyttää toista vaihtoehtoa, jossa luodaan yhteinen peruskuva Sparkista, jota kaikki tehtävät käyttävät suorittaessaan, ja suoritettavat tiedostot julkaistaan ulkoiseen tallennustilaan (esimerkiksi Hadoop) ja määritetään kutsuttaessa. spark-lähetä linkkinä. Tässä tapauksessa voit suorittaa eri versioita Spark-tehtävistä rakentamatta uudelleen Docker-kuvia, käyttämällä esimerkiksi WebHDFS:ää kuvien julkaisemiseen. Lähetämme tiedoston luomispyynnön (tässä {host} on WebHDFS-palvelun isäntä, {port} on WebHDFS-palvelun portti, {polku-tiedostoon-hdfs} on haluttu polku tiedostoon HDFS:llä):
curl -i -X PUT "http://{host}:{port}/webhdfs/v1/{path-to-file-on-hdfs}?op=CREATE
Saat seuraavanlaisen vastauksen (tässä {location} on URL-osoite, jota käytetään tiedoston lataamiseen):
Lataa Spark-suoritettava tiedosto HDFS:ään (tässä {path-to-local-file} on polku Spark-suoritettavaan tiedostoon nykyisessä isännässä):
curl -i -X PUT -T {path-to-local-file} "{location}"
Tämän jälkeen voimme tehdä spark-submitin käyttämällä HDFS:ään ladattua Spark-tiedostoa (tässä {class-name} on luokan nimi, joka on käynnistettävä tehtävän suorittamiseksi):
On huomattava, että HDFS:n käyttämiseksi ja tehtävän toimivuuden varmistamiseksi sinun on ehkä muutettava Dockerfile-tiedostoa ja enterpoint.sh-skriptiä - lisää Dockerfile-tiedostoon käsky kopioida riippuvaiset kirjastot /opt/spark/jars-hakemistoon ja sisällytä HDFS-määritystiedosto aloituspisteen SPARK_CLASSPATH:iin. sh.
Toinen käyttötapaus - Apache Livy
Lisäksi kun tehtävää kehitetään ja tulos on testattava, herää kysymys sen käynnistämisestä osana CI/CD-prosessia ja sen suorituksen tilan seurantaa. Tietysti voit käyttää sitä paikallisella spark-submit-kutsulla, mutta tämä monimutkaistaa CI-/CD-infrastruktuuria, koska se vaatii Sparkin asentamista ja määrittämistä CI-palvelinagenteille/-agenteille ja Kubernetes API:n käyttöoikeuden määrittämistä. Tässä tapauksessa kohdetoteutus on päättänyt käyttää Apache Livyä REST-sovellusliittymänä Kubernetes-klusterin sisällä olevien Spark-tehtävien suorittamiseen. Sen avulla voit suorittaa Spark-tehtäviä Kubernetes-klusterissa tavallisilla cURL-pyynnöillä, mikä on helppo toteuttaa minkä tahansa CI-ratkaisun perusteella, ja sen sijoittaminen Kubernetes-klusterin sisälle ratkaisee todennusongelman vuorovaikutuksessa Kubernetes API:n kanssa.
Korostetaan se toisena käyttötapauksena - Spark-tehtävien suorittaminen osana CI/CD-prosessia Kubernetes-klusterissa testisilmukassa.
Hieman Apache Livystä - se toimii HTTP-palvelimena, joka tarjoaa web-rajapinnan ja RESTful API:n, jonka avulla voit etäkäynnistää spark-submitin välittämällä tarvittavat parametrit. Perinteisesti se on toimitettu osana HDP-jakelua, mutta se voidaan ottaa käyttöön myös OKD:hen tai mihin tahansa muuhun Kubernetes-asennukseen käyttämällä asianmukaista luetteloa ja Docker-otoksia, kuten tämä - github.com/ttauveron/k8s-big-data-experiments/tree/master/livy-spark-2.3. Meidän tapauksessamme rakennettiin samanlainen Docker-kuva, mukaan lukien Spark-versio 2.4.5 seuraavasta Docker-tiedostosta:
Luotu kuva voidaan rakentaa ja ladata olemassa olevaan Docker-tietovarastoon, kuten sisäiseen OKD-tietovarastoon. Ota se käyttöön käyttämällä seuraavaa luetteloa ({registry-url} - Docker-kuvarekisterin URL-osoite, {image-name} - Docker-kuvan nimi, {tag} - Docker-kuvatunniste, {livy-url} - haluttu URL-osoite, jossa palvelin on käytettävissä Livy; "Reitti"-luetteloa käytetään, jos Red Hat OpenShiftiä käytetään Kubernetes-jakeluna, muussa tapauksessa käytetään vastaavaa NodePort-tyyppistä Ingress- tai Service-luetteloa):
Kun se on otettu käyttöön ja podi on käynnistetty onnistuneesti, Livy-graafinen käyttöliittymä on saatavilla linkistä: http://{livy-url}/ui. Livyllä voimme julkaista Spark-tehtävämme esimerkiksi Postimiehen REST-pyynnöllä. Alla on esimerkki kokoelmasta, jossa on pyyntöjä (konfiguraatioargumentit muuttujineen, jotka ovat välttämättömiä käynnistetyn tehtävän toiminnalle, voidaan välittää "args"-taulukossa):
Suoritetaan ensimmäinen pyyntö kokoelmasta, siirrytään OKD-käyttöliittymään ja tarkistetaan, että tehtävä on käynnistetty onnistuneesti - https://{OKD-WEBUI-URL}/console/project/{project}/browse/pods. Samalla Livy-käyttöliittymään (http://{livy-url}/ui) ilmestyy istunto, jossa Livy API:n tai graafisen käyttöliittymän avulla voit seurata tehtävän etenemistä ja tutkia istuntoa. lokit.
Näytämme nyt kuinka Livy toimii. Tätä varten tutkitaan podin sisällä olevan Livy-säilön lokit Livy-palvelimella - https://{OKD-WEBUI-URL}/console/project/{project}/browse/pods/{livy-pod-name }?tab=logs. Niistä voimme nähdä, että kutsuttaessa Livy REST API:ta "livy"-nimisessä säilössä suoritetaan spark-submit, joka on samanlainen kuin yllä käytimme (tässä {livy-pod-name} on luodun podin nimi Livy-palvelimen kanssa). Kokoelmassa on myös toinen kysely, jonka avulla voit suorittaa tehtäviä, jotka isännöivät etänä Spark-suoritettavaa tiedostoa Livy-palvelimen avulla.
Kolmas käyttötapaus - Spark Operator
Nyt kun tehtävä on testattu, herää kysymys sen suorittamisesta säännöllisesti. Alkuperäinen tapa suorittaa säännöllisesti tehtäviä Kubernetes-klusterissa on CronJob-kokonaisuus ja voit käyttää sitä, mutta tällä hetkellä operaattoreiden käyttö sovellusten hallintaan Kubernetesissa on erittäin suosittua ja Sparkille on olemassa melko kypsä operaattori, joka on myös käytetään yritystason ratkaisuissa (esimerkiksi Lightbend FastData Platform). Suosittelemme sen käyttöä - Sparkin nykyisessä vakaassa versiossa (2.4.5) on melko rajalliset konfigurointimahdollisuudet Spark-tehtävien suorittamiseen Kubernetesissa, kun taas seuraava suuri versio (3.0.0) ilmoittaa täyden tuen Kubernetesille, mutta sen julkaisupäivä ei ole tiedossa. . Spark Operator kompensoi tämän puutteen lisäämällä tärkeitä konfigurointivaihtoehtoja (esimerkiksi asentamalla ConfigMapin Hadoop-käyttökonfiguraatiolla Spark-podeihin) ja mahdollisuuden suorittaa säännöllisesti ajoitettuja tehtäviä.
Korostetaan se kolmantena käyttötapauksena - Spark-tehtävien säännöllinen suorittaminen Kubernetes-klusterissa tuotantosilmukassa.
Käytä virallisen arkiston luetteloita (https://github.com/GoogleCloudPlatform/spark-on-k8s-operator/tree/master/manifest). On syytä huomata seuraava - Cloudflow sisältää operaattorin, jonka API-versio on v1beta1. Jos käytetään tämäntyyppistä asennusta, Spark-sovellusluettelokuvausten tulee perustua Gitin esimerkkitageihin sopivalla API-versiolla, esimerkiksi "v1beta1-0.9.0-2.4.0". Operaattorin versio löytyy "versiot"-sanakirjan operaattoriin sisältyvästä CRD:n kuvauksesta:
oc get crd sparkapplications.sparkoperator.k8s.io -o yaml
Jos operaattori on asennettu oikein, vastaavaan projektiin ilmestyy aktiivinen pod Spark-operaattorilla (esimerkiksi cloudflow-fdp-sparkoperator Cloudflow-asennuksen Cloudflow-tilassa) ja vastaava Kubernetes-resurssityyppi nimeltä "sparkapplications" tulee näkyviin. . Voit tutkia saatavilla olevia Spark-sovelluksia seuraavalla komennolla:
oc get sparkapplications -n {project}
Jotta voit suorittaa tehtäviä Spark Operatorilla, sinun on tehtävä kolme asiaa:
Luo Docker-kuva, joka sisältää kaikki tarvittavat kirjastot sekä kokoonpano- ja suoritettavat tiedostot. Kohdekuvassa tämä on CI/CD-vaiheessa luotu ja testiklusterissa testattu kuva;
julkaista Docker-kuva Kubernetes-klusterista saatavilla olevaan rekisteriin;
Tämä luettelo määrittää palvelutilin, jolle sinun on ennen luettelon julkaisemista luotava tarvittavat roolisidokset, jotka tarjoavat tarvittavat käyttöoikeudet, jotta Spark-sovellus voi olla vuorovaikutuksessa Kubernetes API:n kanssa (tarvittaessa). Meidän tapauksessamme sovellus tarvitsee oikeudet podien luomiseen. Luodaan tarvittava roolisidonta:
On myös syytä huomata, että tämä luettelon määrittely voi sisältää "hadoopConfigMap"-parametrin, jonka avulla voit määrittää ConfigMapin Hadoop-määrityksellä ilman, että sinun tarvitsee ensin sijoittaa vastaava tiedosto Docker-kuvaan. Se sopii myös tehtävien suorittamiseen säännöllisesti - "schedule"-parametrilla voidaan määrittää aikataulu tietyn tehtävän suorittamiselle.
Tämän jälkeen tallennamme manifestimme spark-pi.yaml-tiedostoon ja käytämme sitä Kubernetes-klusteriimme:
oc apply -f spark-pi.yaml
Tämä luo objektin tyyppiä "sparkapplications":
oc get sparkapplications -n {project}
> NAME AGE
> spark-pi 22h
Tässä tapauksessa luodaan pod, jossa on sovellus, jonka tila näytetään luoduissa "kipinäsovelluksissa". Voit tarkastella sitä seuraavalla komennolla:
oc get sparkapplications spark-pi -o yaml -n {project}
Tehtävän suorittamisen jälkeen POD siirtyy "Completed" -tilaan, joka päivittyy myös "sparkapplikaatioissa". Sovelluslokeja voi tarkastella selaimessa tai käyttämällä seuraavaa komentoa (tässä {sparkapplications-pod-name} on käynnissä olevan tehtävän podin nimi):
oc logs {sparkapplications-pod-name} -n {project}
Spark-tehtäviä voidaan hallita myös erikoistuneen sparkctl-apuohjelman avulla. Asenna se kloonaamalla arkisto ja sen lähdekoodi, asentamalla Go ja rakentamalla tämä apuohjelma:
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
Tarkastellaan käynnissä olevien Spark-tehtävien luetteloa:
Tarkastellaan käynnissä olevien Spark-tehtävien luetteloa:
sparkctl list -n {project}
Tarkastellaan käynnistetyn Spark-tehtävän tapahtumien luetteloa:
sparkctl event spark-pi -n {project} -f
Tarkastellaan käynnissä olevan Spark-tehtävän tilaa:
sparkctl status spark-pi -n {project}
Lopuksi haluaisin tarkastella havaittuja haittoja Sparkin nykyisen vakaan version (2.4.5) käytöstä Kubernetesissa:
Ensimmäinen ja ehkä suurin haittapuoli on Data Localityn puute. Kaikista YARNin puutteista huolimatta sen käytössä oli myös etuja, esimerkiksi periaate toimittaa koodia dataan (eikä datasta koodiksi). Sen ansiosta Spark-tehtävät suoritettiin solmuissa, joissa laskelmiin osallistuvat tiedot sijaitsivat, ja tiedon toimittamiseen kulunut aika verkon yli lyheni merkittävästi. Kun käytät Kubernetesia, kohtaamme tarpeen siirtää tehtävään liittyviä tietoja verkon yli. Jos ne ovat riittävän suuria, tehtävien suoritusaika voi pidentää merkittävästi ja vaatia myös melko paljon levytilaa, joka on varattu Spark-tehtäväesiintymille niiden väliaikaista tallennusta varten. Tätä haittaa voidaan lieventää käyttämällä erikoisohjelmistoa, joka varmistaa tietojen sijainnin Kubernetesissa (esimerkiksi Alluxio), mutta tämä tarkoittaa itse asiassa tarvetta tallentaa täydellinen kopio tiedoista Kubernetes-klusterin solmuihin.
Toinen tärkeä haittapuoli on turvallisuus. Oletusarvoisesti Spark-tehtävien suorittamiseen liittyvät tietoturvaominaisuudet ovat poissa käytöstä, Kerberosin käyttöä ei käsitellä virallisessa dokumentaatiossa (vaikka vastaavat vaihtoehdot esiteltiin versiossa 3.0.0, mikä vaatii lisätyötä) ja tietoturvadokumentaatio käyttämällä Sparkia (https://spark.apache.org/docs/2.4.5/security.html) vain YARN, Mesos ja Standalone Cluster näkyvät avainsäilöinä. Samanaikaisesti käyttäjää, jolle Spark-tehtävät käynnistetään, ei voida määrittää suoraan - määritämme vain palvelutilin, jolla se toimii, ja käyttäjä valitaan määritettyjen suojauskäytäntöjen perusteella. Tässä yhteydessä käytetään joko pääkäyttäjää, joka ei ole turvallista tuottavassa ympäristössä, tai käyttäjää, jolla on satunnainen UID, mikä on hankalaa tietojen käyttöoikeuksien jakamisessa (tämä voidaan ratkaista luomalla PodSecurityPolicies ja linkittämällä ne vastaavat palvelutilit). Tällä hetkellä ratkaisuna on joko sijoittaa kaikki tarvittavat tiedostot suoraan Docker-kuvaan tai muokata Spark-käynnistyskomentosarjaa käyttämään organisaatiossasi käyttöön otettua salaisuuksien tallennus- ja hakumekanismia.
Spark-töiden suorittaminen Kubernetesilla on virallisesti vielä kokeellisessa tilassa, ja käytettäviin artefakteihin (määritystiedostoihin, Dockerin peruskuviin ja käynnistysskripteihin) saattaa tulla merkittäviä muutoksia tulevaisuudessa. Ja todellakin, kun materiaalia valmisteltiin, versiot 2.3.0 ja 2.4.5 testattiin, käyttäytyminen oli merkittävästi erilaista.
Odotetaan päivityksiä - äskettäin julkaistiin uusi Spark-versio (3.0.0), joka toi merkittäviä muutoksia Sparkin työhön Kubernetesissa, mutta säilytti tämän resurssienhallinnan tuen kokeellisen tilan. Ehkä seuraavat päivitykset todella mahdollistavat täysin YARNin luopumisen ja Spark-tehtävien suorittamisen Kubernetesissa ilman pelkoa järjestelmäsi turvallisuudesta ja ilman tarvetta muokata toiminnallisia komponentteja itsenäisesti.