Product SiteDocumentation Site

12.2. الحوسبة الظاهرية

الحوسبة الظاهرية (virtualization) هي إحدى أهم تطورات الحوسبة في السنوات الأخيرة. يغطي المصطلح العديد من المفاهيم والتقنيات المستخدمة لمحاكاة الحواسيب الظاهرية بدرجات متفاوتة من الاستقلال عن العتاد الفعلي. يمكن لمخدم فيزيائي واحد عندها أن يستضيف العديد من الأنظمة التي تعمل في الوقت نفسه بمعزل عن بعضها. تطبيقات هذه التقنية عديدة، وهي مشتقة غالبًا من فكرة العزل: كاختبار بيئات لها إعدادات مختلفة مثلاً، أو فصل الخدمات المقدمة عبر حواسيب ظاهرية (virtual) مختلفة لزيادة الأمن.
هناك الكثير من حلول الحوسبة الظاهرية، لكل منها ميزاته وعيوبه. يركز هذا الكتاب على Xen، و LXC، وKVM، لكن هناك حلول أخرى تستحق الذكر منها:

12.2.1. ‏Xen

Xen هو حل محاكاة ”شبه ظاهرية – paravirtualization“. يقدم Xen طبقة عزل رقيقة، تدعى ”المشرف – hypervisor“، بين العتاد والأنظمة العليا؛ تعمل بمثابة مرجع يتحكم بالوصول للعتاد من الحواسيب الظاهرية. لكنها تعالج عدداً قليلاً من التعليمات، أما البقية فتنفذ مباشرة على العتاد بالنيابة عن الأنظمة الظاهرية. الميزة الأساسية هي أن مستوى الأداء لا ينخفض، والنظم تعمل بسرعات تقترب من السرعة الأصلية؛ لكن نقطة الضعف هي أن نوى نظم التشغيل التي يمكن استخدامها مع مشرف Xen يجب تعديلها لتناسب العمل على Xen.
لنمض بعض الوقت في التعرف على المصطلحات. المُشرف هو أدنى طبقة، يعمل مباشرة على العتاد، بل تحت النواة حتى. يستطيع هذا المشرف تقسيم البرمجيات الأخرى إلى عدة نطاقات domains، التي يمكن اعتبارها كحواسيب ظاهرية متعددة. يدعى أحد هذه النطاقات (أول نطاق يتم تشغيله) باسم dom0، ويتمتع بدور خاص، حيث يستطيع هذا النطاق فقط التحكم بالمشرف وتنفيذ النطاقات الأخرى. تعرف هذه النطاقات الأخرى باسم domU. بكلمات أخرى، من وجهة نظر المستخدم، يقابل dom0 ”المستضيف – host“ في نظم المحاكاة الأخرى، بينما يمكن اعتبار domU على أنه ”الضيف – guest“.
استخدام Xen في دبيان يحتاج ثلاثة مكونات:
  • المشرف نفسه. الحزمة المناسبة هي إما xen-hypervisor-4.4-amd64 أو xen-hypervisor-4.4-armhf أو xen-hypervisor-4.4-arm64. حسب العتاد المستخدم.
  • نواة تعمل فوق المشرف. أي نواة أحدث من 3.0 سوف تعمل، بما في ذلك الإصدارة 3.16 المعتمدة في جيسي.
  • معمارية i386 تحتاج أيضًا لمكتبة قياسية مع الترقيعات المناسبة للاستفادة من Xen؛ هذه متوفرة في الحزمة libc6-xen.
لتفادي عناء اختيار هذه المكونات يدويًا، تم توفير عدد من الحزم المريحة للمستخدم (مثل xen-linux-system-amd64)؛ كل من هذه الحزم تسحب تجميعة من حزم المشرف والنواة معروفة بتناسبها. يحضر المشرف معه أيضًا حزمة xen-utils-4.4، التي تحوي أدوات للتحكم بالمشرف من dom0. تحضر هذه الحزمة بدورها المكتبة القياسية المناسبة. خلال تثبيت كل هذا، تنشئ سكربتات الإعداد أيضًا مدخلة جديدة في قائمة محمل الإقلاع Grub، لبدء تشغيل النواة المختارة لنطاق dom0. لكن لاحظ أن هذه المدخلة لا تكون الأولى عادة في القائمة، ولذلك لن تحدد افتراضيًا. إذا لم يكن هذا السلوك مرغوبًا، يمكن تغييره بالأوامر التالي:
# mv /etc/grub.d/20_linux_xen /etc/grub.d/09_linux_xen
# update-grub
بعد تثبيت هذه المتطلبات، يأتي دور اختبار سلوك dom0 نفسه؛ هذا يحتاج إعادة الإقلاع إلى المشرف ونواة Xen. يجب أن يقلع النظام بالأسلوب العادي، مع بعض الرسائل الإضافية على الشاشة خلال خطوات التهيئة المبكرة.
الآن حان وقت تثبيت أنظمة مفيدة على نطاقات domU، باستخدام الأدوات من حزمة xen-tools. توفر هذه الحزمة الأمر xen-create-image، الذي يؤتمت معظم المهمة. البارامتر الإجباري الوحيد هو --hostname، لإعطاء اسم للنطاق domU؛ الخيارات الأخرى هامة، لكن يمكن تخزينها في ملف الضبط /etc/xen-tools/xen-tools.conf، وغيابها من سطر الأوامر لا يسبب خطأ. من المهم إذاً التحقق من محتويات هذا الملف قبل إنشاء الصور، أو استخدام بارامترات إضافية عند استدعاء xen-create-image. نذكر من البارامترات الهامة:
  • --memory، لتحديد كمية RAM المخصصة للنظام الجديد؛
  • --size و --swap، لتحديد حجم ”الأقراص الظاهرية“ المتاحة للـ domU؛
  • --debootstrap، لتثبيت النظام الجديد مع debootstrap؛ في تلك الحالة، يستخدم خيار --dist أيضًا أغلب الأحيان (مع اسم توزيعة ما مثل jessie).
  • يبين --dhcp أن الحصول على إعدادات الشبكة في domU يتم من خلال DHCP بينما يسمح --ip بتحديد عنوان IP ستاتيكي (ثابت).
  • أخيراً، يجب اختيار طريقة التخزين للصور المنشأة (التي سيراها domU على أنها أقراص صلبة). أبسط طريقة، التي تقابل الخيار --dir، هي إنشاء ملف على dom0 لكل جهاز يجب تقديمه للـ domU. هناك بديل للأنظمة التي تستخدم LVM، وهو استخدام الخيار --lvm، متبوعاً باسم مجموعة حيزات (VG)؛ عندئذ سينشئ xen-create-image حيزاً منطقيًا جديداً داخل تلك المجموعة، وسيكون هذا الحيز الجديد متاحاً للـ domU بشكل قرص صلب.
بعد تحديد هذه الخيارات، يمكننا إنشاء صورة domU:
# xen-create-image --hostname testxen --dhcp --dir /srv/testxen --size=2G --dist=jessie --role=udev

[...]
General Information
--------------------
Hostname       :  testxen
Distribution   :  jessie
Mirror         :  http://ftp.debian.org/debian/
Partitions     :  swap            128Mb (swap)
                  /               2G    (ext3)
Image type     :  sparse
Memory size    :  128Mb
Kernel path    :  /boot/vmlinuz-3.16.0-4-amd64
Initrd path    :  /boot/initrd.img-3.16.0-4-amd64
[...]
Logfile produced at:
         /var/log/xen-tools/testxen.log

Installation Summary
---------------------
Hostname        :  testxen
Distribution    :  jessie
MAC Address     :  00:16:3E:8E:67:5C
IP-Address(es)  :  dynamic
RSA Fingerprint :  0a:6e:71:98:95:46:64:ec:80:37:63:18:73:04:dd:2b
Root Password   :  adaX2jyRHNuWm8BDJS7PcEJ
لدينا الآن حاسوب ظاهري، لكنه لا يعمل حاليًا (وبالتالي فهو لا يشغل سوى المساحة على القرص الصلب في dom0). طبعاً يمكننا إنشاء المزيد من الصور، وربما استخدمنا بارامترات أخرى.
قبل تشغيل هذه الحواسيب الظاهرية، علينا تحديد طريقة الوصول إليها. يمكن طبعاً اعتبارها حواسيب منفصلة، ونصل إليها فقط من خلال سطر أوامر النظام، لكن هذا نادراً ما يناسب نموذج الاستخدام. في معظم الأحيان، يعتبر domU كمخدم بعيد، ويتم الوصول إليه عبر الشبكة فقط. لكن من الصعب جداً إضافة بطاقة شبكة من أجل كل domU؛ ولذلك يسمح Xen بإنشاء واجهات شبكة ظاهرية، يستطيع كل نطاق أن يراها ويستعملها بالطريقة القياسية. لاحظ أن هذه البطاقات، بالرغم من أنها ظاهرية، إلا أنها غير مفيدة ما لم تتصل بأي شبكة، حتى لو كانت شبكة ظاهرية. لدى Xen عدة نماذج شبكية لهذا الغرض:
  • أبسط نموذج هو النموذج الجسري bridge model؛ وفيه تعمل جميع بطاقات eth0 (في أنظمة dom0 وdomU على حد سواء) كما لو كانت موصولة مباشرة مع تحويلة إيثرنت Ethernet switch.
  • بعدها يأتي نموذج التوجيه routing model، حيث يعمل dom0 كموجه (راوتر) ما بين أنظمة domU والشبكة الخارجية (الفيزيائية).
  • أخيراً، نموذج NAT، وفيه يصل dom0 ثانية بين أنظمة domU وباقي عناصر الشبكة، لكن لا يمكن الوصول مباشرة من الخارج إلى أنظمة domU، وتمر البيانات عبر dom0 باستخدام network address translation (ترجمة عنوان الشبكة).
هذه الأنماط الثلاثة تحتاج عدداً من الواجهات ذات المسميات الغريبة، مثل vif*، وveth*، ‏peth* وأيضًا xenbr0. يرتب مشرف Xen هذه الواجهات في التخطيط الذي يعرفه المستخدم، حيث يتم التحكم بأدوات من فضاء المستخدم (user-space tools). سوف نقتصر على شرح النموذج الجسري، بما أن نموذج NAT ونموذج التوجيه يناسبان بعض الحالات الخاصة فقط.
الإعداد القياسي لحزم Xen لا يؤثر على إعداد الشبكة للنظام. لكن خدمة xend معدّة لدمج الواجهات الشبكية الظاهرية في أي جسر شبكة سابق (يأخذ xenbr0 الأولوية إذا كان هناك أكثر من جسر واحد). علينا إذاً إعداد جسر في /etc/network/interfaces (وهذا يحتاج تثبيت حزمة bridge-utils، ولهذا السبب توصي بها حزمة xen-utils-4.4) لاستبدال المدخلة السابقة eth0:
auto xenbr0
iface xenbr0 inet dhcp
    bridge_ports eth0
    bridge_maxwait 0
بعد إعادة التشغيل للتأكد أن الجسر يُنشَأ آليَّاً، يمكننا الآن تشغيل domU باستخدام أدوات التحكم بـXen، بالأخص الأمر xl. يسمح هذا الأمر بإجراء العديد من التعديلات على النطاقات، مثل سردها أو تشغيلها وإيقافها.
# xl list
Name                                        ID   Mem VCPUs      State   Time(s)
Domain-0                                     0   463     1     r-----      9.8
# 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   366     1     r-----     11.4
testxen                                      1   128     1     -b----      1.1
لاحظ أن النطاق testxen يستهلك ذاكرة حقيقية من الـRAM المتاحة للنطاق dom0، وليست ذاكرة ظاهرية. يجب أخذ الحيطة إذن عند بناء مخدم لاستضافة نسخ Xen، وتزويده بذاكرة فيزيائية مناسبة.
ڤوالا! آلتنا الظاهرية قيد الإقلاع. يمكننا الوصول إليها بإحدى طريقتين. الطريقة المعتادة هي الاتصال بها ”عن بعد“ عبر الشبكة، كما كنا سنتصل بأي حاسب حقيقي؛ هذا يحتاج عادة مخدم DHCP أو بعض إعدادات DNS. الطريقة الأخرى، ولعلها الطريقة الوحيدة إذا كانت إعدادات الشبكة غير صحيحة، هي استخدام طرفية hvc0، باستخدام الأمر xl console:
# xl console testxen
[...]

Debian GNU/Linux 8 testxen hvc0

