آشنایی با داکر و دستورات آن – بخش اول

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

داکر چیست؟!

Docker مجموعه ای از محصولات پلت فرم به عنوان سرویس (Platform as a service = PaaS) است که از مجازی سازی در سطح سیستم عامل برای ارائه نرم افزار در بسته هایی به نام کانتینر استفاده می کند. نرم افزاری که کانتینرها را میزبانی می کند Docker Engine نامیده می شود. اولین بار در سال ۲۰۱۳ شروع شد و توسط Docker, Inc توسعه یافته است. (ویکی‌پدیا)

 

داکر چگونه کار می‌کند؟!

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

 

  1. Linux Namespace: each process sees its own personal view of the system (files, process, network interface, hostname,)
  2. Linux control Groups: limit the number of resources the process can consume (CPU, memory, network bandwidth,)

 

پس در واقع وقتی از داکر استفاده میکنیم، قطعا از کرنل لینوکس استفاده میکند و اگر روی سیستم عاملهای دیگری بخواهیم از داکر استفاده کنیم ابزارهایی هستند که در بکگراوند برای راه اندازی داکر کرنل لینوکس را ابتدا فراهم میکنند که بتوانیم از داکر استفاده کنیم.

Docker linux interface

Docker Registry

همانطور که ما برای پکیج های مختلف پروژه ها به زبانهای مختلف از سیستم‌هایی همچون پکیج منیجر استفاده میکنیم برای اینکه ما برای داکر بتوانیم پکیجهایی که داریم را در اختیار بقیه قرار دهیم از Registry استفاده میکنیم. برای اینکار ابتدا از پکیج Build میگیریم و سپس یک image از آن میسازیم و این image فایلی است که قابل حمل است و از آن نمونه میگیریم و میتوانیم از آن استفاده کنیم. وقتی که ما image را در resistry قرار دهیم و آن را push کنیم هر شخصی میتواند از آن استفاده کند یعنی آن را pull میکند و برای استفاده در نرم افزار خودش آن را Deploy میکند، همانطور که ما میتوانیم imageهایی که لازم داریم را از آنجا pull و در نهایت Deploy کنیم.

در واقع وقتی ما Image را Deploy میکنیم و یک نمونه از Image را در نرم افزار خود استفاده میکنیم، یک container از آن میسازیم و container اجرا میشود. همچنین ما میتوانیم همزمان چندین نمونه از container را اجرا کنیم و در طول کل اجرا ما درگیر جزئیات نحوه اجرای نرم افزار نمیشویم و همه موارد داخل پکیج و image لحاظ شده است. این همان کاری است که Docker برای ما انجام می‌دهد. در واقع ما درگیر Dependencyها و اینکه چه نسخه ای از نرم افزارها را نصب کنیم و این نرم افزارها در همه محیطهای development و production یکی باشد نخواهیم بود و با استفاده از داکر هم میتوانیم این محیط یکسان را داشته باشیم و هم به روند توسعه راحتتر پروژه و تخصیص منابع و بهینه سازی بهتر پروژه کمک کنیم.

وقتی میخواهیم یک image نصب کنیم و از دستورات داکر استفاده میکنیم به صورت پیشفرض منبع و سورس image داکرهاب درنظر گرفته میشود مگر اینکه آدرس image و رجستری را بنویسیم و وقتی که میخواهیم image را از داکرهاب نصب کنیم مشخصات لاگین با اکانت توی داکرهاب را باید وارد کنیم که برای دفعات بعد این مشخصات ذخیره میشود.

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


docker pull image_name:tag

اگر دستور زیر را در محیط ترمینال خود اجرا کنید، یک container nginx ایجاد و اجرا می‌شود اما چگونه؟!


docker container run --publish 80:80 nginx

 

