Linux & Open Source

آزادسازی قدرت: مجازی‌سازی تودرتو در کانتینرها با KVM/QEMU، Podman و LXC

با پیچیده‌تر شدن محیط‌های توسعه، نیاز به عایق‌بندی سخت همراه با دسترسی به سخت‌افزار با عملکرد بالا هرگز بیشتر از این نبوده است. در حالی که کانتینرهای سنتی عایق‌بندی عالی در سطح فرآیند ارائه می‌دهند، زمانی که نیاز به اجرای سیستم‌عامل‌های کامل، تست هایپروایزرها یا اجرای شبیه‌سازهای سنگین سخت‌افزاری دارید، ناکافی هستند. اینجاست که مجازی‌سازی تودرتو (Nested Virtualization) با فناوری کانتینرها ملاقات می‌کند. با اجرای KVM/QEMU در داخل Podman یا LXC، می‌توانید یک استک "مجازی‌سازی چروت‌شده" (chrooted virtualization) ایجاد کنید که بهترین‌های هر دو دنیای را ارائه می‌دهد: سرعت ماشین‌های مجازی و مرزهای امنیتی کانتینرها.

درک معماری

مجازی‌سازی تودرتو به یک ماشین مجازی (VM) اجازه می‌دهد که خودش به عنوان یک هایپروایزر عمل کند. وقتی این را با کانتینرها ترکیب می‌کنیم، در واقع یک مدل عایق‌بندی لایه‌ای (Layered Isolation Model) ایجاد می‌کنیم:

  1. سیستم عامل میزبان (Host OS): سرور فیزیکی که هسته لینوکس را با ماژول‌های بارگذاری‌شده KVM اجرا می‌کند.
  2. لایه کانتینر (Podman/LXC): عایق‌بندی سیستم فایل، جداسازی فضای نام شبکه و فضای نام‌های کاربری را فراهم می‌کند.
  3. ماشین مجازی مهمان (Guest VM) (QEMU/KVM): در داخل کانتینر اجرا می‌شود و از شتاب‌دهی سخت‌افزاری KVM میزبان از طریق نگاشت /dev/kvm استفاده می‌کند.

اجزای حیاتی در اینجا دسترسی به دستگاه /dev/kvm است. بدون آن، QEMU به شبیه‌سازی نرم‌افزاری (TCG) بازمی‌گردد که به طور قابل توجهی کندتر است. با آن، ماشین‌های مجازی کانتینر شده شما با سرعت نزدیک به بومی اجرا می‌شوند.

راه‌اندازی با Podman: ایمن به صورت پیش‌فرض

Podman به صورت پیش‌فرض بدون روت (rootless) است، که آن را به یک کاندیدای عالی برای توسعه ایمن تبدیل می‌کند. برای اجرای KVM در داخل یک کانتینر Podman، باید امتیازات و دستگاه‌های خاصی را منتقل کنیم.

مثال عملی: اجرای یک مهمان KVM در Podman

اول، اطمینان حاصل کنید که میزبان به کاربران بدون روت اجازه دسترسی به KVM را می‌دهد:

# روی میزبان، /etc/selinux/config را بررسی کنید یا قوانین udev را تنظیم کنید
# معمولاً، افزودن کاربران به گروه 'kvm' برای دسترسی با امتیاز لازم است
usermod -aG kvm $USER

سپس، یک تصویر پایه حداقلی که شامل QEMU و ابزارهای KVM است را دریافت کنید. برای این مثال، از یک تصویر مبتنی بر Fedora استفاده می‌کنیم:

# اجرای Podman با نگاشت دستگاه و امتیازات خاص
podman run -it --rm \
  --device /dev/kvm \
  --cap-add=ALL \
  --security-opt seccomp=unconfined \
  fedora:latest \
  bash

توجه: پرچم‌های --cap-add=ALL و seccomp=unconfined برای اینکه QEMU بتواند رابط‌های شبکه و مناطق حافظه را در داخل کانتینر پیکربندی کند، ضروری هستند. در محیط تولید، باید این موارد را به حداقل امتیازات مورد نیاز (مثلاً NET_ADMIN، SYS_NICE) محدود کنید تا امنیت حفظ شود.

در داخل کانتینر، KVM و QEMU را نصب کنید:

dnf install -y qemu-kvm libvirt
virsh list

راه‌اندازی با LXC: سبک و کارآمد

LXC (کانتینرهای لینوکس) در سطح پایین‌تری نسبت به Podman عمل می‌کند و دیدی شفاف‌تر از سیستم ارائه می‌دهد. این برای خطوط CI/CD جایی که زمان راه‌اندازی حیاتی است، ایده‌آل است.

مثال عملی: پیکربندی LXC

# ایجاد یک کانتینر LXC
lxc-create -t download -n my-kvm-box -c download.distribution=fedora -c download.release=38

# تغییر پیکربندی برای اجازه دسترسی به KVM
lxc-attach my-kvm-box -- bash
# در داخل کانتینر:
dnf install -y qemu-kvm libvirt
systemctl enable --now libvirtd

به صورت پیش‌فرض، LXC دستگاه‌ها را عایق‌بندی می‌کند. باید اطمینان حاصل کنید که /dev/kvm در فایل پیکربندی LXC (/var/lib/lxc/my-kvm-box/config) نگاشت شده است:

lxc.cgroup.devices.allow = c 10:236 rwm
lxc.mount.entry = /dev/kvm dev/kvm none bind,optional,create=file

ملاحظات امنیتی

اگرچه قدرتمند است، اما آشکار کردن /dev/kvm برای یک کانتینر، مدل عایق‌بندی سخت استاندارد Docker/Podman را می‌شکند. یک کانتینر آسیب‌دیده می‌تواند در صورت پیکربندی نادرست، نظریاً با سایر ماشین‌های مجازی روی میزبان تعامل کند. برای کاهش ریسک‌ها:

  1. استفاده از فضای نام کاربری (User Namespaces): اطمینان حاصل کنید که کانتینر در یک فضای نام کاربری جداگانه اجرا می‌شود تا اینکه روت در داخل کانتینر، بدون امتیاز روی میزبان باشد.
  2. عایق‌بندی شبکه: از شبکه‌های پل (bridge) با قوانین سختگیرانه فایروال (iptables/nftables) استفاده کنید تا از دسترسی ماشین مجازی کانتینر شده به رابط‌های مدیریت میزبان جلوگیری شود.
  3. محدودیت‌های منابع: محدودیت‌های CPU و حافظه را به کانتینر اعمال کنید تا از حملات تخلیه منابع جلوگیری شود.

نتیجه‌گیری

اجرای KVM/QEMU در داخل کانتینرهای Podman و LXC یک تکنیک پیشرفته است که شکاف بین کانتینرهای سبک‌وزن و مجازی‌سازی کامل را پر می‌کند. این به توسعه‌دهندگان امکان می‌دهد تا هایپروایزرها را تست کنند، سیستم‌عامل‌های ناسازگار را اجرا کنند یا توپولوژی‌های پیچیده چند-VM را شبیه‌سازی کنند بدون اینکه ثبات میزبان را به خطر بیندازند. با مدیریت دقیق مجوزهای دستگاه و بافت‌های امنیتی، می‌توانید محیط‌های توسعه محکم و عایق‌بندی‌شده بسازید که هم عملکرد بالا دارند و هم ایمن هستند. با تکامل زیرساخت‌های بومی ابری، تسلط بر این الگوهای مجازی‌سازی ترکیبی برای مدیران سیستم پیشرفته و مهندسان DevOps ضروری خواهد بود.

Share: