
به اشتراک بگذارید

به اشتراک بگذارید
یک فرمان روی سرور بزنید: systemd-detect-virt. جوابش یک کلمه است و از همان کلمه میفهمید تفاوت KVM و OpenVZ در سرور شما کجا خودش را نشان میدهد. خروجی kvm یعنی ماشین مجازی کامل با کرنل خودش. خروجی openvz یا lxc یعنی کانتینری روی کرنل مشترک میزبان؛ آنجا نصب Docker، بارگذاری ماژول کرنل و ساخت Swap به اجازه میزبان بسته است.
پنج جایی که این دو نوع سرور از هم جدا میشوند
| موضوع | KVM | OpenVZ / LXC |
|---|---|---|
| کرنل | مال خود ماشین | مال میزبان |
| اجرای Docker | نصب معمولی | وابسته به تنظیم میزبان، مثل nesting در LXC |
| ماژول کرنل | فرمان modprobe کار میکند | میزبان باید بار کند |
| فضای Swap | با root فعال میشود | قابلیت CAP_SYS_ADMIN دست میزبان است |
| فایروال | روی ماژولهای کرنل خودتان | ماژولهای netfilter از میزبان |
💡 یک کلمه برای شناختن خانواده مجازیساز
در KVM هر سرور مجازی کرنل خودش را بوت میکند؛ در OpenVZ و LXC همه کانتینرها روی کرنل میزباناند.
✅ همان یک کلمه را در تیکت پشتیبانی بنویسید.
✅ سرور خطا نمیدهد و فقط کند است؟ رد کندی را از هسته مجازی یا vCPU چیست بگیرید.
خطایی که شما را به این صفحه رساند، احتمالاً یک سطر از جدول نشانههاست. سطرتان را پیدا کنید؛ یک کلمه از systemd-detect-virt علت را تأیید یا رد میکند.
📌 عیبیابی به ترتیب جدول نشانهها
◀️ نشانهها؛ وقتی Docker، ماژول کرنل یا Swap روی VPS کار نمیکند
◀️ تشخیص نوع مجازیساز با systemd-detect-virt و دو آزمون دیگر
◀️ مجازیسازی کامل KVM در برابر کانتینری؛ ریشه این محدودیتها
◀️ اگر سرور شما کانتینری است، چه گزینههایی دارید؟

روی VPS کانتینری چند خطای آشنا یک ریشه دارند: کرنلی که سرور روی آن اجرا میشود مال میزبان است. جدول زیر هر نشانه را به فرمان تست و علتش وصل میکند؛ ستون آخر همان کار روی KVM است.
| نشانه | فرمان تست | علت در کانتینر | در KVM |
|---|---|---|---|
| سرویس Docker بالا نمیآید | systemctl status docker | تنظیم میزبان، مثل nesting در LXC و Incus، باز نیست | نصب عادی |
| ماژول بارگذاری نمیشود | sudo modprobe overlay | کانتینر اجازه بار کردن ماژول ندارد | از کرنل خودتان بار میشود |
| فایل Swap فعال نمیشود | sudo swapon /swapfile | میزبان قابلیت CAP_SYS_ADMIN را نداده است | با root فعال میشود |
| نسخه کرنل با توزیع نمیخواند | uname -r | این عدد نسخه کرنل میزبان است | کرنل نصبشده خودتان |
| قاعده فایروال خطای ماژول میدهد | sudo nft list rulesetsudo iptables -L | ماژول netfilter را میزبان بار میکند | کرنل خودتان بار میکند |
طبق پرسشهای متداول Incus، اجرای Docker داخل کانتینر به security.nesting=true روی همان کانتینر نیاز دارد و این تنظیم کار میزبان است. شاید Docker ماژولهایی هم بخواهد که میزبان باید بار کند. در OpenVZ هم Docker به تنظیم میزبان وابسته است. مشکل را از داخل کانتینر حل نمیکنید؛ تفاوت KVM و OpenVZ اینجا یعنی یک تیکت به میزبان.
کانتینر بدون امتیاز (unprivileged) با user namespace ساخته میشود و root آن ماژول بار نمیکند. صفحه راهنمای user_namespaces این کار را مخصوص فرایندی با امتیاز در فضای نام کاربری اولیه، یعنی میزبان، میداند. در کانتینر privileged، پیکربندی پیشفرض LXC قابلیت sys_module را حذف میکند. فرمان swapon هم بدون قابلیت CAP_SYS_ADMIN خطای EPERM میدهد؛ همان Operation not permitted.
⚠️ ماژول را از داخل کانتینر به زور بار نکنید
دانلود فایل ماژول با پسوند ko و امتحان insmod چیزی را درست نمیکند. کرنلی که ماژول را میپذیرد مال میزبان است و ماژول روی همه کانتینرهایش اثر میگذارد. نام دقیق ماژول را برای ارائهدهنده بفرستید؛ در Incus کلید linux.kernel_modules برای همین است.

