Volume vtičniki za shranjevanje Kubernetes: od Flexvolume do CSI

Volume vtičniki za shranjevanje Kubernetes: od Flexvolume do CSI

Ko je bil Kubernetes še različica 1.0.0, so obstajali vtičniki za glasnost. Potrebni so bili za povezavo sistemov s Kubernetesom za shranjevanje obstojnih (trajnih) podatkov vsebnika. Njihovo število je bilo majhno, med prvimi pa so bili takšni ponudniki shranjevanja, kot so GCE PD, Ceph, AWS EBS in drugi.

Vtičniki so bili dostavljeni skupaj s Kubernetesom, zato so tudi dobili ime – in-tree. Vendar se je za mnoge izkazalo, da obstoječi nabor takih vtičnikov ni zadosten. Obrtniki so v jedro Kubernetes s popravki dodali preproste vtičnike, nakar so sestavili svoj Kubernetes in ga namestili na svoje strežnike. Toda sčasoma so razvijalci Kubernetesa to spoznali ribe težave ni mogoče rešiti. Ljudje potrebujejo palica. In v izdaji Kubernetes v1.2.0 se je pojavilo ...

Vtičnik Flexvolume: minimalna ribiška palica

Razvijalci Kubernetes so ustvarili vtičnik FlexVolume, ki je bil logični okvir spremenljivk in metod za delo z gonilniki Flexvolume, ki so jih implementirali razvijalci tretjih oseb.

Ustavimo se in si podrobneje oglejmo, kaj je gonilnik FlexVolume. To je določeno izvršljiva datoteka (binarna datoteka, skript Python, skript Bash itd.), ki ob izvedbi sprejme argumente ukazne vrstice kot vhod in vrne sporočilo z vnaprej znanimi polji v formatu JSON. Po dogovoru je prvi argument ukazne vrstice vedno metoda, preostali argumenti pa njeni parametri.

Volume vtičniki za shranjevanje Kubernetes: od Flexvolume do CSI
Diagram povezave za skupne rabe CIFS v OpenShift. Gonilnik Flexvolume - v središču

Najmanjši nabor metod izgleda tako:

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

Uporaba metod attach и detach bo definiral scenarij, po katerem bo kubelet deloval v prihodnosti, ko bo klical gonilnik. Obstajajo tudi posebne metode expandvolume и expandfs, ki so odgovorni za dinamično spreminjanje velikosti glasnosti.

Kot primer sprememb, ki jih doda metoda expandvolume, in s tem možnostjo spreminjanja velikosti nosilcev v realnem času, s katerim se lahko seznanite naša zahteva po vleku v operaterju Rook Ceph.

In tukaj je primer implementacije gonilnika Flexvolume za delo z 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

Torej, po pripravi dejanske izvršljive datoteke morate naloži gonilnik v gručo Kubernetes. Gonilnik se mora nahajati na vsakem vozlišču gruče v skladu z vnaprej določeno potjo. Privzeto je bilo izbrano:

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

... toda pri uporabi različnih distribucij Kubernetes (OpenShift, Rancher ...) je lahko pot drugačna.

Težave z volumnom Flexvolume: kako pravilno zavreči ribiško palico?

Nalaganje gonilnika Flexvolume v vozlišča gruče se je izkazalo za netrivialno nalogo. Ko enkrat izvedete operacijo ročno, lahko zlahka naletite na situacijo, ko se v gruči pojavijo nova vozlišča: zaradi dodajanja novega vozlišča, samodejnega horizontalnega skaliranja ali - kar je še huje - zamenjave vozlišča zaradi okvare. V tem primeru je treba opraviti delo s shrambo na teh vozliščih nemogoče, dokler jim še vedno ročno ne dodate gonilnika Flexvolume.

Rešitev tega problema je bila ena od primitiv Kubernetes - DaemonSet. Ko se v gruči pojavi novo vozlišče, samodejno vsebuje pod iz našega DaemonSeta, na katerega je pritrjen lokalni nosilec vzdolž poti za iskanje gonilnikov Flexvolume. Po uspešni izdelavi pod kopira potrebne datoteke za delovanje gonilnika na disk.

Tukaj je primer takega DaemonSeta za postavitev vtičnika 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>

... in primer skripta Bash za postavitev gonilnika 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

Pomembno je, da ne pozabite na operacijo kopiranja ni atomsko. Obstaja velika verjetnost, da bo kubelet začel uporabljati gonilnik, preden bo postopek zagotavljanja končan, kar bo povzročilo zrušitev sistema. Pravilen pristop je, da najprej kopirate datoteke gonilnika pod drugim imenom in nato uporabite operacijo atomičnega preimenovanja.

Volume vtičniki za shranjevanje Kubernetes: od Flexvolume do CSI
Diagram dela s Cephom v operaterju Rook: gonilnik Flexvolume v diagramu se nahaja znotraj agenta Rook

Naslednja težava pri uporabi gonilnikov Flexvolume je za večino pomnilnika v vozlišču gruče za to mora biti nameščena potrebna programska oprema (na primer skupni paket ceph za Ceph). Sprva vtičnik Flexvolume ni bil zasnovan za izvajanje tako zapletenih sistemov.

Izvirno rešitev tega problema je mogoče videti v izvedbi gonilnika Flexvolume operaterja Rook:

Sam gonilnik je zasnovan kot odjemalec RPC. Vtičnica IPC za komunikacijo se nahaja v istem imeniku kot sam gonilnik. Spomnimo se, da bi bilo za kopiranje datotek gonilnika dobro uporabiti DaemonSet, ki povezuje imenik z gonilnikom kot nosilec. Po kopiranju potrebnih datotek gonilnika rook ta pod ne umre, ampak se prek priloženega nosilca poveže z vtičnico IPC kot polnopravni strežnik RPC. Paket ceph-common je že nameščen znotraj vsebnika pod. Vtičnica IPC zagotavlja, da bo kubelet komuniciral točno s podom, ki se nahaja na istem vozlišču. Vse genialno je preprosto!..

Nasvidenje, naši ljubeči ... vtičniki v drevesu!

Razvijalci Kubernetes so ugotovili, da je število vtičnikov za shranjevanje znotraj jedra dvajset. In sprememba v vsakem od njih, tako ali drugače, gre skozi celoten cikel izdaje Kubernetes.

Izkazalo se je, da za uporabo nove različice vtičnika za shranjevanje posodobiti morate celotno gručo. Poleg tega vas bo morda presenetilo, da bo nova različica Kubernetesa nenadoma postala nezdružljiva z jedrom Linuxa, ki ga uporabljate ... Zato si obrišete solze in, stisnuvši zobe, uskladite s svojim vodstvom in uporabniki čas za posodobite jedro Linuxa in gručo Kubernetes. Z morebitnimi zastoji pri izvajanju storitev.

Situacija je več kot komična, se vam ne zdi? Celotni skupnosti je postalo jasno, da pristop ne deluje. Z namerno odločitvijo razvijalci Kubernetes sporočajo, da novi vtičniki za delo s shranjevanjem ne bodo več sprejeti v jedro. Poleg tega, kot že vemo, so bile ugotovljene številne pomanjkljivosti pri implementaciji vtičnika Flexvolume ...

Najnovejši dodan vtičnik za količine v Kubernetesu, CSI, je bil pozvan, da enkrat za vselej odpravi težavo s trajnim shranjevanjem podatkov. Njegova alfa različica, natančneje imenovana Out-of-Tree CSI Volume Plugins, je bila objavljena v izdaji Kubernetes 1.9.

Container Storage Interface ali CSI 3000 spinning palica!

Najprej bi rad omenil, da CSI ni samo vtičnik za glasnost, ampak pravi стандарт o ustvarjanju komponent po meri za delo s podatkovnimi skladišči. Sistemi za orkestracijo vsebnikov, kot sta Kubernetes in Mesos, naj bi se »naučili« delati s komponentami, implementiranimi v skladu s tem standardom. In zdaj sem se že naučil Kubernetesa.

Kakšna je struktura vtičnika CSI v Kubernetesu? Vtičnik CSI deluje s posebnimi gonilniki (gonilniki CSI), ki so ga napisali tretji razvijalci. Gonilnik CSI v Kubernetesu mora biti sestavljen vsaj iz dveh komponent (podov):

  • krmilnik — upravlja zunanje trajne pomnilnike. Implementiran je kot strežnik gRPC, za katerega se uporablja primitiv StatefulSet.
  • Node — je odgovoren za namestitev trajnega pomnilnika v vozlišča gruče. Izveden je tudi kot strežnik gRPC, vendar uporablja primitiv DaemonSet.

Volume vtičniki za shranjevanje Kubernetes: od Flexvolume do CSI
Kako deluje vtičnik CSI v Kubernetesu

O nekaterih drugih podrobnostih dela CSI lahko izveste na primer iz članka "Razumevanje C.S.I." prevod katerega smo objavili pred enim letom.

Prednosti takšne izvedbe

  • Za osnovne stvari, kot je registracija gonilnika za vozlišče, so razvijalci Kubernetes implementirali nabor vsebnikov. Ni vam več treba sami ustvariti odgovora JSON z zmožnostmi, kot je bilo storjeno za vtičnik Flexvolume.
  • Namesto "zdrsa" izvršljivih datotek na vozlišča, zdaj nalagamo pode v gručo. To je tisto, kar sprva pričakujemo od Kubernetesa: vsi procesi se odvijajo znotraj vsebnikov, nameščenih z uporabo primitivov Kubernetes.
  • Ni vam več treba razvijati strežnika RPC in odjemalca RPC za implementacijo kompleksnih gonilnikov. Stranko so za nas implementirali razvijalci Kubernetes.
  • Posredovanje argumentov za delo prek protokola gRPC je veliko bolj priročno, prilagodljivo in zanesljivo kot njihovo posredovanje skozi argumente ukazne vrstice. Če želite razumeti, kako CSI dodati podporo za meritve količine uporabe z dodajanjem standardizirane metode gRPC, lahko preberete: naša zahteva po vleku za gonilnik vsphere-csi.
  • Komunikacija poteka prek vtičnic IPC, da ne bi prišlo do zamenjave, ali je kubelet poslal zahtevo pravilnemu modulu.

Vas ta seznam na kaj spominja? Prednosti CSI so reševanje istih problemov, ki niso bili upoštevani pri razvoju vtičnika Flexvolume.

Ugotovitve

CSI kot standard za implementacijo vtičnikov po meri za interakcijo s podatkovnimi skladišči je skupnost zelo toplo sprejela. Poleg tega so gonilniki CSI zaradi svojih prednosti in vsestranskosti ustvarjeni tudi za sisteme za shranjevanje, kot sta Ceph ali AWS EBS, vtičniki za delo s katerimi so bili dodani v prvi različici Kubernetesa.

V začetku leta 2019 vtičniki v drevesu so bili razglašeni za zastarele. Načrtujemo, da bomo še naprej podpirali vtičnik Flexvolume, vendar ne bomo razvijali novih funkcij zanj.

Sami že imamo izkušnje z uporabo ceph-csi, vsphere-csi in smo pripravljeni dodati na ta seznam! Zaenkrat se CSI uspešno spopada z nalogami, ki so mu bile dodeljene, vendar bomo počakali in videli.

Ne pozabite, da je vse novo dober premislek o starem!

PS

Preberite tudi na našem blogu:

Vir: www.habr.com

Dodaj komentar