testxen login: 
بعدها يمكنك بدء جلسة، كما لو كنت تجلس وراء لوحة مفاتيح الحاسب الظاهري. يتم الانفصال عن هذه الطرفية بالمفتاحين Control+]‎.
بعد أن يعمل domU، يمكن استخدامه مثل أي مخدم آخر (بما أنه نظام غنو/لينكس في النهاية). لكن بما أنه حاسب ظاهري فهذه الحالة تسمح ببعض المزايا الإضافية. مثلاً، يمكن إيقاف عمل domU مؤقتاً ثم استكماله، بالأمرين xl pause وxl unpause. لاحظ أن الذاكرة المخصصة للنطاق domU تبقى محجوزة أثناء الإيقاف المؤقت، رغم أنه لا يستهلك أي طاقة حسابية من المعالج. الأمران xl save وxl restore جديران بالاهتمام أيضاً: حفظ domU يحرر الموارد التي كان يستهلكها، بما في ذلك ذاكرة RAM. لا يلاحظ domU عند استعادته (أو استكمال عمله) أي شيء إلا مرور الزمن. إذا كان domU يعمل عند إيقاف تشغيل dom0، فسوف تحفظ سكربتات الحزمة حالة domU آلياً، وتستعيدها عند الإقلاع التالي. هذا يؤدي طبعاً للمتاعب التي تظهر عادة عند إسبات الحاسب المحمول. على سبيل المثال؛ إذا تعلق domU لفترة طويلة، فقد تلغى اتصالاته الشبكية. لاحظ أيضاً أن Xen حتى الآن غير متوافق مع شريحة واسعة من واجهة ACPI لإدارة الطاقة، ما يحول دون إمكانية إسبات النظام المستضيف (dom0).
يمكن إيقاف أو إعادة تشغيل domU إما من داخل domU نفسه (بالأمر shutdown) أو من dom0، بالأمر xl shutdown أو xl reboot.

12.2.2. ‏LXC

بالرغم من أن LXC يستخدم لبناء ”حواسيب ظاهرية“، إلا أن LXC –إذا تحرينا الدقة– ليس نظام محاكاة، بل هو نظام لعزل مجموعات من العمليات عن بعضها مع أنها تعمل على نفس الحاسب المستضيف. يستفيد هذا النظام من مجموعة من التطورات الحديثة في النواة لينكس، التي تعرف باسم مجموعات التحكم—control groups، التي تسمح لعدة زمر مختلفة من العمليات التي تدعى ”المجموعات“ برؤية بعض مظاهر النظام الكلي بشكل مختلف. من أبرز هذه المظاهر هي أرقام تعريف العمليات PIDs، وإعدادات الشبكة، ونقاط الربط في نظام الملفات. لا تستطيع أي مجموعة عمليات معزولة مثل هذه الوصول بأي شكل إلى العمليات الأخرى في النظام، كما يمكن تقييد وصولها إلى نظام الملفات بجزء فرعي محدد. يمكن لها أن تملك واجهة شبكية وجدول توجيه خاصين بها، ويمكن ضبطها حتى ترى مجموعة جزئية فقط من الأجهزة المتاحة المتصلة بالنظام.
يمكن جمع هذه المزايا لعزل عائلة كاملة من العمليات بدءاً من العملية init، وستشبه المجموعة الناتجة حاسوباً ظاهرياً. الاسم الرسمي لهذا الوضع هو ”حاوية—container“ (ومن هنا جاء اسم LXC: ‏LinuX Containers)، لكن الفرق الهام بينها وبين الحواسيب الظاهرية ”الحقيقية“ التي يقدمها Xen أو KVM هو عدم وجود نواة ثانية؛ فالحاوية تستخدم نواة النظام نفسها تماماً. ينطوي هذا على محاسن ومساوئ: من المزايا الأداء الممتاز لعدم وجود عبئ حقيقي، والواقع أن النواة ترى جميع العمليات الجارية في النظام، وبالتالي فإن جدولة المهام ستكون أكثر فعالية مما لو استخدمنا نواتين مستقلتين وكل منهما ستجدول مجموعة مختلفة من المهام. أول العيوب هو استحالة استخدام نواة مختلفة في الحاوية (سواء نسخة مختلفة من لينكس أو نظام تشغيل مختلف بالكامل).
بما أننا نتعامل مع تقنية عزل وليست محاكاة وحسب، فإن إعداد حاويات LXC أعقد من تشغيل مثبت دبيان على جهاز ظاهري. سوف نشرح بعض المتطلبات الأولية، ثم نتجه إلى إعداد الشبكة؛ وبعدها سوف نتمكن من إنشاء النظام الذي سيعمل ضمن الحاوية.

12.2.2.1. الخطوات الأولية

تحوي الحزمة lxc الأدوات اللازمة لتشغيل LXC، ويجب تثبيتها إذن.
يحتاج LXC أيضاً لنظام مجموعات التحكم control groups للإعداد، وهو نظام ملفات ظاهري يتم ربطه على /sys/fs/cgroup. بما أن دبيان 8 قد انتقلت إلى systemd، الذي يعتمد أيضاً على مجموعات التحكم، فهذا يتم تلقائياً أثناء الإقلاع دون الحاجة لأي عمليات إضافية.

12.2.2.2. إعداد الشبكة

الهدف من تثبيت LXC هو إعداد أجهزة ظاهرية؛ وفي حين أننا نستطيع تركها معزولة عن الشبكة طبعاً، والتخاطب معها عبر نظام الملفات فقط، إلا أن معظم حالات الاستخدام تحتاج إعطاء الحاويات وصولاً محدوداً للشبكة على الأقل. في الحالة النموذجية، كل حاوية سيكون لها واجهة شبكية ظاهرية، تتصل بالشبكة الحقيقية عبر جسر. يمكن وصل هذه الواجهة الظاهرية إما مباشرة مع الواجهة الشبكية الفيزيائية للمستضيف (وفي تلك الحالة تتصل الحاوية مباشرة بالشبكة)، أو مع واجهة ظاهرية أخرى معرفة لدى المستضيف (ويمكن للمستضيف بعدها توجيه حركة الشبكة أو حجبها). في كلا الحالتين، سوف نحتاج للحزمة bridge-utils.
أبسط حالة تتلخص بتحرير /etc/network/interfaces، ونقل إعدادات الواجهة الفيزيائية (eth0 مثلاً) إلى واجهة جسرية (عادة br0)، وإعداد الوصلة بينهما. على سبيل المثال، إذا كان ملف إعداد الواجهة الشبكية في البداية يحوي مدخلات تشبه ما يلي:
auto eth0
iface eth0 inet dhcp
فيجب تعطيلها واستبدالها بالتالي:
#auto eth0
#iface eth0 inet dhcp

auto br0
iface br0 inet dhcp
  bridge-ports eth0
إن نتيجة هذا الإعداد ستشبه ما نحصل عليه لو كانت الحاويات أجهزة تتصل بشبكة المستضيف الفيزيائية نفسها. يدير الإعداد ”الجسري“ حركة إطارات الإيثرنت بين جميع الواجهات المجسَّرة، بما فيها الواجهة الفيزيائية eth0 بالإضافة للواجهات الظاهرية المعرفة في الحاويات.
في الحالات التي لا يمكن فيها استخدام هذا الإعداد (مثلاً إذا لم يكن هناك مجال لتعيين عناوين IP عامة للحاويات)، سيتم إنشاء واجهة tap ظاهرية ووصلها مع الجسر. عندها يصبح مخطط الشبكة الموافق لهذا الإعداد هو كأن المستضيف له بطاقة شبكة إضافية متصلة بتحويلة (switch) منفصلة، والحاويات تتصل أيضًا بتلك التحويلة. على المستضيف عندها العمل كبوابة للحاويات إذا كانت تريد التواصل مع العالم الخارجي.
هذا الإعداد ”الغني“ يحتاج –بالإضافة إلى حزمة 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-jessie-amd64 ... 
Downloading debian minimal ...
I: Retrieving Release 
I: Retrieving Release.gpg 
[...]
Download complete.
Copying rootfs to /var/lib/lxc/testlxc/rootfs...
[...]
Root password is 'sSiKhMzI', please change !
root@mirwiz:~# 
لاحظ أن إنشاء نظام الملفات يتم أولاً في /var/cache/lxc، ثم ينقل إلى المجلد الوجهة. هذا يسمح بإنشاء حاويات متطابقة أسرع بكثير، نظراً لأنك تحتاج للنسخ فقط لا أكثر.
لاحظ أيضًا أن سكربت إنشاء قالب دبيان يقبل خيار --arch لتحديد معمارية النظام الذي سيتم تثبيته وخيار --release إذا كنت تريد تثبيت إصدار آخر غير الإصدار المستقر الحالي من دبيان. يمكنك أيضًا ضبط متغير البيئة MIRROR ليشير إلى مرآة دبيان محلية.
يحوي نظام الملفات المنشأ حديثاً نظام دبيان أصغري، ولا تملك الحاوية افتراضياً أي واجهة شبكية (عدا واجهة loopback). بما أن هذا غير مرغوب، سوف نعدل ملف إعداد الحاوية (/var/lib/lxc/testlxc/config) ونضيف بضعة مدخلات lxc.network.*:
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.hwaddr = 4a:49:43:49:79:20
هذه المدخلات تعني، على الترتيب، أنه سيتم إنشاء واجهة شبكية ظاهرية في الحاوية؛ وسيتم تنشيطها آليًا كلما تم تشغيل تلك الحاوية؛ وأنها ستتصل تلقائياً بالجسر br0 على المستضيف؛ وأن عنوان MAC الخاص بها سيكون كما هو محدد. إذا كانت هذه المدخلة الأخيرة ناقصة أو معطلة، سيتم توليد عنوان MAC عشوائي.
من المدخلات المفيدة أيضًا التي يمكن إضافتها لهذا الملف هي تعيين اسم المستضيف hostname:
lxc.utsname = testlxc

