انواع مجازی‌سازی سرور: KVM، کانتینر و تفاوت واقعی

اگر بین KVM و کانتینر و OpenVZ مانده‌اید، اینجا با عدد و دستور می‌بینید هر کدام چه محدودیتی روی کار شما می‌گذارد و کدام را انتخاب کنید.

۶ دقیقه به‌روزرسانی ۲۰ مهر ۱۴۰۵

روی صفحه خرید VPS ایستاده‌اید و دو گزینه می‌بینید: «مجازی‌سازی KVM» و «کانتینر». اختلاف قیمت کم نیست، و هیچ‌کدام توضیح نمی‌دهند که این تفاوت در عمل یعنی چه. اگر فقط یک وب‌سایت وردپرسی روی سرور دارید، تقریباً هیچ تفاوتی حس نمی‌کنید. اگر می‌خواهید ماژول کرنل لود کنید، VPN راه بیندازید، یا فایل‌سیستم را با mount دستکاری کنید، تفاوت از «کمی کندتر» به «اصلاً کار نمی‌کند» تغییر می‌کند. این مقاله درباره همان مرز است.

انواع مجازی‌سازی از دید کسی که باید انتخاب کند

سه خانواده اصلی وجود دارد و هر کدام یک چیز متفاوت را قربانی می‌کنند.

  • مجازی‌سازی کامل (KVM، VMware، Xen HVM): یک کرنل مستقل برای شما اجرا می‌شود. سربار دارد، اما کنترل کامل دارید.
  • مجازی‌سازی سطح سیستم‌عامل (LXC، OpenVZ، Docker): کرنل میزبان بین همه مشترک است. سربار نزدیک صفر، کنترل نزدیک صفر.
  • پارا-مجازی‌سازی (Xen PV): امروز در هاستینگ اشتراکی تقریباً مرده است. اگر جایی دیدید، یعنی زیرساخت قدیمی است.

نکته‌ای که در جدول‌های مقایسه‌ای گم می‌شود: KVM یک ماشین مجازی کامل با BIOS مجازی، دیسک مجازی و کارت شبکه مجازی می‌سازد. کانتینر فقط یک namespace و یک cgroup است که به یک پروسه می‌گوید «تو تنها هستی». همین یک جمله، تمام تفاوت‌های عملی را توضیح می‌دهد.

سربار واقعی KVM چقدر است

عددها را باید اندازه گرفت، نه حدس زد. روی یک میزبان با پردازنده‌ای که vmx دارد، اجرای sysbench cpu --threads=4 run روی ماشین فیزیکی و روی یک KVM با همان تعداد vCPU، معمولاً بین ۲ تا ۵ درصد اختلاف می‌دهد. روی عملیات I/O سنگین، اختلاف بیشتر می‌شود: با virtio-blk و cache mode مناسب، افت به ۵ تا ۱۰ درصد می‌رسد؛ با درایور IDE شبیه‌سازی‌شده، می‌تواند از ۴۰ درصد هم رد شود.

پس سربار KVM مسئله اصلی نیست. مسئله اصلی oversell است. میزبانی که ۳۲ هسته فیزیکی دارد و ۶۴ vCPU می‌فروشد، به شما دروغ نگفته، اما وقتی همه مشتری‌ها همزمان کار کنند، steal time بالا می‌رود. این را با یک دستور ساده می‌بینید:

top -bn1 | head -5
# یا دقیق‌تر:
vmstat 1 5

اگر در ستون st عددی بالای ۵ دیدید، ماشین شما منتظر CPU میزبان است. این عدد در کانتینر هم وجود دارد و همان معنا را می‌دهد. تفاوت این است که در KVM می‌توانید cpu steal را در /proc/stat ببینید و به پشتیبانی نشان دهید؛ در OpenVZ قدیمی، این شمارنده گاهی اصلاً گزارش نمی‌شد.

کجا کانتینر جواب می‌دهد و کجا نمی‌دهد

کانتینر برای بارهایی ساخته شده که با کرنل کاری ندارند. یک اپلیکیشن PHP، یک سرویس Node.js، یک ردیف کانتینر Docker پشت Nginx: همه اینها در LXC یا Docker عالی کار می‌کنند و حافظه کمتری هم می‌خورند، چون هر کانتینر یک کرنل کامل با کش صفحه و ساختارهای داخلی‌اش را در RAM نگه نمی‌دارد.

اما لحظه‌ای که به کرنل نیاز پیدا کنید، داستان تمام می‌شود. سه مثال واقعی:

  1. می‌خواهید WireGuard راه بیندازید. به ماژول wireguard و دستگاه /dev/net/tun نیاز دارید. در کانتینر بدون دسترسی privileged، RTNETLINK answers: Operation not permitted می‌گیرید.
  2. می‌خواهید فایل‌سیستم XFS یا ZFS بسازید. mount در namespace کانتینر فقط اجازه mount کردن چیزهایی را می‌دهد که میزبان از قبل مجاز کرده.
  3. می‌خواهید sysctl را عوض کنید، مثلاً net.ipv4.tcp_congestion_control=bbr. در KVM آزاد است؛ در کانتینر مشترک، یا رد می‌شود یا روی همه تأثیر می‌گذارد.

اینجا اشتباه می‌کنند: کاربری که روی VPS کانتینری نشسته و می‌خواهد BBR را فعال کند، دستور را می‌زند، خروجی خطا نمی‌بیند، و بعد از یک هفته می‌فهمد سرعت شبکه‌اش هیچ تغییری نکرده. چون sysctl -w در آن محیط بی‌صدا نادیده گرفته شده. اگر مقدار را با sysctl net.ipv4.tcp_congestion_control دوباره بخوانید، همان مقدار قبلی را می‌بینید. همیشه بعد از تغییر، مقدار را بازخوانی کنید.

جدول تصمیم: کدام را برای چه کاری

نیاز شماKVMکانتینر (LXC/Docker)
کرنل اختصاصی و نسخه دلخواهبلهخیر
ماژول کرنل، VPN، iptables کاملبلهمحدود یا خیر
تراکم بالا و مصرف حافظه کمضعیف‌تربهتر
زمان راه‌اندازی مجدد۱۰ تا ۳۰ ثانیهزیر ۱ ثانیه
جداسازی امنیتیقویوابسته به تنظیمات میزبان
مهاجرت زنده بین میزبان‌هابلهسخت‌تر

اگر مجبور باشم یک جمله بگویم: برای هر چیزی که به شبکه، کرنل یا فایل‌سیستم سطح پایین دست می‌زند KVM بگیرید، و برای بقیه کانتینر. تفاوت قیمت را باور کنید، چون واقعی است.

مجازی‌سازی تودرتو و دام‌هایی که کمتر گفته می‌شود

اگر داخل VPS خودتان Docker اجرا می‌کنید، در واقع دارید مجازی‌سازی تودرتو انجام می‌دهید. روی KVM این کار بدون مشکل انجام می‌شود، به شرطی که میزبان nested virtualization را فعال کرده باشد. بررسی‌اش یک خط است:

grep -c vmx /proc/cpuinfo
# خروجی بزرگ‌تر از صفر یعنی مجازی‌سازی سخت‌افزاری در دسترس است

اگر خروجی صفر بود، Docker کار می‌کند اما کندتر، چون از qemu نرم‌افزاری استفاده می‌کند. راهنمای راه‌اندازی داکر روی VPS؛ از نصب تا اجرای اولین کانتینر همین مسیر را گام‌به‌گام پوشش می‌دهد.

دام دوم: دیسک. در KVM دیسک معمولاً یک فایل qcow2 یا یک volume روی LVM است. اگر روی qcow2 با cache=writeback کار می‌کنید و میزبان برقش برود، ممکن است چند ثانیه آخر نوشته‌ها را از دست بدهید. برای دیتابیس، cache=none با io=native انتخاب درست‌تری است، هرچند کندتر است. این همان معامله‌ای است که باید آگاهانه انجام دهید، نه پیش‌فرض.

دام سوم: ساعت. ماشین مجازی ساعت خودش را از میزبان می‌گیرد و اگر drift داشته باشد، لاگ‌ها بی‌ترتیب می‌شوند و توکن‌های احراز هویت رد می‌شوند. chronyd را نصب کنید و بعد از هر مهاجرت زنده، یک‌بار chronyc tracking بزنید.

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

