ProHoster > Օրագիր > Վարչակազմը > Volume plugins Kubernetes պահեստավորման համար՝ Flexvolume-ից մինչև CSI
Volume plugins Kubernetes պահեստավորման համար՝ Flexvolume-ից մինչև CSI
Դեռ երբ Kubernetes-ը դեռ v1.0.0 էր, կային ծավալային հավելումներ: Դրանք անհրաժեշտ էին համակարգերը Kubernetes-ին միացնելու համար՝ մշտական (մշտական) կոնտեյների տվյալները պահելու համար: Նրանց թիվը փոքր էր, և առաջիններից էին պահեստավորման այնպիսի մատակարարներ, ինչպիսիք են GCE PD, Ceph, AWS EBS և այլն:
Փլագինները առաքվել են Kubernetes-ի հետ միասին, ինչի պատճառով էլ ստացել են իրենց անվանումը՝ in-tree: Այնուամենայնիվ, շատերի համար նման պլագինների գոյություն ունեցող հավաքածուն անբավարար էր։ Արհեստավորներն ավելացրել են պարզ փլագիններ Kubernetes-ի միջուկում՝ օգտագործելով patches, որից հետո նրանք հավաքել են իրենց սեփական Kubernetes-ը և տեղադրել այն իրենց սերվերների վրա։ Սակայն ժամանակի ընթացքում Kubernetes-ի մշակողները հասկացան դա ձուկ խնդիրը չի կարող լուծվել. Մարդիկ կարիք ունեն ձկնորսական գավազան. Իսկ Kubernetes v1.2.0-ի թողարկման մեջ հայտնվեց...
Flexvolume plugin՝ նվազագույն ձկնորսական գավազան
Kubernetes-ի մշակողները ստեղծեցին FlexVolume plugin-ը, որը փոփոխականների և մեթոդների տրամաբանական շրջանակ էր Flexvolume դրայվերների հետ աշխատելու համար, որոնք իրականացվել էին երրորդ կողմի մշակողների կողմից:
Եկեք կանգ առնենք և ավելի սերտ նայենք, թե ինչ է իրենից ներկայացնում FlexVolume դրայվերը: Սա որոշակի է գործարկվող ֆայլ (երկուական ֆայլ, Python script, Bash script և այլն), որը գործարկվելիս ընդունում է հրամանի տողի արգումենտները որպես մուտքագրում և վերադարձնում JSON ձևաչափով նախապես հայտնի դաշտերով հաղորդագրություն։ Կոնվենցիայով, հրամանի տողի առաջին արգումենտը միշտ մեթոդ է, իսկ մնացած արգումենտները նրա պարամետրերն են:
OpenShift-ում CIFS բաժնետոմսերի միացման դիագրամ: Flexvolume Driver - հենց կենտրոնում
Մեթոդների նվազագույն փաթեթ կարծես սա:
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}
}
Օգտագործելով մեթոդներ attach и detach կսահմանի այն սցենարը, որով կուբելետը կգործի ապագայում վարորդին կանչելիս: Կան նաև հատուկ մեթոդներ expandvolume и expandfs, որոնք պատասխանատու են ձայնի դինամիկ չափափոխման համար։
Որպես փոփոխությունների օրինակ, որը ավելացնում է մեթոդը expandvolume, և դրա հետ միասին ծավալները իրական ժամանակում չափափոխելու ունակությամբ կարող եք ծանոթանալ մեր ձգման խնդրանքը Rook Ceph Operator-ում:
Եվ ահա NFS-ի հետ աշխատելու համար Flexvolume վարորդի ներդրման օրինակ.
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
Այսպիսով, իրական գործարկվող ֆայլը պատրաստելուց հետո դուք պետք է վերբեռնեք դրայվերը Kubernetes կլաստերի վրա. Վարորդը պետք է տեղակայվի յուրաքանչյուր կլաստերի հանգույցում՝ ըստ կանխորոշված ճանապարհի: Լռելյայն ընտրվել է.
... բայց Kubernetes-ի տարբեր բաշխումներ օգտագործելիս (OpenShift, Rancher...) ուղին կարող է տարբեր լինել:
Flexvolume-ի խնդիրներ. ինչպե՞ս ճիշտ գցել ձկնորսական գավազանը:
Flexvolume դրայվերը կլաստերային հանգույցների վրա բեռնելը պարզվեց, որ աննշան խնդիր էր: Մեկ անգամ կատարելով գործողությունը ձեռքով, հեշտ է հանդիպել մի իրավիճակի, երբ նոր հանգույցներ են հայտնվում կլաստերում՝ նոր հանգույցի ավելացման, ավտոմատ հորիզոնական մասշտաբի կամ, որ ավելի վատ է, հանգույցի փոխարինման պատճառով անսարքության պատճառով: Այս դեպքում պետք է աշխատել այս հանգույցների պահեստավորման հետ անհնար է, մինչև դեռ ձեռքով չավելացնեք նրանց մեջ Flexvolume դրայվերը:
Այս խնդրի լուծումը Kubernetes-ի պրիմիտիվներից մեկն էր. DaemonSet. Երբ կլաստերում հայտնվում է նոր հանգույց, այն ավտոմատ կերպով պարունակում է մեր DaemonSet-ի մի պատիճ, որին կցվում է տեղական ծավալ՝ Flexvolume դրայվերները գտնելու ճանապարհին: Հաջողությամբ ստեղծվելուց հետո պատիճը պատճենում է անհրաժեշտ ֆայլերը, որպեսզի վարորդը աշխատի սկավառակի վրա:
Ահա այսպիսի DaemonSet-ի օրինակ՝ Flexvolume հավելվածը տեղադրելու համար.
... և Flexvolume դրայվերը տեղադրելու համար Bash սցենարի օրինակ.
#!/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
Կարևոր է չմոռանալ, որ պատճենահանման գործողությունը ատոմային չէ. Մեծ հավանականություն կա, որ kubelet-ը կսկսի օգտագործել վարորդը նախքան իր տրամադրման գործընթացի ավարտը, ինչը կհանգեցնի համակարգի խափանման: Ճիշտ մոտեցումն այն է, որ նախ պատճենեք վարորդի ֆայլերը այլ անունով, այնուհետև օգտագործեք ատոմային անվանափոխության գործողություն:
Ceph-ի հետ աշխատելու դիագրամ Rook օպերատորում. դիագրամում Flexvolume դրայվերը գտնվում է Rook գործակալի ներսում:
Flexvolume դրայվերների օգտագործման հաջորդ խնդիրն այն է, որ պահեստավորման մեծ մասը կլաստերի հանգույցում է դրա համար անհրաժեշտ ծրագրակազմը պետք է տեղադրվի (օրինակ, ceph-common փաթեթը Ceph-ի համար): Սկզբում Flexvolume plugin-ը նախատեսված չէր նման բարդ համակարգերի ներդրման համար:
Այս խնդրի օրիգինալ լուծումը կարելի է տեսնել Rook օպերատորի Flexvolume դրայվերի ներդրման մեջ.
Վարորդն ինքնին նախագծված է որպես RPC հաճախորդ: IPC կապի վարդակից գտնվում է նույն գրացուցակում, ինչ վարորդը: Մենք հիշում ենք, որ վարորդների ֆայլերը պատճենելու համար լավ կլինի օգտագործել DaemonSet-ը, որը գրացուցակը կապում է վարորդի հետ որպես ծավալ: Rook driver-ի անհրաժեշտ ֆայլերը պատճենելուց հետո այս պատիճը չի մեռնում, այլ միանում է IPC վարդակին կցված ծավալի միջոցով՝ որպես լիարժեք RPC սերվեր: Ceph-common փաթեթն արդեն տեղադրված է պատիճ կոնտեյների ներսում: IPC վարդակից ապահովում է, որ kubelet-ը կշփվի հենց այն պատի հետ, որը գտնվում է նույն հանգույցի վրա: Ամեն ինչ հնարամիտ պարզ է..
Մնաս բարով, մեր սիրալիր... ծառի մեջ գտնվող պլագիններ:
Kubernetes-ի ծրագրավորողները հայտնաբերել են, որ միջուկում պահեստավորման համար նախատեսված հավելումների թիվը քսան է: Եվ դրանցից յուրաքանչյուրի փոփոխությունը, այսպես թե այնպես, անցնում է Kubernetes-ի թողարկման ամբողջական ցիկլով:
Պարզվում է, որ պահեստավորման հավելվածի նոր տարբերակը օգտագործելու համար, դուք պետք է թարմացնեք ամբողջ կլաստերը. Ի հավելումն սրան, դուք կարող եք զարմանալ, որ Kubernetes-ի նոր տարբերակը հանկարծ անհամատեղելի կդառնա ձեր օգտագործած Linux միջուկի հետ... Այսպիսով, դուք մաքրում եք արցունքներդ և ատամները կրճտացնելով համակարգում եք ձեր ղեկավարության և օգտատերերի հետ ժամանակը. թարմացնել Linux միջուկը և Kubernetes կլաստերը: Ծառայությունների մատուցման հնարավոր պարապուրդով:
Իրավիճակն ավելի քան զավեշտական է, չե՞ք կարծում: Ամբողջ համայնքի համար պարզ դարձավ, որ մոտեցումը չի աշխատում։ Կամավոր որոշմամբ Kubernetes-ի ծրագրավորողները հայտարարում են, որ պահեստավորման հետ աշխատելու նոր պլագիններն այլևս չեն ընդունվի միջուկում։ Բացի այդ, ինչպես արդեն գիտենք, Flexvolume plugin-ի ներդրման ժամանակ հայտնաբերվել են մի շարք թերություններ...
Kubernetes-ի ծավալների համար վերջին ավելացված պլագինը՝ CSI, կոչ արվեց մեկընդմիշտ փակել խնդիրը մշտական տվյալների պահպանման հետ: Դրա ալֆա տարբերակը, որն ավելի ամբողջությամբ կոչվում է «Out-of-Tree CSI Volume Plugins», հայտարարվել է թողարկման մեջ: Կուբերնեթ 1.9.
Բեռնարկղերի պահեստավորման միջերես կամ CSI 3000 պտտվող ձող:
Նախ ուզում եմ նշել, որ CSI-ն ոչ միայն ծավալային պլագին է, այլ իրական стандарт տվյալների պահեստների հետ աշխատելու համար հատուկ բաղադրիչներ ստեղծելու մասին. Կոնտեյներային նվագախմբային համակարգերը, ինչպիսիք են Kubernetes-ը և Mesos-ը, պետք է «սովորեին», թե ինչպես աշխատել այս ստանդարտի համաձայն իրականացվող բաղադրիչների հետ: Իսկ հիմա ես արդեն սովորել եմ Kubernetes-ը։
Ի՞նչ կառուցվածք ունի CSI plugin-ը Kubernetes-ում: CSI plugin-ն աշխատում է հատուկ դրայվերների հետ (CSI վարորդներ) գրված է երրորդ կողմի մշակողների կողմից: Kubernetes-ում CSI վարորդը պետք է նվազագույնը բաղկացած լինի երկու բաղադրիչից (pods).
Հատուկ արարիչ սարք — կառավարում է արտաքին կայուն պահեստները: Այն իրականացվում է որպես gRPC սերվեր, որի համար օգտագործվում է պարզունակը StatefulSet.
Հանգույց - պատասխանատու է կլաստերային հանգույցներում կայուն պահեստավորման տեղադրման համար: Այն նաև ներդրված է որպես gRPC սերվեր, բայց այն օգտագործում է պարզունակ DaemonSet.
Ինչպես է CSI plugin-ն աշխատում Kubernetes-ում
CSI-ի աշխատանքի այլ մանրամասների մասին կարող եք ծանոթանալ, օրինակ, հոդվածից «Հասկանալով C.S.I.' որի թարգմանությունը մենք հրապարակել ենք մեկ տարի առաջ։
Նման իրականացման առավելությունները
Հիմնական բաների համար, ինչպիսիք են հանգույցի համար վարորդ գրանցելը, Kubernetes-ի մշակողները ներդրեցին կոնտեյներների մի շարք: Դուք այլևս կարիք չունեք ինքներդ JSON պատասխան ստեղծելու հնարավորություններով, ինչպես դա արվեց Flexvolume հավելվածի համար:
Գործարկվող ֆայլերը հանգույցների վրա «սայթաքելու» փոխարեն, մենք այժմ բլոկներ ենք վերբեռնում կլաստերի մեջ: Սա այն է, ինչ մենք ի սկզբանե ակնկալում ենք Kubernetes-ից. բոլոր գործընթացները տեղի են ունենում բեռնարկղերի ներսում, որոնք տեղակայված են Kubernetes պրիմիտիվների միջոցով:
Բարդ դրայվերներ իրականացնելու համար այլևս կարիք չկա մշակել RPC սերվեր և RPC հաճախորդ: Հաճախորդը մեզ համար իրականացվել է Kubernetes-ի մշակողների կողմից:
Փաստարկների փոխանցումը gRPC արձանագրության վրա աշխատելու համար շատ ավելի հարմար, ճկուն և հուսալի է, քան հրամանի տողի փաստարկների միջոցով: Հասկանալու համար, թե ինչպես կարելի է CSI-ին ավելացնել ծավալի օգտագործման չափման աջակցություն՝ ավելացնելով ստանդարտացված gRPC մեթոդ, կարող եք կարդալ. մեր ձգման խնդրանքը vsphere-csi վարորդի համար:
Հաղորդակցությունը տեղի է ունենում IPC վարդակների միջոցով, որպեսզի չշփոթվի, թե արդյոք kubelet-ը հարցումն ուղարկել է ճիշտ pod:
Այս ցանկը ձեզ ինչ-որ բան հիշեցնու՞մ է: CSI-ի առավելություններն են լուծելով այդ նույն խնդիրները, որոնք հաշվի չեն առնվել Flexvolume plugin-ը մշակելիս։
Արդյունքները
CSI-ն, որպես տվյալների պահեստների հետ փոխազդեցության համար հատուկ պլագինների ներդրման ստանդարտ, շատ ջերմ ընդունվեց համայնքի կողմից: Ավելին, իրենց առավելությունների և բազմակողմանիության շնորհիվ CSI դրայվերները ստեղծվում են նույնիսկ պահեստավորման համակարգերի համար, ինչպիսիք են Ceph կամ AWS EBS, պլագիններ, որոնց հետ աշխատելու համար ավելացվել են Kubernetes-ի հենց առաջին տարբերակում:
2019-ի սկզբին, ծառի ներդիրային հավելումներ ճանաչվել են հնացած. Մենք նախատեսում ենք շարունակել աջակցել Flexvolume plugin-ին, սակայն նոր գործառույթ չենք մշակի դրա համար:
Մենք ինքներս արդեն ունենք ceph-csi, vsphere-csi օգտագործման փորձ և պատրաստ ենք ավելացնել այս ցանկին: Առայժմ CSI-ն արագորեն հաղթահարում է իրեն տրված առաջադրանքները, բայց մենք կսպասենք և կտեսնենք:
Մի մոռացեք, որ ամեն նորը հինի լավ վերաիմաստավորում է: