پلاگین های حجمی برای ذخیره سازی Kubernetes: از Flexvolume تا CSI

پلاگین های حجمی برای ذخیره سازی Kubernetes: از Flexvolume تا CSI

زمانی که Kubernetes هنوز نسخه 1.0.0 بود، پلاگین های حجمی وجود داشت. آنها برای اتصال سیستم‌ها به Kubernetes برای ذخیره داده‌های کانتینری دائمی (دائمی) مورد نیاز بودند. تعداد آنها کم بود و از جمله اولین ارائه دهندگان ذخیره سازی مانند GCE PD، Ceph، AWS EBS و دیگران بودند.

پلاگین ها همراه با Kubernetes تحویل داده شدند، به همین دلیل نام خود را - in-tree گرفتند. با این حال، برای بسیاری، مجموعه موجود از چنین پلاگین هایی ناکافی بود. صنعتگران پلاگین های ساده ای را با استفاده از وصله ها به هسته Kubernetes اضافه کردند و پس از آن Kubernetes خود را مونتاژ کردند و آن را روی سرورهای خود نصب کردند. اما با گذشت زمان، توسعه دهندگان Kubernetes متوجه این موضوع شدند ماهی مشکل قابل حل نیست مردم نیاز دارند میله ماهیگیری. و در انتشار Kubernetes v1.2.0 ظاهر شد ...

پلاگین Flexvolume: حداقل چوب ماهیگیری

توسعه دهندگان Kubernetes پلاگین FlexVolume را ایجاد کردند که یک چارچوب منطقی از متغیرها و روش های کار با درایورهای Flexvolume بود که توسط توسعه دهندگان شخص ثالث پیاده سازی شده بود.

بیایید توقف کنیم و نگاهی دقیق تر به درایور FlexVolume بیاندازیم. این یک امر مسلم است فایل اجرایی (فایل باینری، اسکریپت پایتون، اسکریپت Bash و غیره)، که هنگام اجرا، آرگومان های خط فرمان را به عنوان ورودی می گیرد و پیامی با فیلدهای از پیش شناخته شده در قالب JSON برمی گرداند. طبق قرارداد، اولین آرگومان خط فرمان همیشه یک متد است و آرگومان های باقیمانده پارامترهای آن هستند.

پلاگین های حجمی برای ذخیره سازی Kubernetes: از Flexvolume تا CSI
نمودار اتصال برای سهام CIFS در OpenShift. درایور Flexvolume - درست در مرکز

حداقل مجموعه ای از روش ها به نظر می رسد این:

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.

و در اینجا نمونه ای از اجرای درایور Flexvolume برای کار با 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

بنابراین، پس از تهیه فایل اجرایی واقعی، باید درایور را در خوشه Kubernetes آپلود کنید. درایور باید در هر گره خوشه ای طبق یک مسیر از پیش تعیین شده قرار گیرد. به طور پیش فرض انتخاب شد:

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

... اما هنگام استفاده از توزیع های مختلف Kubernetes (OpenShift، Rancher...) ممکن است مسیر متفاوت باشد.

مشکلات Flexvolume: چگونه میله ماهیگیری را به درستی ریخته کنیم؟

آپلود درایور Flexvolume در گره های خوشه ای یک کار غیر ضروری بود. با انجام یک بار عملیات به صورت دستی، به راحتی می توان با موقعیتی مواجه شد که گره های جدیدی در خوشه ظاهر می شوند: به دلیل اضافه شدن یک گره جدید، مقیاس بندی خودکار افقی، یا - بدتر از آن - جایگزینی یک گره به دلیل نقص. در این صورت کار با ذخیره سازی روی این گره ها باید انجام شود غیرممکن است، تا زمانی که هنوز به صورت دستی درایور Flexvolume را به آنها اضافه کنید.

راه حل این مشکل یکی از اولیه های کوبرنتیس بود - DaemonSet. هنگامی که یک گره جدید در خوشه ظاهر می شود، به طور خودکار حاوی یک پاد از DaemonSet ما است که یک حجم محلی در طول مسیر برای یافتن درایورهای Flexvolume به آن متصل می شود. پس از ایجاد موفقیت آمیز، پاد فایل های لازم را برای کار درایور روی دیسک کپی می کند.

در اینجا نمونه ای از چنین DaemonSet برای چیدمان یک افزونه 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>