12.2.2.4. تشغيل الحاوية

الآن وبعد أن أصبحت صورة الجهاز الظاهري جاهزة، دعنا نشغل الحاوية:
root@mirwiz:~# lxc-start --daemon --name=testlxc
root@mirwiz:~# lxc-console -n testlxc
Debian GNU/Linux 8 testlxc tty1

testlxc login: root
Password: 
Linux testlxc 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1 (2015-05-24) 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  28164  4432 ?        Ss   17:33   0:00 /sbin/init
root        20  0.0  0.1  32960  3160 ?        Ss   17:33   0:00 /lib/systemd/systemd-journald
root        82  0.0  0.3  55164  5456 ?        Ss   17:34   0:00 /usr/sbin/sshd -D
root        87  0.0  0.1  12656  1924 tty2     Ss+  17:34   0:00 /sbin/agetty --noclear tty2 linux
root        88  0.0  0.1  12656  1764 tty3     Ss+  17:34   0:00 /sbin/agetty --noclear tty3 linux
root        89  0.0  0.1  12656  1908 tty4     Ss+  17:34   0:00 /sbin/agetty --noclear tty4 linux
root        90  0.0  0.1  63300  2944 tty1     Ss   17:34   0:00 /bin/login --     
root       117  0.0  0.2  21828  3668 tty1     S    17:35   0:00  \_ -bash
root       268  0.0  0.1  19088  2572 tty1     R+   17:39   0:00      \_ ps auxfw
root        91  0.0  0.1  14228  2356 console  Ss+  17:34   0:00 /sbin/agetty --noclear --keep-baud console 115200 38400 9600 vt102
root       197  0.0  0.4  25384  7640 ?        Ss   17:38   0:00 dhclient -v -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.e
root       266  0.0  0.1  12656  1840 ?        Ss   17:39   0:00 /sbin/agetty --noclear tty5 linux
root       267  0.0  0.1  12656  1928 ?        Ss   17:39   0:00 /sbin/agetty --noclear tty6 linux
root@testlxc:~# 
نحن الآن داخل الحاوية؛ ووصولنا إلى العمليات مقيد بالعمليات التي بدأت من داخل الحاوية نفسها، كما أن وصولنا إلى نظام الملفات مقيد إلى المجموعة الجزئية المعينة لهذه الحاوية من نظام الملفات الكامل (/var/lib/lxc/testlxc/rootfs). يمكننا الخروج من الطرفية باستخدام Control+a q.
لاحظ أننا بدأنا الحاوية كعملية في الخلفية، بفضل الخيار --daemon للأمر lxc-start. يمكننا مقاطعة الحاوية بالأمر lxc-stop --name=testlxc.
تحوي الحزمة lxc سكربت تهيئة يستطيع تشغيل حاوية واحدة أو أكثر آلياً عند إقلاع المستضيف (يعتمد السكربت على أمر lxc-autostart الذي يشغل كل الحاويات التي يكون خيار lxc.start.auto فيها مضبوطاً على القيمة 1). يمكن التحكم بدقة أكبر بترتيب التشغيل من خلال 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. الخطوات الأولية

