Product SiteDocumentation Site

12.2. مجازی‌سازی

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

12.2.1. Xen

Xen یک راهکار “paravirtualization” است که شامل یک لایه انتزاعی سبک به نام “hypervisor” می‌باشد که بین سخت‌افزار و سیستم‌های بالایی قرار می‌گیرد؛ این لایه مانند یک داور دسترسی از ماشین‌های مجازی به سخت‌افزار را کنترل می‌کند. اگرچه، تنها شامل چند دستورالعمل کوتاه است، باقی عملیات به طور مستقیم از طرف سخت‌افزار و به نیابت از سیستم‌های دیگر انجام می‌شوند. مزیت اصلی آن این است که عملکرد کاهش نمی‌یابد و سیستم‌های تقریبا با سرعت اصلی سخت‌افزار اجرا می‌شوند؛ اشکال اصلی آن این است که کرنل‌های سیستم عامل‌ها به منظور استفاده از hypervisor باید سازگار با Xen باشند.
بیایید چند عبارت را بررسی کنیم. hypervisor پایین‌ترین لایه است که به صورت مستقیم روی سخت‌افزار اجرا می‌شود، حتی پایین‌تر از کرنل. این hypervisor می‌تواند سایر نرم‌افزارها را درون چندین دامنه قرار دهد، که می‌توانند به عنوان ماشین‌های مجازی دیده شوند. یکی از این دامنه‌ها (اولین آن‌ها که آغاز می‌شود) به عنوان dom0 شناخته می‌شود و نقش ویژه‌ای دارد، چرا که تنها این دامنه می‌تواند hypervisor و اجرای سایر دامنه‌ها را کنترل کند. سایر دامنه‌ها به عنوان domU شناخته می‌شوند. به عبارت دیگر، و از دید کاربر، dom0 به عنوان “میزبان” برای سایر سیستم‌های مجازی عمل می‌کند در صورتی که domU به عنوان یک “میهمان” دیده می‌شود.
استفاده از Xen تحت دبیان نیازمند سه مولفه است:
  • The hypervisor itself. According to the available hardware, the appropriate package will be either xen-hypervisor-4.11-amd64, xen-hypervisor-4.11-armhf, or xen-hypervisor-4.11-arm64.
  • A kernel that runs on that hypervisor. Any kernel more recent than 3.0 will do, including the 4.19 version present in Buster.
  • معماری i386 همچنین نیازمند یک کتابخانه استاندارد است که بتواند از اصلاحیه‌های موجود در Xen بهره‌مند شود؛ این کتابخانه در بسته libc6-xen موجود است.
The hypervisor also brings xen-utils-4.11, which contains tools to control the hypervisor from the dom0. This in turn brings the appropriate standard library. During the installation of all that, configuration scripts also create a new entry in the GRUB bootloader menu, so as to start the chosen kernel in a Xen dom0. Note, however, that this entry is not usually set to be the first one in the list, but it will be selected by default.
زمانی که این پیشنیازها نصب شوند، گام بعدی آزمایش عملکرد خود dom0 است؛ این عمل شامل راه‌اندازی مجدد hypervisor و کرنل Xen می‌باشد. سیستم باید به شیوه استاندارد خود راه‌اندازی شده، همراه با چندین پیام که طی گام‌های اولیه راه‌اندزای در کنسول نمایش می‌یابند.
اکنون زمان آن فرا رسیده است که با استفاده از ابزار موجود در xen-tools به نصب سیستم‌های کاربردی روی domU بپردازیم. این بسته شامل دستور xen-create-image می‌باشد که تقریبا این فرآیند را خودکارسازی می‌کند. تنها پارامتر ضروری آن --hostname است که نام domU را مشخص می‌کند؛ سایر گزینه‌ها نیز مهم هستند ولی می‌توانند درون فایل پیکربندی /etc/xen-tools/xen-tools.conf قرار بگیرند که نبود آن‌ها خطایی را در هنگام اجرای دستور صادر نمی‌کند. بنابراین مهم است که محتوای این فایل را قبل از ایجاد هر image بررسی کرده یا از پارامترهای اضافی هنگام فراخوانی xen-create-image استفاده کنیم. پارامترهای مهم قابل ذکر عبارتند از:
  • --memory، برای مشخص کردن میزان RAM اختصاص یافته به سیستم جدید؛
  • --size و --swap، برای تعریف اندازه "دیسک‌های مجازی" موجود برای domU؛
  • --debootstrap-cmd, to specify the which debootstrap command is used. The default is debootstrap if debootstrap and cdebootstrap are installed. In that case, the --dist option will also most often be used (with a distribution name such as buster).
  • --dhcp بیان می‌کند که پیکربندی شبکه domU باید از طریق DHCP انجام شود در صورتی که --ip امکان استفاده از نشانی ایستای IP را فراهم می‌کند.
  • در انتها، از یک روش ذخیره‌سازی به منظور ایجاد image استفاده کرد (آن‌هایی که به عنوان درایوهای هارد دیسک از domU در نظر گرفته می‌شوند). ساده‌ترین روش، با توجه به گزینه --dir، ایجاد یک فایل در dom0 به ازای هر دستگاه domU فراهم‌کننده آن است. برای سیستم‌هایی که از LVM استفاده می‌کنند، گزینه جایگزین استفاده از --lvm است، که همراه با نام یک گروه آرایه آورده می‌شود؛ سپس xen-create-image اقدام به ایجاد یک گروه منطقی درون آرایه‌ها می‌کند که این گروه منطقی به عنوان یک درایو هارد دیسک به domU معرفی می‌گردد.
