المحتوى عن 'docker'.



مزيد من الخيارات

  • ابحث بالكلمات المفتاحية

    أضف وسومًا وافصل بينها بفواصل ","
  • ابحث باسم الكاتب

نوع المُحتوى


التصنيفات

  • التخطيط وسير العمل
  • التمويل
  • فريق العمل
  • دراسة حالات
  • نصائح وإرشادات
  • التعامل مع العملاء
  • التعهيد الخارجي
  • التجارة الإلكترونية
  • الإدارة والقيادة
  • مقالات ريادة أعمال عامة

التصنيفات

  • PHP
    • Laravel
    • ووردبريس
  • جافاسكريبت
    • Node.js
    • jQuery
    • AngularJS
    • Cordova
  • HTML5
  • CSS
    • Sass
    • إطار عمل Bootstrap
  • SQL
  • سي شارب #C
    • منصة Xamarin
  • بايثون
    • Flask
    • Django
  • لغة روبي
    • إطار العمل Ruby on Rails
  • لغة Go
  • لغة جافا
  • لغة Kotlin
  • برمجة أندرويد
  • لغة Swift
  • لغة R
  • لغة TypeScript
  • سير العمل
    • Git
  • صناعة الألعاب
    • Unity3D
  • مقالات برمجة عامة

التصنيفات

  • تجربة المستخدم
  • الرسوميات
    • إنكسكيب
    • أدوبي إليستريتور
    • كوريل درو
  • التصميم الجرافيكي
    • أدوبي فوتوشوب
    • أدوبي إن ديزاين
    • جيمب
  • التصميم ثلاثي الأبعاد
    • 3Ds Max
    • Blender
  • مقالات تصميم عامة

التصنيفات

  • خواديم
    • الويب HTTP
    • قواعد البيانات
    • البريد الإلكتروني
    • DNS
    • Samba
  • الحوسبة السّحابية
    • Docker
  • إدارة الإعدادات والنّشر
    • Chef
    • Puppet
    • Ansible
  • لينكس
  • FreeBSD
  • حماية
    • الجدران النارية
    • VPN
    • SSH
  • مقالات DevOps عامة

التصنيفات

  • التسويق بالأداء
    • أدوات تحليل الزوار
  • تهيئة محركات البحث SEO
  • الشبكات الاجتماعية
  • التسويق بالبريد الالكتروني
  • التسويق الضمني
  • استسراع النمو
  • المبيعات

التصنيفات

  • إدارة مالية
  • الإنتاجية
  • تجارب
  • مشاريع جانبية
  • التعامل مع العملاء
  • الحفاظ على الصحة
  • التسويق الذاتي
  • مقالات عمل حر عامة

التصنيفات

  • الإنتاجية وسير العمل
    • مايكروسوفت أوفيس
    • ليبر أوفيس
    • جوجل درايف
    • شيربوينت
    • Evernote
    • Trello
  • تطبيقات الويب
    • ووردبريس
    • ماجنتو
  • أندرويد
  • iOS
  • macOS
  • ويندوز

التصنيفات

  • شهادات سيسكو
    • CCNA
  • شهادات مايكروسوفت
  • شهادات Amazon Web Services
  • شهادات ريدهات
    • RHCSA
  • شهادات CompTIA
  • مقالات عامة

أسئلة وأجوبة

  • الأقسام
    • أسئلة ريادة الأعمال
    • أسئلة العمل الحر
    • أسئلة التسويق والمبيعات
    • أسئلة البرمجة
    • أسئلة التصميم
    • أسئلة DevOps
    • أسئلة البرامج والتطبيقات
    • أسئلة الشهادات المتخصصة

التصنيفات

  • ريادة الأعمال
  • العمل الحر
  • التسويق والمبيعات
  • البرمجة
  • التصميم
  • DevOps