بعكس الأدوات الأخرى مثل VirtualBox، لا تقدم KVM نفسها أي واجهة للمستخدم لإنشاء وإدارة الحواسيب الظاهرية. تقدم حزمة qemu-kvm برنامجاً تنفيذيًا قادراً على تشغيل حاسوب ظاهري، بالإضافة إلى سكربت تهيئة يحمل وحدات النواة المناسبة.
لحسن الحظ، توفر Red Hat أيضًا مجموعة أخرى من الأدوات لمعالجة هذه المشكلة، من خلال تطوير المكتبة libvirt وأدوات virtual machine manager المقترنة بها. تسمح libvirt بإدارة الحواسيب الظاهرية بأسلوب قياسي، بغض النظر عن نظام المحاكاة المستخدم وراء الكواليس (حاليًا هناك دعم لنظم QEMU، وKVM، وXen، وLXC، وOpenVZ، وVirtualBox، وVMWare وأيضاً UML). ‏virtual-manager هي واجهة رسومية تعتمد على libvirt لإنشاء وإدارة الحواسيب الظاهرية.
سوف نثبت الحزم المطلوبة أولاً، بالأمر apt-get install qemu-kvm libvirt-bin virtinst virt-manager virt-viewer. تقدم الحزمة libvirt-bin الخدمة libvirtd، التي تسمح بالإدارة (البعيدة ربما) للحواسيب الظاهرية التي تعمل على المستضيف، وتشغيل الحواسيب الظاهرية المناسبة عند إقلاع المستضيف. بالإضافة لذلك، توفر هذه الحزمة أداة virsh ذات الواجهة النصية، التي تسمح بالتحكم بالإجهزة التي تديرها خدمة libvirtd.
تقدم الحزمة virtinst الأداة virt-install، التي تسمح بإنشاء الحواسيب الظاهرية من سطر الأوامر. أخيراً، يسمح virt-viewer بالوصول إلى الطرفية الرسومية للحاسب الظاهري.

12.2.3.2. إعداد الشبكة

كما في Xen و LXC، أكثر الخيارات شيوعاً عند إعداد الشبكة هو استخدام جسر يجمع الواجهات الشبكية لعدة حواسيب ظاهرية (انظر قسم 12.2.2.2, “إعداد الشبكة”).
أو يمكن، كما هو الإعداد الافتراضي الذي تقدمه KVM، إعطاء الحاسب الظاهري عنوناً داخلياً (ضمن المجال 192.168.122.0/24)، وإعداد NAT حتى يتمكن الجهاز الظاهري من الوصول إلى الشبكة الخارجية.
سنفترض في تتمة هذا القسم أن المستضيف لديه واجهة فيزيائية eth0 وجسر 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
               --ram 1024                4
               --disk /srv/kvm/testkvm.qcow,format=qcow2,size=10 5
               --cdrom /srv/isos/debian-8.1.0-amd64-netinst.iso  6
               --network bridge=br0      7
               --vnc                     8
               --os-type linux           9
               --os-variant debianwheezy

Starting install...
Allocating 'testkvm.qcow'             |  10 GB     00:00
Creating domain...                    |    0 B     00:00
Guest installation complete... restarting guest.

1