داکر در پشت پرده دنبال یک image به اسم nginx می‌گردد، اگر آن را در کش لوکال پیدا کند از آن استفاده میکند در غیر اینصورت آخرین ورژن آن را از Registry دانلود میکند، در قدم بعدی یک container از آن میسازد و آن را run میکند و در واقع بخش publish آن پورت ۸۰ لوکالهاست من را به پورت ۸۰ داخل container وصل میکند و به صورت اتوماتیک همه ترافیکهایی که روی پورت ۸۰ لوکال من قرار میگیرد به پورت ۸۰ داخل container انتقال داده میشود. بعد از اجرای دستور فوق با باز کردن localhost خود روی مرورگر میتوانید پیام nginx را مشاهده کنید.

(اگر میخواهید از محیط اجرا خارج شوید با فشار دادن دکمه های Ctr + c میتوانید آن را متوقف کنید.)

اگر میخواهید دستور فوق را در بکگراوند اجرا کنید، یعنی container در حال اجرا باشد ولی از محیط اجرای contsiner روی ترمینال خارج شوید به کامند فوق –detach را اضافه کنید.


docker container run --publish 80:80 --detach nginx

بعد از اجرای دستور فوق یک Unique Container ID چاپ میشود.

نکته: همانطور که قبلا اشاره کردم، ما میتوانیم یک image ایجاد کنیم و آن را توی Docker Registry قرار دهیم، وقتی که ما برای ایجاد  image موردنیازمون از سایر imageهایی که داخل Docker Registry وجود دارد استفاده میکنیم و به نوعی برای آن Dependencyهایی ایجاد میکنیم، وقتی که میخواهیم imageی که ایجاد کردیم را push کنیم این imageهایی که قبلا استفاده کردیم همراه image ما push نمیشود و فقط اسم و مشخصات آن قرار میگیرد و در حین استفاده و نصب مجدد docker از registry آن را دانلود میکند، دقیقا مثل نصب پکیجهای php که داخل vendorقرار میگیرند و یا پکیجهای node_modules…

تفاوت image و container

  • یک image در واقع اپلیکیشنی است که ما میخواهیم اجرا کنیم.
  • یک container در واقع یک نمونه از imageی است که میخواهیم آن را اجرا کنیم.
  • ما میتوانیم تعداد زیادی container داشته باشیم که از یک image ساخته شده اند.

همانطور که ما برای پروژه‌ها و پکیجهای مختلف ورژن کنترلی مانند github داریم برای imageهایی هم که موجود هستند از Docker Hub استفاده میکنیم.

نکته: وقتی میخواهیم یک image نصب کنیم به صورت پیشفرض منبع و سورس image داکرهاب درنظر گرفته میشود مگر اینکه آدرس image و رجستری را بنویسیم و وقتی که میخواهیم image را از داکرهاب نصب کنیم مشخصات لاگین با اکانت توی داکرهاب را باید وارد کنیم که برای دفعات بعد این مشخصات ذخیره میشود. برای هر image معمولا Version tagهایی وجود دارد که اگر آن را ننویسیم به صورت پیشفرض آخرین ورژن pull می شود.

 

دستورات داکر Docker

نمایش ورژن داکر 


docker --version
/// output: Docker version 17.12.0-ce, build c97c6d6

نمایش ورژن داکر به همراه جزئیات بیشتر


docker version

// Output
Client: Docker Engine - Community
 Version:           18.09.0
 API version:       1.39
 Go version:        go1.10.4
 Git commit:        4d60db4
 Built:             Wed Nov  7 00:47:43 2018
 OS/Arch:           darwin/amd64
 Experimental:      false

 

نمایش اطلاعات با جزئیات در مورد داکر 


docker info

// Output
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 17.12.0-ce
Storage Driver: overlay2
...

 

تفاوت run و start موقع اجرای یک container

ما میتوانیم به دو صورت زیر یک container را اجرا کنیم، تفاوت این دو دستور چیست؟


docker container run IMAGE_NAME

docker container start IMAGE_NAME

وقتی از run استفاده میکنیم، همیشه یک container جدید ساخته می‌شود ولی وقتی از start استفاده میکنیم containerی که وجود دارد و قبلا stop شده است اجرا می‌شود.

 

نمایش لیست imageهای داکر

docker image ls

docker image ls

نمایش لیست تمام imageهای داکر


 docker container ls -a / docker image ls --all

