داکر (Docker) و کاربرد آن در علم داده — راهنمای کاربردی

۵۶۳ بازدید
آخرین به‌روزرسانی: ۰۷ تیر ۱۴۰۲
زمان مطالعه: ۱۶ دقیقه
داکر (Docker) و کاربرد آن در علم داده — راهنمای کاربردی

از زمانی که «داکر» (Docker) به طور عمومی انتشار یافت تا به امروز، حدود شش سال زمان می‌گذرد. این برنامه کامپیوتری به دلیل قابلیت‌های جالب توجهی که فراهم می‌کرد، توانست خیلی سریع به محبوبیت بالایی دست پیدا کند و در حوزه‌های گوناگون مورد استفاده قرار بگیرد. در این مطلب، به مبحث داکر (Docker) و کاربرد آن در علم داده پرداخته خواهد شد. در همین راستا، ابتدا چیستی داکر، دلایل استفاده از آن، تعاریف داکر، نحوه نصب و ساخت ایمیج داکر و در نهایت، چگونگی استفاده از آن در راستای «علم داده» (Data Science) مورد بررسی قرار خواهد گرفت. همچنین در نوشته «داکر چیست» نیز به معرفی جامع داکر و ارائه راهنمایی برای شروع به کار با آن پرداخته شده است.

داکر چیست؟

«داکر» (Docker)، یک برنامه کامپیوتری است که با استفاده از آن شبیه‌سازی سطح سیستم‌عامل انجام می‌شود. این برنامه توسط «شرکت داکر» (Docker, Inc) ساخته شده و توسعه داده می‌شود و برای اولین بار در سال ۲۰۱۳ منتشر شد. از داکر برای ساخت بسته‌های نرم‌افزاری استفاده می‌شود که به آن‌ها «کانتینر» (Container) گفته می‌شود. کانتینرها نسبت به یکدیگر ایزوله هستند و برنامه‌های خود، ابزارها، کتابخانه‌ها و فایل‌های پیکربندی خود را دارند. این کانتینرها می‌توانند با یکدیگر از طریق کانال‌های خوش تعریف ارتباط برقرار کنند. همه کانتینرها به وسیله یک کرنل سیستم عامل مجرد اجرا می‌شوند و بنابراین، نسبت به ماشین‌های مجازی سبک‌تر هستند.

کانتینرها از ایمیج‌هایی (Images) ساخته شده‌اند که محتوای دقیق آن‌ها را مشخص می‌کند. ایمیج‌ها معمولا با ترکیب و ویرایش ایمیج‌های استاندارد دانلود شده از مخازن عمومی ساخته می‌شوند. داکر، ابتدا برای سیستم‌عامل لینوکس ساخته شده بود تا از قابلیت ایزوله‌سازی منابع کرنل لینوکس مانند cgroups و namespaces و همچنین، سیستم فایل‌های یونیون مونت مانند OverlayFS و دیگر موارد استفاده کند. این کار با این هدف انجام می‌شد که به کانتینرهای مستقل امکان اجرای یک نمونه لینوکس مجرد را بدهد و از سربار شروع و نگهداری ماشین‌های مجازی اجتناب کند.

اما بعدها، برای سیستم‌عامل‌های ویندوز و مک‌او‌اس نیز توسعه یافت. داکر یک «رابط برنامه‌نویسی کاربردی» (Application Programming Interface | API) را برای فراهم کردن یک کانتینر سبک پیاده‌سازی می‌کند که می‌تواند یک برنامه را به صورت توکار پردازش کند. با توجه به اینکه کانتینرهای داکر بسیار سبک هستند، یک سرور یا ماشین مجازی تنها می‌تواند چندین ظریف را به طور هم‌زمان اجرا کند. برای تسلط بیشتر بر داکر، مطالعه مطلب «آموزش‌ داکر (Docker) — مجموعه مقالات مجله فرادرس» توصیه می‌شود.

داکر با ابزارهای زیرساخت گوناگونی مانند سرویس‌های وب آمازون (Amazon Web Services)، «انسیبل» (Ansible)، «سی‌اف‌انجین» (CFEngine)، «شف» (Chef)، «پلتفرم ابری گوگل» (Google Cloud Platform)، «اوپن‌استک» (OpenStack)، «اوراکل کلود» (Oracle Cloud)، «پاپت» (Puppet)، «پروگت» (ProGet)، «سالت» (Salt)، «ویگرنت» (Vagrant)، «اوپن‌شیفت» (OpenShift)، «مایکروسافت آژور» (Microsoft Azure) و بسیاری از دیگر موارد  قابل یکپارچه‌سازی است.