يحدد خيار --connect ”المشرف“ المستخدم. شكله هو شكل URL يحوي اسم نظام المحاكاة (xen://‏، qemu://‏، lxc://‏، openvz://‏، vbox://، وهكذا) والحاسب الذي يجب أن يستضيف الجهاز الظاهري (يمكن ترك هذا فارغًا في حالة الاستضافة المحلية). لالإضافة لذلك، في حالة استخدام QEMU/KVM، يستطيع كل مستخدم إدارة الحواسيب الظاهرية ولكن بصلاحيات مقيدة، ويسمح مسار URL بتمييز حواسيب ”النظام“ (/system) من الحواسيب الظاهرية (/session).

2

بما أن طريقة إدارة KVM تطابق طريقة إدارة QEMU، فإن الخيار --virt-type kvm يسمح بتحديد استخدام KVM بالرغم من أن URL يبدو وكأنه QEMU.

3

خيار --name يحدد اسمًا (فريداً) للجهاز الظاهري.

4

يسمح خيار --ram بتحديد كمية الذاكرة (بالميغابايت) المخصصة للجهاز الظاهري.

5

يحدد --disk موقع ملف الصورة التي تمثل القرص الصلب لجهازنا الظاهري؛ سوف يتم إنشاء ذلك الملف –ما لم يكن موجوداً مسبقاً– بالحجم المحدد بالبارامتر size (بالغيغابايت). يسمح المتغير format باختيار إحدى الصيغ المتعددة لتخزين ملفات الصور. الصيغة الافتراضية (raw) هي ملف وحيد يطابق القرص بالحجم والمحتويات تماماً. لقد اخترنا صيغة متقدمة أكثر هنا، هذه الصيغة خاصة بـ QEMU وهي تسمح بالبدء مع ملف صغير يكبر فقط عندما يبدأ الجهاز الظاهري باستهلاك المساحة فعلاً.

6

يستخدم خيار --cdrom للإشارة إلى موقع القرص الضوئي المستخدم للتثبيت. يمكن أن يكون المسار مساراً محلياً لصورة ISO، أو URL يمكن الحصول منه على الملف، أو ملف جهاز يمثل سواقة CD-ROM فيزيائية (مثل /dev/cdrom).

7

يحدد --network طريقة دمج بطاقة الشبكة الظاهرية في إعدادات الشبكة في المستضيف. السلوك الافتراضي (الذي حددنا استخدامه صراحة في مثالنا) هو دمجها في أي جسر شبكي سابق. إذا لم يكن هناك أي جسر من قبل، فلن يستطيع الجهاز الظاهري الوصول إلى الشبكة الفيزيائية إلا من خلال NAT، لذلك يأخذ عنواناً ضمن مجال شبكة فرعية داخلية (192.168.122.0/24).

8

يصرح --vnc أن الطرفية الرسومية يجب أن تكون متاحة عبر استخدام VNC. السلوك الافتراضي لمخدم VNC المرفق هو الإنصات إلى الواجهة المحلية فقط؛ إذا كان عميل VNC سيعمل على حاسب آخر، فإن الاتصال يحتاج لإعداد نفق SSH (انظر قسم 9.2.1.3, “إنشاء الأنفاق المشفرة باستخدام توجيه المنافذ”). أو يمكن استخدام --vnclisten=0.0.0.0 حتى يصبح الوصول لمخدم VNC ممكناً من جميع الواجهات؛ لكن انتبه إلى أنك إذا استخدمت هذا الخيار، فعليك تصميم الجدار الناري بما يتناسب معه.

9

يسمح الخياران --os-type و--os-variant بتحسين بعض متغيرات الجهاز الظاهري، اعتماداً على بعض المزايا المعروفة لنظام التشغيل المذكور هنا.
عند هذه النقطة، بدأ الجهاز الظاهري يعمل، ونحتاج الاتصال بالطرفية الرسومية لمتابعة عملية التثبيت. إذا تم تنفيذ العملية السابقة من بيئة سطح مكتب رسومية، فيجب أن يبدأ هذا الاتصال آلياً. إذا لم يحدث هذا، أو إذا كنا نعمل عن بعد، يمكن تشغيل virt-viewer من أي بيئة رسومية لفتح الطرفية الرسومية (لاحظ أن كلمة سر الجذر للنظام البعيد ستطلب مرتين لأن العملية تحتاج لاتصالي 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
----------------------------------
  - testkvm              shut off

دعنا نبدأ تشغيل جهازنا التجريبي:
# virsh -c qemu:///system start testkvm
Domain testkvm started
يمكننا الآن الحصول على تعليمات الاتصال بالطرفية الرسومية (يمكن تمرير لوحة عرض VNC المعادة كمتغير للبرنامج vncviewer):
# virsh -c qemu:///system vncdisplay testkvm
:0
من أوامر virsh الفرعية المتاحة أيضاً:
  • reboot لإعادة إقلاع الجهاز الظاهري؛
  • shutdown لبدء عملية إيقاف تشغيل نظيفة؛
  • destroy، لإيقاف عمل الجهاز الظاهري قسراً؛
  • suspend لإيقاف عمله مؤقتاً؛
  • resume لاستكمال عمله؛
  • autostart لتفعيل (أو تعطيل، إذا استخدم الخيار --disable) تشغيل الجهاز الظاهري تلقائياً عند إقلاع المستضيف؛
  • undefine لإزالة كافة آثار الجهاز الظاهري من libvirtd.
جميع هذه الأوامر الفرعية تأخذ الاسم المُعِّرف للجهاز الظاهري كمتغير لها.

12.2.3.5. تثبيت نظام مبني على RPM في دبيان باستخدام yum

إذا كان الجهاز الظاهري سيعمل بنظام دبيان (أو أحد مشتقاته)، يمكن تهيئة النظام باستخدام debootstrap، كما شرحناه سابقاً. أما إذا كان الجهاز الظاهري سيعمل بنظام مبني على RPM (مثل فيدورا، أو 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-1.1503.el7.centos.2.8.x86_64.rpm
# rpm --nodeps --root "$rootdir" -i centos-release-7-1.1503.el7.centos.2.8.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-1.1503.el7.centos.2.8.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