تمّ العثور على 9 نتائج

  1. لعلك تتساءل عن السبب الذي يجعلنا نستخدم Docker لتثبيت lamp أو lemp في حين أننا نستطيع تثبيتهما يدويًا؟ فتثبيتهما سهل ولا يحتاج إلى الكثير من التعقيد، لماذا نلجأ إلى Docker؟ دعني أجيب عن هذا السؤال، إنّ docker برنامج خفيف ويغنينا عن الحاجة إلى الآلات الوهمية مثل Virtualbox أو Xen أو غيرهما لنختبر أو نثبت أنظمة التشغيل. وفائدته معنا في هذا المقال أننا نستطيع استخدامه لسحب نسخ جاهزة من LAMP أو LEMP لتشغيلها في بضع دقائق، بدلًا من التثبيت اليدوي لأباتشي، ثم قاعدة بيانات مثل MariaDB أو mySQL، ثم PHP. وتحدث هذه الحالة التي تحتاج فيها إلى نسخة جاهزة وسريعة لاختبار شيء ما عليها إن كنت مطورًا أو مختبرًا أو شغوفًا بالبرمجة وتريد أن تختبر تطبيقًا يعمل في الويب، فتجد نفسك في حاجة إلى تثبيت كل تلك الخطوات التي ذكرتها في الفقرة السابقة، ولعلك جربت هذا من قبل ووجدتها عملية مرهقة وطويلة، وهنا تبرز ميزة Docker حيث يمكننا تثبيت وتشغيل برامج جاهزة ومعدة مسبقًا مباشرة دون الحاجة إلى خوض تفاصيلها التقنية كأننا نثبتها لأول مرة بأنفسنا. وهو ما سنشرحه في هذا المقال على LAMP أو LEMP. تثبيت LAMP/LEMP باستخدام Docker دعنا نبحث في docker عن نسخ جاهزة من LAMP أو LEMP: $ sudo docker search lamp وسيكون الخرج مشابهًا لهذا: NAME DESCRIPTION STARS OFFICIAL AUTOMATED reinblau/lamp Dockerfile for PHP-Projects with MySql client 17 [OK] dockie/lamp 6 [OK] nickistre/ubuntu-lamp LAMP server on Ubuntu 4 [OK] nickistre/ubuntu-lamp-wordpress LAMP on Ubuntu with wp-cli installed 4 [OK] nickistre/centos-lamp LAMP on centos setup 3 [OK] damienlagae/lamp Docker LAMP with supervisord 3 [OK] boolean93/lamp LAMP based on linode/lamp 2 [OK] drunomics/lamp 1 [OK] avatao/lamp LAMP base image 1 [OK] nickistre/ubuntu-lamp-xdebug LAMP on Ubuntu with xdebug installed 1 [OK] nickistre/centos-lamp-wordpress LAMP on CentOS setups with wp-cli installed 1 [OK] linuxconfig/lamp Automated build LAMP stack environment for... 1 [OK] greyltc/lamp a super secure, up-to-date and lightweight... 0 [OK] kazaoki/lamp ローカルフォルダをマウントす... 0 [OK] greyltc/lamp-gateone LAMP stack with gateone server & webdav 0 [OK] fauria/lamp Modern, developer friendly LAMP stack. Inc... 0 [OK] drunomics/lamp-memcached LAMP + Memcached base image. 0 [OK] rpawel/lamp Apache 2.4 + php5-fpm container 0 [OK] lioshi/lamp Docker image for LAMP + MySql under debian 0 [OK] nickistre/centos-lamp-xdebug LAMP on centos with xDebug 0 [OK] greyltc/lamp-aur LAMP stack (in Arch with php7) with AUR ac... 0 [OK] alledia/lamp General LAMP for our tests, based on phusi... 0 [OK] greatfox/lamp 0 [OK] cnrk/lamp LAMP stack Docker image. 0 [OK] grmanit/lamp Based on tutum/lamp with additional settin... 0 [OK] وكما ترى من النتيجة أعلاه، فهناك الكثير من نسخ LAMP المتوفرة لتوزيعات آرتش وCent OS وأوبنتو، وهي مرتبة وفق تقييم المستخدمين لها. وبالمثل يمكننا أن نبحث عن LEMP أيضًا: $ sudo docker search lemp ثم اختر نسخة lemp مناسبة لك، سأحمّل أنا مثلًا nickistre/ubuntu-lamp: $ docker pull nickistre/ubuntu-lamp ويكون الخرج مشابهًا لهذا: Using default tag: latest latest: Pulling from nickistre/ubuntu-lamp faecf96fd5ab: Pull complete 995977506e98: Pull complete efb63fb8dcb6: Pull complete a3ed95caeb02: Pull complete 61626f5cc06d: Pull complete d42e54d21590: Pull complete 4a32d1f581a1: Pull complete 52f44a8dd6d0: Pull complete ce6c1074ae9e: Pull complete 2fa559435609: Pull complete 93a433221384: Pull complete 521d09b9a2d1: Pull complete 6222edddc59d: Pull complete 8fa401b50efc: Pull complete 683063a5d5e0: Pull complete 1f87fa5088b3: Pull complete c5ee1c14048f: Pull complete Digest: sha256:e913d43c204b3cdb931156c1a680c712acfe8db531225ec7b9e4708fc7ebe93c Status: Downloaded newer image for nickistre/ubuntu-lamp:latest سيحمّل الأمر أعلاه نسخة LAMP لأوبنتو، يمكنك تحميل نسختك الخاصة لتوزيعتك كما أوضحنا قبل قليل. وإن لم ترغب في تحميل واستخدام النسخ التي يوفرها docker من الطرفية، فيمكنك تحميلها من Docker hub حيث تجد آلاف النسخ المستضافة هناك. اذهب إلى الرابط أعلاه وابحث عن نسخة LAMP التي تريدها وحمّلها. في حالتي أنا، فقد اخترت نسخة nickistre/ubuntu-lamp كما قلت قبل قليل: اضغط على النسخة التي تريد لمعرفة مزيد من البيانات عنها مثل كيفية تثبيتها واستخدامها: ستجد النسخ التي تحملها في مجلد var/lib/docker/، ولسرد تلك النسخ نفذ الأمر التالي: $ docker images مثال للخرج: REPOSITORY TAG IMAGE ID CREATED SIZE nickistre/ubuntu-lamp latest 5e750e4f49e4 2 days ago 633 MB reinblau/lamp latest 2813b461f843 9 days ago 697.9 MB hello-world latest 690ed74de00f 5 months ago 960 B والآن نشغّل النسخة بعد أن حمّلناها: $ docker run -it nickistre/ubuntu-lamp /bin/bash ستجد نفسك قد دخلت بشكل آلي إلى المجلد الجذر للحاوية على الويب كمستخدم جذر: root@184851ac9ebd:/# شغّل خدمة أباتشي: # service apache2 start ثم خدمة MySQL: # service mysql start تأكد ما إن كان خادم أباتشي يعمل أم لا، بفتح هذه الصفحة في متصفحك http://container_IP/. ولكي تجد عنوان IP، اكتب ifconfig أو ip addr في طرفية الحاوية، يجب أن ترى هنا صفحة اختبار خادم أباتشي. ويمكنك معرفة إصدارات أباتشي وMySQL وPHP بهذه الأوامر بالترتيب: # apache2 -v # mysql -v # php -v وهكذا نكون قد ثبتنا LAMP في أوبنتو واستخدمناه، ويمكنك الآن أن تختبر تطبيقك كما كنت تريد، دون أن تشغل بالك بتثبيت كل تلك الحزم يدويًا أو على حاسوبك، حتى لو كان في آلة وهمية. ترجمة -بتصرف- لمقال Deploy LAMP and/or LEMP stacks easily using Docker لصاحبه SK
  2. تمهيد بشكل عام، نستعمل حاويات Docker لمرة وحيدة فقط، وهي تعمل إلى أن ينتهي تنفيذ الأمر الموكل إليها. لكن في بعض الأحيان تحتاج التطبيقات إلى الوصول إلى بيانات أو حفظها بعد حذف الحاوية. أمثلة عن البيانات التي تحتاج التطبيقات إلى الوصول إليها تتضمن قواعد البيانات، والمحتوى المولّد من قِبل المستخدم لمواقع الويب، وملفات السجلات. يمكن الوصول إلى تلك البيانات بشكلٍ دائم باستخدام حجوم Docker (أي Docker Volumes). المتطلبات المسبقة خادوم أوبنتو 16.04 (أو 14.04) مضبوطٌ كما في درس «الإعداد الابتدائي لخادوم أوبنتو 14.04»، بما في ذلك إعداد حساب مستخدم عادي لكنه يملك امتيازات الجذر (root) عبر الأداة sudo. برمجية Docker مثبّتة على حاسوبك ملاحظة: صحيحٌ أننا نفترض أنَّنا سنستعمل Docker على أوبنتو 16.04، لكن أوامر docker التي تتعامل مع حجوم Docker والمذكورة في هذا الدرس يجب أن تعمل عملًا صحيحًا على بقية الأنظمة لطالما كانت Docker مثبّتةً عليها وأُضيف المستخدم sudo إلى المجموعة docker. يمكن إنشاء حجوم Docker ووصلها بأمرٍ واحد ألا وهو الأمر المُستخدَم لإنشاء الحاوية، أو يمكن إنشاء الحجوم بشكل مستقلٍ عن أيّة حاوية ثم وصلها إليها لاحقًا. سنناقش في هذا الدرس أربع طرائق مختلفة لمشاركة البيانات بين الحاويات. أولًا: إنشاء حجم مستقل أتى الأمر docker volume create مع إصدار 1.9 من Docker والذي يسمح لك بإنشاء حجم دون ربطه بأية حاوية. سنستخدم هذا الأمر لإنشاء حجم باسم DataVolume1: docker volume create --name DataVolume1 إذا عُرِض الاسم، فذلك يُشير إلى نجاح تنفيذ الأمر السابق: DataVolume1 لكي نستعمل هذا الحجم، علينا إنشاء حاوية جديدة مبنية على صورة ubuntu مستعملين الخيار ‎--‎rm لحذف الحاوية تلقائيًا بعد خروجنا منها، وسنستخدم الخيار ‎-v لوصل الحجم الجديد. الخيار ‎-v يتطلب ذكر اسم الحجم متبوعًا بنقطتين رأسيتين : ثم المسار المطلق لمكان وصل الحجم داخل الحاوية. إذا لم يكن المجلد المذكور في المسار السابق موجودًا في صورة التوزيعة، فسيُنشَأ ثم سيُنفَّذ الأمر السابق؛ وفي حال كان المجلد موجودًا، فسيؤدي وصل الحجم إليه إلى إخفاء المحتوى الموجود في الصورة الأصلية. docker run -ti --rm -v DataVolume1:/datavolume1 ubuntu لنكتب بعض البيانات إلى الحجم قبل إغلاق الحاوية: root@802b0a78f2ef:/# echo "Example1" > /datavolume1/Example1.txt ولاستعمالنا الخيار ‎--rm عند إنشاء الحاوية، فستُحذَف الحاوية تلقائيًا عند خروجنا منها. لكن الحجم سيبقى متاحًا للوصول. root@802b0a78f2ef:/# exit يمكننا أن نتحقق أنَّ الحجم ما يزال موجودًا في النظام عبر الأمر docker volume inspect: docker volume inspect DataVolume1 الناتج: [ { "Name": "DataVolume1", "Driver": "local", "Mountpoint": "/var/lib/docker/volumes/datavolume1/_data", "Labels": null, "Scope": "local" } ] ملاحظة: يمكننا أيضًا تفحص البيانات الموجودة في المسار المذكور في سطر Mountpoint لكن لا يُستحسَن تعديلها، لأنَّ ذلك قد يؤدي إلى حدوث عطب في البيانات إن كانت الحاوية تعمل وتجري تعديلات على تلك الملفات. لنبدأ الآن حاويةً جديدةً ونربط الحجم DataVolume1 إليها: docker run --rm -ti -v DataVolume1:/datavolume1 ubuntu سنُنفِّذ الأمر الآتي داخل الحاوية: root@d73eca0365fc:/# cat /datavolume1/Example1.txt الناتج: Example1 لنخرج الآن من الحاوية بالأمر exit. ثانيًا: إنشاء حجم مرتبط بحاوية لكن سيبقى موجودًا بعد حذفها سنُنشِئ في المثال الآتي حجمًا وحاويةً في آنٍ واحد، ومن ثم سنحذف الحاوية، ثم سنربط الحجم إلى حاويةٍ جديدة. سنستخدم الأمر docker run لإنشاء حاوية جديدة بناءً على صورة ubuntu، وسيؤدي استخدام الخيار ‎-t إلى منحنا وصولًا إلى الطرفية، والخيار ‎-i سيسمح لنا بالتفاعل مع الحاوية. ولغرض التوضيح، سأستخدم الخيار ‎--name لتحديد اسم للحاوية، ثم سأستخدم الخيار ‎-v لإنشاء حجم جديد، وسنسميّه DataVolume2، وسنستخدم النقطتين الرأسيتين لفصل الاسم عن مسار وصل الحجم في الحاوية. وفي النهاية سنطلب إنشاء الحاوية لتبدأ تنفيذها بالأمر الافتراضي الموجود في ملف Docker لصورة Ubuntu (الذي هو الأمر bash) لكي نحصل على وصول إلى الصدفة (shell): docker run -ti --name=Container2 -v DataVolume2:/datavolume2 ubuntu ملاحظة: الخيار ‎-v هو خيارٌ مرنٌ جدًا، إذ يستطيع إنشاء وصل ترابطي، أو يمكنه إنشاء حجم جديد بتعديلٍ بسيط جدًا في شكله. فلو بدأ أوّل وسيطٍ بشرطة مائلة / أو ‎~/‎ فسيُنشِئ وصلًا ترابطيًا، لكن إن حذفت الشرطة في أوّل وسيط، فسيُنشِئ حجمًا. ‎-v /path:/path/in/container وصل المسار ‎/path في الجهاز المضيف إلى ‎/path/in/container في الحاوية. ‎-v path:/path/in/container إنشاء حجم باسم path دون علاقة بالمضيف. ولمّا كنا داخل الحاوية، فلنكتب بعض البيانات إلى الحجم: root@87c33b5ae18a:/# echo "Example2" > /datavolume2/Example2.txt root@87c33b5ae18a:/# cat /datavolume2/Example2.txt الناتج: Example2 سنخرج من الحاوية باستخدام الأمر exit. سنُعيد الآن تشغيل الحاوية مرةً أخرى، وسيتم وصل الحجم تلقائيًا. docker start -ai Container2 لنتأكد من أنَّ الحجم قد وصِلَ إلى الحاوية وما تزال البيانات موجودةً فيه: root@87c33b5ae18a:/# cat /datavolume2/Example2.txt الناتج: Example2 لنخرج مرةً أخرى من الحاوية بالأمر exit. لن تسمح لنا Docker بحذف الحجم إذا كان مرتبطًا بحاوية، لننظر ماذا سيحدث لو جربنا ذلك: docker volume rm DataVolume2 ستخبرنا الرسالة الآتية أنَّ الحجم ما يزال مستخدم وستعطينا المُعرِّف الكامل للحاوية: Error response from daemon: Unable to remove volume, volume still in use: remove DataVolume2: volume is in use - [719f98391ecf1d6f0f053ffea1bbd84cd2dc9cf6d31d5a4f348c60d98392804c] يمكننا استخدام المُعرِّف السابق لحذف الحاوية: docker rm 719f98391ecf1d6f0f053ffea1bbd84cd2dc9cf6d31d5a4f348c60d98392804c لن يؤثر حذف الحاوية على الحجم المرتبط بها، وما زال موجودًا في النظام، ونستطيع التحقق من ذلك باستخدام الأمر docker volume ls: docker volume ls الناتج: DRIVER VOLUME NAME local DataVolume2 نستطيع الآن استخدام الأمر docker volume rm لحذف الحجم بتمرير اسمه إلى الأمر السابق: docker volume rm DataVolume2 أنشأنا في هذا المثال حجمًا فارغًا مع الحاوية الذي يرتبط بها في آنٍ واحد. أما في المثال القادم فسنرى ماذا سيحدث لو أنشأنا حجمًا ووصلناه إلى مجلدٍ فيه بيانات موجودة مسبقًا في الحاوية. ثالثًا: إنشاء حجم وربطه بمجلدٍ فيه بيانات عمومًا، لا يكون هنالك فرقٌ بين إنشاء حجم باستخدام الأمر docker volume create وبين إنشائه عند تشغيل الحاوية، لكن هنالك استثناءٌ وحيدٌ لهذه القاعدة، ويحدث عندما نُنشِئ حجمًا في نفس وقت إنشاء الحاوية وكان المسار الذي نريد ربط الحجم فيه مجلدًا موجودًا في الصورة الأصلية وفيه بيانات، وفي هذه الحالة ستُنسَخ البيانات الموجودة في ذاك المجلد إلى الحجم. كمثال عن الحالة السابقة، سنُنشِئ حاويةً ونصل الحجم الجديد إلى المجلد ‎/var الموجود مسبقًا في صورة التوزيعة والذي يحتوي على بيانات: docker run -ti --rm -v DataVolume3:/var ubuntu جميع المحتوى الموجود في مجلد ‎/var في الصورة الأصلية سيُنسَخ إلى الحجم، ثم يمكننا وصل الحجم إلى الحاوية الجديدة. وفي هذه المرة، سنُنفِّذ الأمر ls بدلًا من الأمر الافتراضي bash، والذي سيُظهِر محتويات الحجم دون الحاجة إلى الدخول إلى الصدفة: docker run --rm -v DataVolume3:/datavolume3 ubuntu ls DataVolume3 كما توقعنا، سيحتوي الحجم DataVolume3 على نسخةٍ من محتويات مجلد ‎/var في الصورة الأصلية: backups cache lib local lock log mail opt run spool tmp من غير المرجّح أن نصل المجلد ‎/var بهذه الطريقة، لكن قد تستفيد من المعلومات السابقة إذا أردت إنشاء صورة خاصة بك وتريد طريقةً سهلةً للحفاظ على البيانات. سنشرح في المثال الآتي كيفية مشاركة الحجم مع أكثر من حاوية. رابعًا: مشاركة البيانات بين أكثر من حاوية Docker كل ما فعلناه منذ بداية هذا الدرس هو وصل الحجم إلى حاوية واحدة فقط بنفس الوقت، لكننا نرغب عادةً بالسماح بمشاركة البيانات بين أكثر من حاوية عبر وصل الحجم إلى عدِّة حاوية معًا. وهذا سهلٌ جدًا، لكن هنالك مشكلة محورية: لا تدعم Docker حاليًا ميزة التعامل مع قفل الملفات (file locking)، فلو احتاجت أكثر من حاوية إلى الكتابة على الحجم، فيجب أن تكون البرمجيات الموجودة في تلك الحاويات مصممةً لكي تكتب إلى أماكن تخزين البيانات المشتركة، لتجنّب تلف البيانات. إنشاء الحاوية Container4 والحجم DataVolume4 سنستخدم الأمر docker run لإنشاء حاوية جديدة باسم Container4 ووصل حجم جديد إليها: docker run -ti --name=Container4 -v DataVolume4:/datavolume4 ubuntu سنُنشِئ الآن ملفًا ونضع فيه بعض المحتوى النصي: root@db6aaead532b:/# echo "This file is shared between containers" > /datavolume4/Example4.txt ثم سنخرج من الحاوية بالأمر exit. سنعود الآن إلى سطر الأوامر في الجهاز المضيف، حيث سنُنشِئ حاويةً جديدةً ونصل فيها الحجم DataVolume4. إنشاء الحاوية Container5 ووصل الحجم الذي كان موصولًا في Container4 سنُنشِئ حاويةً جديدةً باسم Container5 ونصل فيها الحجم الذي كان موصولًا في Container4: docker run -ti --name=Container5 --volumes-from Container4 ubuntu root@81e7a6153d28:/# cat /datavolume4/Example4.txt This file is shared between containers لنضف بعض النصوص إلى أحد الملفات من الحاوية الثانية: root@81e7a6153d28:/# echo "Both containers can write to DataVolume4" >> /datavolume4/Example4.txt ثم سنخرج من الحاوية بالأمر exit. سنتأكد الآن أنَّ البيانات الجديدة أصبحت متاحةً للحاوية Container4. رؤية التغييرات التي أجريناها في Container5 لنتحقق من أنَّ الحاوية Container5 قد كتبت البيانات على حجم DataVolume4 بإعادة تشغيل الحاوية Container4: docker start -ai Container4 root@db6aaead532b:/# cat /datavolume4/Example4.txt This file is shared between containers Both containers can write to DataVolume4 بعد أن تأكدنا من إمكانية القراءة والكتابة إلى الحجم من كلا الحاويتين، فسنخرج من الحاوية بالأمر exit. أكرِّر أنَّ Docker لا تملك ميزةً لقفل الملفات، لذا يجب أن تقفل التطبيقاتُ الملفاتَ بنفسها. لكن من الممكن وصل حجم Docker للقراءة فقط لكي نضمن عدم حدوث تلف في البيانات نتيجةً لخطأٍ ما، وذلك عبر إضافة الخيار ‎:ro. تشغيل الحاوية Container6 ووصل الحجم للقراءة فقط نستطيع –بعد وصل الحجم إلى الحاوية– أن نفصله ثم نصله مرةً أخرى للقراءة فقط، لكننا نستطيع أيضًا إنشاء حاوية تصل الحجم كما نشاء مباشرةً. وذلك بإضافة ‎:ro بعد اسم الحاوية التي سنحاول وصل الحجم المرتبط بها: docker run -ti --name=Container6 --volumes-from Container4:ro ubuntu سنتحقق من أنَّ الحجم موصولٌ للقراءة فقط بمحاولتنا حذف الملف الذي أنشأناه سابقًا: root@ab63aebe534c:/# rm /datavolume4/Example4.txt rm: cannot remove '/datavolume4/Example4.txt': Read-only file system بعد إغلاق هذه الحاوية (كالمعتاد، بالأمر exit) فيمكننا حذف الحاويات التي أنشأناها إضافةً إلى الحجم: docker rm Container4 Container5 Container6 docker volume rm DataVolume4 لقد رأينا في هذا المثال كيفية مشاركة البيانات بين حاويتين باستخدام الحجوم، بالإضافة إلى طريقة وصل الحجوم للقراءة فقط. الخلاصة أنشأنا في هذا الدرس حجم بيانات الذي يسمح لنا بالاحتفاظ بالبيانات حتى بعد حذفنا للحاوية. وشاركنا حجمًا بين عدِّة حاويات، ونوهنا إلى أهمية أن تكون التطبيقات المستعملة في الحاويات قادرةً على قفل الملفات لمنع تلف البيانات. وفي النهاية شاهدنا كيف يمكن وصل الحجم للقراءة فقط. إذا كنتَ مهتمًا بكيفية مشاركة البيانات بين الحاويات والنظام المضيف، فأنصحك بقراءة درس «كيفية مشاركة البيانات بين حاوية Docker والمضيف». ترجمة -وبتصرّف- للمقال How To Share Data between the Docker Container and the Hostلصاحبته Melissa Anderson
  3. تمهيد عمومًا، نستعمل حاويات Docker لمرة وحيدة فقط، وهي تعمل إلى أن ينتهي تنفيذ الأمر الموكل إليها. وافتراضيًا تكون البيانات المُنشَأة داخل الحاوية متاحةً فقط إلى الحاوية وقابلة للوصول عند تشغيل الحاوية فقط. حجوم Docker (أي Docker volumes) يمكن أن تُستخدَم لمشاركة الملفات بين النظام المضيف (host system) وحاوية Docker. لنقل –على سبيل المثال– أننا نريد استخدام صورة Nginx الرسمية ونحتفظ بسجل دائم لخادوم Nginx لكي نحلل معلوماته لاحقًا. وافتراضيًا، ستكتب صورة Niginx الرسمية سجلاتها إلى ‎/var/log/nginx داخل الحاوية، والتي لا نستطيع في الحالة العادية الوصول إلى ذاك الملف من النظام المضيف. سنشرح في هذا الدرس كيفية جعل البيانات الموجودة داخل الحاوية متاحةً للجهاز المضيف. المتطلبات المسبقة خادوم أوبنتو 16.04 (أو 14.04) مضبوطٌ كما في درس «الإعداد الابتدائي لخادوم أوبنتو 14.04»، بما في ذلك إعداد حساب مستخدم عادي لكنه يملك امتيازات الجذر (root) عبر الأداة sudo. برمجية Docker مثبّتة على حاسوبك إذا كنتَ جديدًا على Docker، فسلسلة «docker ecosystem» المنشورة على الأكاديمية تعطيك لمحةً عن طريقة استعمالها. الخطوة الأولى: الوصل الترابطي لحجم التخزين الأمر الآتي سيُنشِئ مجلدًا باسم nginxlogs في مجلد المنزل (Home) للمستخدم الحالي ويصله وصلًا ترابطيًا (bindmount) إلى ‎/var/log/nginx في الحاوية: docker run --name=nginx -d -v ~/nginxlogs:/var/log/nginx -p 5000:80 nginx لنأخذ دقيقةً من الزمن لتفحص الأمر بالتفصيل: ‎--name=nginx: تسمية الحاوية لكي نستطيع الإشارة إليها لاحقًا بسهولة. ‎-d: فصل العملية الحالية من الطرفية وتشغيلها في الخلفية، وإلا فسنرى مِحَث Nginx فارغ ولن نتمكن من استعمال جلسة الطرفية إلا بعد انتهاء تنفيذ Nginx. ‎-v ~/nginxlogs:/var/log/nginx: ضبط حجم الوصل الترابطي الذي يربِط بين مجلد ‎/var/log/nginx داخل حاوية Nginx إلى مجلد ‎‎~/nginxlogs في الجهاز المضيف. تَستعمِل Docker النقطتين الرأسيتين : لفصل مسار المضيف عن مسار الحاوية، ويجب ذكر مسار المضيف أولًا. ‎-p 5000:80: ضبط تمرير المنافذ؛ حيث تستمع خدمة Nginx داخل الحاوية إلى المنفذ 80 افتراضيًا، وهذا الخيار يؤدي إلى ربط المنفذ 80 في الحاوية إلى المنفذ 5000 في النظام المضيف. nginx: تحديد أنَّ هذه الحاوية يجب بناؤها على صورة Nginx، والتي تُنفِّذ الأمر nginx -g "deamon off"‎ لتشغيل Nginx. ‎-v /path:/path/in/container وصل المسار ‎/path في الجهاز المضيف إلى ‎/path/in/container في الحاوية. ‎-v path:/path/in/container إنشاء حجم باسم path دون علاقة بالمضيف. الخطوة الثانية: الوصول إلى البيانات من المضيف لدينا الآن خادوم Nginx يعمل داخل حاوية موجودة في جهازنا المحلي، ولدينا المنفذ 5000 الموجود في جهاز المضيف مرتبطٌ بالمنفذ 80 للحاوية. افتح عنوان خادوم الويب في متصفحك، مستخدمًا عنوان IP لجهازك المحلي ورقم المنفذ 5000، مثلًا: http://203.0.113.0:5000 ويجب أن تشاهد الرسالة الآتية: وإذا نظرنا الآن في مجلد ‎~/nginxlogs الموجود في المضيف، فسنرى الملف access.log المُنشَأ من حاوية nginx والذي تظهر فيه الطلبية التي أجريناها: cat ~/nginxlogs/access.log يجب أن يحتوي شيئًا شبيهًا بما يلي: 203.0.113.0 - - [11/Nov/2016:00:59:11 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36" "-" إذا أجريتَ أيّة تعديلات إلى مجلد ‎~/nginxlogs فيجب أن تراها من داخل الحاوية مباشرةً. الخلاصة شرحنا في هذا الدرس كيفية إنشاء حجم Docker لمشاركة المعلومات بين الحاوين والنظام المضيف، مما يفيدنا كثيرًا في بيئات التطوير، حيث من الضروري الوصول إلى السجلات لتحليلها. ترجمة -وبتصرّف- للمقال How To Share Data between the Docker Container and the Host لصاحبته Melissa Anderson
  4. تمهيد عندما تُنشِئ حاوية Docker فسيُسنَد إليها مُعرِّف عالمي فريد (UUID) وهو ضروريٌ لتفادي التضاربات في الأسماء ولتسهيل أتمتة إنشاء الحاويات دون تدخل البشر. وهو مفيدٌ لكي يتعرف الحاسوب المضيف (والشبكة) على المضيف. لكن يصعب التفريق بين الحاويات بالنسبة للبشر، سواءً كنّا نقصد الاسم الطويل (64 محرف) أو المُعرِّف القصير (12 محرف) الذي يبدو كالآتي 285c9f0f9d3d. توفِّر Docker أسماءً مولّدةً تلقائيًا للحاويات تأتي من جمع كلمتين عشوائيتين بشرطة سفلية، مثلًا: evil_ptolemy، مما يُسهِّل التفريق بين الحاويات، لكن الأسماء العشوائية لا تعطينا أيّة فكرة عن وظيفة الحاوية مَثَلُهَا كمثل مُعرِّف UUID. سأخبرك بثلاث نصائح التي ستُسهِّل من التعرف على الحاويات. أولًا: سمِّ الحاوية عندما تُنشِئها وذلك بإضافة الخيار ‎--name=meaningful_name إلى الأمر docker run، وبهذا سيصبح اسم الحاوية ذا معنى عند استخدام الجلسات التفاعلية وفي ناتج بعض الأوامر مثل docker ps. لكن هنالك بعض المحدوديات، لأن أسماء الحاويات يجب أن تكون فريدةً، لهذا لا يمكن استخدام نفس الاسم لأكثر من حاوية. ضع ما يلي في سطر الأوامر أو في ملف Docker: docker run –name=meaningful_name على سبيل المثال، إذا أردنا إنشاء حاوية مبنيةً على صورة nginx فسنُنفِّذ الأمر: docker run --name nginx -d nginx وسيظهر الاسم في قائمة الحاويات التي تعمل حاليًا: docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 08f333ef7216 nginx "nginx -g 'daemon off" 15 seconds ago Up 14 seconds 80/tcp, 443/tcp nginx صحيحٌ أنَّ الاسم سيظهر في ناتج الأمر docker ps ويمكن استخدامه لإدارة الحاوية، لكنه لن يظهر في مِحَث (prompt) سطر الأوامر إذا فتحتَه، أو في السجلات. ولفعل ذلك عليك أن تُسنِد «اسم مضيف» (hostname) إلى الحاوية. ثانيًا: إسناد اسم مضيف إلى الحاوية القيمة المُمرَّرة إلى الخيار ‎--hostname ستُضبِط اسم المضيف داخل الحاوية في الملفين ‎/etc/hostname و ‎/etc/hosts. وبناءً على ذلك، سيظهر اسم المضيف في مِحَث سطر الأوامر، وسيلعب اسم المضيف دورًا في ضبط خدمة DNS للحاوية وقد يكون مفيدًا عند تعلم التعامل مع أكثر من حاوية. لكنه ليس ضروريًا للوصول إلى الحاوية من خارجها، إلا أنَّه سيظهر في ملفات السجل التابعة للحاوية، وعندما تُكتَب تلك الملفات إلى جهاز تخزين مستقل عن الحاسوب المضيف، فسيسهل التعرف على الحاوية بناءً على اسم المضيف الخاص بها. ضع ما يلي في سطر الأوامر أو في ملف Docker: docker run –hostname=value أو docker run -h value وصحيحٌ أنَّ ‎--name و ‎--hostname مفيدان للتعرف على الحاويات، لكن الأمر ليس متعلقًا بإطلاق اسم على الحاوية فحسب، وإنما ستستفيد منه (في السجلات مثلًا) إذا ضبطتَ الحاوية لكي تُحذَف تلقائيًا بعد انتهاءك منها. ثالثًا: حذف الحاويات تلقائيًا بعد انتهاء تنفيذها عندما تجرّب مع حاويات Docker، فقد تستفيد في بعض الأحيان من الحفاظ على الحاوية بعد انتهاء تنفيذها. يمكنك حفظ البيانات مثل ملفات السجلات وتتفحص آخر حالة للحاوية. لكن في بعض الأحيان لا ترغب في بقاء الحاوية بعد انتهاء التجربة معها، وفي هذه الحالة يمكنك استخدام الخيار ‎--rm لحذفها عند انتهاء تنفيذها. وهذا سيُسهِّل من «تنظيف» بيئة التجارب. لكن انتبه! إذا كنتَ تستخدم حجوم Docker ‏(Docker volumes) فالخيار ‎--rm سيؤدي إلى حذف أيّة حجوم مرتبطة بالحاوية. ضع ما يلي في سطر الأوامر أو في ملف Docker: docker run –rm ستستفيد من هذا الخيار كثيرًا عند إنشائك لصورة Docker وتحتاج إلى الوصول إلى حاوية للتجربة عليها، لكنك لا تريد أن تملأ كامل قرصك بحاويات لن تستعملها مرةً أخرى. الخلاصة هنالك ثلاثة خيارات للأمر docker run: الخيار ‎--name و ‎--hostname و ‎--rm التي تُسهِّل من تعاملك مع حاويات Docker عندما تحاول تعلم التعامل معها. يمكنك العثور على مزيدٍ من المعلومات حول الأمر docker run في درس «التعامل مع حاويات Docker». ترجمة -وبتصرّف- للمقال Naming Docker Containers: 3 Tips for Beginners لصاحبته Melissa Anderson
  5. Docker هي أداةٌ لإنشاء الحاويات تُستخدَم لتوفير برمجيات مع نظام ملفات الذي يحتوي كل شيءٍ تحتاج له تلك البرمجيات لتعمل. استخدام حاويات Docker يضمن أنَّ البرمجيات ستعمل عملًا صحيحًا بغض النظر عن النظام الذي ستعمل داخله، لأنَّ بيئة التشغيل ستكون متماثلة في جميع الحالات. سنوفِّر في هذا الدرس لمحةً عن العلاقة بين صور Docker (أي Docker images) وحاويات Docker (أي Docker containers). ثم سنتعلم كيفية تشغيل وإيقاف وحذف الحاويات. لمحة عن حاويات Docker يمكننا أن نتخيل «صورة Docker» على أنها قالبٌ (template) يُستخدم لإنشاء حاويات Docker. تبدأ الصور عادةً بنظام ملفات رئيسي، وتُضاف التعديلات على نظام الملفات (والمعاملات المترافقة معها) على شكل طبقات متتالية. وعلى النقيض من توزيعات لينكس الاعتيادية، تحتوي صورة Docker على المكوِّنات الأساسية اللازمة لتشغيل التطبيق (ولا تحتوي على جميع الأدوات الموجودة في التوزيعات التقليدية). ولا تتغير صور Docker، وإنما تكوِّن نقطة انطلاق لإنشاء حاويات Docker. هذا المزيج بين الطبقات المتاحة للقراءة فقط والتي تعلوها طبقةٌ قابلةٌ للكتابة والقراءة يُشكِّل ما يُعرَف بنظام الملفات الاتحادي (union file system). فعند حدوث تغيير إلى ملفٍ موجودٍ في حاوية فسيُنسَخ الملف من الفضاء المتاح للقراءة فقط إلى الطبقة التي يُسمَح فيها بالقراءة والكتابة، ثم ستُطبَّق التغييرات، والنسخة الموجودة في الطبقة المتاحة للقراءة والكتابة تؤدي إلى «إخفاء» الملف الأصلي لكنها لا تحذفه. التغييرات التي تحدث في الطبقة المتاحة للقراءة والكتابة تتواجد في الحاويات المستقلة فقط، وعندما تُحذَف إحدى الحاويات فستضيع جميع التغييرات إلا إن اتخذنا إجراءات لحفظها. التعامل مع الحاويات في كل مرة تستعمل فيها الأمر docker run سيؤدي إلى إنشاء حاوية جديدة من الصورة التي حدَّدتَها. ما سبق قد يُسبِّب بعض الالتباس، لذا لنأخذ بعض الأمثلة للتوضيح. الخطوة الأولى: إنشاء حاويتَين الأمر docker run الآتي سيُنشِئ حاويةً جديدةً تستعمل الصورة ubuntu، ويمنحنا الخيار ‎-t وصولًا إلى الطرفية، والخيار ‎-i يسمح لنا بالتفاعل معها. سنعتمد على الأمر الافتراضي الموجود في ملف Docker لتوزيعة أوبنتو (وهو bash) لكي نحصل على وصولٍ للصدفة (shell): $ docker run -ti ubuntu سيتغير مِحَث سطر الأوامر (prompt) ليُشير إلى أننا نعمل داخل الحاوية بحساب الجذر، متبوعًا بمُعرِّفٍ ذي 12 محرفًا للحاوية، ويبدو المِحث كالآتي: root@11cc47339ee1:/# سنُجري تعديلًا على الحاوية عبر كتابة جملة نصيّة إلى ملفٍ داخل مجلد ‎/tmp، ثم سنستخدم الأمر cat للتأكد من أنَّ الملف قد تعدّل: echo "Example1" > /tmp/Example1.txt cat /tmp/Example1.txt الناتج: Example1 لنخرج الآن من الحاوية بالأمر exit. سيوقف تشغيل حاويات Docker عند انتهاء تنفيذ الأمر الذي بدأت به، لذا ستتوقف حاويتنا عن العمل عند خروجنا من الصدفة bash. ولو نفَّذنا الأمر docker ps الذي يعرض الحاويات التي تعمل حاليًا، فلن نشاهد حاويتنا مذكورةً بينها: docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES أما إذا استعملنا الخيار ‎-a الذي يعرض جميع الحاويات، سواءً كانت متوقفةً أم تعمل حاليًا، فستظهر عندئذٍ حاويتنا في القائمة: docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 11cc47339ee1 ubuntu "/bin/bash" 6 minutes ago Exited (127) 8 seconds ago small_sinoussi عندما أُنشِئَت الحاوية، أُعطيَتْ مُعرَّفًا واسمٍ مولِّدٍ تلقائيًا. وكان مُعرِّف الحاوية في حالتنا هو 11cc47339ee1 والاسم المولَّد تلقائيًا هو small_sinoussi. الخيار ps -a يُظهِر هذه القيمة بالإضافة إلى اسم الصورة التي بُنيَت الحاوية عليها (ubuntu)، ومتى أُنشِئَت الحاوية (‎6 minutes ago)، وما الأمر الذي بدأت الحاوية به (‎/bin/bash). والناتج يعرض أيضًا حالة الحاوية (Exited) ومتى دخلت الحاوية بهذه الحالة (‎8 seconds ago). إذا ما زالت الحاوية تعمل عند تنفيذ الأمر، فستظهر الحالة Up مع بيان مدّة تشغيلها. إذا أعدنا تنفيذ الأمر السابق، فستُنشَأ حاويةٌ جديدة: docker run -ti ubuntu سنعرف أنَّ هذه حاويةٌ جديدة لأنَّ مُعرِّف الحاوية الظاهر في المِحَث مختلف، وإذا حاولنا عرض الملف Example1 فلن نجده: root@6e4341887b69:/# cat /tmp/Example1 الناتج: cat: /tmp/Example1: No such file or directory قد تظن أنَّ الناتج السابق يعني أنَّ البيانات قد اختفت، لكن ذلك ليس صحيحًا. سنخرج الآن من الحاوية الثانية لنتأكد من أنَّ كلا الحاويتين ما زالتا موجودتين في نظام الملفات، ولم تُحذَف الحاوية الأولى التي أنشأنا فيها الملف. docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6e4341887b69 ubuntu "/bin/bash" About a minute ago Exited (1) 6 seconds ago kickass_borg 11cc47339ee1 ubuntu "/bin/bash" 13 minutes ago Exited (127) 6 minutes ago small_sinoussi الخطوة الثانية: إعادة تشغيل الحاوية الأولى لإعادة تشغيل حاوية موجودة مسبقًا، فسنستخدم الأمر start مع الخيار ‎-a و ‎-i، متبوعًا باسم الحاوية أو مُعرِّفها. احرص على أن تضع مُعرِّف الحاوية التي أنشأتها في نظامك في الأمر الآتي: docker start -ai 11cc47339ee1 سنجد أنفسنا داخل صدفة bash مرةً أخرى، وعندما نستخدم الأمر cat على الملف الذي أنشأناه مسبقًا فسنرى أنَّه ما يزال موجودًا: root@11cc47339ee1:/# cat /tmp/Example1.txt Example1 يمكننا الآن أن نخرج من الحاوية بالأمر exit. الناتج السابق يُظهِر أنَّ التعديلات التي أُجرِيَت داخل الحاوية ستبقى حتى لو أوقفناها ثم أعدنا تشغيلها مرةً أخرى. ولن يُحذَف محتواها إلا عند إزالة الحاوية. وهذا المثال يبيّن أنَّ التعديلات ستبقى محصورةً في الحاوية، ولن تؤثر على ما سواها، وعند بدء حاوية أخرى فستأخذ بنية نظام الملفات من الصورة الأصلية. الخطوة الثالثة: حذف كلا الحاويتين لقد أنشأنا في هذا الدرس حاويتين، وسنختمه بتوضيح كيف نحذفهما. يسمح لنا الأمر docker rm –الذي يعمل على الحاويات المتوقفة فقط– بحذف حاوية أو أكثر عبر تحديد اسمها أو مُعرِّفها كما يلي: docker rm 11cc47339ee1 kickass_borg 11cc47339ee1 kickass_borg لقد حُذِفَت الحاويتان مع جميع محتوياتها. الخلاصة لقد ألقينا نظرةً مفصّلةً على الأمر docker run ورأينا كيف يُنشِئ حاويةً جديدةً في كل مرّة يُنفَّذ فيها، ورأينا أيضًا كيفية الحصول على معلومات عن حاوية متوقفة وكيفية تشغيلها والوصول إليها. ترجمة -وبتصرّف- للمقال Working with Docker Containers لصاحبته Melissa Anderson
  6. قليلة هي تلك المشاريع والابتكارات التي تُحدِث نقلة نوعية في عالم البرمجيات والتقنية بشكل عام، وإن كنا سنشهد في هذه العشرية إحدى هذه المشاريع، فهو Docker بامتياز. فما هو Docker هذا؟ هذا المقال يهدف بشكل خاص إلى التعريف بمشروع Docker والفكرة التي جاء بها، وليس لكيفية البدء به (والتي ستكون في مقال منفصل إن شاء الله)، حيث لا يمكن البدء به إذا لم نفهم فكرته وأهميته في عالم البرمجيات. لمن هذا المقال؟لمدراء الخواديم (SysAdmins) بالدرجة الأولىللمبرمجين ومطوري الويب بالدرجة الثانية قبل أن نتحدث عن ماهية Docker أحب أولا ذكر أهم 03 مشاكل نواجهها حاليا كمطورين ومدراء خواديم والتي يحاول Docker معالجتها... 1. جحيم الاعتماديات (the dependecy hell)الأغلبية الساحقة من مشاريع الويب "الجدية" والكبيرة لا تكون قائمة بذاتها، بل هي عبارة عن مكتبات تتواصل فيما بينها أو تعتمد على مكتبات أخرى من أجل أن تعمل، مطوروا Ruby، Python وحتى node.js و php يفهمون ذلك جيدا، وكل من هذه اللغات حاول حل المشكلة على نطاقه الخاص عبر إنشاء أدوات مساعدة تعرف بـ"مدراء الاعتماديات" أو "مدراء حزم" (dependency/package managers) أمثلة ذلك: pip بالنسبة لبايثونgem بالنسبة لروبيnpm بالنسبة لـ node.jsوأخيرا محاولة متواضعة من php عبر composer..وقد تذهب اللغة إلى أبعد من ذلك مثل ما فعلت بايثون بإنشاء بيئات وهمية تعزل فيها المكتبات والاعتماديات مثل مشروع virtualenv. كل من هذه اللغات تستعمل مدراء الاعتماديات/الحزم لجلب وإدارة المكتبات الخارجية التي يعتمد عليها المشروع (third party librairies)، لكن السؤال هنا، إذا كانت هذه اللغات وفرت هذه الأدوات، فأين المشكل؟ في الحيقيقة بالرغم من توفر هذه الأدوات، تبقى هناك مشاكل عالقة دائما خاصة على مستوى تنصيب المشروع على الخواديم (deployment) من ذلك: كثرة الاعتماديات، مما يأخذ وقتا في التنزيل، وأحيانا لا توجد تلك الاعتمادية على منصة الخادوم البعيد وقد تحتاج إلى عمل تجميع يدوي لها، وهذا يجعل الأمر مُتعبا.اعتمادية تعتمد في حد ذاتها على اعتمادية أخرى، قد تكون مثلا تشترط منصة Java بأكملها، وقد تكون أيضا هذه الأخيرة تعتمد على اعتماديات أخرى وهكذا...تعارض الاعتماديات، وجود إحداها يتطلب غياب الأخرى واستحالة عملهما معا في نفس الوقتنسخة الاعتمادية التي تم تنزيلها مغايرة للتي تم تطوير المشروع بها. والنسخة الجديدة تأتي بتغيرات غير متوافقة رجعيا (API backward compatibility)كل هذه المشاكل وغيرها، تجعل من ناقلية المشروع من مكان إلى آخر أو من خادوم إلى آخر، عملية شاقّة. 2. صعوبة نشر، تنصيب، نقل مشاريع الويبمشاريع الويب الكبيرة تحتاج إلى عدد من الاحتياطات: متغيرات بيئة (environment variables) يجب تعيينها مسبقاإعداد لنظام الـ cacheإعداد للخادوم nginx أو غيرهإعدادات أمنيةتحديث النظام وبرمجياته قد يسبب عطلا ما للمشروع،...ماذا عن نقل المشروع من خادوم إلى آخر؟ أو في حالة وجود أكثر من خادوم... وكل منه له نظامه الخاص (من CentOs إلى Ubuntu مثلا أو حتى BSD).... 3. التطوير، التسليم والزرع المتواصل للمشاريع ( continuous delivery/integration)مشاريع الويب الجدية تتبع دورة تطوير معينة، تحسين دائم، إدخال لميزات جديدة بشكل دوري، قفل للثغرات ... إلخ، بعد هذا يجب إجراء سلسلة من الفحوصات (unit tests مثلا) للتأكد من سلامة المشروع وأنه أهل للمرحلة الإنتاجية منه (production ready)، كل هذا سهل محليا،... لكن عملية إبقاء جميع الخواديم مسايرة لوتيرة التطوير هذه أمر شاق ومتعب، خاصة حينما نحتاج إلى تحديث الاعتماديات أو وجود إعتماديات جديدة وبالتالي احتياطات جديدة... هذه المشاكل ليس حصرا، فهناك غيرها من المشاكلة الأمنية (مثال ثغرة في مشروع الويب تمكن المخترق من الوصول إلى النظام)، مشاكل عزل (قاعدة البيانات في نفس بيئة التطبيق نفسه مما قد يسمح للوصول السهل لها من قبل المخترق)، مشاكل نسخ اختياطي (backups)،.. الخ إذا ما هو Docker؟Docker عبارة عن أداة جديدة تستغل ميزات الإصدارات الأخيرة من نواة Linux الخاصة بعزل المهام والعمليات (processes)، عمليات الإدخال والإخراج (i/o)، حجز الذاكرة وتحديدها، صلاحيات القراءة والكتابة للقرص الصلب... وغير ذلك، في إنشاء حاويات (containers) ركز على هذه الكلمة جيدا، حيث أن هذه الحاويات تلعب دور غلاف حاوي لتطبيق ما (مشروع ويب مثلا)، بحيث يصبح قائما بذاته، مكتفٍ ذاتيا. أي أن مشروع الويب وكامل الاعتماديات التي يحتاجها ليعمل + التوزيعة المناسبة له (Fedora, Ubuntu.. الخ) بجميع التهيئات ومتغيرات البيئة التي يحتاجها، كل هذا في حاوية (قد تكون حاوية واحدة أو عدة حاويات تتخاطب في ما بينها عملا بمبدأ "عزل الاهتمامات" SoC). لتقريب الصورة، تخيل أنه باستعمال Docker يمكنك عمل التالي: طورت تطبيقك على Ubuntu أو تعلم أنه يعمل بشكل جيد على توزيعة Ubuntu وبالتحديد الإصدارة 14.04 منها، وبالتالي تقول لـ Docker استعمل نسخة Ubuntu 14.04 (يتكفل هو بتزيل الصورة الخام من Ubuntu 14.04 - حوالي 60 إلى 300 Mb تقريبا- واستعمالها كتوزيعة للحاوية)مشروع الويب خاصتي يستعمل Python وبالتحديد النسخة 2.7 منها، ويعمل بشكل جيد على هذه النسخة، لم أجرب على Python 3، تقول لـ Docker نصب Python2.7 في الحاوية التي بها نظام Ubuntu 14.04 الذي سبق تنزيل صورته الخاممشروع الويب خاصتي يستعمل مكتبة Flask أو Django و مكتبة Numpy الخاصة ببايثون، يتم تثبيتهم عبر pip وبالتالي تقول لـ Docker نصب لي على الحاوية التي بها Ubuntu 14.04 و Python 2.7 السابقة تطبيق Pip عبر مدير حزم Ubuntu (أي apt-get install python-pip) ثم باستعمال pip نصب لي مكتاب بايثون السابق ذكرهامشروع الويب الخاص بي يحتاج قاعدة بيانات MySQL، نصبها يا Docker عبر مدير حزم Ubuntuأيضا نحتاج nginx أو apache، كذلك تطلب من Docker أن ينصبه عبر مدير حزم Ubuntuاجمع لي كل هذا في صورة واحدة (image) يمكن تشغيلها على أي خادوم أو حاسوب به Docker عبر الأمر: docker run my_imageجميع هذه الخطوات يمكن أتمتتها وسردها في ملف واحد اسمه DockerFile، كل سطر من هذا الملف عبارة عن أمر لـ Docker يقوم به (تماما كما قمنا به أعلاه)، مجموع الأوامر يكون الخطوات التي يمر بها Docker لبناء الحاوية التي نريدها، في ما يلي مثال عن ملف DockerFile: FROM ubuntu 14.04 # Install Python RUN apt-get install -y python-dev # Install pip RUN apt-get install -y python-pip # Install requirements.txt ADD requirements.txt /src/requirements.txt RUN cd /src; pip install -r requirements.txt # Add the Flask App ADD . /src # EXPOSE PORT EXPOSE 80 # Run the Flask APP CMD python src/app.pyيمكن حفظ هذه الأوامر في ملف باسم Dockerfile، يمكنك أيضا تشغيل هذا الملف لبناء صورة (image) لحاوية container من خلال Docker عبر الأمر التالي: docker build -t <your username>/my-flask-app .لاحظ النقطة في آخر الأمر، والتي تعني "استعمل ملف DockerFile الموجود في المجلد الحالي"، أما تعليمة t- بعد أمر build هي لاعطاء وسم (tag) للحاوية التي نريد بناءها. عادة من المتعارف عليه هو اعطاء اسم مستخدمك يليه "/" يليه اسم تطبيقك. مفهوم الحاويات (Containers)الحاوية في Linux عبارة عن غلاف يطبّق مجموعات من القيود لعزل عملية أو مجموعة عمليات (processes) عن باقي مهام وعمليات النظام من ناحية السياق (context)، الذاكرة RAM، القراءة والكتابة، الشابكة (Network)... الخ، بحيث تكون في معزل تام عن باقي الـ processes في النظام. أي نفس فكرة الـ sandboxing. مفهوم الحاويات ليس جديدا، فقد بدأ بالظهور منذ أواخر عام 2007، حين عرض مهندسون لدى Google مشروع cgroups (اختصارا لـ Control Groups) ليتم دمجه في نواة Linux، منذ ذلك الوقت cgroups كان اللبنة الأساسية لعزل الموارد وكبحها في نظام Linux على مستوى النواة. بعدها جاء مشروع LXC (اختصارا لـ LinuX Containers) والذي جمع بين cgroups وميزة عزل نطاقات الأسماء (namespace isolation) في نواة Linux، لتوفير إمكانية إنشاء مجموعات منفصلة عن بعضها من العمليات (process groups)، كل مجموعة مكتفية ذاتيا و/أو محدودة المواد، بحيث لا تدري كل مجموعة عن الأخرى بالرغم من أنهم يشاركون نفس النواة (نواة Linux). هذه المجموعات عُرفت باسم الحاويات Containers. على الرغم من أن LXC الأقرب لفكرة Docker، إلا أنه بقي على مستوى منخفض ولم يوفر واجهة برمجية سهلة للمطورين مثل ما قدمه Docker. إضافات Dockerفي أيامه الأولى، اعتمد مشروع Docker على LXC وبنى عليه، أي استعمله كـ backend أو driver، (لكن الآن يمكن استعمال بدائل لـ LXC) لكنه أضاف عدة أمور عصرية، بعضها مستوحى من أنظمة إدارة النسخ (Version Control Systems) من ذلك: مفهوم Docker image لبناء لقطات من الحاويات (نفس فكرة ملفات .iso) يمكن تصديرها واسترادها، وبالتالي يمكن بناء صورة للمشروع بأكمله ثم يكفي استراد تلك الصورة على الخاودم، يتوجب فقط أن يكون Docker مُنصّبا.إمكانية عمل "إيداع" (Commit) للتغيرات التي قمت بها على صورة المشروع الخاص بك، وبالتالي إمكانية الرجوع للوراء في حال الخطأ، هذه الميزة تسمح أيضا لـ Docker أن يكون وسيلة حفظ احتياطي "backup".كل صورة بنيتها يمكنك مشاركتها مع المجتمع في فهرس docker، والذي كان اسمه Docker index ثم تحول مؤخرا إلى docker hub. ستجد فيه مثلا صور لـتطبيق WordPress منصبة على Ubuntu جاهزة للاستهلاك المباشر، أليس هذا رائعا؟مفهوم الـ Dockerfile الذي سبق عرض ماهيته، وهو وسيلة لأتمتة وسرد خطوات بناء مشروعك أو حاويتك. الأتمتة التي تتيحها ملفات Dockerfiles تسمح بانتهاج نسق Continuous integration الذي تكلمنا عنه، تخيل أنك تريد تجربة مشروعك على Python 3 مثلا، كل ما عليك هو تغيير نسخة Python في ملف Dockerfile وبناء حاوية جديدة لتجرب عليها الناتج، فإن كان جيدا تدفعه للخادوم، وإن لم يكن كذلك تحذفه. نفس الشيء مع إصدارات المكتبات التي يعتمد عليها مشروعك.هذه بعض مما أضافه Docker لما هو موجود، وهي وحدها كفيلة بإحداث قفزة وتحول نوعي في طريقتنا لبناء ونشر البرامج. لكن السؤال الذي قد يطرحه البعض: أليس ما يعمله Docker هو نفسه ما تعمله الآلات الافتراضية Virtual Machines ومحاكاة الأنظمة؟ باختصار، نعم ولا وسنلخص الأمر في النقاط التالية: Docker أخف بكثير من الآلات الافتراضية، يمكنك تشغيل العشرات من الحاويات في حاسوب عادي واحد، في حين لا يمكنك تشغيل 3-4 آلات افتراضية في حاسوب عادي واحد ولو كان قويا نسبيا (يثقل النظام). أي أن Docker يستهلك موارد أقل بكثير.الآلات الافتراضية تقوم بمحاكاة كـــامــل النظام وكل ما فيه ووضعه فوق النظام المضيف، في حين Docker يتشارك النواة (Linux kernel) مع النظام المضيف.ما يقوم به Docker هو تنزيل التوزيعات فقط، أي الـ bins/libs لكل توزيعة وفقط، في حين يتشارك النواة مع النظام المضيف ولا يُنزّل نواة جديدة مع تلك التوزيعة. تلك الـ bins/libs كفيلة لمحاكاة بيئة التوزيعة المرجوة، أما النواة فهي متشابهة بين جميع التوزيعات وبالتالي يتقاسمها مع النظام المضيف (لهذا Docker لا يعمل إلا على Linux).Docker يعزل التطبيق واعتمادياته فقط، في حين الآلات الافتراضية تعزل كامل النظام وما فيه من تطبيقات.الصورتان التاليتان توضحان الفرق بين Docker والآلات الافتراضية: من خلال الصورتين يمكن ملاحظة أن وزن Docker على الخادوم بشكل عام أخف بكثير من الثقل الذي تحدثه الآلات الافتراضية. الجدير بالذكر أيضا أن القائمين على مشروع Docker قاموا بتوفير ما يسمى بـ Docker Hub، يمكن فيه مشاركة صور (images) لمشروعك (إن كان مفتوح المصدر)، تجد فيه صورا للحلول مفتوحة المصدر المعروفة، كصور Wordpress, joomla, mysql, nginx .. الخ، بحيث يمكنك استهلاكها مباشرة أو استيرادها والبناء عليها أدعوك ﻷن تلقي عليه نظرة. يمكن أيضا أن تكون مستودعا خاصا لك، لمشاريعك التجارية غير مفتوحة المصدر / مجانية، تجلب منه وتسترد صورك الخاصة التي قمت ببنائها. إلى هنا نصل إلى خاتمة هذه المقدمة التعريفية. سنقوم في مقال لاحق إن شاء الله بشرح أساسيات Docker بشكل عملي. إذا كانت لغتك الانجليزية جيدة، فأنصحك بمشاهدة الفيديو التالية لفهم أعمق للمقال:
  7. يشرح هذا الدّرس كيفيّة نشر Nginx في حاوية Docker container. نقلّل باحتواء Nginx من نفقات إدارة النظام، فلن نعود في حاجة إلى إدارة Nginx عبر مُدير الحِزَم أو بنائِه من المصدر، تسمح لنا حاوية Docker ببساطة أن نستبدل كامل الحاوية عند إطلاق إصدار جديد من Nginx، نحتاج فقط إلى الحفاظ على ملفّات إعدادات Nginx ومحتوانا. يصف Nginx نفسه كما يلي: يُستَخدَم Nginx من قبل العديد من مديري النُظُم sysadmins في الممارسة العمليّة لتخديم محتوى الويب، ابتداءً من مواقع الملفّات الثابتة flat-file وحتى upstream APIs في NodeJS، سنقوم في هذا الدّرس بتخديم صفحة ويب أساسيّة حتى نستطيع التركيز على إعداد Nginx مع حاوية Docker. إنّ حاويات Docker هي شكل شائع من ممارسات عمليّة قديمة نسبيًّا وهي الاحتواء containerization. يختلف الاحتواء عن الآلات الافتراضية (virtualization) في أنّ الإيهام يقوم بعزل العتاد hardware بعيدًا، بينما يقوم الاحتواء بعزل نظام التشغيل الأساسي بعيدًا أيضًا، يعني هذا من النّاحية العمليّة أنّه يمكننا أخذ تطبيق (أو مجموعة تطبيقات) ووضعها في حاوية (أو حاويات) لجعلها من النمط التركيبي modular، محمولة portable، قابلة للتركيب composable، وخفيفة الوزن lightweight. تعني قابليّة النقل portability أنّنا نستطيع تثبيت مُحرِّك Docker Engine (تتم الإشارة له أيضًا بلُب Docker Core، أو حتى Docker فقط) على مجموعة واسعة من أنظمة التّشغيل، وأي حاوية وظيفيّة مكتوبة من قبل أي شخص ستعمل عليه. إن أردت تعلّم المزيد حول Docker بإمكانك الاطلاع على درس Docker التّمهيدي. سنقوم بتثبيت مُحرِّك Docker على Ubuntu لأغراض هذا الدّرس. سنثبّت إصدار Docker المستقر الحالي لـ Ubuntu وهو 1.8.1. هذا الدّرس مُخصَّص لمستخدمي Nginx الجديدين على Docker، إن كنت تريد الأوامر المجرّدة لإعداد حاوية Nginx لديك تستطيع تطبيق الخطوة الأولى ومن ثمّ الانتقال إلى الخطوة الخامسة. إن كنت ترغب ببناء حاويتك خطوة بخطوة والتعلّم عن تعيين المنافذ port mapping والوضع المنفصل detached mode فقم باتّباع كامل الدّرس. المتطلبات الأساسيةمن أجل احتواء Nginx يجب علينا إتمام ما يلي: إعداد خادوم Ubuntu ويُفضَّل أن يكون مع مفاتيح SSH Keys من أجل الأمان.إعداد مستخدم بصلاحيات الجذر sudo.التحقّق من إصدار النّواة Kernel لدينا.يعتمد Docker 1.8.1 إلى حدٍّ ما على بعض الميّزات الأخيرة للنواة، لذا تأكّد من أن يكون إصدار النّواة 3.10 أو أعلى، تمتلك أنظمة تشغيل لينِكس الحديثة نواة جديدة نسبيًّا، ولكن إن كنت تريد التحقّق قم بتنفيذ الأمر uname –r: uname -rلقد قمنا بتضمين الخَرْج output من نسخة Ubuntu 14.04، والتي تحتوي إصدار نواة أعلى من 3.10، لذا لا يجب أن تقلق ما لم تقم بتنفيذ هذا الأمر على نسخة أقدم: 3.13.0-57-genericالخطوة الأولى – تثبيت Dockerيستضيف Docker على موقعه script بدء للحصول على Docker وتشغيله على جهازنا، نستطيع ببساطة تنفيذ الأمر: sudo curl -sSL https://get.docker.com/ | shلا ينبغي بشكل عام تمرير scripts عشوائيّة من الإنترنت إلى الصّدفة Shell عن طريق الأنبوب (Pipe (| sh، لأنّها قد تقوم بفعل أي شيء، ألقِ نظرة على get.docker.com إن كنت تريد معرفة ما أنت مُقبِلٌ عليه. بعد أن ينتهي تنفيذ الأمر السّابق سنرى الإصدار المُثبَّت كما يلي (قد تكون الأرقام لديك أحدث ولا مشكلة في هذا) وبعض التعليمات حول التشغيل كمستخدم غير جذري non-root\بدون sudo، نقوم في هذا الدّرس بالتشغيل كمستخدم sudo لذا لا داعي للقلق حول هذا الأمر: Client: Version: 1.8.3 API version: 1.20 Go version: go1.4.2 Git commit: f4bf5c7 Built: Mon Oct 12 05:37:18 UTC 2015 OS/Arch: linux/amd64 Server: Version: 1.8.3 API version: 1.20 Go version: go1.4.2 Git commit: f4bf5c7 Built: Mon Oct 12 05:37:18 UTC 2015 OS/Arch: linux/amd64اختياري: قم بتشغيل الحاوية hello-world للتحقّق من أنّ كل شيء يعمل كما هو متوقَّع: sudo docker run hello-worldيجب أن ترى خَرْجًا مشابهًا للتالي: $ docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 535020c3e8ad: Pull complete af340544ed62: Already exists library/hello-world:latest: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security. Digest: sha256:d5fbd996e6562438f7ea5389d7da867fe58e04d581810e230df4cc073271ea52 Status: Downloaded newer image for hello-world:latest Hello from Docker. This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker Hub account: https://hub.docker.com For more examples and ideas, visit: https://docs.docker.com/userguide/نستطيع بعد الانتهاء ممّا سبق الخوض في أساسيّات Docker. الخطوة الثانية (اختيارية) – مراجعة أساسيات الحاوية: التشغيل Run، السرد List، الإزالة Removeيشرح هذا القسم كيفيّة تشغيل حاوية أساسيّة ومن ثمّ إزالتها، إن كنت تعرف مُسبقًا كيفيّة استخدام Docker بشكل عام وتريد التخطّي إلى القسم المتعلّق بـ Nginx فاذهب إلى الخطوة الخامسة. لقد ثبّتنا عميل Docker Client كجزء من تثبيت Docker لدينا، لذا نمتلك أداة سطر الأوامر التي تسمح لنا بالتفاعل مع حاوياتنا. إن قمنا بتنفيذ الأمر التالي: sudo docker ps -aينبغي أن نحصل على خَرْج مُشابِه لما يلي: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a3b149c3ddea hello-world "/hello" 3 minutes ago Exited (0) 3 minutes ago nostalgic_hopperنستطيع مشاهدة بعض المعلومات الأساسيّة حول حاويتنا. سنلاحظ أنّها تملك اسمًا لا معنى له مثل nostalgic_hopper، يتم توليد هذه الأسماء تلقائيًّا إن لم نُحدِّد اسمًا عند إنشاء الحاوية. نرى أيضًا في هذا المثال أنّه تم تشغيل الحاوية منذ 3 دقائق وتم إنشاؤها منذ 3 دقائق. إن قمنا بتشغيل الحاوية مرّة أخرى باستخدام هذا الأمر (مع وضع اسم حاويتنا بدلًا من nostalgic_hopper): sudo docker start nostalgic_hopperومن ثمّ نفّذنا الأمر التالي لعرض الحاويات: sudo docker ps -aيجب أن نشاهد أنّه تم تشغيل الحاوية مؤخّرًا: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a3b149c3ddea hello-world "/hello" 4 minutes ago Exited (0) 9 seconds ago nostalgic_hopperتقوم حاويات Docker افتراضيًّا بتنفيذ الأوامر المسندة إليها ومن ثمّ الخروج. تكون بعض الحاويات مُعدّة لتنفيذ بعض المهام ومن ثمّ الانتهاء من ذلك، بينما يبقى بعضها يعمل بدون وقت مُحدّد. الآن وقد مررنا على بعض أساسيّات Docker فلنقم بإزالة الصّورة image التي تُدعى hello-world، حيث أنّنا لن نحتاجها مرّة أخرى (تذكّر أن تضع اسم حاويتك بدلًا من nostalgic_hopper أو استخدم مُعرِّف ID الحاوية). سنبدأ بعد ذلك باستخدام Nginx. الخطوة الثالثة (اختيارية) – تعلم كيفية عرض expose المنفذ portسنقوم في هذا القسم بتنزيل صورة Nginx Docker image ونرى كيفيّة تشغيل الحاوية بحيث تكون مُتاحة للعوام كخادوم ويب. تكون الحاويات افتراضيًّا غير مُتاحة للوصول من قبل الإنترنت، لذا نحتاج إلى تعيين منفذ الحاوية الدّاخلي إلى منفذ Droplet لدينا، هذا ما سنتعلّمه في هذا القسم. سنحصل في البداية على صورة Nginx. تحتوي الخطوة الخامسة على الأوامر النهائيّة لنشر الحاوية كاملة، لذا إن لم تكن مهتمًّا بتفاصيل التنفيذ تستطيع التخطّي والانتقال إلى هناك. نقوم بتنفيذ الأمر التالي للحصول على صورة Nginx Docker: sudo docker pull nginxيقوم هذا بتنزيل جميع العناصر الضّروريّة للحاوية، يُخبِّئ Docker كل هذا في ذاكرة مؤقتة cache حتى لا نحتاج إلى تنزيل صورة الحاوية في كل مرّة نريد فيها تشغيل الحاوية. تحتفظ Docker بموقع يُدعى Dockerhub وهو مستودع عام لملفّات Docker (يتضمّن كل من الصّور الرسميّة والمُقدَّمة من قبل المستخدمين)، الصّورة التي قمنا بتنزيلها هي صورة Nginx الرسميّة، والتي توفّر علينا عناء بناء الصّورة الخاصّة بنا. فلنقم بتشغيل حاوية Nginx Docker باستخدام هذا الأمر: sudo docker run --name docker-nginx -p 80:80 nginxrun هو أمر إنشاء حاوية جديدة يُحدِّد العَلَم name-- اسم الحاوية (إن تركناه فارغًا سيتم تعيينه تلقائيًّا لنا، مثل nostalgic_hopper في الخطوة الثّانية)يُحدِّد p- المنفذ الذي نقوم بعرضه على هيئة p local-machine-port:internal-container-port-، في هذه الحالة نقوم بتعيين المنفذ 80 في الحاوية إلى المنفذ 80 على الخادومnginx هو عبارة عن اسم الصورة على dockerhub (قمنا بتنزيلها من قبل باستخدام الأمر pull، ولكن يقوم Docker بهذا تلقائيًّا إن كانت الصورة مفقودة)هذا هو كل ما نحتاجه للحصول على Nginx وتشغيله، نقوم الآن بكتابة عنوان IP لـ Droplet لدينا في متصفّح الويب وهنا يجب أن نرى صفحة "Welcome to nginx". سنلاحظ أيضًا في جلسة الصّدفة shell لدينا أنّه يتم تحديث سِجِل Nginx عندما نقوم بطلبات إلى خادومنا، لأنّنا نشغّل الحاويات لدينا بشكل تفاعلي. فلنضغط على الاختصار CTRL+C للعودة إلى جلسة الصّدفة shell لدينا. إن حاولنا الآن تحميل الصفحة سنتلقّى الصّفحة "تم رفض الاتصال" "connection refused"، وقد حدث هذا لأنّنا قمنا بإيقاف تشغيل حاويتنا، بإمكاننا التحقّق من ذلك باستخدام هذا الأمر: sudo docker ps -aيجب أن نرى شيئًا مشابهًا للخَرْج التّالي: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 05012ab02ca1 nginx "nginx -g 'daemon off" 57 seconds ago Exited (0) 47 seconds ago docker-nginxنستطيع أن نرى أنّه تمّ الخروج من حاوية Docker لدينا. لن يكون Nginx مفيدًا جدًّا إن كان يجب علينا أن نكون متصلين attached إلى صورة الحاوية من أجل أن يعمل، لذا سنشرح في الخطوة التالية كيفية فصل detach الحاوية للسماح لها بالعمل بشكل مستقل. نقوم بإزالة الحاوية docker-nginx الحالية عن طريق هذا الأمر: sudo docker rm docker-nginxسنشرح في الخطوة التالية كيفيّة تشغيلها في الوضع المنفصل detached mode. الخطوة الرابعة (اختيارية) – تعلم كيفية التشغيل في الوضع المنفصلنُنشِئ حاوية Nginx جديدة منفصلة باستخدام هذا الأمر: sudo docker run --name docker-nginx -p 80:80 -d nginxأضفنا العَلَم d- لتشغيل هذه الحاوية في الخلفيّة. يجب أن يكون الخَرْج ببساطة مُعرِّف ID الحاوية الجديدة. إن قُمنا بتشغيل أمر السّرد list: sudo docker psسنرى في الخَرْج العديد من الأشياء التي لم نشاهدها من قبل: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b91f3ce26553 nginx "nginx -g 'daemon off" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, 443/tcp docker-nginxبإمكاننا أن نرى أنّه بدلًا من Exited (0) X minutes ago نمتلك الآن Up About a minute، ونرى أيضًا تعيين المنفذ port mapping. إن ذهبنا إلى عنوان IP خادومنا باستخدام المتصفّح فسنشاهد الصفحة "!Welcome to nginx" مرّة أخرى، ولكن في هذه المرّة تعمل الحاوية في الخلفيّة لأنّنا حدّدنا العَلَم d- والذي يُخبِر Docker أن يُشغِّل هذه الحاوية في الوضع المنفصل. نمتلك الآن نسخة من Nginx تعمل في الوضع المنفصل. وبالرغم من ذلك فهي ليست مفيدة بما فيه الكفاية حتى الآن، لأنّنا لا نستطيع تحرير edit ملف الإعدادات ولا تمتلك الحاوية نفاذًا إلى أي من ملفّات مواقع الويب لدينا. نوقف الحاوية بتنفيذ الأمر التّالي: sudo docker stop docker-nginxوالآن وقد توقفت الحاوية عن العمل (نستطيع التحقّق باستخدام الأمر sudo docker ps –a إن أردنا أن نكون متأكدين من ذلك) فبإمكاننا إزالتها بتنفيذ الأمر التّالي: sudo docker rm docker-nginxسنصل الآن إلى الإصدار النّهائي لحاويتنا مع وقفة سريعة لإنشاء ملف مُخصَّص لموقع الإنترنت. الخطوة الخامسة – بناء صفحة ويب ليتم تخديمها على Nginxسنُنشِئ في هذه الخطوة صفحة فهرس index مُخصَّصة لموقعنا، يسمح لنا هذا الإعداد بأن نملك محتوى للموقع بشكل دائم تتم استضافته خارج الحاوية (العابرة transient). فلنقم بإنشاء دليل جديد من أجل محتوى موقعنا بداخل الدّليل الرئيسي home directory والانتقال إليه بتنفيذ الأوامر التالية: mkdir -p ~/docker-nginx/html cd ~/docker-nginx/htmlنُنشِئ الآن ملف HTML (طبّقنا الأوامر من أجل مُحرِّر النّصوص Vim ولكن تستطيع استخدام أي مُحرِّر نصوص آخر). vim index.htmlننتقل إلى وضع الإدخال insert mode عن طريق الضغط على i، ونلصق المحتوى التّالي بداخل الملف السّابق (أو بإمكانك إضافة محتوى HTML الخاص بك): <html> <head> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" integrity="sha256-MfvZlkHCEqatNoGiOXveE8FIwMzZg4W85qfrfIFBfYc= sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==" crossorigin="anonymous"> <title>Docker nginx Tutorial</title> </head> <body> <div class="container"> <h1>Hello Digital Ocean</h1> <p>This nginx page is brought to you by Docker and Digital Ocean</p> </div> </body> </html>إن كنت على معرفة بـ HTML سترى أنّها صفحة ويب بسيطة، قمنا بتضمين وسم <link> يُشير إلى شبكة توزيع محتوى CDN من أجل Bootstrap (وهو إطار عمل CSS يُعطي لصفحتنا مجموعة من التنسيقات المتجاوبة responsive)، تستطيع قراءة المزيد عن Bootstrap. نحفظ هذا الملف الآن عن طريق الضغط على ESC ومن ثمّ wq: و ENTER: تُخبِر (write (w أن يقوم Vim بكتابة التغييرات إلى الملف.تُخبِر (quit (q أن يقوم Vim بالخروج.نمتلك الآن صفحة فهرس index بسيطة بدلًا من صفحة هبوط Nginx الافتراضيّة. الخطوة السادسة – ربط الحاوية إلى نظام الملفات المحليفي هذا القسم سنضع كل ما سبق معًا، سنقوم بتشغيل حاوية Nginx لدينا بحيث تكون قابلة للنفاذ على الإنترنت عبر المنفذ 80، وسنقوم بتوصيلها إلى محتوى موقع الويب لدينا على الخادوم. معلومات أساسية حول مسارات التخزين (volumes) والتي هي الرّبط إلى محتوى خادوم بشكل دائم من قبل الحاوية الخاصة بنايسمح لنا Docker بربط الأدلّة directories من نظام الملفّات المحلّي للجهاز الافتراضي Virtual Machine لدينا إلى حاوياتنا. وفي حالتنا بما أنّنا نريد تخديم صفحات ويب نحتاج إلى إعطاء حاويتنا الملفّات التي نريد تقديمها. كان باستطاعتنا نسخ الملفّات إلى الحاوية كجزء من ملفّات Docker، أو نسخها إلى الحاوية بعد إسقاطها أو توقيفها، ولكن هاتين الطريقتين تبقيان موقعنا في حالة ثابتة بداخل حاويتنا، أمّا باستخدام ميزة حجوم volumes البيانات بإمكاننا إنشاء ارتباط رمزي بين نظام ملفّات Droplet ونظام ملفّات الحاوية، يسمح لنا هذا بتحرير ملفّات صفحات الويب الموجودة حاليًّا وإضافة ملفّات جديدة إلى الدّليل وستكون الحاوية قادرة على النفاذ لها بشكل تلقائي، إن كنت ترغب بقراءة المزيد حول Docker ومسارات التخزين volumes تحقّق من وثائق حجوم البيانات data volumes. تكون حاوية Nginx مُعدَّة افتراضيًّا لتبحث عن صفحة فهرس index في المسار usr/share/nginx/html/، لذا نحتاج في حاوية Docker الجديدة الخاصّة بنا أن نقوم بإعطائها نفاذًا إلى ملفّاتنا في ذلك الموقع. إنشاء الربطلإنشاء الربط نستخدم العَلَم v- لتعيين مُجلَّد من جهازنا المحلّي (docker-nginx/html/~) إلى مسار نسبي في الحاوية (usr/share/nginx/html/). نستطيع إتمام هذا بتنفيذ الأمر التالي: sudo docker run --name docker-nginx -p 80:80 -d -v ~/docker-nginx/html:/usr/share/nginx/html nginxنرى أنّ الإضافة الجديدة إلى الأمر v ~/docker-nginx/html:/usr/share/nginx/html- هي رابط مسار تخزين volume لدينا. تُحدِّد v- أنّنا نقوم بربط مسار تخزين volume.الجزء الذي على يسار ":" هو موقع ملفّنا/دليلنا على الجهاز الافتراضي (docker-nginx/html/~).الجزء الذي على يمين ":" هو الموقع الذي نقوم بالرّبط إليه في حاويتنا (usr/share/nginx/html/).إن قمنا بعد تنفيذ هذا الأمر بالتوجّه باستخدام المتصفّح إلى عنوان IP الخاص بـ DigitalOcean Droplet مثلا (إن كنت على DigitalOcean) لدينا فيجب أن نرى الترويسة الأولى من Hello Digital Ocean (أو أي صفحة ويب أنشأتها في الخطوة الخامسة). إن كنت سعيدًا بإعدادات Nginx الافتراضيّة الأخرى فأنت الآن جاهز. تستطيع رفع المزيد من المحتوى إلى الدّليل docker-nginx/html/~ وستتم إضافته إلى موقعك بشكل مباشر. إن قمنا على سبيل المثال بتعديل ملف الفهرس لدينا وأعدنا تحميل نافذة متصفحنا، سنرى أنّ التحديث يحدث آنيًّا، نستطيع بناء موقع كامل من ملفّات HTML ثابتة بهذه الطريقة، على سبيل المثال إن أضفنا صفحة about.html فبإمكاننا النفاذ إليها على الرّابط http://your_server_ip/about.html بدون الحاجة للتعامل مع حاويتنا. الخطوة السابعة (اختيارية) – استخدام ملف إعدادات Nginx الخاص بناهذ القسم مُخصَّص للمستخدمين المتقدّمين الذين يرغبون باستخدام ملف إعدادات Nginx الخاص بهم مع حاوية Nginx لديهم، قم بتجاوز هذه الخطوة إن كنت لا تملك ملف إعدادات مُخصَّص تريد استخدامه. فلنقم بالعودة دليلًا إلى الوراء كيلا نكتب إلى دليل HTML المتاح للعوام لدينا: cd ~/docker-nginxإن كنّا نرغب بإلقاء نظرة على ملف الإعدادات الافتراضي نقوم فقط بنسخه باستخدام أمر Docker للنسخ: sudo docker cp docker-nginx:/etc/nginx/conf.d/default.conf default.confوبما أنّنا سنقوم باستخدام ملف conf. مُخصَّص من أجل Nginx سنحتاج إلى إعادة بناء الحاوية. نقوم في البداية بإيقاف الحاوية: sudo docker stop docker-nginxنزيل الحاوية باستخدام الأمر: sudo docker rm docker-nginxنستطيع الآن تحرير الملف الافتراضي محليًّا (لتخديم دليل جديد أو استخدام proxy_pass لتمرير حركة مرور البيانات traffic إلى تطبيق أو حاوية أخرى كما كنّا نفعل مع تثبيت Nginx الاعتيادي)، تستطيع القراءة حول ملف إعدادات Nginx في دليل ملف إعدادات Nginx. بعد أن نقوم بحفظ ملف إعداداتنا المُخصَّص يحين الوقت لصنع حاوية Nginx، نضيف ببساطة علم v- آخر مع المسار المناسب لإعطاء حاوية Nginx الجديدة الروابط المناسبة لتعمل من خلال ملف إعداداتنا: sudo docker run --name docker-nginx -p 80:80 -v ~/docker-nginx/html:/usr/share/nginx/html -v ~/docker-nginx/default.conf:/etc/nginx/conf.d/default.conf -d nginxلا يزال هذا الأمر يربط صفحات الموقع المُخصَّصة إلى الحاوية أيضًا. نلاحظ أنّنا سنحتاج إلى إعادة تشغيل الحاوية باستخدام الأمر docker restart بعد أي تغيير لملف الإعدادات أثناء تشغيل الحاوية، لأنّ Nginx لا يقوم بإعادة تحميل فوري إن تمّ تغيير ملف إعداداته: sudo docker restart docker-nginxالخاتمة نمتلك الآن حاوية Nginx قيد التشغيل وتُخدِّم صفحة ويب مُخصَّصة. نوصي من هذه النقطة القراءة حول ربط حاوية Docker إن كنت تريد التعلّم حول ربط الحاويات ببعضها لأغراض استخدام Nginx كوسيط عكسي reverse proxy لتخديم تطبيقات الويب الأخرى المعتمدة على الحاوية. إن كنت تريد إدارة مجموعة من الحاويات مثل حاوية تطبيق، حاوية قاعدة بيانات، وحاوية Nginx، فألقِ نظرة على تركيب Docker Compose. ترجمة -وبتصرّف- لـ How To Run Nginx in a Docker Container on Ubuntu 14.04 لصاحبه Thomas Taege.
  8. docker ecosystem

    يُوفِّر Docker كل الدّوال (Functions) المطلوبة لبناء، رفع Upload، تنزيل Download، بدْء تشغيل وإيقاف الحاويّات؛ وهو مناسِب جدًّا لإدارة كل هذه العمليّات في بيئة من مُستضيف وحيد بعدد محدود من الحاويّات. رغم ذلك يلجأ كثيرون لاستخدام هذه المنصّة كأداة لبناء حاويّات تتوزَّع على عدّة مستضيفات مختلفة. تُمثِّل إدارة عناقيد من المُستضيفات Clustered hosts تحدِّيًّا جدّيًا يتطلّب مجموعةً مختلفة من الأدوات. سنعرِض في هذا المقال المُجدوِلاتِ Schedulers وأدواتِ التّنسيق Orchestration المُستَخدمةَ مع Docker. تُمثّل هذه الأدوات الواجهة الرّئيسة لإدارة الحاويّات والنّشر المُوزَّع. جدولة الحاويات، التنسيق وإدراة العنقودالقدرة على إدارة كل نظام مُستضيف وتفادي تعقيدات البنية التّحتيّة لبيئة العمل هي إحدى الوظائف الأكثر جاذبية عند التّطرق إلى توسّع Scaling التّطبيقات عبر عدة أنظمة مستضيفة. يظهر في هذا الإطار مُصطلح التّنسيق الّذي يشمل جدولة الحاويّات، وإدارة العنقود، وفي بعض الأحيان تجهيز وإعداد مُستضيفات جديدة. تُحيل الجدولة Scheduling عند الحديث عن النّظام البيئي لDocker إلى القدرة على رفع ملفّ يُعرِّف كيفيّة تشغيل حاويّة مُعيَّنة إلى النّظام المُستضيف؛ في حين نعني بالمُجدوِلات الأدواتِ المسؤولةَ عن التّدخّل في نِظام التّهيِئة الأوّليّة Init system لإدارة الخدمات حسب المطلوب. أمّا إدارة العنقود فتُشير إلى التّحكّم في مجموعة من المُستضيفات. يُمكِن أن تشمل هذه العمليّة إضافة أو إخراج مُستضيفات من العنقود، الحصول على معلومات عن حالة المُستضيفات أو الحاويّات، وبدْء تشغيل أو إيقاف العمليّات Processes. ترتبط إدارة العنقود بشكل وثيق مع الجدولة، إذ يجب أن تكون لدى المُجدوِل القدرةُ على الوصول إلى كل واحد من المستضيفات الموجودة في العنقود من أجل جدولة الخدمات. لهذا السبّب يغلُب استخدام نفس الأداة للتّنسيق والجدولة. من أجل إدارة وتشغيل الحاويّات على المُستضيفات المتواجدة على العنقود، يجب على المُجدوِل التّعاطي مع نظام التهيئة الأوّليّة لكلّ واحد من المُستضيفات. يجب على المُجدوِل في نفس الوقت، لتسهيل الإدارة، تقديمُ رؤية مُوَّحّدة لحالة الخدمات على كامل العنقود؛ ممّا يقوده إلى أن يعمل كنظام تهيئة أوليّة عابر للعنقود. لهذا السّبب تلجأ العديد من المُجدوِلات إلى أخذ صوّر طبق الأصل من بنية أوامر أنظمة التّهيئة الأوّليّة، ثمّ تعمل على تجريدها Abstract (إخفاء تعقيدات التّعامل مع بنية هذه الأنظمة). يُعتَبر اختيّارُ المُستضيف أحد أهمّ مسؤوليّات المُجدوِل، حيثُ إنه يتولّى تحديد المُستضيف الّذي ستعمل عليه الخدمة (الحاويّة) أوتوماتيكِيًّا بعدَ اتّخاذ المُدير قرار تنفيذها. يُمكِن للمُدير تحديد قيود على اختيّار المُستضيف، لكن في النّهاية المُجدوِل هو من سيُنفّذ هذه التّعليمات. كيف يتّخذ المُجدوِل قراراته؟تُعرِّف المجدوِلات عادةً سياسة افتراضيّة للجدولة. تُحدِّد هذه السّيّاسة كيف ستُنَفَّذ الخدمات في حال عدم وجود مُدخَلات من طرف المُدير. على سبيل يُمكن أن تكون السّيّاسة الافتراضيّة هيّ وضع الخدمات الجديدة على المُستضيفات الّتي يوجد بها أقلّ عدد من التّطبيقات النّشِطة. تُتيح المُجدوِلات إمكانيّة إعادة كتابة آليّاتِها، ممّا يسمح للمُديرين بتدقيق ضبط عمليّة الاختيّار لتستجيبَ لمُتطَلَّبات مُحدَّدة. على سبيل المثال، إذا وجَب تشغيل حاويّتَين على نفس المُستضيف لكونهما تعملان كوِحدة Unit، فيُمكِن إعلان هذا الغرض أثناء الجدولة. بالمِثل، يُمكِن فصلُ حاويَّتيْن بحيثُ لا تعملان على نفس المُستضيف، لأغراض تتعلّق بالتّوفّر العالي High availability لنظيرَيْن Instances من نفس الخدمة على سبيل المثال. قد تُمثَّل القيود الّتي يُمكِن لمُجدوِل أخذها في الحسبان، على هيأة بيانات وصفيّة Metadata مُوَّجَّهة لأغراض التّحكّم، فتُوضع لصائق Labels على المُستضيفات ليستعين بها المُجدوِل. يكون هذا ضروريًّا إذا كان المُستضيف يحوي تجزئةَ بيانات Data volume يحتاجها أحد التّطبيقات. تحتاج بعض الخدمات إلى أن تُنشَر على كلّ مُستضيف في العنقود، وهو ما تُتيحه المُجدوِلات. ما وظائف إدارة العنقود التي توفرها المُجدوِلات؟ترتبِط وظيفتا الجدولة وإدارة العنقود ارتباطًا وثيقًا لأنّ كلًّا منهما تتطلّب القدرة على العمل على مُستضيفات مُحدَّدة وعلى العنقود ككلّ. تُستخدَم برامج إدارة العناقيد لطلب معلومات عن أعضاء عنقود، إضافة أو حذف أعضاء، أو حتّى الاتّصال بمُستضيف مُعيَّن لإدارة أكثر تخصيصًا. يُمكِن أن تُضاف هذه الوظائف إلى المُجدوِل كما يُمكِن إدراجها ضمن مسؤوليّة برنامج مُستقلّ. ترتبِط إدارة العنقود في كثيرٍ من الحالات بأداة استكشاف الخدمة أو مخزن إعدادات بصيغة مفتاح-قيمة. يُفيد هذا الارتباط في توزيع المعلومات وحفظها عبرَ كامل العنقود، كما أنّ المنصّة في هذه الحالة جاهزة لوظيفتها الأوليّة. في هذه الحالة (ارتباط أداة الإدارة باستكشاف الخدمة ومخزن الإعدادات) يحتاج إجراء بعض مهامّ إدارة العنقود، إن لم تتوفّّر طُرُق Methods للتّخاطُب مع المُجدوِل، إلى تغيير قيّم موجودة في مخزن الإعدادات عن طريق واجهته لبرمجة التّطبيقات Application programming interface, API. على سبيل المثال: تُغَيَّر عضويّات العنقود عن طريق التّعديل على قيّم في مخزن الإعدادات. يُحتفَظ بالبيانات الوصفيّة المُتعلِّقة بالمُستضيفات في مخزن الإعدادات؛ حيثُ يُمكن استخدامها كما ذكرنا سابِقًا لاستهداف مستضيف أو مجموعة من المُستضيفات بقرارات جدولة. كيف تكون الجدولة في حالة تجميع الحاويّات؟يتوجّب في بعض الأحيان إدارة عدّة خدمات كما لو كانت تطبيقًا واحدًا، ففي بعض الحالات لا يُمكن حتى نشر خدمة دون نشر خدمة أخرى مُصاحِبة لها، لارتباط عملهما. تُوفّر عدّة مشاريع تنسيقًا متقدِّمًا يأخذ في الحسبان تجميع الحاويّات، ولهذه الوظيفة عدّة فوائد. تسمح إدارة الحاويّات على مجموعات للمُدير بالتّعامل مع تشكيلة من الحاويّات على أنّها تطبيق واحد. يُبسِّط تشغيلُ عدّة عناصر مُرتبِطة بإحكام إدارةَ التّطبيقات دون أن يكون ذلك على حساب فوائد تقسيمها إلى حاويّات لكلٍّ منها وظيفة منفصِلة؛ حيثُ يسمح للمُدير بالحفاظ على فوائد استخدام التّصميم خدَمي التّوجّه Service-oriented مع تقليل جهد الإدارة. يُمكِن أن يعنيَ تجميعُ التّطبيقات ببساطة جدولتَها وإتاحة إمكانيّة تشغيلها أو إيقافها معًا؛ كما أنّه قد يُشير إلى تصوّرات أكثر تعقيدًا مثل فصل كل مجموعة ضمن شبكة فرعيّة أو العمل على توسّع Scaling مجموعة من الحاويّات بدل العناية بالتّوسّع الفردي لكل واحدة منها. ماذا نعني بالتّجهيز Provisioning؟يرتبِط مفهوم التّجهيز بإدارة العناقيد. نعني بالتّجهيز مجموعة الآليّات الّتي تسمح بإضافة وإعداد مُستضيفات جديدة لتكون جاهزةً للعمل ضمن العنقود. في حالة نشر التّطبيقات عبر Docker فإنّ التّجهيز يعني إعداد Docker وضبطَ المُستضيف الجديد للالتحاق بعنقود موجود. تختلف طريقة التّجهيز بشكل كبير حسب الأدوات المُستخدَمة ونوعيّة المُستضيف، ولكن الهدف في الأخير هو نظام جديد جاهز للعمل. على سبيل المثال، إذا كان المُستضيف آلة تخيّليّة Virtual machine فإن أدواتٍ مثل Vagrant يُمكِن أن تُستخدَم لإعداد المستضيف الجديد. يسمح معظَم مزوّدي الخدمات السّحابية Cloud providers بإنشاء مُستضيفات جديدة اعتمادًا على واجهة تطبيقات برمجيّة API. على الجانب الآخر، يحتاج تجهيزُ عتاد خام (حاسوب بدون نظام تشغيل) لتدخّل يدوي أكثر؛ يُمكن اللّجوء إلى أدوات مثل Ansible، Puppet، Chef أو Salt من أجل الإعداد التّمهيدي للمُستضيف وتجهيزه بالمعلومات المطلوبة للاتّصال بالعنقود. يوجد خيارات للتّجهيز: إمّا أن يكون عمليّة يدويّة يُطلِقها المُدير، أو أن يكون جزْءًا من أدوات إدارة العنقود من أجل أتممة التوسّع Automation. يتطلّب الخيّارُ الأخير تعريفَ إجراء يطلُب مُستضيفات جديدة والشّروط الّتي يجب أن يحصُل حسبها الطّلب. على سبيل المثال، إذا كان تطبيقٌ يُعاني من الحِمل الزّائد على الخادوم، فيُمكِن ضبط مُستضيفات وإلحاقُها بالنِّظام لتتوسَّعَ الحاويّات أفقيًّا عبر البُنية التّحتيّة الجديدة، من أجل التّخفيف من الضّغط على الخادوم. ماهيّ المُجدوِلات الأكثر انتشارًا؟من بين المشاريع الأكثر شهرةً في الجدولة وإدارة العناقيد (الوظائف الأساسيّة): Fleet: أداة الجدولة وإدارة العناقيد ضمن توزيعة CoreOs. تقرأ Fleet معلومات الاتّصال لكل مُستضيف في العنقود من etcd ( أداة استكشاف خدمة وإعداد عموميّ مُوزَّع لكل من الحاويّات والأنظمة المُستضيفة، جزْء من توزيعة CoreOs) وتُوفِّر خدمة إدارة شبيهة بSystemd (نِظام تهيئة أوّليّة بدأت الكثير من توزيعات غنو/لينوكس اعتمادَه ليكون بديلًا عن أنظمة التّهيِئة الأوّليّة التّقليديّة). Marathon: وهو العنصُر المسؤول عن الجدولة وإدارة الخدمات في Mesosphere (نظام تشغيل مُوجَّه لإدارة مراكز البيانات Data centers). يعمل مع mesos (أداة لتجريد وإدارة جميع موارد العنقود) للتّحكّم في الخدمات الّتي تعمل لفترات زمنيّة طويلة. كما أنّه يُوفِّر واجهة ويب لإدارة الحاويّات. Swarm: أعلن مشروع Docker عن مُجدوِل Swarm في ديسمبر/كانون الأوّل سنة 2014، ويأمل في أن يُقدِّمَ مجدوِلًا جيّدًا يُمكنه تقسيم الحاويّات على المُستضيفات المُجهَّزَة على Docker، وذلك باستخدام نفس الصّيّاغة Syntax الّتي يستخدمها Docker. بالنّسبة للجدولة المُتقدّمة والتّحكّم في مجموعات الحاويّات، توجد المشاريع التّاليّة: kubernetes: مُجدوِل مُتقدّم من Google. يُتيح kubernetes تحكّمًا متقدّمًا في الحاويّات؛ حيث يُمكِن توصيف الحاويّات، تجميعها، وإعطاءُها شبكات فرعيّة مستقلّة للاتّصال. compose: مشروع تابِع لـ Docker، أُنشِئ لإضافة إمكانيّة إدارة مجموعات من الحاويّات باستخدام ملفّات إعداد تقريريّة Declarative. يستخدِم روابط Docker لمعرفة معلومات عن علاقات التّبعيّة بين الحاويّات. خلاصةتُمثِّل إدارة العناقيد والجدولة جزأين مهمَّيْن من إعداد وتنفيذ خدمات تعتمد على الحاويّات في بيئة مُوزَّعة مُكوَّنة من عدّة مُستضيفات، إذ تُوفِّران الوظائف الأساسيّة من أجل بدْء تشغيل الخدمات والتّحكّم فيها. يُمكِن عبر استخدام المُجدوِلات بفعاليّة إحداثُ تغييرات كبيرة على عمل التّطبيقات، بالقليل من الجُهد.
  9. docker ecosystem

    مقدّمةيكتسي التّواصل Communication والتّشبيك Networking أهميّةً بالغة عند بناء نُظُم موزَّعة تعمل عليها حاويّات Docker؛ حيثُ تعتمد بنية التّطبيقات الّتي تتبع التّصميم خَدَمي التّوجّه Service-oriented بشكل كبير على تواصُل المكوِّنات في ما بينها حتى تعمل كما يُرادُ لها. سنذكُر في هذا الدّرس أدواتِ وإستراتيجيّات التّشبيك المُتعدّدة المُستخدَمة لضبط الشّبكات الّتي تعمل عليها الحاويّات؛ وذلك من أجل الوصول إلى الوضعية المرغوبة للشّبكة. يُمكن في بعض الحالات الاعتماد على الحلول الّتي يُوفّرها Docker افتراضيًّا، إلّا أنّ في بعض الحالات تتطلّب الاستعانة ببعض المشاريع البديلة. الحل الافتراضي للتّشبيك على Dockerيقدّم Docker افتراضيًا العديد من الأدوات القاعديّة المطلوبة للتّواصل بين الحاويّات Container-to-container وبين الحاويّات والنِّظام المُستضيف Container-to-host. يضبُطُ Docker عند تشغيله واجهة وهميّة Virtual interface جديدة للشّبكة باسم docker0 على النّظام المُستضيف. تعمل هذه الواجهة كجسر Bridge يُمكّن Docker من إنشاء شبكة فرعيّة Subnet تستخدمها الحاويّات في ما بعد؛ إضافةً إلى عملها كنقطة وصل بين آلية التّشبيك في الحاويّة وتلك الموجودة في المُستضيف. تُنشَأ واجهة وهميّة عندما يبدأ Docker تشغيل حاوية جديدة، وتُمنح عنوان IP ضمن مجال الشّبكة الفرعيّة المذكورة سابقًا. يدخُل عنوان IP الواجهة الوهمية الجديدة في إطارالشّبكة الدّاخليّة للحاويّة ممّا يوفِّر مسارًا يُمكن للحاويّة الاتّصال عن طريقه بالجسر docker0 الموجود على المُستضيف. يضبُط Docker آليًّا قواعد Iptables للسّماح بإعادة التّوجيه Forwarding ويُعدّ آليّة ترجمة العناوين على الشّبكة Network address translation (أو NAT اختصارًا) للاستخدام عند تبادل البيانات بين docker0 والعالم الخارجي. 1- كيف تعرِض الحاويّات الخدماتِ للعملاء؟لا تحتاج الحاويّة لأي إعدادات إضافيّة للحصول على الخدمات المُقدَّمة من طرف الحاويّات المتواجدة على نفس المُستضيف، حيثُ إنّ المُستضيف سيُوجِّه الطّلبات الّتي تُرسَل من الواجهة docker0 وتتّجه إليها (كلّ من المصدَر والوِجهة يوجدان على نفس الشّبكة الفرعيّة) إلى المكان المُناسِب. يُمكن للحاويّات عرضُ expose منافذها Ports عبرَ المُستضيف لتلقي البيانات ينقلها هذا الأخير إليها من العالم الخارجي. يُمكن قرن Mapping منافذ الحاويّة المعروضة بمنفذ من النِّظام المستضيف (تُنقل البيانات المُتبادلَة عبر منفذ المُستضيف إلى منافذ الحاويّة المقرونة بها) إمّا باختيار منفَذ مُحدَّد؛ أو ترك هذه المهمّة لـ Docker، في هذه الحالة يختار Docker منفذًا عشوائيًا غير مُستعمل برقم عالٍ. يتولّى Docker في هذا الإطار إدارة قواعد التوّجيه وإعدادت iptables لإيصال البيانات إلى وجهتها الصّحيحة. 2- ما الفرق بين عرض ونشر منفَذ Publishing ؟يُمكِن عند إعداد صورة أو بدْء تشغيل حاويّة، الاختيارُ بين عرض أو نشر المنافذ. من المهمّ التّفريقُ بين الاثنين. يعني عرضُ منفَذ مّا إعلامَ Docker أنّ الحاويّة تستخدِم المنفَذ المذكور، ويُمكن بالتّالي استخدام هذا المنفذ لأغراض الرّبط Linking أو الاستكشاف. يُعطي فحصُ حاويّة - على سبيل المثال - معلوماتٍ عن المنافذ المعروضة، وعند ربط حاويّات فإنّ متغيّرات البيئة تُضبَط لمعرفة المنافِذ المعروضة في الحاويّة الأصليّة.يُمكن - في الإعداد الافتراضي - للنِّظام المُستضيف الوصولُ إلى الحاويّة؛ نفس الشّيء بالنّسبة للحاويّات الموجودة على نفس المُستضيف. تقتصِر فائدة عرض المنافِذ في هذه الحالة على توثيق استخدام المنفذ وجعل هذه المعلومة مُتاحةً للرّبط والتّعيين الآليّيْن. على الجانب الآخر، يؤدّي نشر منفذ إلى جعله متاحًا للعالم الخارجي عبر قرنه بواجهة المُستضيف. 3- ماهيّ روابِط Docker؟يُوفّر Docker آليةً لإعداد الاتّصالات بين الحاويّات، تُسَمّى "روابط Docker" . تحصُل حاويّة جديدة عندَ ربطها بأخرى موجودة على معلومات اتّصال الأخيرة عبر متغيّرات مُشترَكة في بيئة التّنفيذ. تُشكّل هذه الوسيلة طريقةً سهلة للتّأسيس لاتّصال بين حاويّتيْن عبر إعطاء الحاويّة الجديدة معلومات مُفصَّلة عن كيفية النفاذ إلى الحاوية المُصاحِبة. تُضبَط المتغيّرات المُشترَكة حسب المنافذ الّتي تعرضها الحاويّة بينما يضبط Docker عنوان IP الحاويّة ومعلومات اتّصال أخرى. مشاريع للرّفع من قدرات Docker في التّشبيكنموذج التّشبيك المُقدَّم أعلاه يُشكِّل نقطة بدْء جيّدة في بناء وربط الشّبكات. الاتّصال بين الحاويّات الموجودة على نفس المُستضيف يعمل بشكل مُباشر. بالنّسبة للاتّصال بين المُستضيفات فيعمل عن طريق الشّبكات العمومية Public networks ما دامت المنافذ مقرونة بشكل صحيح ومعلومات الاتّصال متوفّرة لدى الطّرف الآخر. على الرّغم من ما سبق، تتطلّب بعض التّطبيقات بيئات شبكيّة خاصّة (نظرًا لبعض الأهداف الأمنيّة أو الوظيفيّة) لا يستطيع نموذج التّشبيك الأصلي في Docker توفيرها. لهذا السّبب أُنشِئت مشاريع عديدة لزيادة قُدُرات Docker في الرّبط بين الشّبكات. 1- إنشاء شبكات فوقيّة Overlay لتجريد Abstract البنية التّحتيّةركّزت العديد من المشاريع على تحسين وظيفي يتمثّل في التأسيس لشبكات فوقيّة Overlay Networks؛ وهيّ عبارة عن شبكات افتراضيّة مبنيّة على اتّصالات موجودة مُسبَقًا. يُمكّن التّأسيس لشبكات فوقيّة من إنشاء بيئات تشبيك منتظِمة يُمكن التّنبّؤ بها، وتربط بين عدّة مستضيفات. يُساعد هذا الأمر في تسهيل ربط الحاويّات بالشّبكة دون الاهتمام بالمُستضيف الذي تعمل عليه هذه الحاويّات. يُمكِن استخدام هذه الطّريقة لبناء شبكة افتراضيّة واحدة تمتدّ على عدّة مُستضيفات، أو لبناء شبكات فرعيّة لكل مُستضيف اعتمادًا على نفس الشبكة الفوقيّة. تُتيح الشّبكات الفوقيّة أيضًا بناء نسيج عنقودي Fabric clusters. تعمل الحوسبة النسيجيّة Fabric computing (يُطلَق عليها أحيانًا الحوسبة التوحيديّة Unified computing) على توحيد عدّة مُستضيفات وإدارتها كما لو كانت كيانًا واحدًا بموارد أكبر. يسمح إنجاز مبدأ الحوسبة النسيجيّة للمُستخدِم النّهائي بإدارة العنقود كوحدة بدلًا من مستضيفات متفرّقة. يلعب ربطُ الشّبكات جزءًا كبيرًا من إنشاء عناقيد حسب هذا المبدأ. 2- الإعداد المتقدّم للتّشبيكتتولّى مشاريعُ أخرى الرّفع من قدرات Docker التّشبيكيّة عن طريق توفير مرونة أكبر. إعداد التّشبيك الأصلي في Docker يقوم بالوظيفة الّتي أُنشئ من أجلها، ولكنّه بسيط جدّا. على الرغم من أنّ الحواجز الوظيفيّة للإعداد الافتراضي للشّبكات في Docker قد تظهر عند تخصيص مُتطلَّبات التّشبيك في مستضيف واحد، إلّا أنّها تظهر بشكل أوضح عند التّعامل مع شبكات عابرة للمُستضيفات. يُلجأ - من أجل إضافة وظائف جديدة إلى "تطويع" تلك الموجودة مُسبَقًا. لا تُضيف هذه المشاريع إعدادات خارقة لكنّها تسمح بربط أجزاء في ما بينها لإنشاء تصوّرات أكثر تعقيدًا لعمل الشّبكات. تمتد الوظائف الّتي تُضيفها هذه المشاريع من مجرّد إنشاء وربط شبكات خاصّة بين بعض المستضيفات إلى ضبط جسور، شبكات محليّة افتراضيّة، تخصيص الشّبكات الفرعيّة والبوّابات Gateways. توجد مشاريع وأدوات أخرى تُستخدم كثيرًا في بيئات Docker لتوفير وظائف جديدة، وذلك رغم أنّها لم تُطوَّر خصّيصًا لـDocker. يتعلّق الأمر خصوصًا بتقنيّات وصلت لمرحلة النّضوج في إنشاء الشّبكات الخاصّة والأنفاق Tunnels الّتي تُستخدَم غالِبًا لتأمين التّواصل بين المستضيفات وعبر المُستضيفات. هل من مشاريع شائعة الاستخدام للتحسين من أداء الشّبكات في Docker؟توجد عدّة مشاريع تُركِّز على توفير شبكة فوقيّة لمستضيفات Docker. في ما يلي بعض أكثر هذه المشاريع شيوعًا: flannel: يُطوِّره فريق CoreOs. أُنشئ هذا المشروع أصلًا لإعطاء كل مُستضيف شبكة فرعيّة خاصّة به ضمنَ شبكة مُشترَكة؛ وهو شرط ضروري لعمل أداة التّنسيق kubernetes الّتي تُطوِّرها Google، لكنّه مفيد أيضًا في حالات أخرى. weave: تُنشئ أداة Wweave شبكة افتراضيّة تربط بين مختلف مُستضيفات Docker. يُسهّل هذا الأمر من توجيه بيانات التّطبيق، إذ أنّ الحاويّات تبدو كما لو كانت كلّها على نفس المُوزِّع Switch. بالنسبة للتّشبيك المتقدّم، تهدف المشاريع أدناه إلى توفير قدرات تطويع أكثر للشّبكة. pipework: يهدف هذا المشروع إلى سد الفجوة في آلية التّشبيك الأصليّة في Docker من حيث نقص الوظائف المتقدِّمة، في انتظار تطّورها حيثُ يُسهّل التحكّم في وضبطَ إعدادات متقدّمة للتّشبيك. الأداة التّاليّة هي مثال على اختيّار برمجيّات موجودة خارج النّظام البيئي لـDocker واستخدامها بإضافة وظائف جديدة إليه. tinc: عبارة عن برنامج لإنشاء شبكة افتراضيّة خاصّة Virtual private network (أو VPN اختصارًا) يعتمد على التّعميّة Encryption والأنفاق. تُقدّم هذه الأداة طريقة وسيلة صلبة لجعل استخدام الشّبكة الخاصّة شفّافًا بالنّسبة لأيّ تطبيق. خاتمةيعتمد نموذج Docker على توفير خدمات عبر عناصر داخليّة وأخرى خارجيّة، وهو ما يجعل من الاعتبارات المُتعلّقة بالشّبكة مهمّةً للغاية. يُوفّر Docker وظائف أساسيّة لإعداد الشّبكات مثل الواجهات الافتراضيّة، الشّبكات الفرعيّة، iptables وإدارة ترجمة العناوين على الشّبكة (NAT)؛ وهيّ الوظائف الّتي تُكمّلها مشاريع أخرى أُنشِئت لإتاحة إمكانية ضبط إعدادات أكثر تقدّمًا. سنتطرّق في الدّرس القادم لكيفيّة عمل المُجدوِلات Schedulers وأدوات التّنسيق orchestration المبنيّة على هذا الأساس بهدف إدارة عنقود حاويّات.