دلایل استفاده از داکر چیست؟

تکرارپذیری: برای یک «دانشمند داده» (Data Scientist)، این موضوع از اهمیت به سزایی برخوردار است که کاری قابل تولید مجدد (تکرار پذیر) انجام دهد. قابلیت تولید مجدد نه تنها بازنگری با دقت (داوری دقیق | Peer Review) را امکان‌پذیر می‌سازد، بلکه اطمینان حاصل می‌کند که مدل، برنامه کاربردی یا تحلیلی که دانشمند داده انجام داده است، بدون مشکل اجرا شود. این امر، استحکام و قدرت بیشتری را فراهم می‌آورد.

برای مثال، اگر مدلی در «زبان برنامه‌نویسی پایتون» (Python Programming Language) ساخته شود، pip-freeze کردن و ارسال فایل حاصل شده requirements.txt به دیگر همکاران به آن صورت، تنها وابستگی‌های خاصی از پایتون را کپسوله می‌کند؛ در حالی که معمولا وابستگی‌های متعددی خارج از پایتون مانند سیستم‌عامل، کامپایلرها، درایورها، فایل‌های پیکربندی یا دیگر داده‌های مورد نیاز برای اجرای کد نیز لازم هستند. این در حالی است که کاربر، تنها با به اشتراک‌گذاری وابستگی‌ها، پوشش‌دهی به همه چیز در کانتینر داکر، بار ساخت مجدد محیط مورد نظر کاربر را کاهش داده و کار او را دسترسی‌پذیرتر می‌کند.

احتمال محیط محاسباتی کاربر: به عنوان یک دانشمند داده، به ویژه در حوزه «یادگیری ماشین» (Machine Learning)، قادر بودن به تغییر دادن سریع محیط محاسباتی می‌تواند به طور مستقیم روی بهره‌وری فرد تاثیرگذار باشد. کار علم داده معمولا با ساخت نمونه اولیه (Prototyping)، کاوش و پژوهش آغاز می‌شود؛ کارهایی که معمولا نیازمند منابع کامپیوتری خاص به صورت فوری نیستند. این کارها معمولا در کامپیوتر یا لپ‌تاپ شخصی انجام می‌شود. اگرچه، معمولا لحظه‌هایی از راه می‌رسد که در آن، منابع محاسباتی به شدت جریان کاری فرد را سرعت می‌بخشند؛ برای مثال، ماشینی با واحدهای پردازنده مرکزی (CPU) بیشتر، یا «واحد پردازنده گرافیکی» (GPU)، برای کارهایی مانند «یادگیری عمیق» (Deep Learning) مناسب‌تر است. دانشمندان داده زیادی هستند که خود را به محیط کامپیوتر محلی که دارند محدود می‌کنند، زیرا شاهد مشکلاتی در ساخت مجدد محیط محلی خود روی یک ماشین از راه دور بوده‌اند. داکر، فرایند پورت کردن محیط (همه کتابخانه‌ها، فایل‌ها و دیگر موارد) را بسیار آسان می‌کند. پورت کردن سریع محیط کامپیوتر، یک مزیت رقابتی بسیار قابل توجه در رقابت‌های «کگل» (Kaggle) نیز محسوب می‌شود، زیرا می‌توان از مزایای منابع کامپیوتری گران روی «سرویس وب آمازون» (Amazon Web Services | AWS) به صورت مقرون به صرفه‌ای استفاده کند. در نهایت، ساخت یک فایل داکر این امکان را به کاربر می‌دهد که بسیاری از چیزهایی که پیرامون محیط محلی خود دوست دارد، مانند  Bash Aliase‌ها یا «پلاگین‌های ویم» (Vim Plugins) را پورت کند.

قدرت بخشیدن به جزئیات مهندسی: راحت بودن با داکر این امکان را برای کاربر فراهم می‌کند که مدل‌ها یا تحلیل‌های خود را به عنوان برنامه‌های کاربردی (Applications) (برای مثال یک نقطه پایانی REST API که می‌تواند پیش‌بینی کند) که کارهای او را برای دیگر افراد دسترسی‌پذیر می‌کند، مستقر کند. علاوه بر آن، برنامه‌های کاربردی دیگری که کاربر ممکن است به عنوان بخشی از جریان کاری «علم داده» (Data Science) نیاز به تعامل با آن‌ها داشته باشد ممکن است در کانتینر داکر وجود داشته باشند؛ به عنوان مثالی از این موارد می‌توان به پایگاه داده یا دیگر برنامه‌های کاربردی اشاره کرد.

