توسعه کانتینرها با Dockerfiles

۱. مرور کلی

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

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

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

آنچه یاد خواهید گرفت

در این آزمایشگاه، شما یاد خواهید گرفت که چگونه موارد زیر را انجام دهید:

  • ایجاد یک Dockerfile برای یک برنامه نمونه
  • ساخت یک تصویر
  • اجرای تصویر به عنوان یک کانتینر به صورت محلی
  • تغییر رفتار کانتینر
  • تصویر را به رجیستری مصنوعات منتقل کنید

پیش‌نیازها

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

تنظیم محیط خودتنظیم

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

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • نام پروژه ، نام نمایشی برای شرکت‌کنندگان این پروژه است. این یک رشته کاراکتری است که توسط APIهای گوگل استفاده نمی‌شود و می‌توانید آن را در هر زمانی به‌روزرسانی کنید.
  • شناسه پروژه باید در تمام پروژه‌های گوگل کلود منحصر به فرد باشد و تغییرناپذیر است (پس از تنظیم، قابل تغییر نیست). کنسول کلود به طور خودکار یک رشته منحصر به فرد تولید می‌کند؛ معمولاً برای شما مهم نیست که چیست. در اکثر آزمایشگاه‌های کد، باید به شناسه پروژه ارجاع دهید (و معمولاً با نام PROJECT_ID شناخته می‌شود)، بنابراین اگر آن را دوست ندارید، یک شناسه تصادفی دیگر ایجاد کنید، یا می‌توانید شناسه خودتان را امتحان کنید و ببینید آیا در دسترس است یا خیر. سپس پس از ایجاد پروژه، آن "منجمد" می‌شود.
  • یک مقدار سوم هم وجود دارد، شماره پروژه که برخی از APIها از آن استفاده می‌کنند. برای اطلاعات بیشتر در مورد هر سه این مقادیر به مستندات مراجعه کنید.
  1. در مرحله بعد، برای استفاده از منابع/APIهای ابری، باید پرداخت صورتحساب را در کنسول ابری فعال کنید . اجرای این آزمایشگاه کد، اگر اصلاً هزینه‌ای نداشته باشد، هزینه زیادی نخواهد داشت. برای خاموش کردن منابع به طوری که پس از این آموزش متحمل پرداخت صورتحساب نشوید، دستورالعمل‌های «پاکسازی» موجود در انتهای آزمایشگاه کد را دنبال کنید. کاربران جدید Google Cloud واجد شرایط برنامه آزمایشی رایگان ۳۰۰ دلاری هستند.

2. نمونه درخواست

یک نمونه برنامه برای تسهیل این آزمایش ارائه شده است. در این بخش، کد منبع را بازیابی کرده و برنامه را به شکل بومی خود می‌سازید و سپس به سراغ فرآیند کانتینرسازی می‌روید.

کد منبع

کد منبع این آزمایشگاه به همراه مستندات برنامه نمونه در مخزن GoogleCloudPlatform/container-developer-workshop موجود است.

پیکربندی گیت

git config --global user.name ${USER}
git config --global user.email ${USER}@qwiklabs.net

کلون کردن برنامه نمونه از مخزن منبع ابری

gcloud source repos clone sample-app ${HOME}/sample-app &&
cd ${HOME}/sample-app &&
git checkout main

خروجی

Cloning into '/home/student_03_49720296e995/sample-app'...
remote: Finding sources: 100% (16/16)
remote: Total 16 (delta 0), reused 16 (delta 0)
Receiving objects: 100% (16/16), 47.23 KiB | 681.00 KiB/s, done.
warning: remote HEAD refers to nonexistent ref, unable to checkout.

Project [qwiklabs-gcp-02-4327c4e03d82] repository [sample-app] was cloned to [/home/student_03_49720296e995/sample-app].
Branch 'main' set up to track remote branch 'main' from 'origin'.
Switched to a new branch 'main'

ساخت اپلیکیشن نمونه

cd ${HOME}/sample-app
./mvnw compile

خروجی

[INFO] Scanning for projects...
...
[INFO] Compiling 1 source file to /home/student_03_49720296e995/sample-app/target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  10.080 s
[INFO] Finished at: 2022-02-23T17:14:30Z
[INFO] ------------------------------------------------------------------------

اجرای برنامه نمونه

cd ${HOME}/sample-app
./mvnw exec:java

خروجی

[INFO] Scanning for projects...
...
Listening at http://localhost:8080

پیش‌نمایش برنامه در حال اجرا

  • روی دکمه پیش‌نمایش وب Cloud Shell کلیک کنید
  • روی پیش‌نمایش روی پورت ۸۰۸۰ کلیک کنید

وقتی کارت تمام شد

  • برای متوقف کردن برنامه در حال اجرا، CTRL + c را در Cloud Shell فشار دهید

۳. داکرفایل

کانتینریزه کردن برنامه با Dockerfile

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

یک Dockerfile خالی در مخزن برنامه نمونه ایجاد کنید.

touch ${HOME}/sample-app/Dockerfile

Dockerfile را در ویرایشگر مورد نظر خود باز کنید.

vi ${HOME}/sample-app/Dockerfile

یک تصویر شروع انتخاب کنید

استفاده از روش Dockerfile برای ساخت یک کانتینر، نیازمند دانش مستقیم در مورد برنامه به منظور مونتاژ کانتینر است. اولین قدم برای ایجاد یک Dockerfile، انتخاب یک image است که به عنوان پایه image شما استفاده خواهد شد. این image باید یک image والد یا base باشد که توسط یک منبع قابل اعتماد، معمولاً شرکت شما، نگهداری و منتشر می‌شود.

دستور FROM یک مرحله ساخت جدید را مقداردهی اولیه می‌کند و تصویر پایه را برای دستورات متوالی بعدی تنظیم می‌کند. بنابراین دستور FROM معمولاً اولین دستور در یک Dockerfile است و فقط می‌تواند قبل از آن یک دستور ARG اختیاری برای پشتیبانی از متغیرها قرار گیرد.

نحو: FROM <image>[:<tag> | @<digest>] [AS <name>]

قالب یک تصویر <image>:<tag> یا <image>@<digest> است. اگر برچسب یا خلاصه‌ای مشخص نشود، به طور پیش‌فرض روی برچسب :latest قرار می‌گیرد. قالب <image> بسته به رجیستری مورد استفاده برای ذخیره تصویر متفاوت است. برای رجیستری Artifact، قالب <image> به <region>-docker.pkg.dev/<project ID>/<repository name>/<image name>:<image tag> است.

برای این آزمایش ما از ایمیج public openjdk:11.0-jdk استفاده می‌کنیم، خط زیر را به Dockerfile خود اضافه کنید

FROM openjdk:11.0-jdk

تنظیم دایرکتوری کاری

دستور WORKDIR دایرکتوری کاری را برای هر دستور متوالی که در Dockerfile دنبال می‌شود، تنظیم می‌کند. برای اطلاعات بیشتر به بخش WORKDIR در مستندات مرجع Dockerfile مراجعه کنید.

نحو: WORKDIR <path>

برای این آزمایش ما از دایرکتوری /app به عنوان WORKDIR خود استفاده می‌کنیم، خط زیر را به انتهای Dockerfile خود اضافه کنید.

WORKDIR /app

فایل‌های برنامه را کپی کنید

دستور COPY دایرکتوری‌ها یا فایل‌ها را از مکان <source> به مسیر <destination> سیستم فایل تصویر کپی می‌کند. می‌توان چندین منبع <source> را مشخص کرد و همه آنها نسبت به زمینه ساخت (build context) هستند. زمینه ساخت در بخش ساخت (Build) بیشتر مورد بحث قرار خواهد گرفت. برای اطلاعات بیشتر به بخش COPY در مستندات مرجع Dockerfile مراجعه کنید.

