پرش به مطلب اصلی

معماری LVM در PVM

در یک پاراگراف

در کلاستر PVM چند میزبان به‌طور هم‌زمان روی یک فضای ذخیره‌سازی می‌خوانند و می‌نویسند. فایل‌سیستم معمولی در این شرایط دوام نمی‌آورد، چون دو میزبان یک بلاک آزاد را به دو فایل متفاوت اختصاص می‌دهند. Shared LVM این مشکل را با قرار دادن یک Lock Manager توزیع‌شده بین LVM و ذخیره‌سازی حل می‌کند تا هر تغییر در متادیتا در کل کلاستر به‌صورت سریالی انجام شود.

در این سند ابتدا معماری LVM پشت صحنه‌ی ذخیره‌سازی PVM را توضیح می‌دهیم و بعد پیاده‌سازی کامل Shared LVM را قدم‌به‌قدم مرور می‌کنیم: Multipath، شناسه نود، pvcreate، vgcreate --share، vgchange --lock-start و در نهایت ثبت فضای ذخیره‌سازی در Storage Manager مربوط به PVM.

اگر با خود LVM تازه‌کار هستید، از LVM چیست؟ شروع کنید. برای دیدن زنجیره‌ی کامل آماده‌سازی از RAID تا ورودی ذخیره‌سازی در PVM، معماری و پیکربندی فضای ذخیره‌سازی را بخوانید.

ساختار LVM: چیست و چرا به آن نیاز داریم​

تصور کنید سه دیسک فیزیکی با ظرفیت‌های ۵۰۰ گیگابایت، ۱ ترابایت و ۲ ترابایت در اختیار دارید. سیستم‌عامل هر کدام را یک فضای جداگانه می‌بیند، پس ذخیره کردن یک فایل ۳ ترابایتی ممکن نیست. LVM (Logical Volume Manager) لایه‌ای است که بین دیسک‌های فیزیکی و سیستم‌عامل قرار می‌گیرد و اجازه می‌دهد همه‌ی آن‌ها را در یک استخر ذخیره‌سازی ادغام کنید و سپس هر مقدار فضا که نیاز دارید از آن بردارید.

در PVM، دیسک هر ماشین مجازی به‌صورت یک Logical Volume داخل همین استخر ذخیره می‌شود. به همین دلیل، درک ساختار LVM پیش‌نیاز کار با PVM است.

سه لایه اصلی LVM: از دیسک فیزیکی تا دیسک مجازی​

ساختار LVM از سه لایه‌ی تو درتو ساخته شده است. یک سناریوی واقعی را دنبال کنیم: سروری دارید که دو دیسک /dev/sda و /dev/sdb به آن متصل است و می‌خواهید از هر دو برای ماشین‌های مجازی استفاده کنید.

پایین‌ترین لایه Physical Volume یا PV است. وقتی دیسکی مثل /dev/sda دارید و می‌خواهید وارد دنیای LVM شوید، ابتدا باید آن را به PV تبدیل کنید. در این فرآیند LVM متادیتای مخصوص خودش را در ابتدای دیسک یا پارتیشن می‌نویسد و از آن لحظه به بعد می‌تواند آن دیسک را بشناسد و مدیریت کند. در سناریوی ما، هر دو دیسک به PV تبدیل می‌شوند.

لایه‌ی میانی Volume Group یا VG است و در واقع همان استخر ذخیره‌سازی شماست. VG مجموعه‌ای از یک یا چند PV است که LVM آن‌ها را به‌عنوان یک فضای واحد نمایش می‌دهد. اگر هر دو PV را در VG به نام MyPool بگذارید، حالا یک استخر واحد با مجموع ظرفیت هر دو دیسک دارید. دیگر مهم نیست داده‌ی شما روی کدام دیسک فیزیکی نشسته، چون VG همه چیز را یکپارچه نشان می‌دهد.

بالاترین لایه Logical Volume یا LV است و همان چیزی است که سیستم‌عامل به‌عنوان یک دیسک یا پارتیشن معمولی می‌شناسد. از فضای VG یک LV به اندازه‌ی ۱۰۰ گیگابایت برای ماشین مجازی اول و یک LV به اندازه‌ی ۲۰۰ گیگابایت برای ماشین مجازی دوم برمی‌دارید. سیستم‌عامل هر LV را دقیقاً مثل یک دیسک معمولی می‌بیند و روی آن فایل‌سیستم می‌سازد.

دیسک فیزیکی/dev/sdaدیسک فیزیکیدیسک فیزیکی/dev/sdbدیسک فیزیکیpv_sda · /dev/sdaPhysical Volume (PV)pv_sda · /dev/sdapv_sdb · /dev/sdbPhysical Volume (PV)pv_sdb · /dev/sdbMyPoolVolume Group (VG)MyPool۱۰۰ گیگابایتLV vm-01۱۰۰ گیگابایت۲۰۰ گیگابایتLV vm-02۲۰۰ گیگابایتoperating systemماشین vm-01operating systemoperating systemماشین vm-02operating system

یک نکته در محیط PVM اهمیت دارد: Qemu به ازای هر دیسک یا فایل ISO که برای ماشین مجازی ساخته می‌شود، یک LV مجزا ایجاد می‌کند.

چرا فایل‌سیستم معمولی در محیط اشتراکی کار نمی‌کند​

برای دیدن مشکل، اول باید بدانیم هنگام نوشتن یک فایل روی دیسک دقیقاً چه اتفاقی می‌افتد. فرض کنید فایلی به نام report.txt را ذخیره می‌کنید. فایل‌سیستم ابتدا یک inode برای این فایل در متادیتای خودش می‌سازد. inode ساختاری است که اطلاعات فایل مثل سطح دسترسی، زمان ایجاد و لیست بلاک‌های دیسک اختصاص‌یافته به آن را نگه می‌دارد. بعد فایل‌سیستم داده‌های واقعی فایل را در بلاک‌های آزاد دیسک می‌نویسد.

حالا تصور کنید همین دیسک هم‌زمان به دو سرور متصل است و هر دو می‌خواهند روی آن بنویسند. سرور اول می‌خواهد report.txt را بنویسد و سرور دوم می‌خواهد backup.tar را بنویسد. هر دو به جدول بلاک‌های آزاد نگاه می‌کنند و هر دو می‌بینند بلاک شماره‌ی ۵۰۰۰ آزاد است. سرور اول بلاک ۵۰۰۰ را به report.txt اختصاص می‌دهد و سرور دوم، بدون آنکه از تصمیم سرور اول خبر داشته باشد، همان بلاک ۵۰۰۰ را به backup.tar اختصاص می‌دهد. نتیجه این است که داده‌های هر دو فایل روی هم نوشته می‌شود و هر دو فایل خراب می‌شوند.

وضعیت بدتر زمانی رخ می‌دهد که دو سرور یک inode یکسان را به دو فایل متفاوت اختصاص دهند. inode ستون فقرات متادیتای فایل‌سیستم است، پس این تداخل کل ساختار فایل‌سیستم را ناسازگار و حتی غیرقابل استفاده می‌کند.

فایل‌سیستم کلاستر و محدودیت‌های آن​

راه‌حل کلاسیک برای مشکل بالا، فایل‌سیستم کلاستر مثل GFS (Global File System) است. فایل‌سیستم کلاستر طوری طراحی شده که چندین سرور بتوانند هم‌زمان و با امنیت کامل به یک فضای ذخیره‌سازی مشترک دسترسی داشته باشند.

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

GFS چه چیزی به ما داد

فایل‌سیستم کلاستر مسئله‌ی دسترسی هم‌زمان را حل کرد، اما هزینه‌ی عملیاتی خودش را هم آورد: وابستگی به شبکه‌ی پایدار، نگهداری quorum، و یک مدل ذخیره‌سازی دوم که باید یاد بگیرید و عیب‌یابی کنید.

رویکرد مبتنی بر GFS مشکلات خاص خودش را داشت: وابستگی به شبکه‌ی پایدار، نیاز به حفظ حداقل N/2 + 1 نود فعال، وابستگی به iLO، و پیچیدگی بالای پیاده‌سازی و نگهداری.

راه‌حل PVM: معماری Shared LVM​

برای غلبه بر محدودیت‌های GFS، در PVM از Shared LVM استفاده می‌شود. Shared LVM معماری سنتی LVM را با سرویس‌های اضافه، مکانیزم‌های قفل‌گذاری و تنظیمات ویژه گسترش می‌دهد تا چندین میزبان بدون نیاز به فایل‌سیستم کلاستر، به‌صورت امن به یک Volume Group مشترک دسترسی داشته باشند. ادامه‌ی این سند همین معماری را از پایین به بالا بررسی می‌کند.

پیکربندی Multipath برای شناسایی فضای ذخیره‌سازی اشتراکی​

وقتی یک فضای ذخیره‌سازی اشتراکی مثل SAN LUN در اختیار سرورهای کلاستر قرار می‌گیرد، اولین قدم پیکربندی Multipath روی هر سرور است. Multipath تضمین می‌کند اگر یکی از مسیرهای اتصال به ذخیره‌ساز قطع شد، مسیر جایگزین به‌صورت خودکار فعال شود و دسترسی به داده‌ها قطع نشود.

پس از پیکربندی موفق Multipath، با fdisk -l یا lsblk بررسی کنید که فضای ذخیره‌سازی اشتراکی درست شناسایی شده است.

fdisk -l
lsblk

سرویس‌های مدیریت قفل در Shared LVM​

وقتی یک Volume Group فقط توسط یک سرور استفاده می‌شود، LVM از مکانیزم قفل داخلی خودش استفاده می‌کند و سرویس اضافه‌ای لازم نیست. در محیط اشتراکی که چندین سرور به یک VG متصل هستند، وضعیت فرق می‌کند. اگر دو سرور هم‌زمان یکی دستور lvcreate و دیگری دستور lvremove را روی همان VG اجرا کنند، هر دو سعی می‌کنند متادیتای یکسان را تغییر دهند و این کار بدون هماهنگی به خرابی متادیتا و از دست رفتن دسترسی به Logical Volumeها می‌انجامد.

برای جلوگیری از این مشکل، Shared LVM از Distributed Locking استفاده می‌کند که چند سرویس اصلی آن را مدیریت می‌کنند: lvmlockd، sanlock، wdmd، plvreaper.timer و pvghamgr.timer.

پیش‌نیاز سیستم‌عامل

برای استفاده از این قابلیت باید از سیستم‌عامل el9 با نسخه‌ی ۷.۰ یا جدیدتر استفاده کنید تا همه‌ی این سرویس‌ها در دسترس باشند.

معماری قفل‌گذاری: lvmlockd و sanlock چگونه با هم کار می‌کنند​

هر زمان یک دستور مدیریتی LVM اجرا می‌شود، درخواست اول به lvmlockd می‌رود. lvmlockd یا LVM Lock Daemon سرویسی است که درخواست‌های قفل در Shared LVM را مدیریت می‌کند. این سرویس پیش از اجرای هر عملیاتی که متادیتا را تغییر می‌دهد، بررسی می‌کند که آیا قفل موردنظر در اختیار میزبان دیگری هست یا نه. اگر قفل آزاد باشد اجازه‌ی اجرا صادر می‌شود و اگر در اختیار میزبان دیگری باشد، عملیات منتظر می‌ماند یا با خطا متوقف می‌شود.

نکته‌ی کلیدی این است که lvmlockd خودش قفل‌ها را ذخیره یا نگهداری نمی‌کند؛ فقط درخواست‌ها را مدیریت می‌کند. ایجاد و نگهداری واقعی قفل‌ها بر عهده‌ی Lock Manager است یعنی sanlock یا DLM.

در این زنجیره، LVM عملیات مدیریتی را انجام می‌دهد، lvmlockd تصمیم می‌گیرد چه نوع قفلی لازم است، و sanlock مسئول ایجاد، نگهداری و آزادسازی قفل است.

ناحیه Lock Area در sanlockذخیره‌سازی اشتراکیناحیه Lock Area در sanlockLock Manager · نگهداری قفل‌هاsanlockLock Manager · نگهداری قفل‌هاتصمیم می‌گیرد چه قفلی لازم استlvmlockdتصمیم می‌گیرد چه قفلی لازم استlvcreate، vgextend و ...دستور LVMlvcreate، vgextend و ...

همه‌ی دستورهایی که متادیتای LVM را تغییر می‌دهند باید قبل از اجرا قفل مناسب را بگیرند: pvcreate، pvremove، vgcreate، vgextend، vgreduce، vgremove، lvcreate، lvremove، lvextend، lvreduce، lvrename و lvconvert.

انواع قفل‌ها در lvmlockd​

نوع قفلدامنهعملیات معمول
Global Lockبزرگ‌ترین قفل در LVM که از عملیات سراسری محافظت می‌کند. در هر لحظه فقط یک میزبان می‌تواند آن را در اختیار داشته باشد.ایجاد یا حذف Volume Group، تغییر ساختار کلی متادیتا، عملیات مربوط به PVها
VG Lockمتادیتای یک Volume Group خاصlvcreate، lvremove، vgextend، vgreduce روی همان VG
LV Lockیک Logical Volume خاص، برای کنترل دسترسی به آنمحدود کردن فعال‌سازی LV به یک میزبان، مثلاً برای LV یک پایگاه داده

هر زمان عملیاتی مثل lvcreate، lvremove، vgextend یا vgreduce روی یک VG انجام می‌شود، ابتدا قفل همان VG گرفته می‌شود تا فقط یک میزبان در هر لحظه بتواند متادیتای آن را تغییر دهد.

قفل‌گذاری مبتنی بر ذخیره‌ساز در sanlock​

سرویس sanlock یک Distributed Lock Manager مبتنی بر ذخیره‌ساز است. برخلاف بسیاری از Lock Managerها که اطلاعات قفل را از طریق شبکه بین سرورها رد و بدل می‌کنند، sanlock اطلاعات قفل را مستقیماً روی فضای ذخیره‌سازی مشترک می‌نویسد. در واقع فضای ذخیره‌سازی مشترک مرجع اصلی وضعیت قفل‌ها است و همه‌ی میزبان‌ها وضعیت را از همان‌جا می‌خوانند.

سه میزبان متصل به یک SAN را در نظر بگیرید. وقتی دستوری در LVM وارد می‌شود، LVM درخواست قفل را به lvmlockd می‌فرستد. lvmlockd از sanlock درخواست قفل می‌کند. sanlock وضعیت قفل را در ناحیه‌ی Lock Area روی ذخیره‌ساز ثبت می‌کند. اگر قفل آزاد باشد اجازه‌ی اجرا صادر می‌شود و پس از اتمام عملیات، قفل آزاد می‌شود.

مفهوم Lease در sanlock​

مفهوم اصلی sanlock بر پایه‌ی Lease یا مالکیت موقت یک منبع بنا شده است. تا زمانی که Lease در اختیار یک میزبان است، میزبان‌های دیگر اجازه تغییر متادیتا را ندارند. میزبانی که قفل را در اختیار دارد، به‌صورت دوره‌ای Lease خود را تمدید می‌کند تا نشان دهد هنوز فعال است.

حالا سناریوی از کار افتادن یک میزبان را در نظر بگیرید. فرض کنید Host1 قفل VG را در اختیار دارد و ناگهان از کار می‌افتد. در این حالت Lease دیگر تمدید نمی‌شود. پس از انقضای زمان تعیین‌شده (Lease Timeout)، sanlock متوجه می‌شود که Host1 دیگر فعال نیست. در نتیجه قفل آزاد می‌شود و میزبان دیگری می‌تواند آن را تصاحب کند. این مکانیزم جلوی باقی ماندن قفل‌های بلاتکلیف را می‌گیرد.

در حالی که قفل VG را در اختیار داردHost1 از کار می‌افتددر حالی که قفل VG را در اختیار داردزمان Lease Timeout تمام می‌شودLease تمدید نمی‌شودزمان Lease Timeout تمام می‌شودLease Timeout منقضی شده استsanlock قفل را آزاد می‌کندLease Timeout منقضی شده استتغییر متادیتا از سرگرفته می‌شودHost2 قفل را تصاحب می‌کندتغییر متادیتا از سرگرفته می‌شود

سرویس wdmd: نگهبان سلامت سیستم​

سرویس wdmd مسئول مدیریت Watchdog سخت‌افزاری یا نرم‌افزاری سیستم است و یکی از مکانیزم‌های حفاظتی sanlock به حساب می‌رود.

این سناریو را دنبال کنید: دو میزبان داریم و Host1 قفل VG را در اختیار دارد و ناگهان دچار Kernel Hang می‌شود. در این وضعیت، قفل هنوز متعلق به Host1 است و sanlock دیگر نمی‌تواند Lease را تمدید کند. Host2 منتظر آزاد شدن قفل می‌ماند، اما اگر Host1 هرگز خاموش نشود، قفل ممکن است برای همیشه بلاتکلیف بماند.

اینجاست که wdmd وارد عمل می‌شود. این سرویس به‌صورت مرتب بررسی می‌کند که sanlock سالم است یا نه. اگر sanlock نتواند Lease را تمدید کند، wdmd متوجه می‌شود وضعیت سیستم خطرناک است و به Watchdog دستور می‌دهد سیستم را ریست کند. پس از ریست شدن Host1، میزبان دوم می‌تواند قفل را بگیرد و از خرابی متادیتا جلوگیری شود.

سرویس plvreaper.timer: پاک‌سازی دیسک‌های غیرفعال​

این سرویس را تیم توسعه‌ی PVM نوشته است. وظیفه‌اش غیرفعال کردن LVهایی است که روی یک نود فعال هستند اما بیش از یک دقیقه هیچ عملیات ورودی/خروجی روی آن‌ها انجام نشده است. این وضعیت معمولاً زمانی رخ می‌دهد که یک ماشین مجازی خاموش شده اما دیسک آن همچنان فعال مانده و دیگر قابل استفاده توسط ماشین مجازی دیگری نیست. plvreaper.timer این دیسک‌های رهاشده را شناسایی و غیرفعال می‌کند تا منابع آزاد شوند.

پیاده‌سازی Shared LVM​

مراحل زیر به‌ترتیب انجام می‌شوند. دقت کنید هر دستور روی کدام نود اجرا می‌شود، چون اجرای یک دستور سراسری روی همه‌ی نودها، یا اجرای یک دستور یک‌باره روی همه‌ی آن‌ها، پیکربندی را خراب می‌کند.

۱. تنظیم شناسه‌ی میزبان​

پس از شناسایی فضای ذخیره‌سازی توسط سرورها، اولین قدم پیکربندی اولیه‌ی هر نود، تنظیم شناسه‌ی نود است. فایل /etc/lvm/lvmlocal.conf را روی هر نود باز کنید و در بخش host_id شماره‌ی نودی را که در sbone تعریف کرده‌اید وارد کنید. این کار باید روی همه‌ی نودها انجام شود و هر نود باید شناسه‌ی منحصربه‌فرد خودش را داشته باشد.

# /etc/lvm/lvmlocal.conf
host_id = 1

۲. ایجاد Physical Volume​

سپس باید روی هر LUN که به کلاستر اضافه شده PV ایجاد کنید. توجه داشته باشید که به ازای هر LV (دیسک) یا VG که ساخته می‌شود، حدود ۲۰ کیلوبایت فضای متادیتا اشغال می‌شود. به همین دلیل فضای متادیتای PV را به‌صورت پیش‌فرض روی ۱ گیگابایت تنظیم می‌کنیم تا امکان ایجاد حدود ۵۲٬۴۲۸ عدد LV فراهم شود. این دستور باید فقط روی یکی از سرورهای کلاستر اجرا شود:

pvcreate --metadatasize 1G /dev/mapper/test

در اینجا /dev/mapper/test نام فضای ذخیره‌سازی شماست.

۳. فعال‌سازی lvmlockd​

فایل /etc/lvm/lvm.conf را باز کنید، گزینه‌ی use_lvmlockd را از حالت توضیح خارج کنید و مقدار آن را برابر ۱ بگذارید. سپس سرویس را ریستارت کنید:

vi /etc/lvm/lvm.conf
systemctl restart lvmlockd.service

