Volume dodaci za Kubernetes pohranu: od Flexvolume do CSI

Volume dodaci za Kubernetes pohranu: od Flexvolume do CSI

Dok je Kubernetes još bio v1.0.0, postojali su dodaci za volumen. Bili su potrebni za povezivanje sustava s Kubernetesom za pohranjivanje postojanih (trajnih) podataka spremnika. Njihov broj je bio mali, a među prvima su bili takvi pružatelji pohrane kao što su GCE PD, Ceph, AWS EBS i drugi.

Dodaci su isporučeni zajedno s Kubernetesom, po čemu su i dobili naziv – in-tree. Međutim, za mnoge se postojeći skup takvih dodataka pokazao nedovoljnim. Obrtnici su pomoću zakrpa dodali jednostavne dodatke jezgri Kubernetesa, nakon čega su sastavili vlastiti Kubernetes i instalirali ga na svoje poslužitelje. Ali s vremenom su Kubernetes programeri to shvatili riba problem se ne može riješiti. Ljudi trebaju štap za ribolov. A u izdanju Kubernetesa v1.2.0 pojavio se...

Dodatak Flexvolume: minimalni štap za pecanje

Programeri Kubernetesa stvorili su dodatak FlexVolume, koji je bio logičan okvir varijabli i metoda za rad s Flexvolume upravljačkim programima koje su implementirali programeri trećih strana.

Zaustavimo se i pobliže pogledajmo što je FlexVolume driver. Ovo je izvjesno izvršna datoteka (binarna datoteka, Python skripta, Bash skripta itd.), koja, kada se izvrši, uzima argumente naredbenog retka kao ulaz i vraća poruku s unaprijed poznatim poljima u JSON formatu. Prema konvenciji, prvi argument naredbenog retka uvijek je metoda, a preostali argumenti su njeni parametri.

Volume dodaci za Kubernetes pohranu: od Flexvolume do CSI
Dijagram povezivanja za CIFS dijeljenja u OpenShiftu. Pokretač Flexvolume - točno u središtu

Minimalni skup metoda izgleda ovako:

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

Korištenje metoda attach и detach će definirati scenarij po kojem će se kubelet ponašati u budućnosti kada poziva upravljački program. Postoje i posebne metode expandvolume и expandfs, koji su odgovorni za dinamičku promjenu veličine glasnoće.

Kao primjer promjena koje metoda dodaje expandvolume, a uz to i mogućnost promjene veličine volumena u stvarnom vremenu, možete se upoznati s njim naš zahtjev za povlačenjem u Rook Ceph Operator.

Evo primjera implementacije Flexvolume upravljačkog programa za rad s NFS-om:

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

Dakle, nakon što pripremite stvarnu izvršnu datoteku, trebate učitati upravljački program u Kubernetes klaster. Upravljački program mora se nalaziti na svakom čvoru klastera prema unaprijed određenoj stazi. Prema zadanim postavkama odabrano je:

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

... ali kada koristite različite Kubernetes distribucije (OpenShift, Rancher...) put može biti drugačiji.

Problemi s Flexvolumeom: kako pravilno zabaciti štap za pecanje?

Prijenos upravljačkog programa Flexvolume u čvorove klastera pokazao se kao netrivijalan zadatak. Nakon što ste jednom izvršili operaciju ručno, lako je naići na situaciju u kojoj se u klasteru pojavljuju novi čvorovi: zbog dodavanja novog čvora, automatskog horizontalnog skaliranja ili - što je još gore - zamjene čvora zbog kvara. U tom slučaju treba raditi s pohranom na tim čvorovima je nemoguće, sve dok im još uvijek ručno ne dodate upravljački program Flexvolume.

Rješenje ovog problema bila je jedna od Kubernetes primitiva - DaemonSet. Kada se novi čvor pojavi u klasteru, on automatski sadrži pod iz našeg DaemonSet-a, na koji je lokalni volumen priključen duž putanje za pronalaženje Flexvolume upravljačkih programa. Nakon uspješnog stvaranja, modul kopira potrebne datoteke za rad upravljačkog programa na disk.

Evo primjera takvog DaemonSeta za postavljanje Flexvolume dodatka:

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>

... i primjer Bash skripte za postavljanje pokretačkog programa 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

Važno je ne zaboraviti da operacija kopiranja nije atomski. Postoji velika vjerojatnost da će kubelet početi koristiti upravljački program prije dovršetka procesa dodjeljivanja, što će uzrokovati pad sustava. Ispravan pristup je prvo kopirati datoteke upravljačkog programa pod drugim imenom, a zatim koristiti operaciju atomskog preimenovanja.

Volume dodaci za Kubernetes pohranu: od Flexvolume do CSI
Dijagram rada s Cephom u Rook operatoru: Flexvolume driver u dijagramu nalazi se unutar Rook agenta

Sljedeći problem kod korištenja upravljačkih programa Flexvolume je onaj za većinu pohrane na čvoru klastera potreban softver za to mora biti instaliran (na primjer, ceph-common paket za Ceph). U početku dodatak Flexvolume nije bio dizajniran za implementaciju tako složenih sustava.

Izvorno rješenje ovog problema može se vidjeti u implementaciji upravljačkog programa Flexvolume operatora Rook:

Sam upravljački program je dizajniran kao RPC klijent. IPC utičnica za komunikaciju nalazi se u istom direktoriju kao i sam upravljački program. Sjećamo se da bi za kopiranje datoteka upravljačkog programa bilo dobro koristiti DaemonSet, koji povezuje direktorij s upravljačkim programom kao volumen. Nakon kopiranja potrebnih rook driver datoteka, ovaj pod ne umire, već se spaja na IPC utičnicu preko priloženog volumena kao punopravni RPC poslužitelj. Paket ceph-common već je instaliran unutar kontejnera pod. IPC utičnica osigurava da će kubelet komunicirati točno s podom koji se nalazi na istom čvoru. Sve genijalno je jednostavno!..

Zbogom, naši dragi... dodaci u stablu!

Programeri Kubernetesa otkrili su da je broj dodataka za pohranu unutar jezgre dvadeset. A promjena u svakom od njih, na ovaj ili onaj način, prolazi kroz puni ciklus izdanja Kubernetesa.

Ispostavilo se da za korištenje nove verzije dodatka za pohranu, trebate ažurirati cijeli klaster. Osim toga, možda ćete se iznenaditi da će nova verzija Kubernetesa odjednom postati nekompatibilna s Linux kernelom koji koristite... Pa brišete suze i škrgućući zubima koordinirate sa svojim menadžmentom i korisnicima vrijeme za ažurirati Linux kernel i Kubernetes klaster. Uz moguće zastoje u pružanju usluga.

Situacija je više nego komična, zar ne? Cijeloj je zajednici postalo jasno da pristup ne funkcionira. Namjernom odlukom, programeri Kubernetesa najavljuju da novi dodaci za rad s pohranom više neće biti prihvaćeni u kernel. Osim toga, kao što već znamo, uočen je niz nedostataka u implementaciji dodatka Flexvolume...

Najnoviji dodani dodatak za volumene u Kubernetesu, CSI, pozvan je da jednom zauvijek riješi problem s trajnom pohranom podataka. Njegova alfa verzija, potpunije nazvana Out-of-Tree CSI Volume Plugins, najavljena je u izdanju Kubernetes 1.9.

Container Storage Interface, ili CSI 3000 spinning štap!

Prije svega, želio bih napomenuti da CSI nije samo dodatak za volumen, već pravi стандарт o izradi prilagođenih komponenti za rad sa skladištima podataka. Sustavi za orkestraciju spremnika kao što su Kubernetes i Mesos trebali su "naučiti" kako raditi s komponentama implementiranim prema ovom standardu. A sada sam već naučio Kubernetes.

Kakva je struktura CSI dodatka u Kubernetesu? Dodatak CSI radi s posebnim upravljačkim programima (CSI vozači) napisali programeri treće strane. CSI drajver u Kubernetesu trebao bi se sastojati minimalno od dvije komponente (pods):

  • kontrolor — upravlja vanjskim trajnim pohranama. Implementiran je kao gRPC poslužitelj za koji se koristi primitiv StatefulSet.
  • Čvor — odgovoran je za postavljanje trajne pohrane na čvorove klastera. Također je implementiran kao gRPC poslužitelj, ali se za njega koristi primitiv DaemonSet.

Volume dodaci za Kubernetes pohranu: od Flexvolume do CSI
Kako CSI dodatak radi u Kubernetesu

O nekim drugim detaljima rada CSI-ja možete saznati, primjerice, iz članka "Razumijevanje C.S.I.' prijevod kojih objavili smo prije godinu dana.

Prednosti takve implementacije

  • Za osnovne stvari poput registracije upravljačkog programa za čvor, programeri Kubernetesa implementirali su skup spremnika. Više ne morate sami generirati JSON odgovor sa mogućnostima, kao što je učinjeno za dodatak Flexvolume.
  • Umjesto "klizanja" izvršnih datoteka na čvorove, sada učitavamo podove u klaster. To je ono što u početku očekujemo od Kubernetesa: svi se procesi odvijaju unutar spremnika raspoređenih pomoću Kubernetes primitiva.
  • Više ne trebate razvijati RPC poslužitelj i RPC klijent za implementaciju složenih upravljačkih programa. Klijenta su za nas implementirali Kubernetes programeri.
  • Prosljeđivanje argumenata za rad preko gRPC protokola mnogo je praktičnije, fleksibilnije i pouzdanije nego njihovo prosljeđivanje kroz argumente naredbenog retka. Da biste razumjeli kako dodati podršku za metriku korištenja količine u CSI dodavanjem standardizirane gRPC metode, možete pročitati: naš zahtjev za povlačenjem za vsphere-csi drajver.
  • Komunikacija se odvija putem IPC utičnica, kako ne bi došlo do zabune je li kubelet poslao zahtjev ispravnom modulu.

Podsjeća li vas ovaj popis na nešto? Prednosti CSI-ja su rješavanje istih problema, koji nisu uzeti u obzir prilikom razvoja dodatka Flexvolume.

Zaključci

Zajednica je vrlo toplo primila CSI kao standard za implementaciju prilagođenih dodataka za interakciju sa skladištima podataka. Štoviše, zbog svojih prednosti i svestranosti, CSI drajveri se čak kreiraju za sustave za pohranu kao što su Ceph ili AWS EBS, dodaci za rad s kojima su dodani u prvoj verziji Kubernetesa.

Početkom 2019. dodaci u stablu proglašeni su zastarjelima. Planiramo nastaviti podržavati dodatak Flexvolume, ali nećemo razvijati nove funkcije za njega.

Mi sami već imamo iskustva s korištenjem ceph-csi, vsphere-csi i spremni smo dodati na ovaj popis! Zasad se CSI uspješno nosi sa zadacima koji su mu dodijeljeni, ali pričekat ćemo i vidjeti.

Ne zaboravite da je sve novo dobro promišljanje starog!

PS

Pročitajte i na našem blogu:

Izvor: www.habr.com

Dodajte komentar