... و نمونه ای از اسکریپت Bash برای چیدمان درایور 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

مهم این است که عملیات کپی را فراموش نکنید اتمی نیست. احتمال زیادی وجود دارد که kubelet قبل از تکمیل فرآیند تهیه، شروع به استفاده از درایور کند و باعث از کار افتادن سیستم شود. روش صحیح این است که ابتدا فایل های درایور را با نام دیگری کپی کنید و سپس از عملیات تغییر نام اتمی استفاده کنید.

پلاگین های حجمی برای ذخیره سازی Kubernetes: از Flexvolume تا CSI
نمودار کار با Ceph در اپراتور Rook: درایور Flexvolume در نمودار در داخل عامل Rook قرار دارد.

مشکل بعدی هنگام استفاده از درایورهای Flexvolume این است که برای بیشتر فضای ذخیره سازی در یک گره خوشه ای نرم افزار لازم برای این کار باید نصب شود (به عنوان مثال، بسته ceph-common برای Ceph). در ابتدا، پلاگین Flexvolume برای پیاده سازی چنین سیستم های پیچیده ای طراحی نشده بود.

یک راه حل اصلی برای این مشکل را می توان در اجرای درایور Flexvolume اپراتور Rook مشاهده کرد:

خود درایور به عنوان یک کلاینت RPC طراحی شده است. سوکت IPC برای ارتباط در همان دایرکتوری خود درایور قرار دارد. ما به یاد داریم که برای کپی کردن فایل های درایور خوب است از DaemonSet استفاده کنیم که دایرکتوری را به عنوان یک حجم به درایور متصل می کند. پس از کپی کردن فایل‌های درایور rook لازم، این پاد از بین نمی‌رود، بلکه از طریق ولوم پیوست شده به عنوان یک سرور RPC تمام عیار به سوکت IPC متصل می‌شود. بسته ceph-common قبلاً در داخل ظرف غلاف نصب شده است. سوکت IPC تضمین می کند که کوبلت دقیقاً با غلافی که در همان گره قرار دارد ارتباط برقرار می کند. همه چیز مبتکرانه ساده است!..

خداحافظ، پلاگین های... درون درختی ما!

توسعه دهندگان Kubernetes کشف کردند که تعداد پلاگین ها برای ذخیره سازی در هسته بیست است. و تغییر در هر یک از آنها، به هر شکلی، از طریق چرخه کامل انتشار Kubernetes می گذرد.

به نظر می رسد که برای استفاده از نسخه جدید افزونه ذخیره سازی، شما باید کل خوشه را به روز کنید. علاوه بر این، ممکن است تعجب کنید که نسخه جدید Kubernetes به طور ناگهانی با هسته لینوکس مورد استفاده شما ناسازگار می شود... بنابراین اشک های خود را پاک می کنید و با دندان قروچه، با مدیریت و کاربران هماهنگ می کنید هسته لینوکس و خوشه Kubernetes را به روز کنید. با توقف احتمالی در ارائه خدمات.

وضعیت فراتر از خنده دار است، فکر نمی کنید؟ برای کل جامعه روشن شد که این رویکرد کارساز نبود. با یک تصمیم عمدی، توسعه دهندگان Kubernetes اعلام می کنند که پلاگین های جدید برای کار با فضای ذخیره سازی دیگر در هسته پذیرفته نمی شوند. علاوه بر این، همانطور که می دانیم، در پیاده سازی افزونه Flexvolume یکسری کاستی ها شناسایی شد...

آخرین افزونه اضافه شده برای حجم در Kubernetes، CSI، درخواست شد تا مشکل را با ذخیره سازی داده ها یک بار برای همیشه ببندد. نسخه آلفا آن، که به طور کامل به عنوان افزونه های حجم CSI خارج از درخت شناخته می شود، در نسخه منتشر شد. Kubernetes 1.9.

رابط ذخیره سازی کانتینر یا میله چرخشی CSI 3000!

اول از همه، من می خواهم توجه داشته باشم که CSI فقط یک افزونه حجم نیست، بلکه واقعی است استاندارد در ایجاد اجزای سفارشی برای کار با انبارهای داده. قرار بود سیستم های ارکستراسیون کانتینری مانند Kubernetes و Mesos نحوه کار با اجزای پیاده سازی شده بر اساس این استاندارد را "یاد بگیرند". و اکنون من قبلا Kubernetes را یاد گرفته ام.

