Shtojcat e vëllimit për ruajtjen e Kubernetes: nga Flexvolume në CSI

Shtojcat e vëllimit për ruajtjen e Kubernetes: nga Flexvolume në CSI

Kur Kubernetes ishte ende v1.0.0, kishte shtojca të volumit. Ato duheshin për të lidhur sistemet me Kubernetes për ruajtjen e të dhënave të vazhdueshme (të përhershme) të kontejnerëve. Numri i tyre ishte i vogël, dhe ndër të parët ishin ofrues të tillë të ruajtjes si GCE PD, Ceph, AWS EBS dhe të tjerë.

Shtojcat u dorëzuan së bashku me Kubernetes, kjo është arsyeja pse ata morën emrin e tyre - në pemë. Sidoqoftë, për shumë, grupi ekzistues i shtojcave të tilla doli të ishte i pamjaftueshëm. Zejtarët shtuan shtojca të thjeshta në bërthamën e Kubernetes duke përdorur arna, pas së cilës ata mblodhën Kubernetet e tyre dhe e instaluan në serverët e tyre. Por me kalimin e kohës, zhvilluesit e Kubernetes e kuptuan këtë peshk problemi nuk mund të zgjidhet. Njerëzit kanë nevojë shufër peshkimi. Dhe në lëshimin e Kubernetes v1.2.0 u shfaq ...

Shtojca Flexvolume: shufra minimale e peshkimit

Zhvilluesit e Kubernetes krijuan shtojcën FlexVolume, e cila ishte një kornizë logjike e variablave dhe metodave për të punuar me drejtuesit Flexvolume të zbatuara nga zhvillues të palëve të treta.

Le të ndalemi dhe të hedhim një vështrim më të afërt se çfarë është drejtuesi FlexVolume. Kjo është e sigurt skedari i ekzekutueshëm (skedar binar, skript Python, skript Bash, etj.), i cili, kur ekzekutohet, merr si hyrje argumentet e linjës së komandës dhe kthen një mesazh me fusha të njohura më parë në formatin JSON. Sipas konventës, argumenti i parë i linjës së komandës është gjithmonë një metodë, dhe argumentet e mbetura janë parametrat e saj.

Shtojcat e vëllimit për ruajtjen e Kubernetes: nga Flexvolume në CSI
Diagrami i lidhjes për aksionet CIFS në OpenShift. Shofer Flexvolume - Mu në qendër

Paketa minimale e metodave duket kështu:

flexvolume_driver mount # отвечает за присоединение тома к pod'у
# Формат возвращаемого сообщения:
{
  "status": "Success"/"Failure"/"Not supported",
  "message": "По какой причине был возвращен именно такой статус",
}

flexvolume_driver unmount # отвечает за отсоединение тома от pod'а
# Формат возвращаемого сообщения:
{
  "status": "Success"/"Failure"/"Not supported",
  "message": "По какой причине был возвращен именно такой статус",
}

flexvolume_driver init # отвечает за инициализацию плагина
# Формат возвращаемого сообщения:
{
  "status": "Success"/"Failure"/"Not supported",
  "message": "По какой причине был возвращен именно такой статус",
  // Определяет, использует ли драйвер методы attach/deatach
  "capabilities":{"attach": True/False}
}

Përdorimi i Metodave attach и detach do të përcaktojë skenarin në të cilin kubelet do të veprojë në të ardhmen kur thërret shoferin. Ka edhe metoda të veçanta expandvolume и expandfs, të cilat janë përgjegjëse për ndryshimin dinamik të madhësisë së volumit.

Si shembull i ndryshimeve që shton metoda expandvolume, dhe me aftësinë për të ndryshuar përmasat e vëllimeve në kohë reale, mund të njiheni me të kërkesën tonë për tërheqje në Operator Rook Ceph.

Dhe këtu është një shembull i zbatimit të drejtuesit Flexvolume për të punuar me NFS:

usage() {
    err "Invalid usage. Usage: "
    err "t$0 init"
    err "t$0 mount <mount dir> <json params>"
    err "t$0 unmount <mount dir>"
    exit 1
}

err() {
    echo -ne $* 1>&2
}

log() {
    echo -ne $* >&1
}