docker image ls --all

نمایش لیست containerها


docker container ls   ## running container
docker container ls --all  /  docker container ls -a  ## list of the all containe
docker container ls -aq    ## all container ID in quiet mode

docker container list

docker container in quite mode

مشاهده لاگهای یک container


docker container logs CONTAINER_NAME

(Show logs for a specific container)

docker container logs

مشاهده پردازشهای یک container 


docker container top CONTAINER_NAME

(Display the running processes of a container)

docker container top

حذف یک container 

به صورت پیشفرض ما فقط میتوانیم containerی را که در حالت اجرا نیست حذف کنیم ولی با اضافه کردن کامند -f میتوانیم آن را force کنیم که حذف شود.


docker container rm CONTAINER_NAME

 docker container rm -f CONTAINER_NAME

docker container rm

مشاهده config یک container با جزئیات آن

وقتی بخواهیم کانفیگ یک کانتینر را بررسی کنیم از جمله network, valum,… و همه مواردی که وجود دارد با استفاده از inspect اینکار را انجام میدهیم.


docker container inspect CONTAINER_NAME

(Details of a container configuration)

docker container inspect

نمایش پرفرمنس و میزان مصرف containerها

طبق تجربه ای که قبلا داشتم برای یکی از APIهایی که توی پروژه داشتیم به خاطر query سنگینی که توی دیتابیس داشتیم خطای پرشدن مصرف مموری را توی لاگ خطاهای پروژه داشتیم یکی از کارهایی که کردم مانیتور container و بهبود و مقایسه میزان مصرف مموری طی هر ریفکتور بود.


docker container stats

(Display performance states for all containers)

docker container stats

اجرای دستورات داخل container

در ابتدا قبل از اینکه استفاده از option مورد نظر یعنی -it رو توضیح بدیم با استفاده از کامند –help ساختار کامند داکر را بررسی کنیم:

با اجرای دستور docker container run –help لیستی از optionهایی که میتوانیم از آنها استفاده کنیم و هچنین ساختار دستور را مشاهده میکنیم.

docker container run --help

اگر سکرول کنیم پایینتر توضیحات آپشنهای -i و -t را مشاهده میکنیم.

docker container run -ith

اجرای یک container و وارد شدن به محیط آن جهت اجرا دستورات

با اجرای دستور زیر میتوانیم همزمان هم ccontainer را اجرا کنیم و هم ترمینال داخل container را جهت اجرای دستورات bash باز نگه داریم.


docker container run -it --name nginx_server nginx bash

docker container run -it --name nginx nginx bash

برای مثال ما میتوانیم یک image خاص مثل alpine یا ubuntu را اجرا کنیم و با استفاده از bash وارد ان شویم و ان را آپدیت کنیم و پکیج های مختلف نصب کنیم و …

docker container run -it ubuntu bash

نکته: با استفاده از دکمه های Ctr + d میتوانیم از محیط container خارج شویم.

وارد شدن به محیط container که قبلا ایجاد شده است

در کامندهای قبل ما همزمان با ایجاد یک container وارد محیط آن هم شدیم و bash را اجرا کردیم. حالا اگر بخواهیم آن را start کنیم با استفاده از راهنمای داکر آن را مشاهده کنیم:

docker container start --help

حال اگر بخواهیم وارد محیط یک container شویم که قبلا ایجاد شده است و دستوراتی را اجرا کنیم به صورت زیر اقدام میکنیم:


docker container start -ai ubuntu 

docker container start -ai ubuntu

اجرای دستورات جدید داخل containerی که در حال اجرا است

همانطور که در دستورات قبل دیدیم با استفاده از run -it  میتوانیم همزمان container را ایجاد و با اضافه کردن کامند وارد محیط کانتینر شویم ولی اگر یک container در حال اجرا داشته باشیم و بخواهیم یک command به آن اضافه کنیم بدون اینکه آن را stop و دوباره start کنیم از دستور زیر استفاده میکنیم:


docker container exec -it CONTAINER_NAME COMMAND

docker container exec ubuntu bash

 

 

 

Comments