نحو: COPY <source>... <destination>

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

COPY . /app

کامپایل کردن برنامه

دستورالعمل RUN دستورات را در یک لایه تصویر جدید روی تصویر فعلی اجرا می‌کند و نتایج را ثبت می‌کند. تصویر ثبت شده حاصل برای مراحل متوالی در Dockerfile استفاده خواهد شد. برای اطلاعات بیشتر به بخش RUN مستندات مرجع Dockerfile مراجعه کنید.

نحو: RUN <command>

برای این آزمایش ما از Maven برای کامپایل برنامه به یک فایل JAR استفاده خواهیم کرد، خط زیر را به انتهای Dockerfile خود اضافه کنید.

RUN ./mvnw compile assembly:single

شروع برنامه

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

نحو: CMD ["executable","param1","param2"]

برای این آزمایش، فایل JAR که کامپایل کرده‌ایم را اجرا می‌کنیم، خط زیر را به انتهای Dockerfile خود اضافه کنید.

CMD ["java","-jar","/app/target/sample-app-1.0.0-jar-with-dependencies.jar"]

داکرفایل نهایی

داکرفایل نهایی به صورت زیر خواهد بود:

FROM openjdk:11.0-jdk
WORKDIR /app
COPY . /app
RUN ./mvnw compile assembly:single
CMD ["java","-jar","/app/target/sample-app-1.0.0-jar-with-dependencies.jar"]

Dockerfile را به صورت محلی کامیت کنید

cd ${HOME}/sample-app
git add Dockerfile
git commit -m "Added Dockerfile"

۴. ساختن

حالا با استفاده از دستور docker build ایمیج را از Dockerfile می‌سازیم. این دستور به daemon داکر دستور می‌دهد تا ایمیج را با استفاده از دستورالعمل‌های Dockerfile ما بسازد. برای اطلاعات بیشتر به مستندات مرجع docker build مراجعه کنید.

تصویر را بسازید

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker build --tag sample-app:${IMAGE_TAG} .

خروجی

Sending build context to Docker daemon  221.2kB
Step 1/4 : FROM openjdk:11.0-jdk
11.0-jdk: Pulling from library/openjdk
0c6b8ff8c37e: Pull complete
412caad352a3: Pull complete
e6d3e61f7a50: Pull complete
461bb1d8c517: Pull complete
e442ee9d8dd9: Pull complete
542c9fe4a7ba: Pull complete
41de18d1833d: Pull complete
Digest: sha256:d72b1b9e94e07278649d91c635e34737ae8f181c191b771bde6816f9bb4bd08a
Status: Downloaded newer image for openjdk:11.0-jdk
---> 2924126f1829
Step 2/4 : WORKDIR /app
---> Running in ea037abb273d
Removing intermediate container ea037abb273d
---> bd9b6d078082
Step 3/4 : COPY . /app
---> b9aec2b5de51
Step 4/4 : RUN ./mvnw compile jar:jar
---> Running in 3f5ff737b7fd
[INFO] Scanning for projects...
...
[INFO] Building jar: /app/target/sample-app-1.0.0.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  22.952 s
[INFO] Finished at: 2022-02-23T18:09:08Z
[INFO] ------------------------------------------------------------------------
Removing intermediate container 331443caebd3
---> 152f65cc441e
Step 5/5 : CMD ["java", "-jar", "/app/target/sample-app-1.0.0.jar"]
---> Running in 3d595a72231c
Removing intermediate container 3d595a72231c
---> 0e40d7548cab
Successfully built 0e40d7548cab
Successfully tagged sample-app:aaa8895

۵. بدوید

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

اجرای یک کانتینر با استفاده از تصویر

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
  --rm \
  -p 8080:8080 \
  sample-app:${IMAGE_TAG}

خروجی

Listening at http://localhost:8080