ساختار پلاگین CSI در Kubernetes چیست؟ پلاگین CSI با درایورهای خاص کار می کند (درایورهای CSI) توسط توسعه دهندگان شخص ثالث نوشته شده است. یک درایور CSI در Kubernetes حداقل باید از دو جزء (pods) تشکیل شده باشد:

  • کنترل کننده - ذخیره‌سازی‌های دائمی خارجی را مدیریت می‌کند. این به عنوان یک سرور gRPC پیاده سازی شده است که برای آن از primitive استفاده می شود StatefulSet.
  • گره - مسئول نصب ذخیره سازی پایدار در گره های خوشه ای است. همچنین به عنوان یک سرور gRPC پیاده سازی شده است، اما از اولیه استفاده می کند DaemonSet.

پلاگین های حجمی برای ذخیره سازی Kubernetes: از Flexvolume تا CSI
چگونه پلاگین CSI در Kubernetes کار می کند

شما می توانید در مورد سایر جزئیات کار CSI، به عنوان مثال، از مقاله " یاد بگیرید.درک C.S.I." ترجمه آن یک سال پیش منتشر کردیم

مزایای چنین پیاده سازی

  • برای موارد اساسی مانند ثبت درایور برای یک گره، توسعه دهندگان Kubernetes مجموعه ای از کانتینرها را پیاده سازی کردند. مانند افزونه Flexvolume، دیگر نیازی به تولید پاسخ JSON با قابلیت‌ها ندارید.
  • به جای "لغزش" فایل های اجرایی روی گره ها، اکنون پادها را در خوشه آپلود می کنیم. این همان چیزی است که در ابتدا از Kubernetes انتظار داریم: همه فرآیندها در داخل کانتینرهایی که با استفاده از Kubernetes primitives مستقر شده اند رخ می دهند.
  • دیگر نیازی به توسعه سرور RPC و کلاینت RPC برای پیاده سازی درایورهای پیچیده ندارید. کلاینت توسط توسعه دهندگان Kubernetes برای ما پیاده سازی شده است.
  • ارسال آرگومان‌ها برای کار روی پروتکل gRPC بسیار راحت‌تر، انعطاف‌پذیرتر و قابل اعتمادتر از انتقال آن‌ها از طریق آرگومان‌های خط فرمان است. برای درک نحوه اضافه کردن پشتیبانی از معیارهای استفاده از حجم به CSI با افزودن یک روش استاندارد gRPC، می‌توانید بخوانید: درخواست کشش ما برای درایور vsphere-csi.
  • ارتباط از طریق سوکت های IPC انجام می شود، به طوری که گیج نشوید که آیا Kubelet درخواست را به pod صحیح ارسال کرده است یا خیر.

آیا این لیست شما را به یاد چیزی می اندازد؟ مزایای CSI عبارتند از حل همان مشکلات، که در هنگام توسعه افزونه Flexvolume مورد توجه قرار نگرفتند.

یافته ها

CSI به عنوان یک استاندارد برای پیاده سازی پلاگین های سفارشی برای تعامل با انبارهای داده، بسیار مورد استقبال جامعه قرار گرفت. علاوه بر این، به دلیل مزایا و تطبیق پذیری آنها، درایورهای CSI حتی برای سیستم های ذخیره سازی مانند Ceph یا AWS EBS ایجاد می شوند، پلاگین هایی برای کار با آنها در اولین نسخه Kubernetes اضافه شده است.

در ابتدای سال 2019، افزونه های درون درختی منسوخ اعلام شده اند. ما قصد داریم به پشتیبانی از افزونه Flexvolume ادامه دهیم، اما عملکرد جدیدی برای آن ایجاد نخواهیم کرد.

ما خودمان قبلاً تجربه استفاده از ceph-csi، vsphere-csi را داریم و آماده ایم به این لیست اضافه کنیم! تا کنون، CSI با وظایف محول شده به آن با سر و صدا کنار می آید، اما ما منتظر می مانیم و خواهیم دید.

فراموش نکنید که هر چیز جدید یک تجدید نظر خوب در مورد قبلی است!

PS

در وبلاگ ما نیز بخوانید:

منبع: www.habr.com

اضافه کردن نظر