این مرحله باید روی همه‌ی نودهای کلاستر انجام شود.

۴. ایجاد Volume Group اشتراکی​

روی هر PV که برای هر LUN ذخیره‌سازی ایجاد کرده‌اید، باید یک VG بسازید:

vgcreate --share --locktype sanlock S1 /dev/mapper/test

پارامتر --share مشخص می‌کند که VG باید از نوع اشتراکی باشد. --locktype sanlock نوع قفل را sanlock تعیین می‌کند. S1 نام Volume Group است و /dev/mapper/test نام فضای ذخیره‌سازی. این دستور هم باید فقط روی یکی از سرورهای کلاستر اجرا شود.

۵. شناساندن Volume Group به نودهای دیگر​

پس از ایجاد VG روی یک نود، ممکن است نودهای دیگر کلاستر آن را نشناسند. برای رفع این مشکل، دستور زیر را روی سرورهای دیگر کلاستر اجرا کنید تا LVM آن‌ها فضای ذخیره‌سازی را شناسایی کند:

lvmdevices --adddev /dev/mapper/test

۶. فعال‌سازی قفل روی فضای ذخیره‌سازی​

برای فعال کردن قفل ذخیره‌سازی‌ای که ساخته‌اید، دستور زیر را اجرا کنید:

vgchange --lock-start S1

این دستور باید روی همه‌ی نودهای کلاستر اجرا شود.

این دستور را روی فضای زیر بار اجرا نکنید

دستور vgchange --lock-start را روی فضای ذخیره‌سازی‌ای که از قبل پیکربندی شده و زیر بار است اجرا نکنید، چون ممکن است اختلال در سرویس‌دهی ایجاد کند.

۷. مشاهده‌ی فضای ذخیره‌سازی​

در این مرحله پیکربندی LVM کامل شده است. برای مشاهده‌ی فضاهای ذخیره‌سازی ایجادشده، دستور زیر را اجرا کنید:

pvgs

این دستور نام فضای ذخیره‌سازی ایجادشده، حجم کل و حجم آزاد، میزبان‌هایی (نودهایی) که از آن استفاده می‌کنند و وضعیت هر نود را نمایش می‌دهد.

۸. افزودن فضای ذخیره‌سازی به PVM​

در بخش Storage Manager یک فضای ذخیره‌سازی جدید اضافه کنید و نوع آن را روی volume group بگذارید. سپس نام فضای ذخیره‌سازی LVM را که در مراحل قبل ساخته‌اید وارد کنید.

برای هر فضای ذخیره‌سازی فقط یک فضای داده و یک فضای ISO

روی هر فضای ذخیره‌سازی LVM فقط می‌توانید یک فضا برای داده و یک فضا برای ISO در مدیریت‌کننده ایجاد کنید. اگر چند فضای ذخیره‌سازی دارید، ISO را فقط روی یکی از آن‌ها در کنار داده ایجاد کنید و از ساختن چند فضای ISO جداگانه خودداری کنید.

جمع‌بندی​

موضوعپاسخ
چرا فایل‌سیستم معمولی نهدو میزبان یک بلاک آزاد را به دو فایل متفاوت اختصاص می‌دهند و هر دو فایل خراب می‌شود
چرا GFS نهوابستگی به شبکه و quorum، وابستگی به iLO و پیچیدگی بالای بهره‌برداری
Shared LVM چه چیزی اضافه می‌کندlvmlockd برای مدیریت درخواست‌ها، sanlock برای قفل‌گذاری توزیع‌شده روی ذخیره‌سازی، wdmd برای حفاظت با Watchdog
وضعیت قفل‌ها کجا نگهداری می‌شودخودِ فضای ذخیره‌سازی مشترک، از طریق ناحیه‌ی Lock Area در sanlock
قفل میزبان از کار افتاده چطور آزاد می‌شودLease در sanlock، پس از انقضای Lease Timeout
دستورهای یک‌باره روی چه چیزی اجرا می‌شوندفقط یکی از سرورهای کلاستر (pvcreate، vgcreate)
دستورهای سراسری روی چه چیزی اجرا می‌شوندهمه‌ی نودها (host_id، lvmlockd، vgchange --lock-start)