فرمان systemd-detect-virt بخشی از systemd است و طبق صفحه راهنمای systemd-detect-virt، مجازیسازی کامل را از کانتینری جدا میکند. اگر فناوری شناختهشدهای نیابد، کد خروج غیرصفر برمیگرداند. سرور بدون systemd پیام command not found میدهد؛ آنوقت سراغ دو آزمون بعدی بروید.
systemd-detect-virt
systemd-detect-virt --vm
systemd-detect-virt --container
گزینه --vm فقط ماشین مجازی را میسنجد و --container فقط کانتینر، یعنی به تعبیر صفحه راهنما «مجازیسازی با کرنل مشترک». از چند لایه، فقط درونیترین گزارش میشود، مگر با –vm؛ پس کانتینر LXC روی میزبان KVM با فرمان اول lxc و با –vm کلمه kvm میدهد. دستگاه آزمایشی ما VPS نبود، ولی همین رفتار را نشان داد: کانتینر Docker با اوبونتو 24.04.5 اول docker داد و با –vm کلمه kvm. برنامههای شما در درونیترین لایه اجرا میشوند و تفاوت KVM و OpenVZ را همان لایه تعیین میکند.
🔸 معنای هر خروجی systemd-detect-virt
خروجی kvm: ماشین مجازی KVM همراه QEMU.microsoft، vmware، xen یا amazon: ماشین مجازی کامل دیگر؛ کرنل باز هم مال شماست.qemu: شبیهسازی QEMU بدون KVM.openvz: کانتینر OpenVZ یا Virtuozzo.lxc: کانتینر LXC، از جمله کانتینر Incus.docker: کانتینر Docker.none: چیزی پیدا نشد.
فهرست کامل: systemd-detect-virt --list.
در کانتینر OpenVZ مسیر /proc/vz هست و /proc/bc نیست؛ کد منبع systemd هم openvz را با همین دو مسیر تشخیص میدهد. نتیجه مثبت: /proc/vz فهرست میشود و برای /proc/bc پیام No such file or directory میآید. فایل /proc/user_beancounters را ویکی OpenVZ محل اطلاعات کنترل منابع میداند؛ بدون sudo هم با root خوانده میشود:
ls -d /proc/vz /proc/bc
sudo cat /proc/user_beancounters
ستون held مصرف فعلی است و maxheld بیشترین مقدار ثبتشده. ستون failcnt میشمارد چند بار درخواست منبع رد شده؛ عدد غیرصفر یعنی برنامهای به سقف خورده.
sudo apt install virt-what
sudo dnf install virt-what
sudo virt-what
خط اول برای اوبونتو است و خط دوم برای خانواده RHEL، مثل AlmaLinux 9. به گفته صفحه راهنمای virt-what، خروجی در هر سطر یک مورد شناساییشده است، مثل kvm یا openvz. خروجی خالی یعنی سرور فیزیکی است یا مجازیسازی ناشناخته دارد؛ آن را مدرک اختصاصی بودن سرور ندانید.

در KVM هر سرور مجازی یک ماشین کامل است، با دیسک و کارت شبکه مجازی و کرنلی که خودش بوت میکند. در کانتینر، فرایندهای شما با سازوکارهای خود کرنل از بقیه جدا میشوند (در LXC با namespace و cgroup) و همه روی کرنل میزبان میمانند.
تاکسی خطی و دربست همین فرق را دارند. مسافران تاکسی خطی یک راننده و یک مسیر دارند و هیچکدام رادیو را عوض نمیکند؛ کانتینرها هم یک کرنل دارند و تنظیمش دست میزبان است. دربست در همان خیابان میرود، ولی راننده مال شماست؛ ماشین KVM هم روی سختافزار مشترک کرنل خودش را دارد. تفاوت KVM و OpenVZ در عمل این است: کار با کرنل در KVM با شماست و در کانتینر با میزبان. سراغ QEMU و VirtIO که بروید، KVM چیست و چه اجزایی دارد نقشه اجزای میزبان را دارد.
سقف منابع در هر دو نوع دست میزبان است؛ در کانتینر با cgroup در LXC یا beancounters در OpenVZ. اینکه ارائهدهنده یک میزبان را بیش از ظرفیت فروخته باشد یا نه، از نوع مجازیساز معلوم نمیشود.
جدول Releases ویکی OpenVZ از ژانویه ۲۰۲۰ ویرایش نشده و هنوز OpenVZ 7 با کرنل 3.10 را نسخه اصلی میداند. پوشه releases در سرور دانلود رسمی OpenVZ تازهتر است: شاخه 7 تا نسخه 7.0.22 در ۲۴ اکتبر ۲۰۲۴ رسیده، با بسته vzkernel-3.10.0-1160.119.1.vz7.224.4. پوشههای 8.0 و 9.0 هم هست و شاخه 9.0 بسته kernel-5.14.0-4.vz9.12.7 را دارد. پس روی OpenVZ ممکن است کرنل 3.10 یا 5.14 ببینید و پسوند vz7 یا vz9 در uname -r با نام همین بستهها میخواند. تاریخ پایان پشتیبانی آنجا نیامده؛ از ارائهدهنده بپرسید.
در این خانواده، LXC رانتایم سطح پایین کانتینر است. LXD طبق اعلامیه ۴ ژوئیه ۲۰۲۳ در linuxcontainers.org به سایتهای Canonical رفت. انشعاب جامعهمحور آن، Incus، کانتینر را بر پایه LXC و ماشین مجازی را بر پایه QEMU میسازد؛ پس نام Incus یا LXD روی پلن، نوع سرور را نمیگوید.
⚠️ نسخهای که uname -r چاپ میکند از میزبان است
در کانتینر، uname -r کرنل میزبان را نشان میدهد و نصب linux-image تازه آن را عوض نمیکند. روی همان کانتینر آزمایشی خودمان هیچ بسته linux-image و پوشه /lib/modules نبود، اما uname -r عدد 6.18.44 را برمیگرداند.

