Volume-laajennukset Kubernetes-tallennustilaa varten: Flexvolumesta CSI:hen

Volume-laajennukset Kubernetes-tallennustilaa varten: Flexvolumesta CSI:hen

Kun Kubernetes oli vielä v1.0.0, siellä oli volyymilaajennuksia. Niitä tarvittiin järjestelmien yhdistämiseen Kubernetesiin pysyvien (pysyvien) säiliötietojen tallentamista varten. Heidän määränsä oli pieni, ja ensimmäisten joukossa olivat sellaiset tallennuspalveluntarjoajat kuin GCE PD, Ceph, AWS EBS ja muut.

Lisäosat toimitettiin Kubernetesin mukana, minkä vuoksi ne saivat nimensä - in-tree. Monille nykyinen tällaisten laajennusten sarja osoittautui kuitenkin riittämättömäksi. Käsityöläiset lisäsivät Kubernetesin ytimeen yksinkertaisia ​​laajennuksia korjaustiedostojen avulla, minkä jälkeen he kokosivat omat Kubernetesi ja asensivat sen palvelimilleen. Mutta ajan myötä Kubernetes-kehittäjät ymmärsivät sen kala ongelmaa ei voida ratkaista. Ihmiset tarvitsevat sauva. Ja Kubernetes v1.2.0:n julkaisussa se ilmestyi...

Flexvolume-laajennus: minimaalinen onki

Kubernetes-kehittäjät loivat FlexVolume-laajennuksen, joka oli muuttujien ja menetelmien looginen kehys työskennellä kolmannen osapuolen kehittäjien toteuttamien Flexvolume-ajurien kanssa.

Pysähdytään ja katsotaan tarkemmin, mikä FlexVolume-ohjain on. Tämä on varmaa suoritettava tiedosto (binääritiedosto, Python-skripti, Bash-skripti jne.), joka suoritettuna ottaa komentoriviargumentteja syötteenä ja palauttaa viestin, jossa on ennalta tunnetut kentät JSON-muodossa. Käytännön mukaan ensimmäinen komentorivin argumentti on aina menetelmä, ja loput argumentit ovat sen parametreja.

Volume-laajennukset Kubernetes-tallennustilaa varten: Flexvolumesta CSI:hen
Kytkentäkaavio CIFS-osuuksille OpenShiftissä. Flexvolume Driver - aivan keskustassa

Minimi joukko menetelmiä näyttää tältä:

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

Käyttämällä menetelmiä attach и detach määrittää skenaarion, jossa kubelet toimii tulevaisuudessa kutsuessaan kuljettajaa. On myös erikoismenetelmiä expandvolume и expandfs, jotka vastaavat äänenvoimakkuuden dynaamisesta koon muuttamisesta.

Esimerkkinä menetelmän lisäämistä muutoksista expandvolume, ja sen avulla voit muuttaa volyymien kokoa reaaliajassa, johon voit tutustua vetopyyntömme Rook Ceph Operatorissa.

Ja tässä on esimerkki Flexvolume-ohjaimen toteutuksesta NFS:n kanssa työskentelemiseen:

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

Joten, kun olet valmistellut varsinaisen suoritettavan tiedoston, sinun on tehtävä lataa ohjain Kubernetes-klusteriin. Ajurin on sijaittava jokaisessa klusterin solmussa ennalta määrätyn polun mukaisesti. Oletuksena se oli valittuna:

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

... mutta käytettäessä erilaisia ​​Kubernetes-jakeluja (OpenShift, Rancher...) polku voi olla erilainen.

Flexvolume-ongelmat: kuinka heittää onki oikein?

Flexvolume-ohjaimen lataaminen klusterin solmuihin osoittautui ei-triviaaliksi tehtäväksi. Kerran manuaalisesti tehtynä on helppo kohdata tilanne, jossa klusteriin ilmaantuu uusia solmuja: uuden solmun lisäämisen, automaattisen vaakaskaalauksen tai - mikä pahempaa - solmun vaihtamisen takia toimintahäiriön vuoksi. Tässä tapauksessa näiden solmujen tallennustilaa tulee käsitellä on mahdotonta, kunnes lisäät Flexvolume-ohjaimen niihin manuaalisesti.

