تفاوت KVM و Xen با LXC در سرور مجازی VPS
تکنولوژی مجازیسازی VPS شما تعیینکننده دسترسی به kernel اختصاصی، swap واقعی و nested virtualization است. در این مطلب تفاوت فنی KVM، Xen و LXC را برای درک بهتر منابع سرور بررسی میکنیم.
آنچه پلن VPS شما در واقع به فروش میرساند
KVM، Xen و LXC سه خانواده مجازیسازی هستند که یک پلن VPS بر پایه آنها ساخته میشود و انتخاب بین آنها، جزئیاتی مربوط به رکهای ارائهدهنده نیست. این انتخاب تعیین میکند که آیا شما هسته (kernel) اختصاصی خود را دارید یا خیر. هر آنچه برای خریدار اهمیت دارد، از همین یک واقعیت ناشی میشود: بارگذاری ماژولها، کنترل swap، اجرای مجازیسازی تو در تو (nested virtualization)، اینکه آیا /proc سرور شما را توصیف میکند یا سرور شخص دیگری را، و اینکه آیا steal time اصلاً قابل اندازهگیری است یا خیر.
مجازیسازی کامل (KVM و Xen HVM) به هر مستأجر یک هسته و یک ماشین مجازی میدهد. Xen نیمهمجازیسازیشده (Paravirtualised) نیز به شما یک هسته میدهد، اما هستهای که میداند یک مهمان است و از هایپروایزر میخواهد کارهای دارای سطح دسترسی بالا (privileged) را برایش انجام دهد. یک پلن کانتینری (LXC، یا خانواده OpenVZ و Virtuozzo) به شما یک سیستم فایل و مجموعهای از namespaceها روی هسته ارائهدهنده میدهد. هر سه مورد تحت همان سه حرف (VPS) به فروش میرسند.
مقایسه KVM و Xen با LXC: هسته اختصاصی در برابر هسته اشتراکی
در KVM و Xen، عبارت uname -r تعیینکننده هسته شماست. شما میتوانید هسته متفاوتی نصب کنید، ماژولی را در آن بارگذاری کنید و سیستم را با آن راهاندازی مجدد کنید. هیچکدام از این اقدامات بر مستأجران دیگر تأثیری ندارد. در طرحهای مبتنی بر کانتینر، uname -r نام هسته ارائهدهنده سرویس است که روی میزبان اجرا میشود و با تمام کانتینرهای دیگر روی آن ماشین به اشتراک گذاشته شده است. شما نمیتوانید آن را تغییر دهید و apt install linux-image-generic فایلهایی را استخراج میکند که هرگز بوت نخواهند شد.
همین تفاوت واحد، ارزشی بیش از هر برگه مشخصات فنی دارد. ادامه این راهنما را به عنوان پیامدهای ناشی از این تفاوت مطالعه کنید.
مجازیسازی کامل: KVM و Xen HVM
KVM (مخفف kernel-based virtual machine) ماژولی در هسته لینوکس است که یک میزبان لینوکسی معمولی را با استفاده از دستورالعملهای Intel VT-x یا AMD-V که در CPU تعبیه شدهاند، به یک هایپروایزر تبدیل میکند. QEMU سختافزار مجازی پیرامون آن شامل دیسک، کارت شبکه و کنسول سریال را فراهم میکند. Xen طراحی متفاوتی دارد. Xen خود یک هایپروایزر مستقل است و پیش از لینوکس بوت میشود. یک دامنه کنترلی دارای امتیاز به نام dom0 پشته مدیریتی را اجرا میکند و هر مستأجر یک domU است. Xen HVM (مخفف hardware virtual machine) از همان افزونههای CPU که KVM استفاده میکند بهره میبرد، معمولاً با درایورهای paravirtual برای دیسک و شبکه، زیرا سختافزار شبیهسازیشده کند است. این ترکیب PVHVM نامیده میشود.
برای یک مستأجر، این دو تقریباً به شکل یکسانی عمل میکنند. شما یک هسته، یک bootloader، یک دستگاه بلوک واقعی، یک modprobe فعال، یک /proc واقعی، فضای swap اختصاصی و قابلیت reboot که واقعاً سیستم را بوت میکند، در اختیار دارید. اگر ارائهدهنده به شما اجازه اتصال یک فایل ISO را بدهد، میتوانید توزیعی را نصب کنید که هرگز توسط آنها ارائه نشده است.
بهای این قابلیت، کاهش تراکم است. مقدار 4 GB رم شما به ماشینتان اختصاص یافته و در زمانی که بیکار هستید، به همسایه دیگری قرض داده نمیشود؛ همچنین هر مهمان یک پردازش QEMU، جداول صفحه (page tables) و کش صفحه (page cache) مخصوص به خود را حمل میکند. همین هزینه است که باعث میشود قیمت یک پلن KVM بالاتر از پلن کانتینری با مشخصات عددی مشابه باشد.
Xen Paravirtualised و نحوه تشخیص آن
مدل Xen PV پیش از آنکه پردازندهها از دستورالعملهای مجازیسازی پشتیبانی کنند، ابداع شد. بهجای آنکه دستورالعملهای سطح دسترسی (privileged) رهگیری شوند، هسته سیستمعامل مهمان (guest kernel) تغییر مییابد تا مستقیماً با هایپروایزر ارتباط برقرار کند. این مدل بدون نیاز به VT-x اجرا میشود که در سال 2005 هدف اصلی آن بود. هسته سیستمعامل توسط pygrub یا pvgrub از داخل ایمیج دیسک شما بارگذاری میشود؛ بنابراین این هسته متعلق به خود شماست، اما باید با پشتیبانی از PV guest کامپایل شده باشد.
نشانههایی که نشان میدهد شما از این مدل استفاده میکنید: lscpu نوع مجازیسازی را بهجای full به صورت para گزارش میدهد، فایل /sys/hypervisor/type وجود دارد و نام Xen را در خود دارد، و دیسکهای شما بهجای vda یا sda با نام xvda شناخته میشوند. ابزارهایی که جداول SMBIOS یا DMI را میخوانند، چیزی برای نمایش پیدا نمیکنند، زیرا یک PV guest هیچ فریموری برای انتشار این اطلاعات ندارد.
هزینه این مدل برای شما، از دست دادن همیشگی قابلیت nested virtualisation است. به یک PV guest هرگز افزونههای مجازیسازی CPU نشان داده نمیشود، بنابراین هیچ هایپروایزری نمیتواند درون آن اجرا شود. خود Xen منسوخ نشده است؛ بلکه مشخصاً Xen PV بخشی است که کمرنگ شده و جهتگیری پروژه به سمت PVH و HVM تغییر یافته است. اگر در یک طرح اشتراکی عبارت "Xen" را دیدید، بپرسید کدام نوع است. HVM یک VPS مدرن و معمولی است، اما PV طرحی است که باید قیمت پایینتری داشته باشد.
سرور مجازی کانتینری: LXC و خانواده OpenVZ
یک سرور مجازی کانتینری مجموعهای از namespaceهای لینوکس (دیدگاههای مجزا از شناسههای پردازش، mountها، رابطهای شبکه، نام میزبان و کاربران) به همراه cgroups (گروههای کنترل، محدودیتهای منابع در هسته) است که روی هسته سیستمعامل میزبان اجرا میشود. init شما یک پردازش روی میزبان است. ls شما مستقیماً روی هسته میزبان اجرا میشود، بدون شبیهسازی و بدون وجود زمانبند (scheduler) دوم در مسیر. به همین دلیل است که کانتینرها سریع و متراکم هستند.
نامهایی که در صفحات سفارش میبینید شامل LXC، کانتینرهای Proxmox VE (که همان LXC هستند)، OpenVZ و Virtuozzo است. OpenVZ 7 و Virtuozzo نوادگان تجاری همان ایده اولیه هستند.
چهار مورد برای شما تغییر میکند:
- ماژولها.
modprobeنمیتواند هیچ چیزی را بارگذاری (insert) کند. اگر WireGuard، ZFS یا یک ماژول خاص netfilter از قبل در هسته ارائهدهنده موجود نباشد، شما به آن دسترسی نخواهید داشت. sysctl. بخش بزرگی از/proc/sysفقطخواندنی (read-only) است. شبکه یک namespace واقعی است، بنابراینnet.ipv4.ip_forwardو فایلهای مجاور آن معمولاً قابلنوشتن هستند. تنظیمات کل سیستم مانندvm.swappinessیاfs.file-maxمتعلق به میزبان است.- کانتینرهای تو در تو (Nested). اجرای Docker داخل یک کانتینر LXC تنها زمانی کار میکند که ارائهدهنده قابلیت nesting را فعال کرده باشد و درایور ذخیرهسازی نیز با آن سازگار باشد. پیش از خرید، این مورد را تست کنید و فرض را بر وجود آن نگذارید.
- نسخه هسته. شما تابع برنامه زمانبندی ارتقای ارائهدهنده هستید، که شامل ریبوتهای سیستم نیز میشود.
چگونه تشخیص دهیم چه چیزی خریداری کردهاید
این دستورات را روی سرور اجرا کنید و پاسخها را در کنار هم تحلیل کنید. هیچ دستور واحدی به تنهایی پاسخ قطعی نمیدهد.
systemd-detect-virt
systemd-detect-virt -c
lscpu | grep -iE 'hypervisor|virtualization'
uname -r
ls /lib/modules/$(uname -r) 2>/dev/null | head -n 3
cat /sys/hypervisor/type 2>/dev/nullsystemd-detect-virt یک شناسه کوتاه از یک واژگان ثابت چاپ میکند. سمت ماشین شامل kvm، qemu، xen، amazon و vmware است. سمت کانتینر شامل lxc، lxc-libvirt، openvz، docker و systemd-nspawn است. هنگامی که چیزی تشخیص داده نشود، none را چاپ کرده و با کد خروجی غیر صفر خارج میشود. فرم -c فقط برای فناوریهای کانتینری پاسخ میدهد، بنابراین هر پاسخی غیر از none در آنجا، صرفنظر از آنچه در صفحه فروش ذکر شده، تکلیف را مشخص میکند.
lscpu نام فروشنده هایپروایزر را ذکر کرده و بیان میکند که نوع مجازیسازی کامل (full) است یا نیمهمجازی (para)؛ این همان روشی است که Xen HVM را از Xen PV متمایز میکند. /sys/hypervisor/type فقط در محیط Xen وجود دارد.
بررسی /lib/modules موردی است که افراد از آن غافل میشوند، در حالی که مستقیمترین روش است. اگر دایرکتوری مربوط به نسخه هسته (kernel) در حال اجرا وجود نداشته باشد یا خالی باشد، در حالی که سیستم به وضوح با همان هسته در حال اجراست، یعنی هسته از فایلسیستم شما نیامده است. این هسته متعلق به میزبان (host) است و درخت ماژولهای آن هرگز در ایمیج شما نصب نشده است. این یعنی شما با یک کانتینر سروکار دارید.
برای دریافت یک نظر دوم مستقل، sudo apt install -y virt-what && sudo virt-what تستهای تشخیص را به عنوان یک ابزار اختصاصی اجرا میکند. این ابزار به دسترسی root نیاز دارد و در محیط bare metal هیچ خروجیای چاپ نمیکند.
چرا /proc اطلاعات ماشین اشتباهی را در کانتینر نشان میدهد
در یک مهمان KVM یا Xen، فایل /proc/meminfo حسابداری هستهٔ خودتان از حافظهای است که هایپروایزر به شما اختصاص داده است. این اطلاعات دربارهٔ ماشین شما صحیح است و هیچ چیزی دربارهٔ میزبان (host) نمیگوید. این دقیقاً هدف از مجازیسازی است.
در یک کانتینر، هستهٔ دومی برای انجام این حسابداری وجود ندارد، بنابراین /proc همان /proc میزبان است. LXCFS یک سیستمفایل کوچک است که برخی از این فایلها را بازنویسی میکند تا با محدودیتهای cgroup شما مطابقت داشته باشند و فایلهای /proc/cpuinfo، /proc/meminfo، /proc/stat، /proc/uptime، /proc/swaps، /proc/diskstats و /sys/devices/system/cpu/online را پوشش میدهد. Proxmox بهصورت پیشفرض آن را mount میکند. بسیاری از ارائهدهندگان کوچکتر این کار را انجام نمیدهند و در نتیجه free -m کل حافظهٔ میزبان را گزارش میدهد، nproc ممکن است تمام هستههای ماشین را نشان دهد و uptime مدتزمان روشن بودن میزبان را گزارش میکند.
این موضوع صرفاً ظاهری نیست، زیرا نرمافزارها اندازهٔ خود را بر اساس این فایلها تنظیم میکنند. nginx با worker_processes auto تعداد هستههایی که میبیند را میشمارد. make -j$(nproc) روی یک میزبان 64 هستهای با سهمیهٔ 2 هسته، 64 کامپایلر را اجرا میکند. یک JVM یا دیتابیس که اندازهٔ کش خود را از MemTotal انتخاب میکند، عددی را برمیگزیند که cgroup شما آن را رد میکند و هسته، پردازش را هنگام رسیدن به محدودیت متوقف (kill) میکند. این توقف در لاگ هستهٔ میزبان ثبت میشود که شما به آن دسترسی ندارید.
اعداد معتبر در cgroup قرار دارند، نه در /proc:
cat /sys/fs/cgroup/memory.max
cat /sys/fs/cgroup/memory.current
cat /sys/fs/cgroup/cpu.maxاینها مسیرهای cgroup v2 هستند که توزیعهای فعلی از آن استفاده میکنند. مقدار memory.max در فایل max به این معنی است که هیچ محدودیتی در آن سطح تعیین نشده است. cpu.max یک سهمیه (quota) و یک دوره (period) را به میکروثانیه چاپ میکند، بنابراین 200000 100000 معادل دو هسته زمان CPU در هر دوره است. در میزبانهای قدیمیتر با cgroup v1، همان مقادیر در مسیرهای /sys/fs/cgroup/memory/memory.limit_in_bytes و /sys/fs/cgroup/cpu/cpu.cfs_quota_us قرار دارند.
Swap و مالکیت واقعی آن
در KVM و Xen، فضای swap متعلق به شماست. این فضا یک فایل یا پارتیشن روی دیسک شماست و هسته سیستمعامل شما عملیات paging را انجام میدهد.
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
swapon --showدستور swapon --show اکنون باید فایل را به همراه اندازه و اولویت آن فهرست کند. اگر swapon از پذیرش فایل خودداری کرد، آن را با dd if=/dev/zero of=/swapfile bs=1M count=2048 بسازید؛ زیرا فایلهای پیشتخصیصیافته (preallocated) که دارای extents نوشتهنشده هستند، در برخی فایلسیستمها رد میشوند. عبارت /swapfile none swap sw 0 0 را به /etc/fstab اضافه کنید، در غیر این صورت swap پس از reboot بعدی از بین میرود.
در container، هیچکدام از این موارد در اختیار شما نیست. دستور swapon به قابلیتی (capability) نیاز دارد که یک container بدون امتیاز (unprivileged) آن را در اختیار ندارد؛ بنابراین ایجاد فایل swap شخصی شما با خطای مجوز مواجه شده و هرگز به دیسک نمیرسد. آنچه در پلنهای میزبانی به عنوان swap نامیده میشود، یک تنظیم cgroup در میزبان (host) است، یعنی memory.swap.max در cgroup v2 که توسط دستگاههای swap خودِ میزبان پشتیبانی میشود. پلنهای قدیمی OpenVZ، سهمیهای تحت عنوان "vswap" ارائه میدادند که رفتار آن بیشتر به اعتبار burst شباهت داشت تا دیسک. شما میتوانید سقف این مقدار را بخوانید، اما کنترلی بر دستگاه زیرین آن ندارید.
مجازیسازی تو در تو و پرچم CPU که فریب میدهد
مجازیسازی تو در تو (Nested virtualisation) به معنای اجرای یک هایپروایزر درون VPS شماست: یک مهمان QEMU، یک Vagrant box، یا یک آزمایشگاه مجازیسازی تو در تو با ماشینهای مجازی اختصاصی. دو شرط باید همزمان برقرار باشند. ارائهدهنده باید قابلیت nesting را روی میزبان فعال کرده باشد و مهمان شما باید به افزونههای مجازیسازی CPU دسترسی داشته باشد.
lscpu | grep -i virtualization
ls -l /dev/kvm
sudo apt install -y cpu-checker && sudo kvm-okدر یک مهمان KVM که nesting در آن فعال است، /dev/kvm وجود دارد و kvm-ok بهوضوح گزارش میدهد که آیا میتوان از شتابدهنده استفاده کرد یا خیر. در Xen HVM این کار از نظر فنی ممکن است اما بهندرت ارائه میشود. در Xen PV این قابلیت امکانپذیر نیست.
در یک کانتینر، این بررسی به شکلی آموزنده با شکست مواجه میشود. /proc/cpuinfo فایل میزبان است، بنابراین پرچم vmx یا svm در آن وجود دارد و واقعاً هم درست است: CPU فیزیکی زیر پای شما واقعاً آن دستورالعملها را دارد. با این حال، این CPU متعلق به شما نیست. هیچ /dev/kvm در فضای نام (namespace) شما وجود ندارد، شما نمیتوانید ماژول kvm_intel را بارگذاری کنید و پرچمی که بهتازگی خواندید، ماشینی را توصیف میکند که شما مهمان آن هستید، نه ماشینی که کنترلش در دست شماست. این واضحترین نمونه از یک قاعده کلی است. در یک کانتینر، /proc فضای نام و سختافزار پیرامون آن را توصیف میکند، نه سروری که مالک آن هستید.
قابلیت AES-NI و ویژگیهای CPU که طرح شما در اختیار میگذارد
AES-NI (مجموعه دستورالعملهای استاندارد رمزنگاری پیشرفته) مجموعهای از دستورالعملهای CPU است که عملیات رمزنگاری AES را چندین برابر سریعتر از محاسبات نرمافزاری مشابه انجام میدهد. پایاندهی TLS، رمزنگاری دیسک، SSH و خطلولههای پشتیبانگیری همگی به این قابلیت متکی هستند.
در KVM، آنچه سیستمعامل مهمان مشاهده میکند توسط مدل CPU تعیین میشود که ارائهدهنده برای QEMU پیکربندی کرده است. با استفاده از حالت host passthrough، شما پرچمهای (flags) واقعی را میبینید. با یک مدل عمومی مانند qemu64، یا یک مدل پایه قدیمی که عمداً انتخاب شده تا امکان مهاجرت مهمانها بین میزبانهای ناهمگون فراهم باشد، ممکن است پرچم aes وجود نداشته باشد و OpenSSL بهطور خودکار و بدون اطلاع، به مسیر نرمافزاری خود بازگردد.
lscpu | grep -ow aes | head -n 1
openssl speed -evp aes-128-gcm
env OPENSSL_ia32cap='~0x200000000000000:~0x20000000000:~0x0:~0x0:~0x0' openssl speed -evp aes-128-gcmدستور سوم، نمونهای از راهنمای OpenSSL برای غیرفعال کردن این دستورالعملها در داخل کتابخانه است: این دستور بیت AES-NI و بیت VAES را پاک میکند و بقیه را دستنخورده باقی میگذارد. دو عدد خروجی (throughput) را با هم مقایسه کنید. اگر این دو عدد به هم نزدیک باشند، یعنی مسیر سریع از ابتدا مورد استفاده نبوده است و بررسی صحیح AES-NI روی یک VPS پیش از نهایی کردن طرح، ارزش صرف 5 دقیقه زمان را دارد.
یک کانتینر هیچ مدل CPU مجزایی در مقابل خود ندارد، بنابراین پرچمهای موجود در /proc/cpuinfo همان پرچمهای واقعی میزبان هستند و برای شما اعمال میشوند. این یکی از مزایای واقعی طرحهای کانتینری است و تنها بخشی از این راهنماست که در آن هسته مشترک به نفع شما عمل میکند.
منشأ steal time و دلیل نبود آن در کانتینر
مقدار steal time زمانی است که CPU مجازی شما آمادهٔ اجرا بوده اما به دلیل اینکه hypervisor در حال اجرای پردازش دیگری بوده، فرصت اجرا نیافته است. این مقدار در st در ابزارهای top و vmstat، و همچنین به عنوان هشتمین فیلد در خط cpu در فایل /proc/stat نمایش داده میشود.
یک سیستمعامل مهمان نمیتواند این مقدار را بهتنهایی اندازهگیری کند، زیرا در لحظاتی که این زمان از دست میرود، سیستمعامل در حال اجرا نیست. hypervisor باید این موضوع را به آن اطلاع دهد. KVM مجموع زمان سپریشده را در صفحهای مینویسد که مهمان از طریق رابط paravirtual clock خود ثبت کرده است، و Xen نیز برای همین کار یک ناحیه وضعیت اجرای اختصاصی برای هر vCPU نگه میدارد. عددی که مشاهده میکنید، در واقع گزارش خودِ hypervisor است؛ به همین دلیل این مقدار وجود دارد و قابلاعتماد است.
مقدار بالای steal به این معناست که host بیش از حد ظرفیت خود منابع فروخته است (oversubscribed) و همسایگان شما در آن لحظه مشغول استفاده از منابع هستند. این عدد نشاندهندهٔ نسبت بین vCPUهای فروختهشده و هستههای فیزیکی است و خواندن steal time برای شناسایی همسایهٔ پرمصرف تنها معیاری است که به شما میگوید آیا طرحی که خریداری کردهاید به اندازهٔ ادعای صفحهٔ مشخصاتش بزرگ است یا خیر.
vmstat 1 5
cat /sys/fs/cgroup/cpu.statدر یک کانتینر، این ستون تغییر نمیکند، زیرا هیچ hypervisorای بین شما و scheduler وجود ندارد. پردازشهای شما در کنار پردازشهای سایر مستأجران به عنوان وظایف عادی در scheduler پردازندهٔ خودِ host قرار میگیرند. رقابت بر سر منابع در اینجا صرفاً به صورت طولانیتر شدن زمان انجام کار ظاهر میشود، بدون آنکه شمارندهای نامی از علت آن ببرد. نزدیکترین معادل برای این وضعیت، quota throttling است: زمانی که ارائهدهنده مقدار cpu.max را تنظیم میکند، /sys/fs/cgroup/cpu.stat تعداد nr_throttled دورهها و throttled_usec میکروثانیههایی را که صرف انتظار برای پنجرهٔ سهمیهٔ بعدی شده است، میشمارد. این مقدار فقط سهمیهٔ خودتان را پوشش میدهد و هرگز رقابت با همسایگان را نشان نمیدهد. یک نکتهٔ احتیاطی: اگر host کانتینرِ ارائهدهنده، خود یک ماشین مجازی باشد، ممکن است مقدار steal در /proc/stat ظاهر شود که این مقدار متعلق به آن host است، نه متعلق به شما.
بیشفروشی (Overselling) و دلیل ارزانتر بودن طرحهای کانتینری
پاسخ صادقانه کوتاه است. هزینه طرحهای کانتینری کمتر است زیرا ارائهدهنده، منابع یک ماشین واحد را با افراد بیشتری به اشتراک میگذارد.
حافظه (RAM) جایی است که بیشترین شکاف در آن دیده میشود. رم یک مهمان KVM به آن اختصاص داده شده است، بنابراین میزبانی با 256 GB رم، تقریباً 256 GB فضا به مهمانان میفروشد (با کسر سربار). محدودیت حافظه در یک کانتینر، یک سقف است نه یک رزرو؛ حافظهای که یک کانتینر استفاده نمیکند، بلافاصله در دسترس سایرین قرار میگیرد. بنابراین ارائهدهنده میتواند مجموع محدودیتهای فروختهشده را چندین برابر رم فیزیکی در نظر بگیرد و در اکثر مواقع نیز مشکلی پیش نیاید. هیچ چیز ساختگی نیست؛ این سیستم تا زمانی که تعداد زیادی از مستأجران همزمان فعال نباشند، بهخوبی کار میکند و پس از آن، عملکرد برای همه مختل میشود.
CPU در تمام انواع طرحها، از جمله KVM، با فروش vCPUهای بیشتر از تعداد هستههای فیزیکی، بیشفروشی میشود. دیسک نیز تقریباً در همه جا بهصورت thin provisioned ارائه میگردد. کانتینرها تراکم بیشتری را به این موارد اضافه میکنند: یک هسته (kernel) مشترک، یک page cache واحد و نبود پردازش QEMU برای هر مهمان؛ بنابراین یک میزبان میتواند چندین برابر بیشتر از حالت عادی، مستأجر بپذیرد.
آنچه در این میان از دست میدهید، ایزولاسیون است و این یک مبادله مهندسی واقعی است، نه یک داستان ترسناک. شما از یک هسته مشترک استفاده میکنید، بنابراین یک باگ در هسته، مشکلی مشترک برای همه است و فرار از کانتینر (container escape) مستقیماً به میزبان ختم میشود. فرار از یک ماشین مجازی نیازمند وجود یک باگ در هایپروایزر است که هدفی بسیار کوچکتر و بسیار دشوارتر محسوب میشود. شما همچنین تابع برنامه ارتقای هسته و ریبوتهای ارائهدهنده هستید. اگر هر یک از این موارد برای شما اهمیت دارد، پیش از انتخاب صرفاً بر اساس قیمت، میزان امنیت واقعی میزبانی VPS را مطالعه کنید.
کدام را بخریم
زمانی که به هسته (kernel) اختصاصی خود نیاز دارید، KVM بخرید: برای استفاده از ماژولهای WireGuard یا ZFS، نسخهٔ خاصی از هسته، مجازیسازی تو در تو (nested virtualization)، کنترل واقعی روی swap، یا ایجاد مرزبندی که بتوانید برای یک حسابرس توضیح دهید. زمانی که سرویسهای معمولی را با بودجهٔ محدود اجرا میکنید، هستهٔ ارائهدهنده بهروز است و تأیید کردهاید که قابلیتهای مورد نیازتان در آن کامپایل شدهاند، یک پلن کانتینری بخرید. Xen HVM را برای اکثر مقاصد معادل KVM در نظر بگیرید و پیش از خرید هر چیزی که هنوز با عنوان Xen PV فروخته میشود، پرسوجو کنید.
دو ساختار خارج از این دستهبندی قرار میگیرند. میکرو ماشینهای مجازی Firecracker به هر مستأجر یک هستهٔ واقعی با هزینهٔ راهاندازی نزدیک به کانتینر میدهند؛ همان چیزی که پلتفرمهای بدون سرور (serverless) بر پایهٔ آن اجرا میشوند. کانتینرهای سیستمی Incus به شما اجازه میدهند مدل کانتینری را روی سختافزاری که کنترل میکنید اجرا کنید، که موقعیتی متفاوت از خرید یک سرویس کانتینری آماده است. اگر واژگان نقطهٔ ابهام هستند، اینکه VPS واقعاً چیست و تفاوت بین VPS، VM و VPC اصطلاحاتی را پوشش میدهند که این راهنما فرض میکند از قبل با آنها آشنا هستید.
FAQ
چگونه بفهمم VPS من KVM است یا یک کانتینر؟
دستور systemd-detect-virt -c را اجرا کنید. هر پاسخی غیر از none به این معناست که شما داخل یک کانتینر هستید، فارغ از اینکه نام محصول در طرح خریداریشده چه باشد. این موضوع را از دو طریق دیگر نیز تأیید کنید، چرا که ابزارهای تشخیص ممکن است فریب بخورند. دستور lscpu نام فروشنده هایپروایزر را نمایش میدهد و مشخص میکند که نوع مجازیسازی کامل (full) است یا نیمهمجازی (para). فایل ls /lib/modules/$(uname -r) در یک کانتینر وجود ندارد یا خالی است، زیرا کرنل در حال اجرا متعلق به میزبان (host) است و درخت ماژولهای آن هرگز در سیستم فایل شما نصب نشده است. ابزار sudo virt-what نیز پاسخی مستقل از برنامهای که صرفاً برای همین پرسش نوشته شده، ارائه میدهد.
چرا free -m حافظه بسیار بیشتری نسبت به طرح من نشان میدهد؟
شما از یک طرح کانتینری استفاده میکنید که در آن LXCFS مونت نشده است؛ بنابراین /proc/meminfo فایل متعلق به میزبان است و free دقیقاً حافظه میزبان را گزارش میکند. سقف واقعی شما در cgroup تعریف شده است. برای مشاهده محدودیت، /sys/fs/cgroup/memory.max و برای مشاهده میزان مصرف فعلی، /sys/fs/cgroup/memory.current را بخوانید؛ یا در میزبانهای قدیمیتر با cgroup v1، فایل /sys/fs/cgroup/memory/memory.limit_in_bytes را بررسی کنید. هر سرویسی که اندازه کش یا استخر worker خود را بر اساس حافظه تنظیم میکند، باید از این عدد استفاده کند، نه از free.
آیا میتوانم Docker یا WireGuard را روی یک VPS از نوع LXC اجرا کنم؟
گاهی اوقات بله، اما این موضوع هرگز به آنچه شما نصب میکنید بستگی ندارد. هر دو به کرنل ارائهدهنده وابسته هستند، زیرا شما نمیتوانید ماژولی را در آن بارگذاری کنید. WireGuard زمانی کار میکند که ماژول از قبل روی میزبان موجود و برای شما در دسترس باشد؛ در غیر این صورت، پیادهسازی فضای کاربری (userspace) یعنی wireguard-go جایگزین آن خواهد بود. Docker نیاز دارد که ارائهدهنده اجازه nesting را بدهد و به یک درایور ذخیرهسازی نیاز دارد که داخل کانتینر کار کند. پیش از خرید بپرسید، یا روی سرویسی که امکان لغو آن را دارید، تست کنید.
چرا VPS کانتینری من هرگز steal time را گزارش نمیکند؟
Steal time تنها زمانی وجود دارد که یک هایپروایزر در حال زمانبندی یک CPU مجازی باشد و این مقدار گزارش میشود زیرا هایپروایزر آن را در صفحهای مینویسد که کرنل شما آن را میخواند. یک کانتینر هیچ هایپروایزری در زیر خود ندارد. پردازشهای شما وظایف عادی در زمانبند میزبان هستند، بنابراین رقابت بر سر منابع باعث میشود همه چیز کندتر انجام شود بدون اینکه شمارندهای برای نشان دادن آن وجود داشته باشد. به جای آن /sys/fs/cgroup/cpu.stat را بخوانید: nr_throttled و throttled_usec زمانی را که cgroup شما در انتظار پنجره سهمیه CPU بعدی خود بوده است میشمارند، که نزدیکترین مفهوم به steal time در یک کانتینر است.