معماری 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 را دقیقاً مثل یک دیسک معمولی میبیند و روی آن فایلسیستم میسازد.
یک نکته در محیط PVM اهمیت دارد: Qemu به ازای هر دیسک یا فایل ISO که برای ماشین مجازی ساخته میشود، یک LV مجزا ایجاد میکند.
چرا فایلسیستم معمولی در محیط اشتراکی کار نمیکند
برای دیدن مشکل، اول باید بدانیم هنگام نوشتن یک فایل روی دیسک دقیقاً چه اتفاقی میافتد. فرض کنید فایلی به نام report.txt را ذخیره میکنید. فایلسیستم ابتدا یک inode برای این فایل در متادیتای خودش میسازد. inode ساختاری است که اطلاعات فایل مثل سطح دسترسی، زمان ایجاد و لیست بلاکهای دیسک اختصاصیافته به آن را نگه میدارد. بعد فایلسیستم دادههای واقعی فایل را در بلاکهای آزاد دیسک مینویسد.
حالا تصور کنید همین دیسک همزمان به دو سرور متصل است و هر دو میخواهند روی آن بنویسند. سرور اول میخواهد report.txt را بنویسد و سرور دوم میخواهد backup.tar را بنویسد. هر دو به جدول بلاکهای آزاد نگاه میکنند و هر دو میبینند بلاک شمارهی ۵۰۰۰ آزاد است. سرور اول بلاک ۵۰۰۰ را به report.txt اختصاص میدهد و سرور دوم، بدون آنکه از تصمیم سرور اول خبر داشته باشد، همان بلاک ۵۰۰۰ را به backup.tar اختصاص میدهد. نتیجه این است که دادههای هر دو فایل روی هم نوشته میشود و هر دو فایل خراب میشوند.
وضعیت بدتر زمانی رخ میدهد که دو سرور یک inode یکسان را به دو فایل متفاوت اختصاص دهند. inode ستون فقرات متادیتای فایلسیستم است، پس این تداخل کل ساختار فایلسیستم را ناسازگار و حتی غیرقابل استفاده میکند.
فایلسیستم کلاستر و محدودیتهای آن
راهحل کلاسیک برای مشکل بالا، فایلسیستم کلاستر مثل GFS (Global File System) است. فایلسیستم کلاستر طوری طراحی شده که چندین سرور بتوانند همزمان و با امنیت کامل به یک فضای ذخیرهسازی مشترک دسترسی داشته باشند.
مکانیزم کار ساده است: وقتی سرور اول میخواهد دادهای بنویسد، 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 مسئول ایجاد، نگهداری و آزادسازی قفل است.
همهی دستورهایی که متادیتای 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 دیگر فعال نیست. در نتیجه قفل آزاد میشود و میزبان دیگری میتواند آن را تصاحب کند. این مکانیزم جلوی باقی ماندن قفلهای بلاتکلیف را میگیرد.
سرویس 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
مراحل زیر بهترتیب انجام میشوند. دقت کنید هر دستور روی کدام نود اجرا میشود، چون اجرای یک دستور سراسری روی همهی نودها، یا اجرای یک دستور یکباره روی همهی آنها، پیکربندی را خراب میکند.
| # | مرحله | روی کدام نود |
|---|---|---|
| ۱ | تنظیم شناسهی میزبان | همهی نودها |
| ۲ | ایجاد Physical Volume | فقط یک نود |
| ۳ | فعالسازی lvmlockd | همهی نودها |
| ۴ | ایجاد Volume Group اشتراکی | فقط یک نود |
| ۵ | شناساندن Volume Group به نودهای دیگر | نودهای باقیمانده |
| ۶ | فعالسازی قفل روی فضای ذخیرهسازی | همهی نودها |
| ۷ | مشاهدهی فضای ذخیرهسازی | فقط یک نود |
| ۸ | افزودن فضای ذخیرهسازی به PVM | Storage Manager |
۱. تنظیم شناسهی میزبان
پس از شناسایی فضای ذخیرهسازی توسط سرورها، اولین قدم پیکربندی اولیهی هر نود، تنظیم شناسهی نود است. فایل /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 را که در مراحل قبل ساختهاید وارد کنید.
روی هر فضای ذخیرهسازی 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) |