ismounted() {
    MOUNT=`findmnt -n ${MNTPATH} 2>/dev/null | cut -d' ' -f1`
    if [ "${MOUNT}" == "${MNTPATH}" ]; then
        echo "1"
    else
        echo "0"
    fi
}

domount() {
    MNTPATH=$1

    NFS_SERVER=$(echo $2 | jq -r '.server')
    SHARE=$(echo $2 | jq -r '.share')

    if [ $(ismounted) -eq 1 ] ; then
        log '{"status": "Success"}'
        exit 0
    fi

    mkdir -p ${MNTPATH} &> /dev/null

    mount -t nfs ${NFS_SERVER}:/${SHARE} ${MNTPATH} &> /dev/null
    if [ $? -ne 0 ]; then
        err "{ "status": "Failure", "message": "Failed to mount ${NFS_SERVER}:${SHARE} at ${MNTPATH}"}"
        exit 1
    fi
    log '{"status": "Success"}'
    exit 0
}

unmount() {
    MNTPATH=$1
    if [ $(ismounted) -eq 0 ] ; then
        log '{"status": "Success"}'
        exit 0
    fi

    umount ${MNTPATH} &> /dev/null
    if [ $? -ne 0 ]; then
        err "{ "status": "Failed", "message": "Failed to unmount volume at ${MNTPATH}"}"
        exit 1
    fi

    log '{"status": "Success"}'
    exit 0
}

op=$1

if [ "$op" = "init" ]; then
    log '{"status": "Success", "capabilities": {"attach": false}}'
    exit 0
fi

if [ $# -lt 2 ]; then
    usage
fi

shift

case "$op" in
    mount)
        domount $*
        ;;
    unmount)
        unmount $*
        ;;
    *)
        log '{"status": "Not supported"}'
        exit 0
esac

exit 1

Pra, pas përgatitjes së skedarit aktual të ekzekutueshëm, ju duhet ngarkoni drejtuesin në grupin Kubernetes. Drejtuesi duhet të vendoset në secilën nyje të grupimit sipas një rruge të paracaktuar. Si parazgjedhje u zgjodh:

/usr/libexec/kubernetes/kubelet-plugins/volume/exec/имя_поставщика_хранилища~имя_драйвера/

... por kur përdorni shpërndarje të ndryshme Kubernetes (OpenShift, Rancher...) rruga mund të jetë e ndryshme.

Problemet e vëllimit të përkuljes: si të hedhim saktë një kallam peshkimi?

Ngarkimi i drejtuesit të Flexvolume në nyjet e grupimit doli të ishte një detyrë jo e parëndësishme. Pasi të keni bërë një herë operacionin manualisht, është e lehtë të hasni në një situatë ku shfaqen nyje të reja në grup: për shkak të shtimit të një nyje të re, shkallëzimit automatik horizontal, ose - çfarë është më keq - zëvendësimit të një nyje për shkak të një mosfunksionimi. Në këtë rast, duhet të bëhet puna me ruajtjen në këto nyje është e pamundur, derisa të shtoni akoma manualisht drejtuesin Flexvolume tek ata.

Zgjidhja e këtij problemi ishte një nga primitivët e Kubernetes - DaemonSet. Kur një nyje e re shfaqet në grup, ai automatikisht përmban një pod nga DaemonSet-i ynë, të cilit i bashkëngjitet një vëllim lokal përgjatë rrugës për të gjetur drejtuesit e Flexvolume. Pas krijimit të suksesshëm, pod kopjon skedarët e nevojshëm që drejtuesi të punojë në disk.

Këtu është një shembull i një DaemonSet të tillë për vendosjen e një shtojce Flexvolume:

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: flex-set
spec:
  template:
    metadata:
      name: flex-deploy
      labels:
        app: flex-deploy
    spec:
      containers:
        - image: <deployment_image>
          name: flex-deploy
          securityContext:
              privileged: true
          volumeMounts:
            - mountPath: /flexmnt
              name: flexvolume-mount
      volumes:
        - name: flexvolume-mount
          hostPath:
            path: <host_driver_directory>

... dhe një shembull i një skripti Bash për paraqitjen e drejtuesit Flexvolume:

#!/bin/sh

set -o errexit
set -o pipefail

VENDOR=k8s.io
DRIVER=nfs

