آشنایی با Docker و Container در لینوکس؛ آموزش عملکرد، معماری و کاربردهای داکر
17 بازدید
آشنایی با Docker و Container در لینوکس؛ آموزش عملکرد، معماری و کاربردهای داکر
مقدمه
در سالهای اخیر، نحوه توسعه، استقرار و مدیریت نرمافزارها تغییرات زیادی کرده است. یکی از فناوریهایی که نقش مهمی در این تغییر داشته، Docker و مفهوم Container است. داکر به تیمهای توسعه و زیرساخت کمک میکند نرمافزار، وابستگیها و تنظیمات مورد نیاز آن را در محیطی قابلانتقال و مستقل بستهبندی و اجرا کنند.
در گذشته، انتقال یک نرمافزار از محیط توسعه به سرور عملیاتی معمولاً با مشکلاتی مانند تفاوت نسخه PHP، Python، Node.js ، کتابخانهها، تنظیمات سیستمعامل یا سرویسهای جانبی همراه بود. Containerization تلاش میکند این تفاوتها را تا حد زیادی کنترل کند و محیط اجرای نرمافزار را قابلپیشبینیتر سازد.
به زبان ساده، Docker روشی برای ساخت، بستهبندی، انتقال و اجرای نرمافزار در محیطهای ایزوله و قابل تکرار است.
________________________________________
Docker چیست؟
Docker یک پلتفرم برای ایجاد و اجرای Containerهاست. در این مدل، برنامه به همراه بسیاری از وابستگیها و تنظیمات مورد نیاز خود در قالب یک Image بستهبندی میشود و سپس از روی آن Image ، یک یا چند Container اجرا میشود.
برای مثال، تصور کنید یک برنامه تحت Laravel دارید که برای اجرا به این اجزا نیاز دارد:
Nginx | PHP-FPM | Laravel | MariaDB | Redis | Queue Worker
در معماری سنتی، ممکن است همه این سرویسها مستقیماً روی یک سرور نصب و پیکربندی شوند. اما در معماری مبتنی بر Docker میتوان هر بخش را در یک Container جداگانه اجرا کرد و ارتباط بین آنها را از طریق شبکه داخلی Docker برقرار نمود.
________________________________________
Container چیست؟
Container یک محیط اجرایی ایزوله برای اجرای یک نرمافزار است. برخلاف ماشین مجازی که معمولاً یک سیستمعامل کامل را اجرا میکند، Containerها از قابلیتهای سیستمعامل میزبان، بهخصوص هسته لینوکس، استفاده میکنند.
به همین دلیل Containerها معمولاً سبکتر و سریعتر از ماشینهای مجازی هستند.
ساختار ساده یک Container را میتوان اینگونه تصور کرد:
Application → Dependencies → Runtime → Container
به عنوان مثال:
Laravel Application → PHP 8.x + Extensions → PHP-FPM → PHP Container
Container در واقع محیطی مستقل برای اجرای برنامه ایجاد میکند، اما این استقلال به معنای داشتن یک سیستمعامل کامل و مستقل نیست.
________________________________________
Docker چگونه در لینوکس کار میکند؟
Docker در لینوکس از قابلیتهای اصلی هسته سیستمعامل برای ایجاد محیطهای ایزوله استفاده میکند. دو مفهوم مهم در این زمینه عبارتاند از:
Namespaces | Control Groups (cgroups)
Namespaces باعث میشوند فرآیندهای داخل Container بتوانند محیطی جدا از سایر فرآیندهای سیستم مشاهده کنند.
برای مثال، Container میتواند فضای پردازشی، شبکه، کاربران و برخی منابع سیستم را به شکل جداگانه مشاهده کند.
از طرف دیگر، cgroups برای کنترل و محدودسازی مصرف منابعی مانند CPU و حافظه مورد استفاده قرار میگیرند.
بنابراین معماری Container را میتوان ترکیبی از ایزولهسازی + کنترل منابع + مدیریت Image و Runtime دانست.
________________________________________
تفاوت Container و Virtual Machine
یکی از مهمترین پرسشها هنگام آشنایی با Docker این است که Container چه تفاوتی با ماشین مجازی دارد.
در ماشین مجازی معمولاً ساختاری شبیه زیر داریم:
Hardware → Hypervisor → Virtual Machine → Guest OS → Application
اما در Container:
Hardware → Host OS / Linux Kernel → Container Runtime → Container → Application
در ماشین مجازی، هر ماشین معمولاً سیستمعامل مهمان خود را دارد؛ در حالی که Containerها از هسته سیستمعامل میزبان استفاده میکنند.
مقایسه کلی
ویژگی Container Virtual Machine
سیستمعامل مستقل معمولاً خیر بله
مصرف منابع کمتر بیشتر
سرعت راهاندازی بسیار سریع معمولاً کندتر
سطح ایزولهسازی بالا بسیار بالا
چگالی استقرار بیشتر کمتر
مناسب برای سرویسها و برنامهها سیستمعاملها و محیطهای مستقل
البته Container و Virtual Machine رقیب مطلق یکدیگر نیستند و در بسیاری از زیرساختهای مدرن حتی در کنار یکدیگر استفاده میشوند.
________________________________________
اجزای اصلی Docker
برای درک بهتر Docker، باید با چند مفهوم اصلی آن آشنا شویم.
Docker Engine | Docker Image | Container | Dockerfile | Registry | Volume | Network | Docker Compose
هرکدام از این اجزا نقش مشخصی در چرخه اجرای نرمافزار دارند.
________________________________________
Docker Engine
Docker Engine موتور اصلی اجرای Containerهاست. این بخش مسئول ایجاد، اجرا و مدیریت Containerها و تعامل با Imageها و سایر اجزای Docker است.
بهصورت ساده:
Docker CLI → Docker Engine → Container
کاربر معمولاً از طریق دستورات Docker با Engine ارتباط برقرار میکند.
________________________________________
Docker Image
Image یک بسته آماده و غیرقابلتغییر برای ایجاد Container است.
برای مثال ممکن است Imageهای مختلفی برای موارد زیر داشته باشید:
Ubuntu | PHP | Nginx | MariaDB | Redis | Node.js
یک Image میتواند شامل سیستم فایل، نرمافزار، کتابخانهها و تنظیمات لازم برای اجرای یک سرویس باشد.
از روی Image میتوان چند Container ایجاد کرد.
مثلاً:
Image → Container 1 | Container 2 | Container 3
________________________________________
Container
Container نمونه در حال اجرای یک Image است.
به بیان ساده:
Image = الگوی آماده
Container = نمونه در حال اجرا
بنابراین اگر یک Image مربوط به PHP داشته باشید، میتوانید چند Container مختلف از روی آن ایجاد کنید.
________________________________________
Dockerfile
Dockerfile یک فایل متنی است که مراحل ساخت یک Image را مشخص میکند.
برای مثال، Dockerfile میتواند تعیین کند:
Base Image → نصب Packageها → کپی فایلها → نصب Dependencyها → تنظیمات → Command اجرا
نمونه ساده:
FROM php:8.3-fpm
RUN docker-php-ext-install pdo_mysql
WORKDIR /var/www
COPY . .
CMD ["php-fpm"]
Dockerfile باعث میشود ساخت محیط نرمافزار قابل تکرار و قابل مدیریت باشد.
________________________________________
Docker Registry چیست؟
Registry محلی یا ابری برای ذخیره و دریافت Docker Imageهاست.
یکی از معروفترین Registryها Docker Hub است، اما سازمانها میتوانند Registry خصوصی خودشان را نیز داشته باشند.
فرآیند کلی به شکل زیر است:
Developer → Build Image → Push → Registry → Pull → Server → Run Container
این قابلیت در فرآیندهای CI/CD اهمیت زیادی دارد.
________________________________________
Docker Volume چیست؟
Containerها برای اجرای سرویسها مناسب هستند، اما اطلاعات دائمی نباید صرفاً داخل لایه قابلتغییر Container نگهداری شوند.
برای نگهداری دادههای پایدار میتوان از Volume استفاده کرد.
مثلاً برای یک پایگاه داده:
MariaDB Container → Docker Volume → Persistent Database Data
در صورت حذف Container، دادههایی که در Volume قرار دارند میتوانند باقی بمانند.
Volumeها برای سرویسهایی مانند موارد زیر بسیار مهم هستند:
MariaDB | MySQL | PostgreSQL | Redis | File Storage
________________________________________
Docker Network چیست؟
Containerها برای ارتباط با یکدیگر به شبکه نیاز دارند. Docker امکان ایجاد Networkهای اختصاصی را فراهم میکند.
برای مثال در یک سیستم وب:
Nginx → PHP-FPM → MariaDB
و در یک معماری کاملتر:
Nginx → PHP-FPM → Redis → Queue Worker
در این ساختار لازم نیست سرویسها مستقیماً روی IP عمومی یکدیگر قرار داشته باشند. میتوانند از شبکه داخلی Docker استفاده کنند.
________________________________________
Docker Compose چیست؟
وقتی یک برنامه فقط یک Container داشته باشد، مدیریت آن نسبتاً ساده است. اما در پروژههای واقعی معمولاً چندین سرویس باید همزمان اجرا شوند.
Docker Compose برای تعریف و مدیریت این سرویسها استفاده میشود.
مثلاً یک پروژه سازمانی میتواند شامل این سرویسها باشد:
Nginx | PHP | Queue | MariaDB | Redis
در فایل Compose میتوان مواردی مانند موارد زیر را تعریف کرد:
Services | Networks | Volumes | Ports | Environment Variables | Dependencies
در نتیجه با یک ساختار مشخص میتوان مجموعهای از سرویسها را ایجاد و مدیریت کرد.
________________________________________
نمونه معماری یک پروژه Laravel با Docker
فرض کنیم یک سامانه سازمانی مبتنی بر Laravel داریم.
یک معماری ساده میتواند چنین ساختاری داشته باشد:
کاربر → Nginx → PHP-FPM → Laravel → MariaDB
در کنار آن:
Laravel → Redis → Queue Worker
و برای نگهداری فایلها:
Application → Persistent Volume
در این معماری، هر سرویس وظیفه مشخصی دارد و تغییر یا بهروزرسانی یک بخش الزاماً به معنای نصب مجدد کل سیستم نیست.
________________________________________
مزایای استفاده از Docker
یکی از مهمترین مزایای Docker ایجاد محیطهای قابل تکرار و قابل انتقال است.
اگر برنامهای روی سیستم توسعهدهنده در یک Container مشخص اجرا شود، همان Image میتواند در محیط آزمایش یا سرور عملیاتی نیز استفاده شود.
مزایای مهم Docker را میتوان در چند دسته خلاصه کرد:
یکسانسازی محیط توسعه و تولید | استقرار سریعتر | کاهش وابستگیها | استفاده بهتر از منابع | ایزولهسازی سرویسها | قابلیت تکرارپذیری | مدیریت سادهتر Deployment | مناسب برای CI/CD
________________________________________
کاهش مشکل «روی سیستم من کار میکند»
یکی از مشکلات رایج در توسعه نرمافزار این است که برنامه روی سیستم توسعهدهنده بهدرستی اجرا میشود، اما روی سرور با خطا مواجه میشود.
علت میتواند تفاوت در موارد زیر باشد:
نسخه PHP | نسخه Node.js | کتابخانهها | Extensionها | تنظیمات سیستمعامل | سرویسهای جانبی
Docker با بستهبندی محیط اجرا کمک میکند این تفاوتها کاهش پیدا کنند.
________________________________________
Docker و DevOps
Docker ارتباط بسیار نزدیکی با مفاهیم DevOps دارد.
در یک چرخه معمول:
Code → Build → Test → Image → Registry → Deploy → Run
میتوان فرآیند استقرار نرمافزار را تا حد زیادی خودکار کرد.
برای مثال، پس از ثبت تغییرات در کد:
Git → CI Pipeline → Docker Build → Test → Registry → Production Deployment
این ساختار باعث میشود انتشار نسخههای جدید نرمافزار سریعتر و قابلکنترلتر شود.
________________________________________
کاربردهای Docker
Docker فقط برای پروژههای کوچک یا برنامههای وب استفاده نمیشود.
کاربردهای آن طیف گستردهای دارد:
توسعه نرمافزار | تست | CI/CD | سرویسهای وب | Microservices | پایگاه داده | محیطهای توسعه | پردازشهای پسزمینه | سرویسهای سازمانی | آزمایش فناوریهای جدید
در معماری Microservices نیز Containerها میتوانند برای اجرای سرویسهای مستقل مورد استفاده قرار گیرند.
برای مثال:
User Service | CRM Service | Finance Service | Notification Service | Reporting Service
هر سرویس میتواند محیط اجرایی مستقل خود را داشته باشد.
________________________________________
Docker در سازمانها
در سازمانهای بزرگ، تعداد سرویسها و نرمافزارها زیاد است و مدیریت مستقیم همه آنها روی سرورها میتواند پیچیده شود.
Docker میتواند به ایجاد استاندارد برای استقرار سرویسها کمک کند.
برای مثال سازمان میتواند استاندارد مشخصی برای موارد زیر داشته باشد:
Imageها | Containerها | Networkها | Volumeها | Logging | Monitoring | Deployment
این موضوع باعث میشود مدیریت زیرساخت از حالت کاملاً دستی فاصله گرفته و به سمت فرآیندهای استاندارد و خودکار حرکت کند.
________________________________________
امنیت Docker
استفاده از Container بهتنهایی به معنای امن بودن سیستم نیست.
امنیت Docker باید در چند لایه مورد توجه قرار گیرد.
Image معتبر | بهروزرسانی منظم | حداقل سطح دسترسی | محدودیت منابع | مدیریت Secretها | محدودسازی شبکه | کنترل دسترسی | ثبت Log | اسکن آسیبپذیری
همچنین نباید دسترسیهای مدیریتی Docker بدون بررسی در اختیار سرویسها یا کاربران قرار گیرد.
یکی از موارد مهم، محافظت از Docker Socket است؛ زیرا دسترسی گسترده به Docker Engine میتواند عملاً سطح دسترسی بسیار بالایی روی میزبان ایجاد کند.
________________________________________
مدیریت منابع در Docker
یکی از قابلیتهای مهم Docker امکان محدود کردن مصرف منابع است.
برای مثال میتوان برای یک Container محدودیتهایی مانند موارد زیر تعیین کرد:
CPU | RAM | Process Count | Storage
این قابلیت بهخصوص در سرورهایی که چندین سرویس همزمان روی آنها اجرا میشود اهمیت دارد.
________________________________________
مدیریت داده و Backup
یکی از اشتباهات رایج این است که تصور شود چون برنامه داخل Container قرار دارد، اطلاعات آن نیز بهصورت خودکار محافظت میشود.
Containerization جایگزین Backup نیست.
در سیستمهای واقعی باید برای دادههای مهم برنامه، پایگاه داده، فایلها و Volumeها برنامه پشتیبانگیری وجود داشته باشد.
ساختار مناسب میتواند شامل موارد زیر باشد:
Database Backup | File Backup | Volume Backup | Off-site Backup | Backup Verification
مهمتر از ایجاد Backup، اطمینان از قابلیت بازیابی آن است.
________________________________________
Docker در محیط Production
اجرای Docker در محیط عملیاتی نیازمند برنامهریزی است.
مواردی مانند مانیتورینگ، Logging، Backup، امنیت، مدیریت منابع، شبکه، Storage و فرآیند Update و Rollback باید از ابتدا در نظر گرفته شوند.
یک محیط Production مناسب فقط با اجرای چند Container ساخته نمیشود؛ بلکه باید یک فرآیند کامل برای مدیریت چرخه عمر سرویسها وجود داشته باشد.
________________________________________
Docker و Kubernetes
Docker و Kubernetes مفاهیم یکسانی نیستند.
Docker بیشتر روی ساخت و اجرای Containerها تمرکز دارد، در حالی که Kubernetes یک پلتفرم برای مدیریت و هماهنگسازی Containerها در مقیاس بزرگ است.
برای یک پروژه کوچک ممکن است Docker Compose کاملاً کافی باشد، اما در زیرساختهای بسیار بزرگ و توزیعشده، Kubernetes میتواند امکانات پیشرفتهتری برای مدیریت Containerها فراهم کند.
بهصورت ساده:
Docker → اجرای Container
Docker Compose → مدیریت چند سرویس Container
Kubernetes → Orchestration در مقیاس بزرگ
________________________________________
چه زمانی Docker انتخاب مناسبی نیست؟
Docker فناوری قدرتمندی است، اما استفاده از آن در همه شرایط ضروری نیست.
اگر یک برنامه بسیار ساده روی یک سرور کوچک دارید و فقط یک سرویس مشخص اجرا میشود، ممکن است نصب مستقیم نرمافزار سادهتر باشد.
همچنین Containerization نیازمند یادگیری مفاهیمی مانند:
Image | Container | Network | Volume | Registry | Compose | Security
است.
بنابراین استفاده از Docker باید بر اساس نیاز واقعی پروژه و زیرساخت انجام شود، نه صرفاً به دلیل محبوبیت این فناوری.
________________________________________
چرخه معمول کار با Docker
یک چرخه معمول توسعه و استقرار میتواند چنین باشد:
توسعه کد → ایجاد Dockerfile → ساخت Image → اجرای Container → تست → Push به Registry → انتقال به سرور → اجرای نسخه جدید
در تیمهای حرفهای این چرخه میتواند با CI/CD کاملاً خودکار شود.
________________________________________
Docker چه تغییری در مدیریت سرورها ایجاد کرده است؟
در روش سنتی، مدیر سیستم ممکن است مجبور باشد روی هر سرور نرمافزارها را جداگانه نصب و تنظیم کند.
برای مثال:
نصب PHP → تنظیم Extensionها → نصب Nginx → نصب Redis → نصب Database → تنظیم Configuration
اما در رویکرد Container-based بخش زیادی از این تنظیمات میتواند در قالب Configuration و Image تعریف شود.
در نتیجه زیرساخت بیشتر به سمت Infrastructure as Code و Configuration as Code حرکت میکند.
این تغییر باعث میشود ایجاد یک محیط جدید، بازسازی محیط قبلی یا انتقال سرویس به سرور دیگر سادهتر شود.
________________________________________
Docker و تحول معماری نرمافزار
Docker فقط یک ابزار برای اجرای برنامه نیست؛ بلکه در بسیاری از سازمانها بخشی از تغییر معماری نرمافزار محسوب میشود.
ترکیب Docker با فناوریهایی مانند:
Git | CI/CD | Cloud | Kubernetes | Monitoring | Logging | Infrastructure as Code
میتواند یک زنجیره کامل برای توسعه و استقرار نرمافزار ایجاد کند.
این موضوع بهخصوص برای سازمانهایی که تعداد زیادی سرویس و نرمافزار دارند اهمیت زیادی دارد.
________________________________________
جمعبندی
Docker یکی از فناوریهای مهم در دنیای مدرن توسعه و زیرساخت نرمافزار است که با استفاده از مفهوم Container امکان بستهبندی و اجرای نرمافزارها را در محیطهایی مستقل، قابلانتقال و تکرارپذیر فراهم میکند.
مفاهیمی مانند:
Image | Container | Dockerfile | Volume | Network | Registry | Docker Compose
هسته اصلی اکوسیستم Docker را تشکیل میدهند.
Docker میتواند توسعه نرمافزار، تست، استقرار، مدیریت سرور و فرآیندهای DevOps را سادهتر و استانداردتر کند. با این حال، استفاده صحیح از آن نیازمند توجه همزمان به امنیت، مدیریت منابع، دادههای پایدار، Backup Monitoring و فرآیندهای عملیاتی است.
در نهایت، Docker را نباید صرفاً یک ابزار برای اجرای برنامه در نظر گرفت؛ بلکه باید آن را یکی از اجزای مهم معماری مدرن زیرساخت نرمافزار دانست که میتواند مسیر حرکت سازمان از استقرارهای دستی به سمت زیرساخت استاندارد، خودکار، قابل تکرار و مقیاسپذیر را هموار کند.
درباره نویسنده
تیم تخصصی واریان شبکه گستر. ارائهدهنده راهکارهای نوین شبکه، امنیت و تحول دیجیتال.