زمانی که این انتخاب‌ّها صورت گیرد، می‌توانیم image خود را برای domU بعدی در Xen ایجاد کنیم:
# xen-create-image --hostname testxen --dhcp --dir /srv/testxen --size=2G --dist=buster --role=udev

[...]
eneral Information
--------------------
Hostname       :  testxen
Distribution   :  buster
Mirror         :  http://deb.debian.org/debian
Partitions     :  swap            512M  (swap)
                  /               2G    (ext4)
Image type     :  sparse
Memory size    :  256M
Kernel path    :  /boot/vmlinuz-4.19.0-5-amd64
Initrd path    :  /boot/initrd.img-4.19.0-5-amd64
[...]
Logfile produced at:
         /var/log/xen-tools/testxen.log

Installation Summary
---------------------
Hostname        :  testxen
Distribution    :  buster
MAC Address     :  00:16:3E:0C:74:2F
IP Address(es)  :  dynamic
SSH Fingerprint :  SHA256:PuAGX4/4S07Xzh1u0Cl2tL04EL5udf9ajvvbufBrfvU (DSA)
SSH Fingerprint :  SHA256:ajFTX54eakzolyzmZku/ihq/BK6KYsz5MewJ98BM5co (ECDSA)
SSH Fingerprint :  SHA256:/sFov86b+rD/bRSJoHKbiMqzGFiwgZulEwpzsiw6aSc (ED25519)
SSH Fingerprint :  SHA256:/NJg/CcoVj+OLE/cL3yyJINStnla7YkHKe3/xEdVGqc (RSA)
Root Password   :  EwmQMHtywY9zsRBpqQuxZTb
اکنون دارای یک ماشین مجازی هستیم که اجرا نمی‌شود (و تنها از فضای موجود در هارد دیسک dom0 استفاده می‌کند). البته که می‌توانیم با استفاده از پارامترهای گوناگون دیگر image بیشتری بسازیم.
قبل از اینکه این ماشین‌های مجازی را روشن کنیم باید راجع به چگونگی دسترسی به آن‌ها تصمیم بگیریم. آن‌ها می‌توانند به عنوان ماشین‌های ایزوله شده تنها از طریق کنسول سیستم خود تعریف شوند، اما این روش به ندرت از الگوی کارکرد تبعیت می‌کند. اکثر مواقع، یک domU به عنوان یک سرور راه دور در نظر گرفته می‌شود که تنها از طریق یک شبکه قابل دسترسی است. با این حال، اختصاص یک کارت شبکه به هر domU ممکن است مناسب نباشد؛ به همین دلیل است که Xen امکان ایجاد رابط‌های مجازی که هر دامنه قادر به مشاهده و استفاده استاندارد از آن‌ها باشد را می‌دهد. به یاد داشته باشید که این کارت‌ها، با وجود مجازی بودن، تنها زمانی مفید هستند که به یک شبکه متصل گردند. Xen دارای چندین مدل شبکه برای این منظور است:
  • ساده‌ترین مدل bridge است؛ تمام کارت‌های شبکه eth0 (در سیستم‌های dom0 و domU) طوری عمل می‌کنند گویی به سوئیچ اصلی Ethernet متصل شده‌اند.
  • سپس مدل routing قرار دارد، به صورتی که dom0 به عنوان یک مسیریاب میان سیستم‌های domU و شبکه خارجی (فیزیکی) قرار می‌گیرد.
  • در نهایت، در مدل NAT، dom0 بین سیستم‌های domU و باقی شبکه قرار می‌گیرد، اما سیستم‌های domU به صورت مستقیم از خارج قابل دسترس نیستند و ترافیک از طریق ترجمه نشانی شبکه یا NAT با استفاده از dom0 انتقال می‌یابد.
این سه مدل شبکه دارای تعدادی رابط با نام‌های نامتعارف هستند از جمله vif*، veth*، peth* و xenbr0. hypervisor موجود در Xen با توجه به لایه تعریف شده آن‌ها را مرتب‌سازی می‌کند که این کار با استفاده از ابزارهای سمت-کاربر صورت می‌گیرد. از آنجا که مدل‌های NAT و routing تنها برای موارد خاص کاربرد دارند، تنها به بررسی مدل bridge می‌پردازیم.
The standard configuration of the Xen packages does not change the system-wide network configuration. However, the xend daemon is configured to integrate virtual network interfaces into any pre-existing network bridge (with xenbr0 taking precedence if several such bridges exist). We must therefore set up a bridge in /etc/network/interfaces (which requires installing the bridge-utils package, which is why the xen-utils-4.11 package recommends it) to replace the existing eth0 entry:
auto xenbr0
iface xenbr0 inet dhcp
    bridge_ports eth0
    bridge_maxwait 0