Ratkaisu tähän ongelmaan oli yksi Kubernetes-primitiivistä - DaemonSet. Kun uusi solmu ilmestyy klusteriin, se sisältää automaattisesti podin DaemonSetistä, johon liitetään paikallinen taltio polun varrella Flexvolume-ajureiden löytämiseksi. Onnistuneen luomisen jälkeen pod kopioi tarvittavat tiedostot levylle, jotta ohjain toimii.

Tässä on esimerkki tällaisesta DaemonSetistä Flexvolume-laajennuksen asettamiseen:

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>

... ja esimerkki Bash-skriptistä Flexvolume-ohjaimen asettamiseen:

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

On tärkeää muistaa, että kopiointitoiminto ei ole atomi. On suuri mahdollisuus, että kubelet alkaa käyttää ohjainta ennen kuin sen valmisteluprosessi on valmis, jolloin järjestelmä kaatuu. Oikea tapa on kopioida ensin ohjaintiedostot eri nimellä ja käyttää sitten atomien uudelleennimeämistoimintoa.

Volume-laajennukset Kubernetes-tallennustilaa varten: Flexvolumesta CSI:hen
Kaavio työskentelystä Cephin kanssa Rook-operaattorissa: kaavion Flexvolume-ohjain sijaitsee Rook-agentin sisällä

Seuraava ongelma käytettäessä Flexvolume-ajureita on useimmille klusterisolmun tallennustilalle tähän tarvittava ohjelmisto on asennettava (esimerkiksi Ceph-yleinen paketti). Alun perin Flexvolume-laajennusta ei suunniteltu toteuttamaan niin monimutkaisia ​​järjestelmiä.

Alkuperäinen ratkaisu tähän ongelmaan on nähtävissä Rook-operaattorin Flexvolume-ohjaintoteutuksessa:

Itse ohjain on suunniteltu RPC-asiakkaaksi. Viestinnän IPC-liitäntä sijaitsee samassa hakemistossa kuin itse ajuri. Muistamme, että ajuritiedostojen kopioimiseen olisi hyvä käyttää DaemonSetiä, joka yhdistää hakemiston ajuriin talteena. Kun tarvittavat rook-ohjaintiedostot on kopioitu, tämä pod ei kuole, vaan kytkeytyy liitteenä olevan taltion kautta IPC-liitäntään täysimittaisena RPC-palvelimena. Ceph-common-paketti on jo asennettu pod-säiliön sisään. IPC-liitäntä varmistaa, että kubelet kommunikoi täsmälleen samassa solmussa sijaitsevan podin kanssa. Kaikki nerokas on yksinkertaista!...

Hyvästi, meidän hellä... puunsisäiset laajennukset!

Kubernetes-kehittäjät havaitsivat, että ytimessä tallennettavia laajennuksia on kaksikymmentä. Ja muutos jokaisessa niistä tavalla tai toisella käy läpi koko Kubernetes-julkaisusyklin.

Osoittautuu, että tallennuslaajennuksen uuden version käyttäminen sinun on päivitettävä koko klusteri. Tämän lisäksi saatat olla yllättynyt siitä, että Kubernetesin uusi versio tulee yhtäkkiä yhteensopimattomaksi käyttämäsi Linux-ytimen kanssa... Joten pyyhit kyyneleet pois ja sovitat hampaitasi puristaen johdon ja käyttäjien kanssa aikaa päivittää Linux-ytimen ja Kubernetes-klusterin. Palvelujen tarjonnan mahdollisilla seisokkeilla.

Tilanne on enemmän kuin koominen, vai mitä? Koko yhteisölle kävi selväksi, että lähestymistapa ei toiminut. Kubernetes-kehittäjät ilmoittavat tahallisella päätöksellä, että uusia tallennustilan kanssa työskenteleviä laajennuksia ei enää hyväksytä ytimeen. Lisäksi, kuten jo tiedämme, Flexvolume-laajennuksen toteutuksessa havaittiin useita puutteita...

Viimeisin lisätty laajennus Kubernetesin, CSI, volyymeille, kehotettiin ratkaisemaan pysyvän tiedontallennusongelman lopullisesti. Sen alfaversio, jota kutsutaan täydellisemmin nimellä Out-of-Tree CSI Volume Plugins, julkistettiin julkaisussa Kubernetes 1.9.

Container Storage Interface tai CSI 3000 kehruutanko!

Ensinnäkin haluaisin huomauttaa, että CSI ei ole vain volyymilaajennus, vaan todellinen стандарт mukautettujen komponenttien luomiseen tietovarastojen kanssa työskentelyä varten. Konttien orkestrointijärjestelmien, kuten Kubernetes ja Mesos, piti "oppia" työskentelemään tämän standardin mukaisesti toteutettujen komponenttien kanssa. Ja nyt olen jo oppinut Kubernetesin.

Mikä on Kubernetesin CSI-laajennuksen rakenne? CSI-laajennus toimii erikoisajureilla (CSI-ajurit) kolmannen osapuolen kehittäjien kirjoittamia. Kubernetesin CSI-ohjaimen tulisi koostua vähintään kahdesta osasta (podista):

  • ohjain — hallitsee ulkoisia pysyviä tallennusvälineitä. Se on toteutettu gRPC-palvelimena, jolle käytetään primitiiviä StatefulSet.
  • Solmu — vastaa pysyvän tallennustilan asentamisesta klusterin solmuihin. Se on myös toteutettu gRPC-palvelimena, mutta se käyttää primitiivistä DaemonSet.

Volume-laajennukset Kubernetes-tallennustilaa varten: Flexvolumesta CSI:hen
Kuinka CSI-laajennus toimii Kubernetesissa

Voit oppia joistakin muista CSI:n työn yksityiskohdista esimerkiksi artikkelista "C.S.I." jonka käännös julkaisimme vuosi sitten.

Tällaisen toteutuksen edut

  • Perusasioita, kuten ohjaimen rekisteröintiä varten, Kubernetes-kehittäjät ottivat käyttöön joukon säiliöitä. Sinun ei enää tarvitse luoda JSON-vastausta ominaisuuksineen itse, kuten tehtiin Flexvolume-laajennukselle.
  • Sen sijaan, että "liukuttaisimme" suoritettavat tiedostot solmuihin, lataamme nyt podeja klusteriin. Tätä odotamme aluksi Kubernetesilta: kaikki prosessit tapahtuvat Kubernetes-primitiivien avulla käyttöönotetuissa säilöissä.
  • Sinun ei enää tarvitse kehittää RPC-palvelinta ja RPC-asiakasta toteuttaaksesi monimutkaisia ​​ohjaimia. Asiakkaan toteuttivat meille Kubernetes-kehittäjät.
  • Argumenttien välittäminen gRPC-protokollan kautta on paljon kätevämpää, joustavampaa ja luotettavampaa kuin niiden välittäminen komentoriviargumenttien kautta. Voit lukea, kuinka CSI:lle voidaan lisätä tuki volyymin käyttömittareille lisäämällä standardoitu gRPC-menetelmä: vetopyyntömme vsphere-csi-ohjaimelle.
  • Viestintä tapahtuu IPC-liitäntöjen kautta, jotta ei jää hämmennyksiin, lähettikö kubelet pyynnön oikeaan koteloon.

Muistuttaako tämä lista sinua jostain? CSI:n edut ovat ratkaisemaan samat ongelmat, joita ei otettu huomioon Flexvolume-laajennusta kehitettäessä.

Tulokset

Yhteisö otti erittäin lämpimästi vastaan ​​CSI:n standardina mukautettujen lisäosien toteuttamiseen tietovarastojen kanssa vuorovaikutuksessa. Lisäksi etujensa ja monipuolisuutensa ansiosta CSI-ajurit luodaan jopa tallennusjärjestelmiin, kuten Ceph tai AWS EBS, joiden kanssa työskentelyyn tarkoitettuja laajennuksia lisättiin Kubernetesin aivan ensimmäiseen versioon.

Vuoden 2019 alussa in-tree-laajennukset on julistettu vanhentuneiksi. Aiomme jatkaa Flexvolume-laajennuksen tukemista, mutta emme kehitä sille uusia toimintoja.

Meillä itsellämme on jo kokemusta ceph-csi:n, vsphere-csi:n käytöstä ja olemme valmiita lisäämään tähän listaan! Toistaiseksi CSI selviytyy sille osoitetuista tehtävistä räjähdysmäisesti, mutta odotellaan ja katsotaan.

Älä unohda, että kaikki uusi on hyvää vanhan ajattelua!

PS.

Lue myös blogistamme:

Lähde: will.com

Lisää kommentti