داکر در عمل :: مسائل حل شده و فضای نامی PID

هر برنامه در حال اجرا یا فرآیند- در ساختار لینوکس دارای یک شماره منحصر به فرد است این شناسه فرآیند (PID) نامیده می شود. فضای نام PID مجموعه ای از اعداد است که برای شناسایی فرایندها استفاده می‌شود. لینوکس امکاناتی جهت ایجاد فضای نامی PID چندگانه دارد.هر فضای نامی (Namespace) مجموعه ای کامل از PIDهای ممکن دارد.این بدان معنی است که هر فضای نامی PID حاوی PID 1 ، 2 ، 3 و غیره خواهد بود.

فضاهای نامی چندگانه هستند یعنی ممکن است یک PID زیر مجموعه یک PID دیگر باشد که به آن نظارت دارد. یک فضای نامی، PID 1 ممکن است به یک پوسته فرمان مانند bash مراجعه کند.
ایجاد یک فضای نامی PID منحصر برای یک کانتینر یکی از ویژگی‌های اصلی داکر است.

موارد زیر را اجرا کنید تا در عمل تمام توضیحات را درک کنید:

docker run -d --name  namespaceA  busybox:latest  /bin/sh -c "sleep 30000" 
docker run -d --name namespaceB  busybox:latest  /bin/sh  -c "nc -l -p 0.0.0.0:80"

docker exec namespaceA ps   #قسمت1
docker exec namespaceB ps  #قسمت2

فرمان صادر شده در قسمت 1 لیستی مانند زیر به نمایش در می‌آورد:

PID      USER        COMMAND
1          root          /bin/sh -c sleep 30000
5          root          sleep 30000  
6          root           ps

فرمان صادر شده در قسمت 2 لیستی مانند لیست بالا با کمی تغییرات ایجاد می‌کند

PID      USER        COMMAND
1          root          /bin/sh -c sleep 30000
7          root          sleep 30000  
8          root           ps

در این مثال با docker exec می‌توانید دستوراتی که می‌خواهید را درون کانتینرها به اجرا در بیاورید. در این مثال ما از فرمان ps استفاده کردیم که برنامه‌های درحال اجرا به همراه PID آنها به نمایش در می‌آورد. همانطور که می‌بینید هر کانتینر PID 1 دارد.

بدون فضای نامی PID، پردازش‌های درون یک کانتینر باید با مابقی میزبان‌های دیگر PID‌ها را به اشتراک بگذارد. مانند بسیاری از ویژگی‌های داکر، شما می‌توانید کانتینرهای سفارشی خود را بدون فضای نامی PID ایجاد کنید. شما خودتان می‌توانید با تنظیم PID-Flag در داکر شناسه‌های سفارشی خودتان را تنظیم کنید. حالا برای آزمون کردن این موارد آماده شود ، یک کانتینر BusyBox اجرا و دستور ps را امتحان کنید:

docker run --pid host busybox:lastest ps
نکته: شما هم می‌توانید PID را جدا و هم یکپارچه با دستور بالا ببنید

در ادامه مثال پیشین، یعنی پایش وب سرور را در نظر بگیرید.فرض کنید از داکر استفاده نمی‌کنید و ngnixرا مستقیم روی کامپیوترتان اجرا کرده اید. دوباره فرض کنید فراموش کرده‌اید که ngnixروی سیستم خودتان دارید و پروژی جدیدی را با ngnix روی کامپیوترتان شروع می‌کنید ؛ قطعا قادر به اجرا ngnix جدید نخواهید بود چون قبلی تمام منابع را در دست گرفته و شما منابع لازم برای اجرای نسخه جدید را نخواهید داشت. این تنها یک نمونه کوچک از تداخلات نرم‌افزاری است. حالا همین کار رای برو یک کانتینر با دو اجرا ngnix انجام می‌دهیم:

docker run –d --name webConflict nginx:latest 
docker logs webConflict

با اجرای دو دستور بالا قطعا موردی برای نمایش در خروجی نخواهیم داشت

docker exec webConflict nginx -g 'daemon off;'

با اجرای دستور بالا خروجی مانند این خروجی خواهید داشت

2019/03/29 22:04:35 [emerg] 10#0: bind() to 0.0.0.0:80 failed (98: Address already in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) ...

فرآیند دوم نمی‌تواند اجرا شود و پیام مبتنی بر استفاده از پورت را به شما می‌دهد. این مورد درگیری پورت (Port Conflict) نامیده می‌شود. این مسئله رایج در سیستم‌های دنیای واقعی می‌باشد. حال راهکار اجرا هر کدام آنها با استفاده از داکر است. مانند این:

docker run -d --name webA nginx:latest

ابتدا یک نمونه از ngnix را با استفاده از داکر اجرا می‌کنیم

docker logs webA

بررسی عملکرد ، احتمال بسیار زیاد خالی باشد

docker run -d --name webB nginx:latest

حالا دومین نمونه را اجرا کردیم

docker logs webB

بررسی عملکرد نسخه دوم، احتمال بسیار زیاد خالی می‌باشد.

این کار یک راه حل عمومی برای برنامه‌هایی است که ممکن است با هم تداخل کنند. یک پارکینگ را در نظر بگیرید. پارکینگ دارای ویژگی‌های زیر است:

  • سیستم پرداخت
  • چند فضای پارک اختصاصی
  • فضای پارک شماره‌گذاری شده

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

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

  • برخی مشکلات منابع مشترک که می‎توانم به آنها اشاره کنم:
  • دو برنامه به طور همزمان میخواهند به یک پورت شبکه متصل شوند.
  • دو برنامه از یک فایل مشترک بهره می‌برند.
  • دو برنامه می‌خواهند از نسخه‌های مختلف کتابخانه‌های نصب شده به صورت عمومی استفاده کنند.
  • دو نسخه از یک برنامه می‌خواهند از یک PID مشترک استفاده کنند.
  • دو برنامه که نصب دارید یک متغییر محیطی برنامه‌های دیگر را تغییر می‌دهد و موجب خرابی برنامه‌های دیگر می‌شود.

تمام این مشکلات زمانی رخ می‌دهد که یک یا چند برنامه دارای وابستگی یکسان باشند.