driver_dir=$VENDOR${VENDOR:+"~"}${DRIVER}
if [ ! -d "/flexmnt/$driver_dir" ]; then
  mkdir "/flexmnt/$driver_dir"
fi

cp "/$DRIVER" "/flexmnt/$driver_dir/.$DRIVER"
mv -f "/flexmnt/$driver_dir/.$DRIVER" "/flexmnt/$driver_dir/$DRIVER"

while : ; do
  sleep 3600
done

Është e rëndësishme të mos harroni se operacioni i kopjimit nuk është atomike. Ekziston një shans i madh që kubelet të fillojë të përdorë drejtuesin përpara se të përfundojë procesi i sigurimit të tij, gjë që do të shkaktojë një gabim në sistem. Qasja e duhur është që së pari të kopjoni skedarët e drejtuesit me një emër tjetër dhe më pas të përdorni një operacion riemërtimi atomik.

Shtojcat e vëllimit për ruajtjen e Kubernetes: nga Flexvolume në CSI
Diagrami i punës me Ceph në operatorin Rook: drejtuesi Flexvolume në diagram ndodhet brenda agjentit Rook

Problemi tjetër kur përdorni drejtuesit Flexvolume është ai për shumicën e ruajtjes në një nyje grupi duhet të instalohet softueri i nevojshëm për këtë (për shembull, paketa ceph-common për Ceph). Fillimisht, shtojca Flexvolume nuk ishte krijuar për të zbatuar sisteme të tilla komplekse.

Një zgjidhje origjinale për këtë problem mund të shihet në zbatimin e drejtuesit Flexvolume të operatorit Rook:

Vetë shoferi është projektuar si një klient RPC. Priza IPC për komunikim ndodhet në të njëjtin direktori si vetë drejtuesi. Kujtojmë se për të kopjuar skedarët e drejtuesve do të ishte mirë të përdornim DaemonSet, i cili lidh direktorinë me drejtuesin si vëllim. Pas kopjimit të skedarëve të nevojshëm të shoferit rook, ky pod nuk vdes, por lidhet me prizën IPC përmes vëllimit të bashkangjitur si një server RPC i plotë. Paketa ceph-common është instaluar tashmë brenda kontejnerit të pod. Priza IPC siguron që kubelet do të komunikojë saktësisht me podin që ndodhet në të njëjtën nyje. Çdo gjë e zgjuar është e thjeshtë!..

Mirupafshim, shtojcat tona të dashura... në pemë!

Zhvilluesit e Kubernetes zbuluan se numri i shtojcave për ruajtje brenda bërthamës është njëzet. Dhe një ndryshim në secilën prej tyre, në një mënyrë ose në një tjetër, kalon në ciklin e plotë të lëshimit të Kubernetes.

Rezulton se për të përdorur versionin e ri të shtojcës së ruajtjes, ju duhet të përditësoni të gjithë grupin. Përveç kësaj, mund të habiteni që versioni i ri i Kubernetes do të bëhet papritur i papajtueshëm me kernelin Linux që po përdorni... Kështu që ju fshini lotët dhe, duke kërcitur dhëmbët, koordinoni me menaxhmentin dhe përdoruesit tuaj kohën për të përditësoni kernelin Linux dhe grupin Kubernetes. Me ndërprerje të mundshme në ofrimin e shërbimeve.

Situata është më se komike, nuk mendoni? U bë e qartë për të gjithë komunitetin se qasja nuk po funksiononte. Me një vendim të qëllimshëm, zhvilluesit e Kubernetes njoftojnë se shtojcat e reja për të punuar me ruajtjen nuk do të pranohen më në kernel. Për më tepër, siç e dimë tashmë, një sërë mangësish u identifikuan në zbatimin e shtojcës Flexvolume...

Shtojca më e fundit e shtuar për vëllime në Kubernetes, CSI, u thirr për të mbyllur çështjen me ruajtjen e vazhdueshme të të dhënave një herë e përgjithmonë. Versioni i tij alfa, i referuar më gjerësisht si Shtojcat e vëllimit CSI jashtë pemës, u njoftua në version Kubernetes 1.9.

Ndërfaqja e ruajtjes së kontejnerëve, ose shufra rrotulluese CSI 3000!