After rebooting to make sure the bridge is automatically created, we can now start the domU with the Xen control tools, in particular the xl command. This command allows different manipulations on the domains, including listing them and, starting/stopping them. You might need to increase the default memory by editing the variable memory from configuration file (in this case, /etc/xen/testxen.cfg). Here we have set it to 1024 (megabytes).
# xl list
Name                                        ID   Mem VCPUs	State	Time(s)
Domain-0                                     0  1894     2     r-----      63.5
# xl create /etc/xen/testxen.cfg
Parsing config from /etc/xen/testxen.cfg
# xl list
Name                                        ID   Mem VCPUs	State	Time(s)
Domain-0                                     0  1505     2     r-----     100.0
testxen                                     13  1024     0     --p---       0.0
به یاد داشته باشید که domU ایجاد شده بنام ... از حافظه واقعی گرفته شده از RAM که معمولا برای dom0 در نظر گرفته می‌شود، استفاده می‌کند و نه یک حافظه شبیه‌سازی شده. بنابراین هنگام راه‌اندازی یک سرور مبتی بر Xen باید دقت عمل در تخصیص حافظه به خرج داد.
بسیار خوب! ماشین مجازی ما راه‌اندازی شد. دو روش دسترسی به آن وجود دارد. روش معمول اتصال ... به آن است، مانند یک ماشین حقیقی که از طریق شبکه متصل می‌شویم؛ اینکار نیازمند برپایی یک سرور DHCP یا پیکربندی DNS جداگانه است. روش دیگر، که در صورت اشتباه بودن پیکربندی شبکه می‌تواند تنها روش ممکن باشد، استفاده از کنسول hvc0 همراه با دستور xl console است:
# xl console testxen
[...]

Debian GNU/Linux 10 testxen hvc0

testxen login: 
در این حالت می‌توان یک نشست جداگانه برای دسترسی به ماشین مجازی ایجاد کرد. قطع اتصال این کنسول با استفاده از کلید ترکیبی Control+] انجام می‌شود.
زمانی که domU آغاز گردد، می‌تواند مانند هر سرور دیگری مورد استفاده قرار گیرد (چرا که یک سیستم گنو/لینوکس است). اگرچه، وضعیت ماشین مجازی آن برخی قابلیت‌های دیگر را فراهم می‌کند. برای نمونه، یک domU با استفاده از دستورات xl pause و xl unpause می‌تواند به صورت موقت متوقف شده یا ادامه یابد. به یاد داشته باشید که یک domU متوقف شده با اینکه از قدرت پردازنده استفاده نمی‌کند، اما هم اکنون حافظه اختصاص یافته به خود را دارد. استفاده از دستورات xl save و xl restore نیز قابل توجه است: ذخیره‌سازی یک domU تمام منابع اختصاص یافته به آن، از جمله RAM، را آزادسازی می‌کند. در زمان بازگرداندن (یا ادامه، به این منظور) یک domU چیزی به جز گذشت زمان را احساس نمی‌کند. اگر هنگام خاموش کردن dom0 یک domU در حال اجرا باشد، اسکریپت‌های پیکربندی به صورت خودکار domU را ذخیره‌سازی کرده تا در راه‌اندازی بعدی از سر گرفته شود. این عمل البته ناملایمت‌های عملیات hibernate کردن یک رایانه لپ‌تاپ را به همراه دارد، برای نمونه؛ به طور مشخص اگر domU به مدت زمان طولانی در حالت تعلیق باشد، ارتباطات شبکه ممکن است منقضی گردند. به یاد داشته باشید که Xen به شدت ناسازگار با بخش مدیریت قدرت ACPI است، که عملیات متوقف‌سازی سیستم میزبان (dom0) را انجام می‌دهد.
متوقف‌سازی یا راه‌اندازی مجدد یک domU می‌تواند از طریق خود آن (با دستور shutdown) یا از طریق dom0 با استفاده از xl shutdown یا xl reboot انجام شود.

12.2.2. LXC

با اینکه از آن برای ساخت “ماشین‌های مجازی” استفاده می‌شود، LXC به طور دقیق یک سیستم مجازی‌سازی نیست، بلکه سیستمی برای جدا کردن گروهی از فرآیندها نسبت به یکدیگر می‌باشد که درون یک میزبان اجرا می‌شوند. این سیستم از پیشرفت‌های اخیر در کرنل لینوکس بهره می‌برد، که بنام گروه‌های کنترل شناخته می‌شوند، به این معنی که مجموعه‌های مختلف از فرآیندها که “گروه” نامیده می‌شوند دید متفاوتی نسبت به جنبه‌های کلی سیستم دارند. از جمله این جنبه‌ها می‌توان به شناسه‌های فرآیند، پیکربندی شبکه و نقاط اتصال اشاره کرد. چنین گروهی از فرآیندهای ایزوله‌شده هیچ گونه دسترسی دیگر به سایر فرآیندهای سیستم ندارند و دسترسی آن‌ها به فایل سیستم تنها محدود به مجموعه‌ای کوچک می‌گردد. از این رو می‌تواند رابط شبکه و جدول مسیریابی مربوط به خود را داشته باشد و می‌تواند طوری پیکربندی شود که تنها مجموعه کوچکی از دستگاه‌های موجود در سیستم را مشاهده کند.
این ویژگی‌ها می‌توانند به منظور جدا کردن خانواده فرآیند آغازی توسط init با یکدیگر ترکیب شده که نتیجه نهایی آن مشابه با ماشین مجازی است. نام رسمی چنین تنظیمی “مخزن” است (با توجه به نام LXC که برابر است با: LinuX Containers) اما تفاوت عمده آن با ماشین‌های مجازی “واقعی” مانند Xen یا KVM در نبود یک کرنل دوم است؛ مخزن از همان کرنل سیستم میزبان استفاده می‌کند. اینکار مزایا و معایب خود را دارد: مزایای آن شامل عملکرد فوق‌العاده به دلیل نبود overhead و این حقیقت که کرنل یک دید سراسری نسبت به تمام فرآیندهای اجرایی روی سیستم دارد، به این منظور که عملیات زمان‌بندی می‌تواند به شیوه‌ای موثرتر انجام شود نسبت به حالتی که دو کرنل جداگانه باید مجموعه‌‌های مختلف از وظایف را مدیریت می‌کردند. از میان معایت نیز می‌توان به غیرممکن بودن اجرای یک کرنل مختلف درون یک مخزن اشاره کرد (خواه یک نسخه متفاوت لینوکس خواه یک سیستم عامل دیگر).
از آنجا که با مفهوم ایزوله کردن و نه یک راهکار مجازی‌سازی ساده سروکار داریم، برپایی مخازن LXC بسیار پیچیده‌تر از اجرای debian-installer در یک ماشین مجازی است. ابتدا چندین پیشنیاز را بررسی کرده سپس به قسمت پیکربندی شبکه می‌رویم؛ در این قسمت است که می‌توانیم سیستم را درون یک مخزن اجرا کنیم.

12.2.2.1. گام‌های مقدماتی

بسته lxc شامل ابزار مورد نیاز برای نصب و اجرای LXC است.
LXC همچنین به سیستم پیکربندی control groups نیاز دارد که به صورت یک فایل سیستم مجازی به /sys/fs/cgroup متصل می‌شود. از آنجا که دبیان ۸ به systemd روی آورده، که خود مبتنی بر گروه‌های کنترل است، اینکار در زمان راه‌اندازی سیستم بدون هیچ پیکربندی خاص صورت می‌گیرد.

12.2.2.2. پیکربندی شبکه

The goal of installing LXC is to set up virtual machines; while we could, of course, keep them isolated from the network, and only communicate with them via the filesystem, most use cases involve giving at least minimal network access to the containers. In the typical case, each container will get a virtual network interface, connected to the real network through a bridge. This virtual interface can be plugged either directly onto the host's physical network interface (in which case the container is directly on the network), or onto another virtual interface defined on the host (and the host can then filter or route traffic). In both cases, the bridge-utils package will be required.
The simple case is just a matter of editing /etc/network/interfaces, moving the configuration for the physical interface (for instance, eth0) to a bridge interface (usually br0), and configuring the link between them. For instance, if the network interface configuration file initially contains entries such as the following:
auto eth0
iface eth0 inet dhcp
آن‌ها باید غیرفعال شده و با مدخل‌های زیر جایگزین گردند:
#auto eth0
#iface eth0 inet dhcp

auto br0
iface br0 inet dhcp
  bridge-ports eth0
تاثیر این پیکربندی مشابه با حالتی خواهد بود که مخازن به صورت ماشین‌هایی به شبکه فیزیکی یکسانی از طریق میزبان متصل می‌شدند. پیکربندی “bridge” انتقال فریم‌های Ethernet را بین تمام رابط‌های bridged مدیریت می‌کند که شامل eth0 همراه با رابط‌های تعریف شده برای مخازن می‌باشد.
In cases where this configuration cannot be used (for instance, if no public IP addresses can be assigned to the containers), a virtual tap interface will be created and connected to the bridge. The equivalent network topology then becomes that of a host with a second network card plugged into a separate switch, with the containers also plugged into that switch. The host must then act as a gateway for the containers if they are meant to communicate with the outside world.
علاوه بر bridge-utils، این پیکربندی “غنی” نیازمند بسته vde2 است؛ فایل /etc/network/interfaces سپس به صورت زیر در می‌آید:
# Interface eth0 is unchanged
auto eth0
iface eth0 inet dhcp

# Virtual interface 
auto tap0
iface tap0 inet manual
  vde2-switch -t tap0

# Bridge for containers
auto br0
iface br0 inet static
  bridge-ports tap0
  address 10.0.0.1
  netmask 255.255.255.0
شبکه می‌تواند یا به صورت ایستا درون مخازن یا به صورت پویا از طریق سرور DHCP درون میزبان برپا شود. چنین سرور DHCP باید طوری پیکربندی شود که به پرس و جوهای موجود در رابط br0 پاسخ دهد.

12.2.2.3. برپایی سیستم

اکنون بیاید فایل سیستم مورد نیاز مخزن را برپا کنیم. از آنجا که این “ماشین مجازی” به صورت مستقیم روی سخت‌افزار اجرا نخواهد شد، در مقایسه با یک فایل سیستم استاندارد رعایت برخی نکات ضروری است، به خصوص تا آنجا که به کرنل، دستگاه‌ها و کنسول‌ها مربوط باشد. خوشبختانه lxc شامل اسکریپت‌هایی است که اکثر این پیکربندی را به صورت خودکار انجام می‌دهند. برای نمونه، دستورات پیش رو (که نیازمند بسته‌های debootstrap و rsync هستند) اقدام به نصب یک مخزن دبیان می‌کنند:
root@mirwiz:~# lxc-create -n testlxc -t debian
debootstrap is /usr/sbin/debootstrap
Checking cache download in /var/cache/lxc/debian/rootfs-stable-amd64 ... 
Downloading debian minimal ...
I: Retrieving Release 
I: Retrieving Release.gpg 
[...]
Download complete.
Copying rootfs to /var/lib/lxc/testlxc/rootfs...
[...]
root@mirwiz:~# 
به یاد داشته باشید که فایل سیستم به صورت اولیه در /var/cache/lxc ایجاد شد، سپس به مقصد خود انتقال یافت. اینکار امکان ایجاد مخازن مشابه را با سرعت بیشتری فراهم می‌کند، چرا که تنها عملیات رونوشت‌گیری مورد نیاز است.
Note that the Debian template creation script accepts an --arch option to specify the architecture of the system to be installed and a --release option if you want to install something else than the current stable release of Debian. You can also set the MIRROR environment variable to point to a local Debian mirror.
فایل سیستم تازه ایجاد شده اکنون شامل یک سیستم پایه دبیان است و مخزن پیشفرض آن هیچ رابط شبکه‌ای ندارد (بجز گزینه loopback). از آنجا که این مورد نظر ما نیست، به ویرایش فایل پیکربندی مخزن (/var/lib/lxc/testlxc/config) پرداخته و چندین مدخل lxc.network.* را در آن ایجاد می‌کنیم:
lxc.net.0.type = veth
lxc.net.0.flags = up
lxc.net.0.link = br0
lxc.net.0.hwaddr = 4a:49:43:49:79:20
وجود این مدخل‌ها به این معنی است که یک رابط مجازی برای مخزن ایجاد خواهد شد؛ که به صورت خودکار هنگام آغاز مخزن شروع می‌شوند؛ که به صورت خودکار به bridge موجود در میزبان بنام br0 متصل می‌شوند؛ که نشانی MAC آن مطابق بالا خواهد بود. در صورت فقدان یا غیرفعال بودن این گزینه آخر، از یک نشانی MAC تصادفی استفاده خواهد شد.
یک مدخل مفید دیگر در آن فایل تنظیم نام میزبان است:
lxc.uts.name = testlxc

12.2.2.4. آغاز مخزن

Now that our virtual machine image is ready, let's start the container with lxc-start --daemon --name=testlxc.
In LXC releases following 2.0.8, root passwords are not set by default. We can set one running lxc-attach -n testlxc passwd. Now we can login:
root@mirwiz:~# lxc-console -n testlxc
Debian GNU/Linux 9 testlxc console	

testlxc login: root
Password: 
Linux testlxc 4.19.0-5-amd64 #1 SMP Debian 4.19.37-5 (2019-06-19) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@testlxc:~# ps auxwf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2  56736  6608 ?        Ss   09:28   0:00 /sbin/init
root        32  0.0  0.1  46096  4680 ?        Ss   09:28   0:00 /lib/systemd/systemd-journald
root        75  0.0  0.1  67068  3328 console  Ss   09:28   0:00 /bin/login --
root        82  0.0  0.1  19812  3664 console  S    09:30   0:00  \_ -bash
root        88  0.0  0.1  38308  3176 console  R+   09:31   0:00      \_ ps auxwf
root        76  0.0  0.1  69956  5636 ?        Ss   09:28   0:00 /usr/sbin/sshd -D
root@testlxc:~# 
اکنون درون مخزن هستیم؛ دسترسی به فرآیندها تنها محدود به آن‌هایی است که توسط مخزن آغاز شده باشند و دسترسی به فایل سیستم تنها بخش کوچکی از فایل سیستم کامل /var/lib/lxc/testlxc/rootfs را شامل می‌شود. با استفاده از کلید ترکیبی Control+a q می‌توانیم از کنسول خارج شویم.
به یاد داشته باشید که مخزن را به عنوان یک فرآیند پس‌زمینه اجرا کردیم، به لطف گزینه --daemon از lxc-start. با استفاده از دستور lxc-stop --name=testlxc می‌توانیم مخزن را متوقف کنیم.
بسته lxc شامل یک اسکریپت راه‌اندازی است که به صورت خودکار یک یا چند مخزن را در زمان راه‌اندازی میزبان آغاز می‌کند (مبتنی بر lxc-autostart است که به صورت خودکار مخازن شامل گزینه lxc.start.auto برابر ۱ را راه‌اندازی می‌کند). با استفاده از lxc.start.order و lxc.group می‌توان کنترل بیشتری روی ترتیب اجرای مخازن اعمال کرد: به صورت پیشفرض، اسکریپت راه‌اندازی ابتدا مخازنی را آغاز می‌کند که جزو گروه onboot باشند سپس به سراغ مخازن دیگر می‌رود). در هر دو مورد، ترتیب درون هر گروه توسط گزینه lxc.start.order مشخص می‌شود.

12.2.3. مجازی‌سازی با KVM

KVM، که مخفف عبارت Kernel-based Virtual Machine است، در درجه اول یک افزونه کرنل به حساب می‌آید که اکثر زیرساخت مورد نیاز یک مجازی‌ساز را فراهم می‌کند اما خود یک مجازی‌ساز نیست. کنترل واقعی مجازی‌سازی توسط برنامه‌ای مبتنی بر QEMU انجام می‌شود. نگران نباشید اگر در این قسمت دستورات مربوط به qemu-* را مشاهده کنید: تمام آن‌ها مرتبط با KVM هستند.
برخلاف سایر سیستم‌های مجازی‌سازی، KVM از ابتدا درون کرنل لینوکس قرار گرفت. توسعه‌دهندگان آن تصمیم گرفتند از مجموعه دستورالعمل‌های پردازنده برای مجازی‌سازی (Intel-VT و AMD-V) استفاده کنند که اینکار باعث می‌شود KVM سبک، ظریف و سازگار با منابع پایین باشد. نقطه ضعف آن این است که KVM روی هر رایانه‌ای نمی‌تواند اجرا شود بلکه فقط برخی پردازنده‌های خاص از آن پشتیبانی می‌کنند. برای رایانه‌های مبتنی بر x86، می‌توانید به دنبال پرچم‌های مخصوص پردازنده به نام “vmx” یا “svm” در فایل /proc/cpuinfo بگردید.
با پشتیبانی مداوم Red Hat از توسعه آن، KVM کم و بیش به مرجع مجازی‌سازی در لینوکس تبدیل شده است.

12.2.3.1. گام‌های مقدماتی

KVM برخلاف ابزاری مانند VirtualBox، شامل رابط کاربری برای مدیریت ماشین‌های مجازی نیست. بسته qemu-kvm تنها شامل یک فایل اجرایی برای آغاز یک ماشین مجازی است، همراه با اسکریپت‌های راه‌اندازی که اقدام به بارگیری افزونه‌های مناسب کرنل می‌کنند.
خوشبختانه، Red Hat برای غلبه بر این مشکل مجموعه ابزاری فراهم کرده است که شامل کتابخانه libvirt و ابزارهای virtual machine manager می‌شوند. libvirt امکان مدیریت ماشین‌های مجازی را به یک شیوه یکسان فراهم می‌کند، جدا از سیستم مجازی‌سازی که در پشت صحنه قرار دارد (هم اکنون از QEMU، KVM، Xen، LXC، OpenVZ، VirtualBox، VMWare و UML پشتیبانی می‌کند). virtual-manager یک رابط گرافیکی است که با استفاده از libvirt ماشین‌های مجازی را مدیریت می‌کند.
We first install the required packages, with apt-get install libvirt-clients libvirt-daemon-system qemu-kvm virtinst virt-manager virt-viewer. libvirt-daemon-system provides the libvirtd daemon, which allows (potentially remote) management of the virtual machines running of the host, and starts the required VMs when the host boots. libvirt-clients provides the virsh command-line tool, which allows controlling the libvirtd-managed machines.
بسته virtinst شامل virt-install می‌شود که امکان ایجاد ماشین‌های مجازی از خط فرمان را فراهم می‌کند. در نهایت، virt-viewer اجازه دسترسی به کنسول گرافیکی یک ماشین مجازی را بوجود می‌آورد.

12.2.3.2. پیکربندی شبکه

درست مانند Xen و LXC، متداول‌ترین پیکربندی شبکه شامل یک bridge که رابط‌های شبکه ماشین‌های مجازی را گروه‌بندی می‌کند، می‌باشد ( قسمت 12.2.2.2, “پیکربندی شبکه” را مشاهده کنید).
به طور متقابل، در پیکربندی پیشفرض فراهم شده توسط KVM، یک نشانی خصوصی به ماشین مجازی اختصاص می‌یابد (در محدوده 192.168.122.0/24) و NAT طوری تنظیم می‌شود که ماشین مجازی بتواند به شبکه خارجی دسترسی داشته باشد.
باقیمانده این قسمت با توجه به اینکه میزبان دارای یک رابط فیزیکی eth0 و bridge br0 است ادامه می‌یابد، به طوری که اولی به دومی متصل شده است.

12.2.3.3. نصب با virt-install

ایجاد یک ماشین مجازی بسیار شبیه یک سیستم عادی است، با این تفاوت که ویژگی‌های ماشین مجازی به صورت گزینه‌های بی‌پایان در خط فرمان قرار می‌گیرند.
در عمل، یعنی از یک نصب کننده دبیان استفاده خواهیم کرد، با راه‌اندازی ماشین مجازی روی یک درایو DVD-ROM که به یک تصویر از DVD دبیان ذخیره شده در سیستم میزبان نگاشت شده است. ماشین مجازی از طریق پروتکل VNC کنسول گرافیکی خود را آماده می‌کند ( قسمت 9.2.2, “استفاده از میزکارهای گرافیکی راه‌دور” را مشاهده کنید) که اینکار به ما اجازه می‌دهد فرآیند نصب را کنترل کنیم.
ابتدا باید به libvirtd بگوییم تصاویر دیسک را در کجا ذخیره کند، مگر مکان پیشفرض /var/lib/libvirt/images/ مناسب باشد.
root@mirwiz:~# mkdir /srv/kvm
root@mirwiz:~# virsh pool-create-as srv-kvm dir --target /srv/kvm
Pool srv-kvm created

root@mirwiz:~# 
اکنون بیایید فرآیند نصب ماشین مجازی را آغاز کرده و نگاهی بر مهم‌ترین گزینه‌های virt-install بیندازیم. این دستور، ماشین مجازی و پارامترهای آن را در libvirtd ثبت می‌کند سپس به اجرای آن پرداخته تا فرآیند نصب ادامه یابد.
# virt-install --connect qemu:///system  1
               --virt-type kvm           2
               --name testkvm            3
               --memory 1024                4
               --disk /srv/kvm/testkvm.qcow,format=qcow2,size=10 5
               --cdrom /srv/isos/debian-9.9.0-amd64-netinst.iso  6
               --network bridge=virbr0      7
               --graphics vnc                     8
               --os-type linux           9
               --os-variant debian9

Starting install...
Allocating 'testkvm.qcow'             |  10 GB     00:00

1

گزینه --connect مشخص می‌کند از کدام “hypervisor” استفاده شود. فرم استفاده از آن شامل یک URL همراه با سیستم مجازی‌سازی مرتبط (xen://، qemu://، lxc://، openvz://، vbox://) و ماشینی که باید از آن میزبانی کند می‌باشد (در صورت استفاده از localhost می‌تواند خالی باشد). علاوه بر این و در مورد QEMU/KVM، هر کاربر می‌تواند با استفاده از مجوزهای محدودشده ماشین‌های مجازی را مدیریت کند و مسیر URL امکان تفاوت قائل شدن بین ماشین‌های “سیستم” (/system) را از دیگر (/session) فراهم می‌کند.

2

از آنجا که KVM به شیوه مشابه QEMU مدیریت می‌شود، --virt-type kvm امکان مشخص کردن استفاده از KVM با وجود تشابه با URL QEMU را فراهم می‌کند.

3

گزینه --name یک نام (منحصربفرد) برای ماشین مجازی تعریف می‌کند.

4

The --memory option allows specifying the amount of RAM (in MB) to allocate for the virtual machine.

5

The --disk specifies the location of the image file that is to represent our virtual machine's hard disk; that file is created, unless present, with a size (in GB) specified by the size parameter. The format parameter allows choosing among several ways of storing the image file. The default format (qcow2) allows starting with a small file that only grows when the virtual machine starts actually using space.

6

گزینه --cdrom به منظور یافتن دیسک نوری برای فرآیند نصب استفاده می‌شود. مسیر می‌تواند شامل یک مسیر محلی برای فایل ISO، یک URL که فایل می‌تواند از آنجا دریافت شود یا فایل دستگاه مربوط به یک درایو فیزیکی CD-ROM باشد (/dev/cdrom).

7

گزینه --network مشخص می‌کند کارت مجازی شبکه چطور با پیکربندی سیستم میزبان ادغام شود. عملکرد پیشفرض آن (که در این نمونه به صورت صریح بیان کرده‌ایم) ادغام آن با شبکه bridge از قبل موجود در سیستم است. اگر چنین bridge موجود نباشد، ماشین مجازی تنها با استفاده از NAT می‌تواند به شبکه فیزیکی دسترسی یابد، بنابراین یک نشانی در محدوده زیرشبکه 192.168.122.0/24 دریافت می‌کند.

8

--graphics vnc states that the graphical console should be made available using VNC. The default behavior for the associated VNC server is to only listen on the local interface; if the VNC client is to be run on a different host, establishing the connection will require setting up an SSH tunnel (see قسمت 9.2.1.3, “ایجاد تونل‌های رمزگذاری شده با پورت فورواردینگ” ). Alternatively, --graphics vnc,listen=0.0.0.0 can be used so that the VNC server is accessible from all interfaces; note that if you do that, you really should design your firewall accordingly.

9

گزینه‌های --os-type و --os-variant، با توجه به برخی از ویژگ‌های سیستم عامل اشاره شده، امکان بهینه‌سازی چندین پارامتر ماشین مجازی را فراهم می‌کنند.
در این نقطه، ماشین مجازی در حال اجرا است و به منظور ادامه فرآیند نصب باید به کنسول گرافیکی متصل شویم. اگر عملیات قبل از طریق یک میزکار گرافیکی صورت گرفته باشد، این ارتباط به صورت مستقیم برقرار می‌شود. در غیر اینصورت، یا در حالتی که از راه دور اینکار را انجام می‌دهیم، virt-viewer با استفاده از هر محیط گرافیکی برای باز کردن کنسول گرافیکی می‌تواند اجرا شود (به یاد داشته باشید که دو مرتبه گذرواژه root درخواست می‌شود چرا که ۲ ارتباط SSH مورد نیاز است):
$ virt-viewer --connect qemu+ssh://root@server/system testkvm
root@server's password: 
root@server's password: 
زمانی که فرآیند نصب به پایان برسد، ماشین مجازی راه‌اندازی مجدد می‌گردد تا قابل استفاده شود.

12.2.3.4. مدیریت ماشین‌های مجازی با virsh

اکنون که نصب به پایان رسیده است، بیایید چگونگی مدیریت ماشین‌های مجازی را بررسی کنیم. اولین کاری که باید بکنیم پرسش از libvirtd برای فهرستی از ماشین‌های مجازی موجود است:
# virsh -c qemu:///system list --all
 Id Name                 State
----------------------------------
  8 testkvm              shut off
بیایید ماشین مجازی آزمایشی خود را آغاز کنیم:
# virsh -c qemu:///system start testkvm
Domain testkvm started
اکنون می‌توانیم دستورالعمل‌های ارتباط به کنسول گرافیکی را دریافت کنیم (نمایش VNC بازگشتی می‌تواند به عنوان پارامتر vncviewer استفاده شود):
# virsh -c qemu:///system vncdisplay testkvm
127.0.0.1:0
سایر دستورات virsh عبارتند از:
  • reboot برای راه‌اندازی مجدد یک ماشین مجازی؛
  • shutdown برای درخواست یک shutdown تمیز؛
  • destroy برای توقف خشن آن؛
  • suspend برای توقف عادی آن؛
  • resume برای ادامه فعالیت آن؛
  • autostart برای فعال کردن (یا غیر فعال کردن با گزینه --disable) راه‌اندازی ماشین مجازی به صورت خودکار در زمان راه‌اندازی میزبان؛
  • undefine برای حذف تمام نشانه‌های ماشین مجازی از libvirtd.
تمام این دستورات شناسه ماشین مجازی را به عنوان یک پارامتر دریافت می‌کنند.

12.2.3.5. نصب یک سیستم مبتنی بر RPM در دبیان با استفاده از yum

اگر قرار باشد ماشین مجازی به منظور اجرای دبیان (یا یکی از توزیع‌های آن) راه‌اندازی گردد، سیستم می‌تواند با استفاده از debootstrap همانطور که توضیح داده شد راه‌اندازی شود. اما اگر قرار باشد ماشین مجازی به منظور اجرای یک سیستم مبتنی بر RPM (مانند Fedora، CentOS یا Scientific Linux) راه‌اندازی گردد، اینکار باید با استفاده از ابزار yum صورت گیرد (که در بسته‌ای با همین نام قرار دارد).
این فرآیند شامل استفاده از rpm به منظور استخراج مجموعه‌ای از فایل‌ها، شامل فایل‌های پیکربندی yum، سپس فراخوانی yum برای استخراج سایر بسته‌های باقیمانده می‌باشد. اما از آنجا که فراخوانی yum خارج از chroot صورت می‌گیرد، باید برخی تغییرات موقتی را ایجاد کنیم. در نمونه زیر، chroot هدف عبارت است از /srv/centos.
# rootdir="/srv/centos"
# mkdir -p "$rootdir" /etc/rpm
# echo "%_dbpath /var/lib/rpm" > /etc/rpm/macros.dbpath
# wget http://mirror.centos.org/centos/7/os/x86_64/Packages/centos-release-7-6.1810.2.el7.centos.x86_64.rpm
# rpm --nodeps --root "$rootdir" -i centos-release-7-6.1810.2.el7.centos.x86_64.rpm
rpm: RPM should not be used directly install RPM packages, use Alien instead!
rpm: However assuming you know what you are doing...
warning: centos-release-7-6.1810.2.el7.centos.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
# sed -i -e "s,gpgkey=file:///etc/,gpgkey=file://${rootdir}/etc/,g" $rootdir/etc/yum.repos.d/*.repo
# yum --assumeyes --installroot $rootdir groupinstall core
[...]
# sed -i -e "s,gpgkey=file://${rootdir}/etc/,gpgkey=file:///etc/,g" $rootdir/etc/yum.repos.d/*.repo