Volume plugins za Kubernetes skladište: od Flexvolume do CSI

Volume plugins za Kubernetes skladište: od Flexvolume do CSI

Kada je Kubernetes još bio v1.0.0, postojali su dodaci za volumen. Bili su potrebni za povezivanje sistema sa Kubernetesom za skladištenje trajnih (trajnih) podataka kontejnera. Njihov broj je bio mali, a među prvima su bili takvi dobavljači skladištenja podataka kao što su GCE PD, Ceph, AWS EBS i drugi.

Dodaci su isporučeni zajedno sa Kubernetesom, zbog čega su i dobili ime - u stablu. Međutim, za mnoge se postojeći skup takvih dodataka pokazao nedovoljnim. Majstori su dodali jednostavne dodatke u Kubernetes jezgro koristeći zakrpe, nakon čega su sastavili svoj Kubernetes i instalirali ga na svoje servere. Ali s vremenom su Kubernetes programeri to shvatili riba problem se ne može riješiti. Ljudi trebaju štap za pecanje. A u izdanju Kubernetes v1.2.0 pojavilo se...

Flexvolume dodatak: minimalan štap za pecanje

Kubernetes programeri su kreirali dodatak FlexVolume, koji je bio logički okvir varijabli i metoda za rad sa Flexvolume drajverima implementiranim od strane programera treće strane.

Zaustavimo se i pogledajmo bliže šta je FlexVolume drajver. Ovo je izvesno izvršnu datoteku (binarni fajl, Python skripta, Bash skripta, itd.), koji, kada se izvrši, uzima argumente komandne linije kao ulaz i vraća poruku sa unapred poznatim poljima u JSON formatu. Po konvenciji, prvi argument komandne linije je uvijek metoda, a preostali argumenti su njegovi parametri.

Volume plugins za Kubernetes skladište: od Flexvolume do CSI
Dijagram povezivanja za CIFS Shares u OpenShift. Flexvolume Driver - desno u centru

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 definisati scenario u kojem će kubelet delovati u budućnosti prilikom pozivanja drajvera. Postoje i posebne metode expandvolume и expandfs, koji su odgovorni za dinamičku promjenu veličine volumena.

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

A evo i primjera implementacije Flexvolume drajvera za rad sa 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 otpremite drajver u Kubernetes klaster. Drajver mora biti lociran na svakom čvoru klastera prema unaprijed određenoj putanji. Podrazumevano je odabrano:

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

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

Flexvolume problemi: kako pravilno zabaciti štap za pecanje?

Učitavanje Flexvolume drajvera u čvorove klastera pokazalo se kao netrivijalan zadatak. Nakon što jednom ručno izvršite operaciju, lako je doći do situacije da 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 obaviti rad sa pohranom na ovim čvorovima je nemoguće, dok im i dalje ručno ne dodate Flexvolume drajver.

Rješenje ovog problema bio je jedan od Kubernetes primitiva - DaemonSet. Kada se novi čvor pojavi u klasteru, on automatski sadrži pod iz našeg DaemonSet-a, na koji je povezan lokalni volumen duž putanje za pronalaženje Flexvolume drajvera. Nakon uspješnog kreiranja, pod kopira potrebne datoteke za rad drajvera na disk.

Evo primjera takvog DaemonSeta za postavljanje dodatka 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>

... i primjer Bash skripte za postavljanje Flexvolume drajvera:

#!/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 je operacija kopiranja nije atomska. Postoji velika šansa da će kubelet početi koristiti drajver prije nego što se njegov proces obezbjeđivanja završi, što će uzrokovati pad sistema. Ispravan pristup je da prvo kopirate datoteke drajvera pod drugim imenom, a zatim koristite operaciju atomskog preimenovanja.

Volume plugins za Kubernetes skladište: od Flexvolume do CSI
Dijagram rada sa Ceph u Rook operatoru: Flexvolume drajver na dijagramu se nalazi unutar Rook agenta

Sljedeći problem pri korištenju Flexvolume drajvera je taj za većinu skladišta 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 sistema.

Originalno rješenje ovog problema može se vidjeti u implementaciji Flexvolume drajvera Rook operatora:

Sam drajver je dizajniran kao RPC klijent. IPC utičnica za komunikaciju nalazi se u istom direktoriju kao i sam drajver. Sjećamo se da bi za kopiranje datoteka drajvera bilo dobro koristiti DaemonSet, koji povezuje direktorij sa drajverom kao volumen. Nakon kopiranja potrebnih fajlova drajvera za rook, ovaj pod ne umire, već se povezuje na IPC socket preko priloženog volumena kao punopravni RPC server. Ceph-common paket je već instaliran unutar pod kontejnera. IPC socket osigurava da će kubelet komunicirati sa tačno podom koja se nalazi na istom čvoru. Sve genijalno je jednostavno!..

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

Kubernetes programeri su otkrili da je broj dodataka za skladištenje unutar jezgre dvadeset. I promjena u svakom od njih, na ovaj ili onaj način, prolazi kroz cijeli ciklus izdanja Kubernetesa.

Ispostavilo se da za korištenje nove verzije dodatka za pohranu, morate ažurirati cijeli klaster. Osim toga, možda ćete biti iznenađeni što će nova verzija Kubernetesa odjednom postati nekompatibilna sa Linux kernelom koji koristite... Tako da brišete suze i, škrgućući zube, koordinirate sa svojim menadžmentom i korisnicima vrijeme za ažurirajte Linux kernel i Kubernetes klaster. Uz moguće zastoje u pružanju usluga.

Situacija je više nego komična, zar ne? Cijeloj zajednici postalo je jasno da pristup ne funkcionira. Namjernom odlukom, Kubernetes programeri najavljuju da novi dodaci za rad sa 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 zatvori problem s upornim skladištenjem podataka. Njegova alfa verzija, potpunije nazvana Out-of-Tree CSI Volume Plugins, objavljena je u izdanju Kubernetes 1.9.

Container Storage Interface, ili CSI 3000 spinning štap!

Prije svega, želio bih napomenuti da CSI nije samo volume plugin, već pravi standardna o kreiranju prilagođenih komponenti za rad sa skladištima podataka. Sistemi za orkestraciju kontejnera kao što su Kubernetes i Mesos su trebali da „nauče“ kako da rade sa komponentama implementiranim prema ovom standardu. A sada sam već naučio Kubernetes.

Koja je struktura CSI dodatka u Kubernetesu? CSI dodatak radi sa posebnim drajverima (CSI drajveri) koje su napisali programeri treće strane. CSI drajver u Kubernetesu trebao bi se minimalno sastojati od dvije komponente (pods):

  • kontrolor — upravlja vanjskim trajnim skladištima. Implementiran je kao gRPC server, za koji se koristi primitiv StatefulSet.
  • čvor — odgovoran je za montiranje trajne memorije na čvorove klastera. Takođe je implementiran kao gRPC server, ali koristi primitiv DaemonSet.

Volume plugins za Kubernetes skladište: od Flexvolume do CSI
Kako CSI dodatak radi u Kubernetesu

O nekim drugim detaljima CSI-jevog rada možete saznati, na primjer, iz članka “Razumijevanje C.S.I." prevod kojih objavili smo prije godinu dana.

Prednosti takve implementacije

  • Za osnovne stvari kao što je registracija drajvera za čvor, programeri Kubernetesa implementirali su skup kontejnera. Više ne morate sami da generišete JSON odgovor sa mogućnostima, kao što je urađeno za dodatak Flexvolume.
  • Umjesto „klizanja“ izvršnih datoteka na čvorove, sada postavljamo podove u klaster. To je ono što u početku očekujemo od Kubernetesa: svi procesi se odvijaju unutar kontejnera koji su raspoređeni koristeći Kubernetes primitive.
  • Više ne morate da razvijate RPC server i RPC klijent za implementaciju složenih drajvera. Klijenta su za nas implementirali Kubernetes programeri.
  • Prosljeđivanje argumenata za rad preko gRPC protokola je mnogo praktičnije, fleksibilnije i pouzdanije od njihovog prosljeđivanja kroz argumente komandne linije. Da biste razumjeli kako dodati podršku za metriku upotrebe volumena u CSI dodavanjem standardizirane gRPC metode, možete pročitati: naš zahtjev za povlačenjem za vsphere-csi drajver.
  • Komunikacija se odvija preko IPC soketa, kako ne bi bilo zabune da li je kubelet poslao zahtjev na ispravan pod.

Podsjeća li vas ova lista na nešto? Prednosti CSI su rješavanje istih problema, koji nisu uzeti u obzir pri razvoju dodatka Flexvolume.

nalazi

CSI kao standard za implementaciju prilagođenih dodataka za interakciju sa skladištima podataka je veoma toplo prihvaćen od strane zajednice. Štaviše, zbog svojih prednosti i svestranosti, CSI drajveri se kreiraju čak i za sisteme za skladištenje kao što su Ceph ili AWS EBS, dodaci za rad sa kojima su dodani u prvoj verziji Kubernetesa.

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

Mi sami već imamo iskustva u korištenju ceph-csi, vsphere-csi i spremni smo dodati na ovu listu! Za sada, CSI se sa zadacima koji su mu dodijelili s praskom nosi, ali sačekać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