تعاریف داکر

پیش از پرداختن به چگونگی کار با داکر، برخی از تعاریف پیرامون داکر وجود دارد که کاربر باید با آن‌ها آشنا باشد. در ادامه، این موارد شرح داده شده‌اند.

  • Image: «بلوپرینت» (Blueprint) همان چیزی است که کاربر قصد دارد آن را بسازد. برای مثال، «اوبونتو» (Ubuntu) + «تنسورفلو» (TensorFlow) با «درایورهای انویدیا» (Nvidia Drivers) و اجرای «سرور ژوپیتر» (Jupyter Server).
  • کانتینر (Container): یک instantiation از ایمیج است که کاربر باید ایجاد کند. کاربر می‌تواند چندین کپی از یک ایمیج واحد در حال اجرا داشته باشد. درک تمایز بین ایمیج و کانتینر بسیار حائز اهمیت است، زیرا این موضوع معمولا برای افراد تازه‌وارد بسیار سردرگم کننده است. اگر تفاوت بین ایمیج و کانتینر برای فردی واضح نبود، باید در همین لحظه مطالعه ادامه این متن را متوقف کند و در این رابطه بیشتر مطالعه کند.
  • «داکرفایل» (Dockerfile): دستورالعمل ساخت یک ایمیج است. داکرفایل‌ها حاوی نحو خاص داکر هستند. در مستندان رسمی داکر درباره داکرفایل چنین آمده است:

یک Dockerfile، سند متنی حاوی همه دستوراتی است که کاربر می‌تواند در خط فرمان برای اسمبل کردن یک ایمیج فراخوانی کند.

  • کامیت (Commit): مانند گیت، کانتینرهای داکر نیز کنترل نسخه را ارائه می‌کنند. کاربر می‌تواند حالت (State) کانتینر داکر را در هر زمان به عنوان یک ایمیج جدید با کامیت کردن تغییرات ذخیره کند.
  • «داکرهاب» (DockerHub) / «ایمیج رجیستری» (Image Registry): محلی که افراد می‌توانند ایمیج‌های داکر عمومی (یا خصوصی) خود را قرار دهند تا همکاری و به اشتراک‌گذاری را تسهیل کنند.
  • «لایه» (Layer): ویرایش یک ایمیج موجود، که به وسیله دستورالعملی که در داکرفایل ارائه شده است، انجام می‌شود. لایه‌ها در توالی به تصویر پایه اعمال شده‌اند تا ایمیج نهایی ساخته شود.

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

نصب داکر

می‌توان نسخه Docker Community Edition را به صورت رایگان دانلود و نصب کرد. دستورالعمل لازم برای انجام این کار، از این مسیر [+] در دسترس است.

ساخت اولین ایمیج داکر

پیش از ساخت کانتینر داکر، ساخت یک Dockerfile که ایمیج را توصیف می‌کند مفید خواهد بود. در ادامه، کد مربوط به Dockerfile ارائه شده است.

1# reference: https://hub.docker.com/_/ubuntu/
2FROM ubuntu:16.04
3
4# Adds metadata to the image as a key value pair example LABEL version="1.0"
5LABEL maintainer="Hamel Husain <youremail@gmail.com>"
6
7##Set environment variables
8ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
9
10RUN apt-get update --fix-missing && apt-get install -y wget bzip2 ca-certificates \
11    build-essential \
12    byobu \
13    curl \
14    git-core \
15    htop \
16    pkg-config \
17    python3-dev \
18    python-pip \
19    python-setuptools \
20    python-virtualenv \
21    unzip \
22    && \
23apt-get clean && \
24rm -rf /var/lib/apt/lists/*
25
26RUN echo 'export PATH=/opt/conda/bin:$PATH' > /etc/profile.d/conda.sh && \
27    wget --quiet https://repo.continuum.io/archive/Anaconda3-5.0.0.1-Linux-x86_64.sh -O ~/anaconda.sh && \
28    /bin/bash ~/anaconda.sh -b -p /opt/conda && \
29    rm ~/anaconda.sh
30
31ENV PATH /opt/conda/bin:$PATH
32
33RUN pip --no-cache-dir install --upgrade \
34        altair \
35        sklearn-pandas
36
37# Open Ports for Jupyter
38EXPOSE 7745
39
40#Setup File System
41RUN mkdir ds
42ENV HOME=/ds
43ENV SHELL=/bin/bash
44VOLUME /ds
45WORKDIR /ds
46ADD run_jupyter.sh /ds/run_jupyter.sh
47RUN chmod +x /ds/run_jupyter.sh
48
49# Run a shell script
50CMD  ["./run_jupyter.sh"]

دستور From

1FROM ubuntu:16.04

دستور FROM، جادویی‌ترین بخش داکر را کپسوله می‌کند. این دستور ایمیج مبنا را تعیین می‌کند که ساخت (Build) بر فراز آن انجام خواهد شد. علاوه بر تعیین ایمیج پایه با FROM، داکر محیط محلی را به منظور یافتن ایمیجی با نام ubuntu:16.04 جستجو می‌کند و اگر نتواند آن را به صورت محلی پیدا کند، Docker Registry را بررسی می‌کند که به طور پیش‌فرض «داکرهاب» (DockerHub) است. این مکانیزم لایه‌بندی راحت است، زیرا کاربر معمولا می‌خواهد برنامه‌های خود را روی سیستم‌عاملی مانند اوبونتو نصب کند.

به جای نگرانی پیرامون چگونگی نصب اوبونتو از پایه، می‌توان برنامه‌ها را روی ایمیج رسمی اوبونتو نصب کرد. طیف وسیعی از ایمیج‌ها در داکر قرار گرفته است که شامل مواردی می‌شود که چیزی بیش از یک سیستم‌عامل را فراهم می‌کنند؛ برای مثال می‌توان یک کانتینر را بر فراز «ایمیج داکر رسمی آناکوندا» (Official Anaconda Docker Image) ساخت. مهم‌تر آنکه، کاربر می‌تواند ایمیجی که ساخته است را در هر زمانی منتشر کند، حتی اگر آن ایمیج با لایه‌بندی روی ایمیج دیگری ساخته شده باشد. احتمالات ممکن بی‌پایان هستند!

در این مثال، ایمیج پایه Ubuntu: 16.04 تعیین می‌شود و بنابراین، مخزن داکرهاب با نام Ubuntu بررسی می‌شود. بخشی از تصویر که پس از دو نقطه آمده است (یعنی ۱۶.۰۴) تگی است که به کاربر امکان تعیین نسخه ایمیجی را می‌دهد که قصد نصب آن را دارد. اگر کاربر قصد گردش در مخزن DockerHub repo را داشته باشد، متوجه خواهد شد که نسخه‌های گوناگون اوبونتو با تگ‌های گوناگون وجود دارند.

تصویری از مخزن رسمی داکرهاب اوبونتو در دسامبر ۲۰۱۷

برای مثال، ubuntu:xenial ،ubuntu:xenial-20171201 ،ubuntu:16.04 و ubuntu:latest همه به اوبونتو ۱۶.۰۴ اشاره دارند و همه alias‌هایی برای یک چیز واحد هستند. علاوه بر آن، لینک‌های فراهم شده در این مخزن لینک، متناظر با داکرفایل‌هایی هستند که برای ساخت ایمیج برای هر نسخه مورد استفاده قرار گرفته است. کاربر همیشه نمی‌تواند داکرفایل‌ها را روی مخزن داکرهاب پیدا کند، زیرا برای نگهداری‌کنندگان اختیاری است که داکرفایل را بسته به چگونگی ساخته شدن قرار دهند. یکی از راه‌های مفید آن است که چندین داکرفایل توسط کاربر بررسی شوند تا مفهوم داکرفایل را بهتر بفهمد.

یک تگ دیگر که نیازمند توجه ویژه است، تگ latest محسوب می‌شود. این تگ مشخص می‌کند که کاربر در صورت تعیین نکردن تگ در دستور FROM، کار pull کردن به صورت پیش‌فرض انجام می‌شود. برای مثال، اگر دستور From شبیه زیر بود، pull کردن با ایمیج اوبونتو ۱۶.۰۴ انجام می‌شود. دلیل این امر، همانطور که در اسکرین‌شات بالا معلوم است، تخصیص تگ  latest به اوبونتو ۱۶.۰۴ محسوب می‌شود (در حال حاضر نسخه‌های جدیدتری از اوبونتو آمده است، ولیکن در این مطلب آخرین نسخه‌های موجود تا سال ۲۰۱۷ بررسی شده‌اند).

1FROM ubuntu

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

دستور LABEL

این دستور، «فراداده‌ها» (Metadata) را به ایمیج کاربر اضافه می‌کند و استفاده از آن کاملا اختیاری است. برای مثال، با قطعه کدی که در زیر ارائه شده، نام سازنده ایمیج به آن اضافه می‌شود تا هم کاربران دیگر بدانند که برای گفتگو پیرامون این ایمیج با چه کسی باید تماس بگیرند و هم اینکه خود کاربر می‌تواند کانتینرهای داکر خود را جستجو کند؛ به ویژه وقتی که آن‌ها به صورت هم‌زمان روی یک سرور اجرا می‌شوند.

1LABEL maintainer="Hamel Husain <youremail>"

دستور ENV

1ENV LANG=C.UTF-8 LC_ALL=C.UTF-8

این کار به کاربر این امکان را می‌دهد تا متغیرهای محیط را تغییر دهد و انجام چنین کاری خیلی هم سرراست است.

دستور RUN

این دستور معمولا کاری که کاربر می‌خواهد در ساخت (Build) یک ایمیج داکر انجام دهد را صورت می‌دهد. کاربر می‌تواند یک دستور دلخواه «شل» (Shell) مانند apt-get و pip install را برای نصب بسته‌ها و وابستگی‌هایی که نیاز دارند اجرا کند.

1RUN apt-get update --fix-missing && apt-get install -y wget bzip2    
2    build-essential \
3    ca-certificates \
4    git-core \
5    
6...

در اینجا، برخی از ابزارها مانند byobu ،htop ،curl و آناکوندا به همراه کتابخانه‌هایی که به صورت پیش‌فرض در آناکوندا نصب نیستند، نصب می‌شوند. دستورات پس از RUN، کاری با داکر انجام نمی‌دهند، بلکه دستورات نرمال داکر هستند که اگر کاربر خودش این بسته‌ها را نصب کند، آن‌ها را اجرا می‌کند. جای نگرانی برای افرادی که با این بسته‌ها یا دستورات لینوکس آشنایی ندارند، وجود ندارد. همچنین، یک پیشنهاد مهم‌تر این است که برای یادگیری هرچه بهتر داکر، فایل‌های داکر دیگر موجود در گیت‌هاب یا داکرهاب بررسی شوند و بخش‌های مرتبطی که فرد به آن‌ها نیاز دارد را به داکرفایل خود اضافه کند.

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

1# reference: https://hub.docker.com/_/ubuntu/
2FROM ubuntu:16.04
3
4# Adds metadata to the image as a key value pair example LABEL version="1.0"
5LABEL maintainer="Hamel Husain <www.github.com/hamelsmu>"
6
7##Set environment variables
8ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
9
10RUN apt-get update --fix-missing && apt-get install -y wget bzip2 ca-certificates \
11    build-essential \
12    byobu \
13    curl \
14    git-core \
15    htop \
16    pkg-config \
17    python3-dev \
18    python3-pip \
19    python-setuptools \
20    python-virtualenv \
21    unzip \
22    && \
23apt-get clean && \
24rm -rf /var/lib/apt/lists/*
25
26RUN echo 'export PATH=/opt/conda/bin:$PATH' > /etc/profile.d/conda.sh && \
27    wget --quiet https://repo.continuum.io/archive/Anaconda3-5.0.0.1-Linux-x86_64.sh -O ~/anaconda.sh && \
28    /bin/bash ~/anaconda.sh -b -p /opt/conda && \
29    rm ~/anaconda.sh
30
31ENV PATH /opt/conda/bin:$PATH
32
33RUN pip3 --no-cache-dir install --upgrade \
34        altair \
35        sklearn-pandas
36
37# Open Ports for Jupyter
38EXPOSE 7745
39
40#Setup File System
41RUN mkdir ds
42ENV HOME=/ds
43ENV SHELL=/bin/bash
44VOLUME /ds
45WORKDIR /ds
46ADD run_jupyter.sh /ds/run_jupyter.sh
47RUN chmod +x /ds/run_jupyter.sh
48
49# Run the shell
50CMD  ["./run_jupyter.sh"]

دستور EXPOSE

دستور EXPOSE در صورتی که کاربر تمایل به نمایش دادن یک فایل داشته باشد، مفید است؛ برای مثال، کاربر از یک نوت‌بوک ژوپیتر یا نوعی سرویس وب، درون یک کانتینر استفاده می‌کند. مستندات داکر برای تشریح عملکرد دستور EXPOSE بسیار قدرتمند هستند. دستور EXPOSE در واقع پورت را منتشر نمی‌کند.

بلکه، به عنوان نوعی سند بین فردی که ایمیج را ساخته و کسی که کانتینر را اجرا می‌کند، پیرامون اینکه کدام پورت‌ها قرار است منتشر شوند، عمل خواهد کرد. برای منتشر کردن پورت، هنگامی که کانتینر اجرا می‌شود، با استفاده از پرچم p- روی docker run برای انتشار و نگاشت یک یا تعداد بیشتری از پورت‌ها، یا پرچم p- برای انتشار همه پورت‌های نمایش داده شده استفاده می‌کند و آن‌ها را به پورت‌های مرتبه بالاتری نگاشت می‌کند.

دستور VOLUME

1VOLUME /ds

این دستور به کاربر امکان به اشتراک‌گذاری داده‌ها بین کانتینر داکر و کامپیوتر میزبان را می‌دهد. دستور VOLUME به کاربر امکان مونت (Mount) کردن خارجی موارد مانت شده را می‌دهد. «دایرکتوری میزبان» (Host Directory)، تنها هنگامی تعریف می‌شود که یک کانتینر اجرا نمی‌شود (زیرا کاربر ممکن است این کانتینر را روی کامپیوترهای متفاوتی اجرا کند)، نه هنگامی که ایمیج تعریف شده است. در حال حاضر، کاربر می‌تواند نام پوشه را با کانتینتر داکری که تمایل دارد با کانتینر میزبان به اشتراک بگذارد، تعیین کند. در همین رابطه از راهنمای کاربری داکر:

دایرکتوری میزان در زمان اجرای کانتینر تعریف شده است. دایرکتوری میزبان (مونت پوینت (Mountpoint)) به طور ذاتی وابسته به میزبان (Host-Dependent) است. این کار برای حفظ قابلیت حمل ایمیج است. از آنجا که نمی‌توان تضمین کرد که یک دایرکتوری هاست داده شده در همه میزبان‌ها موجود باشد؛ کاربر نمی‌تواند یک دایرکتوری میزبان را از  درون Dockerfile مونت کند. دستور VOLUME از تعیین کردن پارامتر host-dir پشتیبانی نمی‌کند. کاربر باید مونت‌پوینت را هنگامی که کانتینر را می‌سازد و یا اجرا می‌کند، تعیین کند.

علاوه بر آن، این volume‌ها برای داده‌های مستقر در بیرون از فایل سیستم کانتینر دارای معنا هستند که اغلب، در صورت کار با حجم زیادی از داده‌هایی که کاربر قصد ندارد ایمیج داکر را با حضور آن‌ها بزرگ کند، مفید واقع می‌شوند. هنگامی که کاربر یک ایمیج داکر را ذخیره می‌کند، هر نوع داده‌ای در این دایرکتوری VOLUME، به عنوان بخشی از ایمیج ذخیره نخواهد شد، اگرچه داده‌هایی که بیرون از این دایرکتوری در کانتینر موجود هستند، ذخیره خواهند شد.

دستور WORKDIR

1WORKDIR /ds

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

1CMD [./run_jupyter.sh”]

که فرض می کند دایرکتوری در حال کار ds/ است.

دستور ADD

1ADD run_jupyter.sh /ds/run_jupyter.sh

این دستور، به کاربر این امکان را می‌دهد تا یک کپی از فایل‌ها را از کامپیوتر میزبان در یک کانتینر داکر، جایی که داکر اجرا می‌شود، قرار دهد. برخی کاربران، از این دستور برای اجرای اسکریپت بش و «وارد کردن» (Import) چیزهای مفید در یک کانتینر مانند فایل‌های bashrc. استفاده می‌کنند. در کد بالا، باید به این نکته توجه کرد که کانتینر میزبان به طور کامل در اینجا تعیین نشده است، زیرا مسیر میزبان مرتبط به دایرکتوری context است که کاربر هنگام اجرای کانتینر تعیین می‌کند (در ادامه مورد بررسی قرار خواهد گرفت). این مساله تنها هنگامی اتفاق می‌افتد که فایل run_jupyter.sh در دایرکتوری context ریشه هنگام اجرای کانتینر باشد. بنابراین، به همین دلیل است که هیچ مسیری در مقابل فایل منبع وجود ندارد. از راهنمای کاربر داکر:

1ADD <src>... <dest>

دستور ADD، فایل‌های جدید، پوشه‌ها یا URL‌های فایل از راه دور را از <src> کپی می‌کند و آن‌ها را به فایل‌سیستم <dest> اضافه می‌کند.

دستور CMD

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

راهی که ممکن است برای انجام این کار به ذهن برخی از افراد برسد این است که بش شل را اجرا کنند (که تا وقتی Kill نشود، در حال اجرا باقی می‌ماند).

1CMD [./run_jupyter.sh”]

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

1CMD ["/bin/bash"]

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

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

ساخت ایمیج داکر

اطلاعات زیادی پیرامون فایل‌های داکر وجود داشت. اما جای نگرانی نیست. دیگر مباحثی که از این لحظه به بعد بیان می‌شوند خیلی سر راست هستند.

اکنون که recipe به صورت یک داکرفایل (DockerFile) ساخته شد، زمان آن رسیده است که یک ایمیج ساخته شود. چنین کاری با دستور زیر انجام می‌شود.

این کار، یک ایمیج داکر می‌سازد (نه یک کانتینر؛ به مخاطبانی که تفاوت این دو را به خاطر نمی‌آورند توصیه می‌شود که به ابتدای این مطلب مراجعه کرده و یک بار دیگر تعاریف را مطالعه کنند)؛ این ایمیج داکر در زمان دیگری قابل اجرا است.

ساخت و اجرای یک کانتینر از داکر ایمیج

اکنون ، کاربر آماده به کار انداختن هر آنچه است که تاکنون آمده شد. می‌توان این محیط را با اجرای دستورات زیر بالا آورد:

پس از اجرای کد بیان شده در بالا، کانتینر بالا خواهد بود و کار می‌کند. سرور ژوپیتر هنگام اجرا بالا خواهد بود، زیرا:

1CMD [./run_jupyter.sh”]

دستور در پایان داکرفایل است. اکنون، کاربر باید قادر به دسترسی به نوت‌بوک ژوپیتر در پورتی باشد که روی آن خدمت می‌کند؛ در این مثال، این پورت باید از مسیر /http://localhost:7745 با رمز tutorial در دسترس باشد. اگر کاربر این کانتینر داکر را از راه دور اجرا می‌کند، باید local port forwarding را اجرا کند تا بتواند به سرور ژوپیتر از مرورگر خود دسترسی داشته باشد.

تعامل با کانتینر

هنگامی که کانتینر بالا و در حال اجرا است، دستورات بیان شده در زیر، مفید خواهند بود.

  • افزودن یک جلسه ترمینال جدید به کانتینر: این مورد هنگامی مفید است که کاربر بخواهد برخی از نرم‌افزارها را نصب و یا از شل استفاده کند.

  • ذخیره کردن حالت کانتینر به عنوان یک ایمیج جدید: با اینکه کاربر شروع به کار با یک داکرفایل با همه کتابخانه‌هایی کرده که تمایل دارد آن‌ها را نصب کند، ممکن است در طول زمان تغییرات قابل توجهی در وضعیت کانتینر با افزودن کتابخانه‌ها و بسته‌های بیشتر به صورت تعاملی ایجاد کند. این کار برای ذخیره کردن حالت کانتینر کاربر به عنوان یک ایمیج است که می‌تواند بعدا آن را به اشتراک بگذارد (یا لایه‌ای در بالا). چنین کاری را می‌توان با دستور داکر کامیت CLI انجام داد.
1docker commit <container_name> new_image_name:tag_name(optional)

برای مثال، اگر کاربر بخواهد که حالت کانتینر را که container1 نامیده می‌شود به عنوان یک ایمیج که hamelsmu/tutorial:v2 نامیده می‌شود فراخوانی کند، کافی است دستور زیر را اجرا کند.

1docker commit container_1 hamelsmu/tutorial:v2

ممکن است برای عده‌ای جالب باشد که چرا /hamelsmu در مقابل نام ایمیج قرار دارد. دلیل این امر صرفا آسان‌تر کردن push کردن این کانتینر به داکرهاب، در آینده است؛ زیرا hamelsmu نام کاربری داکرهاب نویسنده این مطلب است. افرادی که از داکر در محل کار خود استفاده می‌کنند، این امکان وجود دارد که یک مخزن داکر پرایوت داخلی داشته باشند که بتوانند ایمیج‌های داکر خود را در آن push کنند.

  • لیست کردن کانتینرهای در حال اجرا: معمولا از این کار زمانی استفاده می‌شود که فرد نام کانتینری که در حال حاضر در حال اجرا است را فراموش می‌کند.
1docker ps -a -f status=running

در صورت اجرای دستور بالا، بدون پرچم status=running، کاربر لیست همه کانتینرهای موجود در سیستم را مشاهده خواهد کرد (حتی اگر دیگر در حال اجرا نباشند). این دستور برای مواقعی مفید است که کاربر بخواهد کانتینرهای قدیمی را ردیابی کند. لیست کردن همه ایمیج‌های که کاربر به صورت محلی ذخیره کرده نیز با دستور زیر انجام می‌شود.

docker images
  • قرار دادن ایمیج در داکرهاب (یا رجیستری دیگری): اگر کاربر بخواهد کار خود را با دیگر افراد به اشتراک بگذارد، یا یک ایمیج را به راحتی روی «ابر» (Cloud) ذخیره کند، این کار بسیار مفید خواهد بود. البته، کاربر باید اطمینان حاصل کند که هیچ اطلاعات خصوصی را ضمن انجام این کار، با دیگر کاربران به اشتراک نمی‌گذارد (مخازن خصوصی نیز در داکرهاب وجود دارد). ابتدا، باید یک مخزن داکرهاب ساخت و ایمیج را به طور مناسبی نام‌گذاری کرد. این کار شامل اجرای دستور docker login برای آنکه کاربر ابتدا به اکانت خود در داکرهاب یا دیگر رجیستری‌ها متصل شود نیز می شود. برای مثال، در اینجا برای قرار دادن ایمیج در این کانتینر [+]، ابتدا ایمیج محلی با عنوان hamelsmu/tutorial نام‌گذاری شده است (در اینجا از hamelsmu استفاده شده است)؛ برای مثال، دستور CLI به صورت زیر است.
1docker push hamelsmu/tutorial:v2

داکر ایمیج ذکر شده در بالا، در این مخزن [+] با تگ v2 پوش می‌شود. شایان ذکر است که اگر ایمیج به صورت عمومی به نمایش دربیاید، دیگر افراد می‌توانند به راحتی لایه‌بندی را بر فراز این ایمیج انجام دهند. درست مانند لایه‌بندی که پیش از این در همین مطلب، روی ایمیج ubuntu انجام شد. این کار برای دیگر افرادی که به دنبال بازتولید یا توسعه بخشیدن به پژوهش‌های فرد خاصی هستند، بسیار مفید خواهد بود.

دست یافتن به قدرت‌های جادویی داکر (Docker) و کاربرد آن در علم داده

اکنون که کاربران می‌دانند چطور با داکر کار کنند، می‌توانند کارهای زیر را انجام بدهند:

  • به اشتراک‌گذاری پژوهش‌های تکرارپذیر با همکاران و دوستان
  • شرکت در رقابت‌های کگل و پیروز شدن در آن‌ها با انتقال دادن کدها به یک محیط محاسباتی بزرگ‌تر به طور موقت و در صورت نیاز
  • نمونه‌سازی اولیه درون کانتینر داکر روی لپ‌تاپ کاربر و سپس، انتقال دادن همان محاسبات به سرور بدون نیاز به انجام تلاش خیلی زیاد، در حالی که بسیاری از ویژگی‌هایی که کاربر در محیط کار محلی خود به آن‌ها علاقه دارد (مانند پلاگین‌های ویم، اسکریپت‌های بش، خط فرمان سفارشی‌سازی شده و aliase‌ها) در آن وجود دارند.
  • instantiate سریع همه مخازنی که برای اجرای «تنسورفلو» (Tensorflow)، «پای‌تورچ» (Pytorch) و دیگر کتابخانه‌های یادگیری عمیق روی GPU با استفاده از Nvidia-Docker (در صورتی که کاربر بخواهد چنین کاری را از پایه انجام بدهد، بسیار دشوار خواهد بود) نیاز هستند.
  • انتشار مدل‌ها به عنوان برنامه‌های کاربردی؛ برای مثال، به عنوان یک rest api که از کانتینر داکر پیش‌بینی انجام می دهد. هنگامی که برنامه کاربر در داکر قرار گرفت، می‌تواند تکرار شود.

داکر انویدیا

انگیزه اصلی بسیاری از افراد برای یادگیری داکر نمونه‌سازی اولیه مدل‌های «یادگیری عمیق» (Deep Learning) روی یک GPU یکتا و انتقال محاسبات به وب سرور آمازون هنگامی که نیاز به قدرت بیشتری است، محسوب می‌شود.

اگرچه، برای کپسوله‌سازی مناسب همه وابستگی‌ها مانند درایورها برای GPU‌های انویدیا نیاز به استفاده از Nvidia-Docker به جای داکر دارد. این امر، نیاز به کار بیشتری علاوه بر استفاده از داکر دارد، اما اگر افراد درک درستی از داکر داشته باشند در این راستا به مشکل بر نمی‌خورند.

اگر نوشته بالا برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

^^

بر اساس رای ۳ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
towardsdatascience
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *