Kubernetesi mahutite pluginate haldus: Flexvolume'ist CSI-ni

Kubernetesi mahutite pluginate haldus: Flexvolume'ist CSI-ni

Aegadel, mil Kubernetes oli veel v1.0.0, eksisteerisid mahutite pluginaid (volume plugins). Need olid vajalikud Kubernetes'i süsteemide ühendamiseks, mis salvestasid konteinerite püsivaid (püsivaid) andmeid. Nende arv oli väike, ja esimesed olid sellised salvestusteenuse pakkujad nagu GCE PD, Ceph, AWS EBS ja teised.

Pluginaid tarniti koos Kubernetesiga, miks neid nimetatakse ka in-tree. Kuid paljudele praegusest komplektist ei piisanud. Kätetöölised lisasid lihtsaid pluginaid Kubernetes'i tuumale läbi plaastrite, pärast mida kogusid nad omaenda Kubernetes'i ja paigaldasid selle oma serveritesse. Kuid aja jooksul mõistsid Kubernetes'i arendajad, et probleemi niisama ei lahenda. Inimesele on vaja kalapüügi varustust. Ja Kubernetesi versioonis v1.2.0 ilmnes see...

Flexvolume plugin: lihtne kalapüügivahend

Kubernetes'i arendajad lõid FlexVolume'i plugina, mis oli loogiline sidumine muutujaid ja meetodeid, et töötada välja kolmandate osapoolte Flexvolume-draiveritega.

Vaatame lähemalt, mida FlexVolume'i draiver endast kujutab. See on teatud täitmisfail. (binaarfail, Python-skript, Bash-skript jne), mis täitmisel võtab sisendiks käskude rea argumendid ja tagastab sõnumi, millel on eelnevalt määratletud väljad JSON-formaadis. Esimene käskude rea argument on kokkuleppe kohaselt alati meetod ja ülejäänud argumendid on tema parameetrid.

Kubernetesi mahutite pluginate haldus: Flexvolume'ist CSI-ni
CIFS Share'ide ühendusskeem OpenShiftis. Flexvolume draiver — täpselt keskel

Minimaalne meetodite komplekt näeb välja nii:

flexvolume_driver mount # vastutab mahuti liitmise eest pod'iga
# Tagastatava sõnumi formaat:
{
  "status": "Success"/"Failure"/"Not supported",
  "message": "Miks see staatus tagastati",
}

flexvolume_driver unmount # vastutab mahuti lahtiühendamise eest pod'ist
# Tagastatava sõnumi formaat:
{
  "status": "Success"/"Failure"/"Not supported",
  "message": "Miks see staatus tagastati",
}

flexvolume_driver init # vastutab plugina initsialiseerimise eest
# Tagastatava sõnumi formaat:
{
  "status": "Success"/"Failure"/"Not supported",
  "message": "Miks see staatus tagastati",
  // Määrab, kas draiver kasutab meetodeid attach/detach
  "capabilities":{"attach": True/False}
}

Meetodite kasutamine attach ja detach määrab stsenaariumi, mille alusel kubelet tulevikus draiveri kutse tegemisel tegutseb. Samuti on olemas spetsiaalsed meetodid expandvolume ja expandfs, mis vastutavad mahuti dünaamilise suuruse muutmise eest.

Muudatuste näitena, mida meetod lisab expandvolume, ja koos sellega — võimalus teostada mahutite suuruse muutmist reaalajas, saate tutvuda meie pull request’iga Rook Ceph Operatori juures.

Siin on Flexvolume-draiveri teostuse näide NFS-i toe jaoks:

usage() {
    err "Vale vale. Kasutamine: "
    err "t$0 init"
    err "t$0 mount  "
    err "t$0 unmount "
    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": "Mountimine ebaõnnestus: ${NFS_SERVER}:${SHARE} asukohas ${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": "Eemaldamine ebaõnnestus asukohas ${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

Nüüd, pärast täidetud täitefaili ettevalmistamist, on vajalik lastata draiver Kubernetes klastrisse. Draiver peab olema igas klastrisõlmes, järgides eelnevalt kokkulepitud teed. Vaikimisi on valitud:

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

… kuid erinevate Kubernetes'i jaotuste (OpenShift, Rancher…) puhul võib tee olla teine.

Flexvolume probleemid: kuidas õigesti vasardada?

Flexvolume draiveri paigaldamine klastrisõlmedesse osutus mitte triviaalseks ülesandeks. Kui teha operatsioon kord käsitsi, võib juhtuda, et klastris lisanduvad uued sõlmed: uue sõlme lisamise, automaatse horisontaalse skaleerimise tõttu või — mis veelgi hullem — sõlme asendamise tõttu rikke tõttu. Sellisel juhul tuleb neid sõlmi kasutada ei ole võimalik, kuni lisate neile Flexvolume draiveri ikka veel käsitsi.

Selle probleemi lahenduseks osutus Kubernetes'e primitiiv — DaemonSet. Kui klastris ilmub uus sõlm, paigaldatakse sellele automaatselt pod meie DaemonSet'ist, millele liitub kohalik maht teel, kus asuvad Flexvolume draiverid. Kui pod on edukalt loodud, kopeerib see draiveri töötamiseks vajalikud failid kettale.

Siin on näide sellisest DaemonSet'ist Flexvolume pistiku paigaldamiseks:

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

… ja Bash-skripti näide Flexvolume-draiveri kasutamiseks:

#!/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

Oluline on mitte unustada, et koopiamoodul ei ole atomaarne. On suur tõenäosus, et kubelet hakkab draiverit kasutama enne, kui selle ettevalmistamise protsess on lõppenud, mis põhjustab süsteemi tõrke. Õige lähenemine on esmalt kopeerida draiverifailid teise nime alla, seejärel kasutada atomaarset ümbernimetamist.

Kubernetesi mahutite pluginate haldus: Flexvolume'ist CSI-ni
Cephi töötamise skeem Rooki operaatoris: Flexvolume-draiver asub skeemil Rooki agendi sees

J volgende probleem, kui kasutada Flexvolume-draivereid, on see, et kliendi sõlme peab olema vajalik tarkvara (näiteks ceph-common paket Cephi jaoks). Alguses ei olnud Flexvolume plugin mõeldud nii keeruliste süsteemide rakendamiseks. (например, пакет ceph-common для Ceph). Изначально плагин Flexvolume не был задуман для реализации настолько сложных систем.

Originaalne lahendus selle probleemiga on nähtav Rooki operaatori Flexvolume-draiveri teostuses:

Ise draiver on teostatud RPC-klientina. IPC-sokkel suhtlemiseks asub samas kataloogis, kus on ise draiver. Me mäletame, et draiveri failide koopiate tegemiseks oleks hea kasutada DaemonSet'i, mis ühendab endale draiveriga katalooge kui mahtu. Pärast Rooki draiveri vajalike failide kopeerimist ei sure see pod, vaid ühendub IPC-sokliga kinnitatud mahu kaudu täisfunktsionaalse RPC-serverina. Pakett ceph-common on juba paigaldatud pod'i konteinerisse. IPC-sokkel tagab, et kubelet suhtleb just selle pod'iga, mis asub koos temaga ühel sõlmel. Kõik geniaalne on lihtne!..

Head aega, meie armsad… in-tree pluginate!

Kubernetes'i arendajad avastasid, et tuumapõhiste salvestuspluginate arv on kakskümmend. Ja igas neist muudatused läbivad igal juhul täiskohalise Kubernetes'i väljaandetsükli.

Selgub, et uue salvestusplugina versiooni kasutamiseks, on vaja värskendada tervet klastrit.. Lisaks sellele võite üllatuda, et uus Kubernetes versioon osutub äkki ühilduvaks kasutatava Linuxi kärgaga... Ja seetõttu pühite pisarad ja hammastega näksides lepite ülemuse ja kasutajatega kokku Linuxi kärje ja Kubernetes klastrite uuendamise aja. Võimaliku teenusekatkestusega.

Situatsioon on rohkem kui koomiline, eks? Kogu kogukond mõistis, et lähenemine ei toimi. Otsustavatel hetkedel kuulutavad Kubernetes arendajad, et uusi pluginaid andmete salvestamiseks ei võeta enam tuuma. Lisaks teame, et Flexvolume plugina rakenduses on tuvastatud mitmeid puudujääke...

Lõpuks tuleb küsimus püsivatest andmete salvestamisest selgeks teha viimasena lisatud plugina abil Kubernetesest — CSI. Selle alfa versioon, mida nimetatakse täielikult Out-of-Tree CSI Volume Plugins, kuulutati välja väljaandes Kubernetes 1.9.

Container Storage Interface, või järgnevalt CSI 3000!

Esimese asjana sooviksin märkida, et CSI — see pole lihtsalt volume plugin, vaid tõeline standard kasutajate komponentide loomise jaoks andmete salvestamiseks. Eeldati, et konteinerite orkestreerimise süsteemid, nagu Kubernetes ja Mesos, peavad õppima selle standardi järgi rakendatud komponentidega töötama. Ja siit juba Kubernetes on õppinud.

Milline on CSI-plugina struktuur Kuberneteses? CSI-plugin töötab spetsiaalsete draiveritega (CSI-draiveritega), mille on kirjutanud kolmanda osapoole arendajad. CSI-draiver Kuberneteses peab minimaalset koosnema kahest komponendist (pod’ist):

  • Kontroller — haldab väliseid püsivaid ladustamisi. Vabastatakse gRPC-serverina, mille jaoks kasutatakse primitiivi StatefulSet.
  • Sõlm — vastutab püsivate ladustamiste mountimise eest klastrisõlmedes. Samuti rakendatakse gRPC-serverina, kuid selle jaoks kasutatakse primitiivi DaemonSet.

Kubernetesi mahutite pluginate haldus: Flexvolume'ist CSI-ni
CSI-plugina tööskeem Kuberneteses

Mõningate teiste CSI töödetailide kohta saate lugeda näiteks artiklist «Understanding the CSI», mille tõlked me avaldasime aasta tagasi.

Sellise rakenduse plussid

  • Põhiasjade jaoks — näiteks sõlme draiveri registreerimiseks — on Kubernetes arendajad rakendanud konteinerite komplekti. Ei ole enam vaja ise luua JSON-vastust capabilities'idega, nagu see tehti Flexvolume plugina puhul.
  • Käivitatavates failidesse «sisestamise» asemel laadime nüüd klastrisse pod’id. Just seda me Kuberneteselt ootame: kõik protsessid toimuvad konteinerites, mis on paigutatud Kubernetes'e primitiivide abil.
  • Komplekssete draiverite rakendamiseks ei pea enam arendama RPC-serverit ja RPC-klienti. Klienti on meie eest rakendanud Kubernetes'e arendajad.
  • Argumentide edastamine gRPC-protokolli kaudu on palju mugavam, paindlikum ja usaldusväärsem kui nende edastamine käsurea argumentidena. Kuidas lisada CSI-sse mahude kasutamise mõõdikute toeks standardiseeritud gRPC-meetodi, saab tutvuda meie pull request’iga vsphere-csi draiveri jaoks.
  • Suhtlus toimub IPC-soketite kaudu, et mitte segadusse minna, millisele pod’ile kubelet päringu saatis.

Kas see nimekiri meenutab teile midagi? CSI eelised on lahendus nendele probleemidele, mis ei olnud arvesse võetud Flexvolume'i pistiku loomisel.

Järeldused

CSI kui kasutajapoolsete pluginite standard andmesalvestussektoritega suhtlemiseks on kogukonna poolt väga soojalt vastu võetud. Veelgi enam, oma eeliste ja mitmekesisuse tõttu luuakse CSI draivereid isegi selliste salvestuslahenduste jaoks nagu Ceph või AWS EBS, mille pluginad on lisatud juba Kubernetes'i esimeses versioonis.

2019. aasta alguses kuulutati in-tree pluginad aegunud. Flexvolume'i plugina toetamine jätkub, kuid selle jaoks uusi funktsioone ei arendata.

Meil on juba kogemus ceph-csi ja vsphere-csi kasutamisel ning oleme valmis seda nimekirja täiendama! Praegu täidab CSI sellele pandud ülesandeid suurepäraselt, aga eks näeme, mis edasi saab.

Ärge unustage, et kõik uus on hästi ümber mõtestatud vana!

P.S.

Lugege ka meie blogist:

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster