Product SiteDocumentation Site

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

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

12.2.1. Xen

Xen یک راهکار “paravirtualization” است که شامل یک لایه انتزاعی سبک به نام “hypervisor” می‌باشد که بین سخت‌افزار و سیستم‌های بالایی قرار می‌گیرد؛ این لایه مانند یک داور دسترسی از ماشین‌های مجازی به سخت‌افزار را کنترل می‌کند. اگرچه، تنها شامل چند دستورالعمل کوتاه است، باقی عملیات به طور مستقیم از طرف سخت‌افزار و به نیابت از سیستم‌های دیگر انجام می‌شوند. مزیت اصلی آن این است که عملکرد کاهش نمی‌یابد و سیستم‌های تقریبا با سرعت اصلی سخت‌افزار اجرا می‌شوند؛ اشکال اصلی آن این است که کرنل‌های سیستم عامل‌ها به منظور استفاده از hypervisor باید سازگار با Xen باشند.
Let's spend some time on terms. The hypervisor is the lowest layer, which runs directly on the hardware, even below the kernel. This hypervisor can split the rest of the software across several domains, which can be seen as so many virtual machines. One of these domains (the first one that gets started) is known as dom0, and has a special role, since only this domain can control the hypervisor and the execution of other domains. These other domains are known as domU. In other words, and from a user point of view, the dom0 matches the “host” of other virtualization systems, while a domU can be seen as a “guest”.
استفاده از Xen تحت دبیان نیازمند سه مولفه است:
  • The hypervisor itself. According to the available hardware, the appropriate package providing xen-hypervisor will be either xen-hypervisor-4.14-amd64, xen-hypervisor-4.14-armhf, or xen-hypervisor-4.14-arm64.
  • A kernel that runs on that hypervisor. Any kernel more recent than 3.0 will do, including the 5.10 version present in Bullseye.
  • معماری i386 همچنین نیازمند یک کتابخانه استاندارد است که بتواند از اصلاحیه‌های موجود در Xen بهره‌مند شود؛ این کتابخانه در بسته libc6-xen موجود است.
The hypervisor also brings xen-utils-4.14, 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 bullseye).
  • --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=bullseye --role=udev

General Information
--------------------
Hostname       :  testxen
Distribution   :  bullseye
Mirror         :  http://deb.debian.org/debian
Partitions     :  swap            512M  (swap)
                  /               2G    (ext4)
Image type     :  sparse
Memory size    :  256M
Bootloader     :  pygrub

[...]
Logfile produced at:
	 /var/log/xen-tools/testxen.log

Installation Summary
---------------------
Hostname        :  testxen
Distribution    :  bullseye
MAC Address     :  00:16:3E:C2:07:EE
IP Address(es)  :  dynamic
SSH Fingerprint :  SHA256:K+0QjpGzZOacLZ3jX4gBwp0mCESt5ceN5HCJZSKWS1A (DSA)
SSH Fingerprint :  SHA256:9PnovvGRuTw6dUcEVzzPKTITO0+3Ki1Gs7wu4ke+4co (ECDSA)
SSH Fingerprint :  SHA256:X5z84raKBajUkWBQA6MVuanV1OcV2YIeD0NoCLLo90k (ED25519)
SSH Fingerprint :  SHA256:VXu6l4tsrCoRsXOqAwvgt57sMRj2qArEbOzHeydvV34 (RSA)
Root Password   :  FS7CUxsY3xkusv7EkbT9yae
اکنون دارای یک ماشین مجازی هستیم که اجرا نمی‌شود (و تنها از فضای موجود در هارد دیسک dom0 استفاده می‌کند). البته که می‌توانیم با استفاده از پارامترهای گوناگون دیگر image بیشتری بسازیم.
Before turning these virtual machines on, we need to define how they'll be accessed. They can of course be considered as isolated machines, only accessed through their system console, but this rarely matches the usage pattern. Most of the time, a domU will be considered as a remote server, and accessed only through a network. However, it would be quite inconvenient to add a network card for each domU; which is why Xen allows creating virtual interfaces that each domain can see and use in a standard way. Note that these cards, even though they're virtual, will only be useful once connected to a network, even a virtual one. Xen has several network models for that:
  • ساده‌ترین مدل 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 package recommends it) to replace the existing eth0 entry (be careful to use the correct network device name):
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  3918     2     r-----      35.1
# 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  2757     2     r-----      45.2
testxen                                      3  1024     1     r-----       1.3
به یاد داشته باشید که domU ایجاد شده بنام ... از حافظه واقعی گرفته شده از RAM که معمولا برای dom0 در نظر گرفته می‌شود، استفاده می‌کند و نه یک حافظه شبیه‌سازی شده. بنابراین هنگام راه‌اندازی یک سرور مبتی بر Xen باید دقت عمل در تخصیص حافظه به خرج داد.
بسیار خوب! ماشین مجازی ما راه‌اندازی شد. دو روش دسترسی به آن وجود دارد. روش معمول اتصال ... به آن است، مانند یک ماشین حقیقی که از طریق شبکه متصل می‌شویم؛ اینکار نیازمند برپایی یک سرور DHCP یا پیکربندی DNS جداگانه است. روش دیگر، که در صورت اشتباه بودن پیکربندی شبکه می‌تواند تنها روش ممکن باشد، استفاده از کنسول hvc0 همراه با دستور xl console است:
# xl console testxen
[...]

Debian GNU/Linux 11 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 انجام شود.
اغلب زیردستورات xl شامل یک یا چند آرگومان هستند، که بیشتر شامل نام یک domU می‌شود. این آرگومان‌ها به خوبی در صفحه راهنمای xl(1) توضیح داده شده‌اند.

12.2.2. LXC

با اینکه از آن برای ساخت “ماشین‌های مجازی” استفاده می‌شود، LXC به طور دقیق یک سیستم مجازی‌سازی نیست، بلکه سیستمی برای جدا کردن گروهی از فرآیندها نسبت به یکدیگر می‌باشد که درون یک میزبان اجرا می‌شوند. این سیستم از پیشرفت‌های اخیر در کرنل لینوکس بهره می‌برد، که بنام گروه‌های کنترل شناخته می‌شوند، به این معنی که مجموعه‌های مختلف از فرآیندها که “گروه” نامیده می‌شوند دید متفاوتی نسبت به جنبه‌های کلی سیستم دارند. از جمله این جنبه‌ها می‌توان به شناسه‌های فرآیند، پیکربندی شبکه و نقاط اتصال اشاره کرد. چنین گروهی از فرآیندهای ایزوله‌شده هیچ گونه دسترسی دیگر به سایر فرآیندهای سیستم ندارند و دسترسی آن‌ها به فایل سیستم تنها محدود به مجموعه‌ای کوچک می‌گردد. از این رو می‌تواند رابط شبکه و جدول مسیریابی مربوط به خود را داشته باشد و می‌تواند طوری پیکربندی شود که تنها مجموعه کوچکی از دستگاه‌های موجود در سیستم را مشاهده کند.
These features can be combined to isolate a whole process family starting from the init process, and the resulting set looks very much like a virtual machine. The official name for such a setup is a “container” (hence the LXC moniker: LinuX Containers), but a rather important difference with “real” virtual machines such as provided by Xen or KVM is that there is no second kernel; the container uses the very same kernel as the host system. This has both pros and cons: advantages include excellent performance due to the total lack of overhead, and the fact that the kernel has a global vision of all the processes running on the system, so the scheduling can be more efficient than it would be if two independent kernels were to schedule different task sets. Chief among the inconveniences is the impossibility to run a different kernel in a container (whether a different Linux version or a different operating system altogether).
از آنجا که با مفهوم ایزوله کردن و نه یک راهکار مجازی‌سازی ساده سروکار داریم، برپایی مخازن 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 or enp1s0) 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 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. برپایی سیستم

Let us now set up the filesystem to be used by the container. Since this “virtual machine” will not run directly on the hardware, some tweaks are required when compared to a standard filesystem, especially as far as the kernel, devices and consoles are concerned. Fortunately, the lxc package includes scripts that mostly automate this configuration. For instance, the following commands (which require the debootstrap and rsync packages) will install a Debian container:
# 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...
[...]
# 
به یاد داشته باشید که فایل سیستم به صورت اولیه در /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.
The lxc package further creates a bridge interface lxcbr0, which by default is used by all newly created containers via /etc/lxc/default.conf and the lxc-net service:
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
These entries mean, respectively, that a virtual interface will be created in every new container; that it will automatically be brought up when said container is started; and that it will be automatically connected to the lxcbr0 bridge on the host. You will find these settings in the created container's configuration (/var/lib/lxc/testlxc/config), where also the device' MAC address will be specified in lxc.net.0.hwaddr. Should this last entry be missing or disabled, a random MAC address will be generated.
یک مدخل مفید دیگر در آن فایل تنظیم نام میزبان است:
lxc.uts.name = testlxc
The newly-created filesystem now contains a minimal Debian system and a network interface.

12.2.2.4. آغاز مخزن

Now that our virtual machine image is ready, let's start the container with lxc-start --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 if we want. We can login with:
# lxc-console -n testlxc
Connected to tty 1
Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself

Debian GNU/Linux 11 testlxc tty1

testlxc login: root
Password: 
Linux testlxc 5.10.0-11-amd64 #1 SMP Debian 5.10.92-1 (2022-01-18) 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.
Last login: Wed Mar  9 01:45:21 UTC 2022 on console
root@testlxc:~# ps auxwf
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.2  18964 11464 ?        Ss   01:36   0:00 /sbin/init
root          45  0.0  0.2  31940 10396 ?        Ss   01:37   0:00 /lib/systemd/systemd-journald
root          71  0.0  0.1  99800  5724 ?        Ssl  01:37   0:00 /sbin/dhclient -4 -v -i -pf /run/dhclient.eth0.pid [..]
root          97  0.0  0.1  13276  6980 ?        Ss   01:37   0:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
root         160  0.0  0.0   6276  3928 pts/0    Ss   01:46   0:00 /bin/login -p --
root         169  0.0  0.0   7100  3824 pts/0    S    01:51   0:00  \_ -bash
root         172  0.0  0.0   9672  3348 pts/0    R+   01:51   0:00      \_ ps auxwf
root         164  0.0  0.0   5416  2128 pts/1    Ss+  01:49   0:00 /sbin/agetty -o -p -- \u --noclear [...]
root@testlxc:~# 
اکنون درون مخزن هستیم؛ دسترسی به فرآیندها تنها محدود به آن‌هایی است که توسط مخزن آغاز شده باشند و دسترسی به فایل سیستم تنها بخش کوچکی از فایل سیستم کامل /var/lib/lxc/testlxc/rootfs را شامل می‌شود. با استفاده از کلید ترکیبی Control+a q می‌توانیم از کنسول خارج شویم.
Note that we ran the container as a background process, thanks to lxc-start starting using the --daemon option by default. We can interrupt the container with a command such as 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. گام‌های مقدماتی

Unlike such tools as VirtualBox, KVM itself doesn't include any user-interface for creating and managing virtual machines. The virtual qemu-kvm package only provides an executable able to start a virtual machine, as well as an initialization script that loads the appropriate kernel modules.
Fortunately, Red Hat also provides another set of tools to address that problem, by developing the libvirt library and the associated virtual machine manager tools. libvirt allows managing virtual machines in a uniform way, independently of the virtualization system involved behind the scenes (it currently supports QEMU, KVM, Xen, LXC, OpenVZ, VirtualBox, VMWare, and UML). virt-manager is a graphical interface that uses libvirt to create and manage virtual machines.
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, “استفاده از میزکارهای گرافیکی راه‌دور” را مشاهده کنید) که اینکار به ما اجازه می‌دهد فرآیند نصب را کنترل کنیم.
We first need to tell libvirtd where to store the disk images, unless the default location (/var/lib/libvirt/images/) is fine.
# mkdir /srv/kvm
# virsh pool-create-as srv-kvm dir --target /srv/kvm
Pool srv-kvm created

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


Starting install...
Allocating 'testkvm.qcow'

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 دریافت می‌کند.
The default network configuration, which contains the definition for a virbr0 bridge interface, can be edited using virsh net-edit default and started via virsh net-start default if not already done automatically during system start.

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.4, “ایجاد تونل‌های رمزگذاری شده با پورت فورواردینگ” ). 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، با توجه به برخی از ویژگ‌های سیستم عامل اشاره شده، امکان بهینه‌سازی چندین پارامتر ماشین مجازی را فراهم می‌کنند.
The full list of OS types can be shown using the osinfo-query os command from the libosinfo-bin package.
در این نقطه، ماشین مجازی در حال اجرا است و به منظور ادامه فرآیند نصب باید به کنسول گرافیکی متصل شویم. اگر عملیات قبل از طریق یک میزکار گرافیکی صورت گرفته باشد، این ارتباط به صورت مستقیم برقرار می‌شود. در غیر اینصورت، یا در حالتی که از راه دور اینکار را انجام می‌دهیم، virt-viewer با استفاده از هر محیط گرافیکی برای باز کردن کنسول گرافیکی می‌تواند اجرا شود (به یاد داشته باشید که دو مرتبه گذرواژه root درخواست می‌شود چرا که ۲ ارتباط SSH مورد نیاز است):
$ virt-viewer --connect qemu+ssh://root@server/system testkvm
root@server's password: 
root@server's password: 
Connecting to installer session using virt-viewer

شكل 12.1. Connecting to installer session using virt-viewer

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

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.
تمام این دستورات شناسه ماشین مجازی را به عنوان یک پارامتر دریافت می‌کنند.