کلید این قفل دست میزبان است: یا دسترسی لازم را باز میکند، یا سرور را به یک ماشین KVM میبرید. پیش از هر دو، این چهار مورد را برای تیکت جمع کنید:
systemd-detect-virt و systemd-detect-virt --vmuname -rبرای Docker روی LXC یا Incus، nesting را بخواهید و برای ماژول، نامش را. این دو فرمان Incus سمت میزبان اجرا میشوند:
incus config set <container> security.nesting=true
incus config set <container_name> linux.kernel_modules=<modules>
در OpenVZ هم نام ماژول یا قابلیت را مشخص بفرستید؛ پذیرفتنش به سیاست میزبان بستگی دارد.
اگر میزبان نپذیرفت، تفاوت KVM و OpenVZ به تصمیم خرید میرسد. برای کرنل سفارشی، ویندوز، Swap دلخواه یا ماژولی که میزبان بار نمیکند، ماشین KVM لازم دارید. مهاجرت یعنی سرور تازه و انتقال داده، پس اول نسخه پشتیبان بگیرید. روی سرور تازه، systemd-detect-virt باید kvm بگوید؛ بعد Docker را با راهنمای نصب داکر روی اوبونتو 24.04 راه بیندازید.
آزمون شما openvz یا lxc نشان داد؟ پیش از نوشتن تیکت، این هفت مورد را مرور کنید.
یعنی systemd-detect-virt فناوری شناختهشدهای نیافت. اگر VPS خریدهاید و none دیدید، virt-what را هم بزنید و از ارائهدهنده بپرسید.
نه. کرنل مال شماست، اما سختافزار میزبان بین ماشینها تقسیم میشود.
به شرطی که میزبان security.nesting=true را فعال کند و ماژولهای لازم را بار کند.
از داخل سرور نه؛ ارتقای کرنل کار میزبان است.
نه. کانتینر روی کرنل لینوکس میزبان اجرا میشود و ویندوز مجازیسازی کامل مثل KVM میخواهد.
روی سرور دانلود رسمی، نسخه 7.0.22 تاریخ ۲۴ اکتبر ۲۰۲۴ دارد و شاخه 9.0 با کرنل 5.14 هم هست. تاریخ پایان پشتیبانی را از ارائهدهنده بپرسید.
یا سرور فیزیکی است یا مجازیسازی ناشناخته دارد. صفحه راهنمای آن میگوید پیش از خواندن خروجی، کد خروج 0 را بررسی کنید.
جمعبندی؛ اول یک کلمه، بعد تصمیم برای کسی که پشت ترمینال نشسته، تفاوت KVM و OpenVZ یک سؤال است: کرنل مال کیست؟ خروجی kvm یعنی Docker، ماژول، Swap و فایروال را خودتان تنظیم میکنید. خروجی openvz یا lxc یعنی همین کارها از مسیر میزبان میگذرد و insmod از داخل کانتینر فقط وقت میگیرد. پیش از تیکت، خروجی systemd-detect-virt و عدد uname -r را کنار متن خطا بگذارید؛ در OpenVZ سطرهای failcnt را هم اضافه کنید. اگر میزبان دسترسی را باز نکرد، مهاجرت به KVM کرنل را به دست شما میدهد. نام پلن را ملاک نگیرید؛ نوع سرور را خروجی فرمان میگوید.
🚀 آزمون kvm گفت؟ پردازنده را هم وارسی کنید
خروجی kvm چیزی درباره پردازنده نمیگوید: هر هسته مجازی سرور از پردازنده فیزیکی چقدر میگیرد؟
کلمهای که systemd-detect-virt روی سرور شما چاپ کرد چه بود؟ همان یک کلمه را با متن خطا بیاورید؛ سطر جدول را از روی همین دو پیدا میکنیم.
مستنداتی که این مطلب بر آن تکیه دارد