پیش از هر تصمیمی درباره تغییر نوع مجازی‌سازی، مطمئن شوید مشکل از نوع مجازی‌سازی است. در نُه مورد از ده موردی که کاربر فکر می‌کند «KVM لازم دارم»، مشکل واقعی یک کوئری کند MySQL یا یک cron بدتنظیم است. راهنمای تشخیص علت لود بالای سرور؛ راهنمای عملی و گام‌به‌گام دقیقاً همین ترتیب را دنبال می‌کند: اول load average و iowait، بعد پروسه‌ها، و آخر از همه سخت‌افزار.

اگر به این نتیجه رسیدید که به کنترل کامل کرنل و جداسازی سخت‌گیرانه نیاز دارید، مسیر طبیعی بعدی یک سرور اختصاصی است، نه یک VPS بزرگ‌تر. و اگر بار شما متغیر است و می‌خواهید منابع را بالا و پایین ببرید، سرور ابری با مجازی‌سازی KVM همان چیزی است که هم کنترل می‌دهد و هم انعطاف.

یک نکته عملی که وقت زیادی صرفه‌جویی می‌کند: پیش از هر مهاجرت بین دو نوع مجازی‌سازی، فایل‌ها را با rsync منتقل کنید، نه با کپی ساده. دستور پایه این است:

rsync -avz --progress --exclude='*.sock' \
  /var/www/ user@new-host:/var/www/

راهنمای کامل انتقال فایل با scp و rsync؛ راهنمای عملی برای سرور گزینه‌های حفظ مجوزها و انتقال افزایشی را توضیح می‌دهد. و اگر بعد از مهاجرت دسترسی SSH را از دست دادید، بازنصب سرور و کار با حالت rescue؛ نجات داده‌ها وقتی دسترسی را از دست دادید مسیر بازیابی را نشان می‌دهد.

پرسش‌های پرتکرار

آیا KVM همیشه از کانتینر سریع‌تر است؟

خیر، و این باور غلط رایجی است. KVM سربار بیشتری دارد، پس روی بارهای سبک و پرتعداد، کانتینر معمولاً سریع‌تر و ارزان‌تر تمام می‌شود. KVM وقتی برنده است که به قابلیت‌های کرنل یا جداسازی سخت‌گیرانه نیاز داشته باشید، نه در سرعت خام.

چطور بفهمم VPS من KVM است یا کانتینر؟

سریع‌ترین راه، systemd-detect-virt است. اگر خروجی kvm بود، مجازی‌سازی کامل دارید؛ اگر lxc، openvz یا docker بود، کانتینر هستید. راه دوم، نگاه به /proc/cpuinfo و نبود پرچم vmx یا svm است که نشانه کانتینر بودن است.

روی کانتینر می‌توانم Docker نصب کنم؟

در بعضی پیکربندی‌ها بله، اما به دسترسی privileged نیاز دارید و همان دسترسی، جداسازی امنیتی را تقریباً از بین می‌برد. اگر Docker بخشی از معماری شماست، از ابتدا KVM انتخاب کنید تا بعداً مجبور به مهاجرت نشوید.

تفاوت OpenVZ با LXC چیست؟

OpenVZ یک کرنل وصله‌خورده اختصاصی می‌خواهد و از جریان اصلی لینوکس جدا است؛ به همین دلیل نسخه کرنل آن معمولاً قدیمی می‌ماند. LXC روی کرنل استاندارد اجرا می‌شود و همان ابزارهای cgroup و namespace را استفاده می‌کند. اگر امروز انتخاب می‌کنید، LXC را بردارید.

قبل از سفارش، یک بار systemd-detect-virt بزنید و ببینید واقعاً به چه چیزی نیاز دارید. اگر جواب «کرنل» بود، KVM. اگر جواب «سرعت و هزینه» بود، کانتینر. همین یک تصمیم، بیشتر از هر تنظیم دیگری روی تجربه شما اثر می‌گذارد.

آیا این مطلب برایتان مفید بود؟