پیش‌نمایش اجرای برنامه در یک کانتینر

  • روی دکمه پیش‌نمایش وب Cloud Shell کلیک کنید
  • روی پیش‌نمایش روی پورت ۸۰۸۰ کلیک کنید
  • برای متوقف کردن کانتینرها، CTRL + c را در Cloud Shell فشار دهید

تغییر رفتار کانتینر

اجرای Docker Run از پیکربندی پیش‌فرض در Dockerfile استفاده می‌کند. دستورالعمل‌ها و پارامترهای اضافی را می‌توان برای تغییر این رفتار اضافه کرد.

فعال کردن ثبت وقایع TRACE

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
  --rm \
  -p 8080:8080 \
  sample-app:${IMAGE_TAG} \
  java -Dorg.slf4j.simpleLogger.defaultLogLevel=trace -jar /app/target/sample-app-1.0.0-jar-with-dependencies.jar

پیش‌نمایش اجرای برنامه در یک کانتینر

  • روی دکمه پیش‌نمایش وب Cloud Shell کلیک کنید
  • روی پیش‌نمایش روی پورت ۸۰۸۰ کلیک کنید
  • به برگه Cloud Shell بروید و گزارش‌های اضافی را مشاهده کنید
  • برای متوقف کردن کانتینر، در Cloud Shell کلیدهای CTRL + c را فشار دهید.

تغییر پورت

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
docker run \
--rm \
-e PORT=8081 \
-p 8081:8081 \
sample-app:${IMAGE_TAG}

پیش‌نمایش اجرای برنامه در یک کانتینر

  • روی دکمه پیش‌نمایش وب Cloud Shell کلیک کنید
  • روی تغییر پورت کلیک کنید
  • عدد ۸۰۸۱ را وارد کنید
  • روی تغییر و پیش‌نمایش کلیک کنید
  • برای متوقف کردن کانتینر، در Cloud Shell کلیدهای CTRL + c را فشار دهید.

۶. هل دادن

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

کامیت Dockerfile را به مخزن sample-app ارسال کنید.

cd ${HOME}/sample-app
export IMAGE_TAG=$(git rev-parse --short HEAD)
git push

تصویر را برای ثبت آثار باستانی برچسب‌گذاری کنید

docker tag sample-app:${IMAGE_TAG} \
    us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/apps/sample-app:${IMAGE_TAG}

اعتبارنامه‌های خود را برای ثبت آثار باستانی پیکربندی کنید

gcloud auth configure-docker us-central1-docker.pkg.dev

وقتی از شما پرسیده شد Do you want to continue (Y/n)? با y پاسخ دهید و Enter را فشار دهید.

تصویر را به رجیستری مصنوعات منتقل کنید

docker push us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/apps/sample-app:${IMAGE_TAG}

خروجی

 The push refers to repository [us-central1-docker.pkg.dev/qwiklabs-gcp-04-b47ced695a3c/apps/sample-app]
  453b97f86449: Pushed
  e86791aa0382: Pushed
  d404c7ee0850: Pushed
  fe4f44af763d: Pushed
  7c072cee6a29: Pushed
  1e5fdc3d671c: Pushed
  613ab28cf833: Pushed
  bed676ceab7a: Pushed
  6398d5cccd2c: Pushed
  0b0f2f2f5279: Pushed
  aaa8895: digest: sha256:459de00f86f159cc63f98687f7c9563fd65a2eb9bcc71c23dda3351baf13607a size: 2424

۷. تبریک می‌گویم!

تبریک می‌گویم، شما codelab را تمام کردید!

آنچه شما پوشش داده‌اید

  • یک Dockerfile برای یک برنامه نمونه ایجاد کرد.
  • یک تصویر ساختیم
  • تصویر را به عنوان یک کانتینر به صورت محلی اجرا کنید
  • رفتار کانتینر تغییر کرد
  • تصویر را به رجیستری مصنوعات منتقل کرد