
مقدمه
داکر ابزار کانتینرسازی محبوبی است که برای فراهم کردن فایلسیستمی حاوی هر چیزی که برای اجرا لازم دارند، به اپلیکیشنهای نرمافزاری استفاده میشود. استفاده از کانتینرهای داکر تضمین میکند نرمافزار فارغ از اینکه کجا دیپلوی شده، به همان شکل رفتار کند؛ چون محیط زمان-اجرایش بهشدت سازگار است.
در این آموزش، مرور کوتاهی از رابطه بین ایمیجهای داکر و کانتینرهای داکر ارائه میدهیم. سپس، نگاهی تفصیلیتر به نحوه اجرا، شروع، توقف و حذف کانتینرها میاندازیم.
نمای کلی
میتوانیم ایمیج داکر را بهعنوان قالب بیاثری در نظر بگیریم که برای ساخت کانتینرهای داکر استفاده میشود. ایمیجها معمولاً با فایلسیستم ریشه شروع و تغییرات فایلسیستمی و پارامترهای اجرایی متناظرشان را در لایههای مرتب و فقط-خواندنی اضافه میکنند. برخلاف توزیع معمول لینوکس، ایمیج داکر معمولاً فقط ضروریاتِ پایه برای اجرای اپلیکیشن را شامل میشود. ایمیجها وضعیت (State) ندارند و تغییر نمیکنند. بهجایش، نقطه شروع کانتینرهای داکر را تشکیل میدهند.
ایمیجها با دستور docker run به حیات میآیند؛ که با افزودن لایه خواندنی-نوشتنی روی ایمیج، کانتینری میسازد. این ترکیبِ لایههای فقط-خواندنی با لایه خواندنی-نوشتنی در بالا، بهعنوان فایلسیستم Union شناخته میشود. وقتی تغییری روی فایل موجودی در کانتینرِ در حال اجرا اعمال میشود، فایل از فضای فقط-خواندنی به لایه خواندنی-نوشتنی کپی میشود؛ جایی که تغییرات اعمال میشوند. نسخه درون لایه خواندنی-نوشتنی، فایل اصلی را مخفی اما حذف نمیکند. تغییرات در لایه خواندنی-نوشتنی فقط درون Instance منفردِ کانتینر وجود دارند. وقتی کانتینری حذف میشود، هر تغییری از بین میرود؛ مگر اینکه اقداماتی برای حفظشان انجام شود.
کار با کانتینرهای داکر
هر بار که از دستور docker run استفاده میکنید، کانتینر جدیدی از ایمیجی که تعیین میکنید میسازد. این میتواند منبع سردرگمی باشد؛ پس بگذارید با چند مثال نگاهی بیندازیم:
گام ۱: ساخت دو کانتینر
دستور docker run زیر کانتینر جدیدی با استفاده از ایمیج پایه ubuntu میسازد. -t به ما ترمینال میدهد و -i اجازه تعامل با آن را میدهد. به دستور پیشفرض در Dockerfile ایمیج پایه اوبونتو یعنی bash تکیه میکنیم تا در شل رها شویم:
docker run -ti ubuntu
پرامپت خط فرمان تغییر میکند تا نشان دهد داخل کانتینر بهعنوان کاربر root هستیم؛ که بهدنبالش شناسه ۱۲ کاراکتری کانتینر میآید.
تغییری میدهیم با echo کردن متنی در دایرکتوری /tmp کانتینر؛ سپس از cat برای تأیید ذخیره موفقش استفاده میکنیم:
echo "Example1" > /tmp/Example1.txt
cat /tmp/Example1.txt
Output
Example1
حالا، از کانتینر خارج شوید:
exit
کانتینرهای داکر بهمحض کامل شدن دستوری که صادرش کردهاند، اجرا را متوقف میکنند؛ پس کانتینر ما وقتی از شل bash خارج شدیم متوقف شد. اگر docker ps را اجرا کنیم—دستور نمایش کانتینرهای در حال اجرا—کانتینرمان را نمیبینیم:
docker ps
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
اگر فلگ -a را اضافه کنیم—which همه کانتینرها، متوقف یا در حال اجرا را نشان میدهد—کانتینرمان در فهرست ظاهر میشود:
docker ps -a
Output
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)، زمان ساخت کانتینر (شش دقیقه پیش) و دستوری که در آن اجرا شد (/bin/bash) را نشان میدهد. خروجی همچنین وضعیت کانتینر (Exited) و اینکه چقدر پیش کانتینر وارد آن وضعیت شده را ارائه میکند. اگر کانتینر هنوز در حال اجرا بود، وضعیت «Up» بهدنبالش مدت اجرا را میدیدیم.
اگر همان دستور را دوباره اجرا کنیم، کانتینر کاملاً جدیدی ساخته میشود:
docker run -ti ubuntu
میتوانیم بفهمیم کانتینر جدید است؛ چون شناسه در پرامپت فرمان متفاوت است و وقتی به دنبال فایل Example1 خود میگردیم، پیدایش نمیکنیم:
cat /tmp/Example1
Output
cat: /tmp/Example1: No such file or directory
این میتواند به نظر برسد که دادهها ناپدید شدهاند؛ اما چنین نیست. الان از کانتینر دوم خارج میشویم تا ببینیم آن و کانتینر اولمان با فایلی که ساختیم، هر دو روی سیستماند:
exit
وقتی کانتینرها را دوباره فهرست میکنیم، هر دو ظاهر میشوند:
docker ps -a
Output
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 برای attach شدن به آن و فلگ -i برای تعاملی کردنش استفاده میکنیم؛ که بهدنبالش شناسه یا نام کانتینر میآید. حتماً شناسه کانتینر خودتان را در دستور زیر جایگزین کنید:
docker start -ai 11cc47339ee1
خودمان را دوباره در پرامپت bash کانتینر مییابیم و وقتی فایلی را که قبلاً ساختیم cat میکنیم، همچنان آنجاست:
cat /tmp/Example1.txt
Output
Example1
حالا میتوانیم از کانتینر خارج شویم:
exit
این خروجی نشان میدهد تغییرات اعمالشده داخل کانتینر، از توقف و شروع کردنش جان سالم به در میبرند. فقط وقتی کانتینر حذف میشود که محتوا پاک میشود. این مثال همچنین نشان میدهد تغییرات به کانتینر منفرد محدود بودند. وقتی کانتینر دومی را شروع کردیم، وضعیت اصلی ایمیج را منعکس میکرد.
گام ۳: حذف هر دو کانتینر
دو کانتینر ساختیم و با حذفشان آموزش کوتاهمان را نتیجه میگیریم. دستور docker rm—که فقط روی کانتینرهای متوقفشده کار میکند—به شما اجازه میدهد نام یا شناسه یک یا چند کانتینر را تعیین کنید؛ پس میتوانیم هر دو را با دستور زیر حذف کنیم:
docker rm 11cc47339ee1 kickass_borg
Output
11cc47339ee1
kickass_borg
هر دوی کانتینرها و هر تغییری که داخلشان دادیم، الان gone شدهاند.
نتیجهگیری
نگاهی تفصیلی به دستور docker run انداختیم تا ببینیم چگونه هر بار که اجرا میشود، خودکار کانتینر جدیدی میسازد. همچنین دیدیم چطور کانتینر متوقفشدهای را پیدا، شروع و به آن وصل شویم.




