في هذه الصفحة
المقدمة
يُعَدُّ Docker واحدًا من الأدوات الأكثر شيوعًا لإدارة الحاويات (Containers)، مما يطرح تساؤلًا هامًا حول كيفية تواصل هذه الحاويات مع بعضها البعض بشكل آمن وفعال.
في هذا المقال، سنستعرض كيفية إعداد الاتصال بين الحاويات في Docker، بدءًا من إعداد التوجيه عبر المنافذ (Port Forwarding) للوصول إلى الحاويات من الجهاز المضيف (Host Machine)، وصولاً إلى كيفية تمكين الاتصال المباشر بين الحاويات دون الحاجة إلى إعداد منفذ خارجي، باستخدام شبكة Docker الافتراضية التي تُعرف بـ "Bridge Network".
كما سنوضح مفهوم Union File System (UFS) الذي يعد الأساس في إدارة الطبقات في Docker. وأخيرًا، سنتناول كيفية إنشاء صورة مخصصة (Customize Image) لتكون متوافقة تمامًا مع متطلباتك الخاصة، مما يسمح لك بإعداد بيئة تشغيل تناسب التطبيق المراد تشغيله.
Accessing Containers From Host Machines
مبدائيا علشان نـ Access اي Container من Host Machine بتاعتنا لازم نعمل (Port Forwarding) بإستخدام ال Command دا:
docker run -d -p 8080:80 <image_name>
والـ 8080: ده الـ Port اللي عاوزين نعمله Mapping من الـ Machine بتاعتنا
والـ 80: ده الـ Port اللي عاوزين نعملها Access على الـ Container
او ممكن نعمل:
docker run -d -p <image_name>
وفي الحاله دي: docker هيفتح Port عشوائي على الـ Host Machine وبعدين نعمل:
docker ps
عشان نعرف البورت العشوائي دا كام.
طيب لو معلمناش Port Forwarding يبقي مستحيل نقدر نعمل Access للـ Container دا من الـ Host Machine بتاعنا لانه هو ف منطقة منعزلة واحدى الطرق عشان نوصله هي الـ Port Forwarding .
Accessing Container From Another Container
طيب انا مش عايز بقا ادخل اصلا ع ال Container دا من الـ Machine بتاعتي بل من Container تاني عندي علي نفس الـ Machine بتاعتي.
طيب تعال نعمل 2 Containers بدون port forwarding أصلا:
docker run -d image_name1
docker run -d image_name2
طيب علشان نـ Access Service بنحتاج ال ip-add او DNS-name صح كده؟
ازاي نعرف ال ip-add بتاع Container؟
احسن طريقه هي تكتب الـ Command دا وهيديلك كل المعلومات ال انت عايزها عن الـ Container دا سواء Ip-address , Gateway, volums, …
docker inspect id_container1
طيب ناخد ال ip address بتاع ال container1 وندخل جوه ال container2 ك الاتي:
- محتاج تفتح shell علي الكونتنير التاني باستخدم ال command line دا:
docker exec -it <container_id2> bash
أو
docker exec -it <container_id> sh
علي حسب نوع ال shell ال نازل مع ال image
- اعمل بس ping command شوف اي الدنيا:
ping ip-add1
هتلاقي مرجعلك response وكله تمام، طيب جرب تعمل access لل web server نفسه بتاع الـ Container الاول ؟
ونزل curl لو مش موجود عندك ع ال image
apk add curl
أو
apt add curl
علي حسب ال image اللي بتسخدمها واعمل http request لل Container التاني مش بس ping بإستخدام
curl ip-add1
هيرد عليك زي الفل برده ، يعني كده ال container الاول بالكامل accessible over network.
Container IP-Address
بس استنا بس كده معلش هو الip-address للكونتينرز دا جه ازاي ومنين!!
مش قولنا ال containers عبارة عن مكان معزول جوه ال os يعني مش vm حتي يكون ليها network interface!
بص ياسيدي عندنا حاجه اسمها bridge-network هي شبكه افتراضيه بيتستخدمها docker وقت ما حضرتك بتعمل docker install
بتنزل معاه automatic.
طيب فايدتها ايه؟ هي بتدي امكانية containers علي نفس ال machine يكلمو بعض.
لما docker بينزل عندك بيكون معاه physical network اسمها Docker 0 بيكون عنده range من ip addresses بيوزعهم علي كل container بيتعمل.
لا يمكن التعديل علي Docker Images
مفيش اختلاف انك لما يكون عندك Container عامله من Image معينه وقعدت تعدل وتضيف وتمسح من ال Image ومجرد ما تمسح الـ Container دا وتعمل Container جديد من نفس ال Image كل شغلك دا هيطير ومفيش حاجه اتحفظت علي ال Image
هتقولي ياعم ما نعمل volume or bind mount ونحفظ عليهم التغيرات دي وخلصنا .. هقولك شاطر انا كنت عايز اخدك للنقطه دي علشان يجي سؤالي بقا
طريقه تعامل الـ Docker Images مع التغيرات
تعرف ليه لما بنمسح الـ Container ومفيش volume كل التعديلات بتطير ولما يكون في volume بيكون ف تعديلا محفوظة عادي ؟
ببساطه لان لما docker قررو يعمول images قالها صريحه كده ال images غير قابله للتعديل هي معموله علشان كل الناس تستخدمها ف مش منطقي حضرتك تعدل فيها وتبوظ شغل ناس تانيه بتستخدم ال image دي.
يعني تخيل معايا image عندها port 80 بتعمل listen لل web services عليه وجيت انت غيرته ل 100 بدل 80 تقوم مبوظ شغل كل الناس اللي عاملة listen علي port 80 اكيد مش منطقي الكلام دا.
Union File System (UFS)
طيب هل ممكن نعمل image علي مزاجنا كده ونستخدمها براحتنا ف اي وقت بالتعديلات بتاعتنا ؟
اكيد ينفع بس مش هقولك ازاي غير لما نفهم الاول نقطه مهمه وهي الـ File System.
خلينا نفهم ازاي ال image بتتعامل مع ال File System علشان نفهم ليه التعديلات بتتمسح وامتي متتمسحش.
بص ياسيدي في نظام اسمه : Union File System (UFS) ودا نظام تشغيل الملفات اللي بيتسخدمه images في docker.
- يعني مثلا علي لينكس بيستخدم نظام اسمه EXT4 or Btrfs
- ويندوز بيستخدم: NTFS
- ماك بيستخدم: APFS
طيب نرجع تاني لـ UFS: دا نظام فريد من نوعه عباره عن شوية Layers فوق بعض كده وكل ال Layers لايمكن تغير فيها يعني من الاخر Read Only.
لما حضرتك بتنشأ ملف جديد دا بينشأ New Layer اسمها Outer Layer بيحط فيها الملف دا والـ Layer الجديدة بتكون Read and Write مش بس Read.
طيب انت ازاي بتقولي Read Only وانا بقدر اعدل ف الملفات الاصليه بتاعت ال image نفسها؟
هقولك لا docker بيضحك عليك!
لما حضرتك بتروح تعمل تعديل ف ملف موجود ف ال Layer الاصلي بتاع ال Image بيروح ياخد منه كوبي ويعمل Outer Layer يحطه جواها ويعدل فيه براحته لكن الاساسي مستحيل يتعدل.
هقولك بس استنا ما انا ممكن امسح ملف مش اعدله هقولك برده بيضحك عليك بيروح يكتب Record ان الملف الفلاني اتمسح لكن مش بيمسحه خالص ولما تيجي تشوف الملف دا هيروح للريكورد يقولك اتمسح لكن هو ف الاصل موجود.
انا عايز اوصلك من كل دا لنقطة واحدة فقط ان اي تعديل بيتم علي ال image بيحصل ف مكان واحد فقط اسمه Outer Layer لما بتمسح ال Container ، ال Outer Layer بتطير كلها وبيفضل ال Read Only Layers بتاع ال Image نفسها علشان كده حضرتك مش بتلاقي التعديلات بتاعتك.
طيب ايه التفسير ان لما بنضيف Volume or Bind Mount بنلاقي التعديلات؟ علشان ببساطة هنا الوضع مختلف خالص
احنا بناخد الملف من نظام تشغيل الملفات بتاع ال Image ننقله بالكامل لـ نظام التشغيل بتاع جهازك نفسه سواء كان Volume or Bind فمهما حصل لل Container ميهمكش ف حاجه انت عندك ال Files علي جهازك نفسه.
جميل جدا تعال نرجع لموضوعنا بقا ازاي نعمل customize image ؟
Image Customization
عاوزين Image علي مزاجنا بتعديلاتنا ومتروحش مننا ف ايه الحل؟
من الاخر كده هناخد نسخه كامله لل Image نحط عليها تعديلاتنا ونحفظ Image جديده خالص ونستخدمها بعدين براحتنا.
هنعمل container وليكن باستخدام ubuntu image ونفتح عليها shell:
docker run -it ubuntu bash
هنعمل شوية تغيرات داخل الـ Container وتعالى مثلاً نضيف ملف جديد ونسيبه فاضي مش مشكلة:
touch newFile
وتعالى كمان نحذف أي فايل ف ال ubuntu image وليكن ملف اسمه legal:
rm /etc/legal
وكمان واحد من اهم ال commands وهو curl مش موجود علي ubuntu يعني تعالى كمان نعمله install علي ال image:
apt install curl
تعالى نبص علي التغيرات اللي حصلت علي الـ Container من خلال:
docker diff id_container
هتلاقي ملفات كتير اتغيرت وملفات اضافت وملف اتحذفت ، ودلوقتي عاوزين نعمل image جديده من ubuntu بس عليها التغيرات بتاعتنا:
docker commit id_container myUbuntuVersion:1.0
هنسمي الimage الجديدة myUbuntuVersion والـ 1.0 عبارة عن tag بتحدد بيه ال version حاليا انت معاك image جديد اسمها myUbuntuVersion:1.0 تقدر تعمل منها Containers عليه كل التغيرات الجديدة:
docker run -it myUbuntuVersion:1.0 bash
حاليا انت داخل الـ Container اللي مستخدم ال image الجديدة يعني لو كتبت curl مش هيزعلك وهتلاقيه وهتلاقي كمان الملف اللي عملناه جديد لو كتبت
ls -l /newFile
بس نسيت اقولك حاجه ان في مشكله صغيره هتقابلك ان حجم ال image الجديد هيكون كبير مقارنة بال image الاصليه.
لو فكرت تعمل:
docker images ls
هيطلعلك كل ال images اللي عندك وحجمها وهتلاحظ فرق كبير في الحجم بين الاتنين ولو ركزت شوية هتعرف أي السبب.
السبب لو تفتكر قولتا في layers ف ال UFS ولما تيجي تعدل حاجه مش بيعدل ف ال File الأساسي بل بياخد نسخه تانيه منه ويعدل جواها ودا بيعمل Duplicate وبيزود الحجم.
فلنا لقاء أخر ازاي نظبط حجم ال images ان شاء الله.
Dockerfile
حاجه اخيره التعديلات اللي عملتها علي ال image الجديدة ازاي تعرف بيها التيم بتاعك وازاي انت نفسك تفتكر شغلك ؟ ببساطة هو اشهر file نعرفه وهو dockerFile دا جواه بتكتب التعليمات والارشادات اللي انت عملتها علشان توصل لل image.
في الختام
يعتبر Docker أداة قوية لإدارة الحاويات، حيث يمكّنك من إعداد بيئات تشغيل منفصلة وآمنة. لتحقيق الاتصال بين الحاويات، يمكن استخدام Port Forwarding للوصول إليها من الجهاز المضيف، أو استخدام Bridge Network للاتصال المباشر بين الحاويات.
وبيعتمد Docker على Union File System (UFS) لإدارة الطبقات، حيث تُعتبر الصور غير قابلة للتعديل، ويضاف كل تغيير كطبقة جديدة تُسمى Outer Layer.
لإنشاء صور مخصصة، يمكنك إجراء تغييرات داخل الحاوية وحفظها باستخدام docker commit لتكوين صورة جديدة تحتوي على التعديلات المطلوبة.
من المهم مراقبة حجم الصور الناتجة عن تكرار الطبقات، ولإدارة ذلك، يمكن استخدام dockerFile، وهو ملف يُسجل التعليمات والخطوات للوصول إلى صورة معينة، مما يسهل مشاركة إعدادات الحاوية مع فريق العمل وإعادة استخدامها.