Para së gjithash, dua të vërej se CSI nuk është vetëm një shtojcë vëllimi, por një e vërtetë standard në krijimin e komponentëve të personalizuar për të punuar me depot e të dhënave. Sistemet e orkestrimit të kontejnerëve si Kubernetes dhe Mesos supozohej të "mësonin" se si të punonin me komponentë të zbatuar sipas këtij standardi. Dhe tani kam mësuar tashmë Kubernetes.

Cila është struktura e shtojcës CSI në Kubernetes? Shtojca CSI punon me drejtues të veçantë (Drejtues CSI) shkruar nga zhvilluesit e palëve të treta. Një drejtues CSI në Kubernetes duhet të përbëhet minimalisht nga dy komponentë (pods):

  • Kontrollues — menaxhon magazinimet e jashtme të vazhdueshme. Zbatohet si server gRPC, për të cilin përdoret primitivi StatefulSet.
  • Nyjë — është përgjegjës për montimin e ruajtjes së vazhdueshme në nyjet e grupimit. Ai zbatohet gjithashtu si një server gRPC, por përdor primitivin DaemonSet.

Shtojcat e vëllimit për ruajtjen e Kubernetes: nga Flexvolume në CSI
Si funksionon shtojca CSI në Kubernetes

Ju mund të mësoni për disa detaje të tjera të punës së CSI, për shembull, nga artikulli "Kuptimi i C.S.I.' përkthimi i të cilave kemi botuar një vit më parë.

Përparësitë e një zbatimi të tillë

  • Për gjërat themelore si regjistrimi i një drejtuesi për një nyje, zhvilluesit e Kubernetes zbatuan një grup kontejnerësh. Nuk keni më nevojë të gjeneroni vetë një përgjigje JSON me aftësi, siç u bë për shtojcën Flexvolume.
  • Në vend që të "rrëshqisim" skedarët e ekzekutueshëm në nyje, ne tani ngarkojmë pods në grup. Kjo është ajo që ne fillimisht presim nga Kubernetes: të gjitha proceset ndodhin brenda kontejnerëve të vendosur duke përdorur primitivët Kubernetes.
  • Nuk keni më nevojë të zhvilloni një server RPC dhe klient RPC për të implementuar drejtues komplekse. Klienti u zbatua për ne nga zhvilluesit e Kubernetes.
  • Kalimi i argumenteve për të punuar mbi protokollin gRPC është shumë më i përshtatshëm, fleksibël dhe më i besueshëm sesa kalimi i tyre përmes argumenteve të linjës së komandës. Për të kuptuar se si të shtoni mbështetje për metrikat e përdorimit të vëllimit në CSI duke shtuar një metodë të standardizuar gRPC, mund të lexoni: kërkesën tonë për tërheqje për shoferin vsphere-csi.
  • Komunikimi ndodh nëpërmjet prizave IPC, në mënyrë që të mos ngatërrohet nëse kubelet e dërgoi kërkesën në podin e duhur.

A ju kujton diçka kjo listë? Përparësitë e CSI janë zgjidhjen e të njëjtave probleme, të cilat nuk u morën parasysh gjatë zhvillimit të shtojcës Flexvolume.

Gjetjet

CSI si një standard për zbatimin e shtojcave të personalizuara për ndërveprim me magazinat e të dhënave u prit shumë ngrohtë nga komuniteti. Për më tepër, për shkak të avantazheve dhe shkathtësisë së tyre, drejtuesit CSI janë krijuar edhe për sistemet e ruajtjes si Ceph ose AWS EBS, shtojca për të punuar me të cilat u shtuan në versionin e parë të Kubernetes.

Në fillim të 2019, shtojcat në pemë janë shpallur të vjetruara. Ne planifikojmë të vazhdojmë të mbështesim shtesën Flexvolume, por nuk do të zhvillojmë funksione të reja për të.

Ne vetë tashmë kemi përvojë në përdorimin e ceph-csi, vsphere-csi dhe jemi gati të shtojmë në këtë listë! Deri më tani, CSI po përballet me detyrat që i janë caktuar, por ne do të presim dhe të shohim.

Mos harroni se çdo gjë e re është një rimendim i mirë i së vjetrës!

PS

Lexoni edhe në blogun tonë:

Burimi: www.habr.com

Shto një koment