تعبئة تطبيق Java في حاويات
في هذه الوحدة، تقوم بتعبئة تطبيق Java في حاويات.
كما ذكرنا سابقا، تعمل الحاويات مباشرة فوق نظام التشغيل المضيف والنواة والأجهزة كعملية نظام عادية. تتطلب الحاويات موارد نظام أقل، ما يؤدي إلى بصمة أصغر، ونفقات أقل، وأوقات بدء تشغيل أسرع للتطبيق. هذه الفوائد هي حالات استخدام كبيرة للتحجيم عند الطلب.
هناك حاويات Windows وحاويات Linux. في هذه الوحدة النمطية، يمكنك استخدام وقت تشغيل Docker المستخدم على نطاق واسع لإنشاء صورة حاوية Linux. ثم نشر صورة حاوية Linux إلى نظام التشغيل المضيف لجهازك المحلي. وأخيرا، يمكنك نشر صورة حاوية Linux إلى خدمة Azure Kubernetes.
نظرة عامة على Docker
يتم استخدام وقت تشغيل Docker لإنشاء صور الحاوية وسحبها وتشغيلها ودفعها، كما هو موضح في الرسم التخطيطي التالي:
يصف الجدول التالي كل أمر Docker:
| أمر Docker | وصف |
|---|---|
docker build |
ينشئ صورة حاوية تتكون من الإرشادات أو الطبقات اللازمة ل Docker لإنشاء حاوية قيد التشغيل من صورة. نتيجة هذا الأمر هي صورة. |
docker pull |
تتم تهيئة الحاويات من الصور، والتي يتم سحبها من السجلات مثل Azure Container Registry. هذا السجل هو المكان الذي تسحب منه خدمة Azure Kubernetes. نتيجة هذا الأمر هي سحب شبكة لصورة، والذي يحدث في Azure. اختياريا، يمكنك سحب الصور محليا. هذا الخيار شائع عند إنشاء الصور التي تتطلب تبعيات أو طبقات قد يحتاجها التطبيق الخاص بك، مثل خادم التطبيق. |
docker run |
المثيل قيد التشغيل للصورة هو حاوية، وينفذ هذا الأمر جميع الطبقات اللازمة لتشغيل تطبيق الحاوية قيد التشغيل والتفاعل معه. نتيجة هذا الأمر هي عملية تطبيق قيد التشغيل على نظام التشغيل المضيف. |
docker push |
يخزن Azure Container Registry الصور بحيث تكون متاحة بسهولة وإغلاق الشبكة لنشر Azure وتوسيع نطاقها. |
استنساخ تطبيق Java
أولا، انسخ مستودع Flight Booking System for Airline Reservations وانتقل إلى مجلد مشروع تطبيق ويب الخطوط الجوية.
ملاحظه
إذا تم الانتهاء من إنشاء خدمة Azure Kubernetes في علامة تبويب CLI، فاستخدم علامة التبويب هذه. إذا كانت لا تزال قيد التشغيل، فافتح علامة تبويب جديدة وانتقل إلى الموقع حيث تفضل استنساخ نظام حجز الطيران لحجوزات شركات الطيران.
شغّل الأوامر التالية:
git clone https://github.com/Azure-Samples/containerize-and-deploy-Java-app-to-Azure.git
cd containerize-and-deploy-Java-app-to-Azure/Project/Airlines
اختياريا، إذا كان لديك Java وMaven مثبتين، يمكنك تشغيل الأمر التالي في وحدة التحكم الطرفية للحصول على فكرة عن تجربة إنشاء التطبيق دون Docker. إذا لم يكن لديك Java وMaven مثبتين، يمكنك المتابعة بأمان إلى القسم التالي، إنشاء ملف Docker. في هذا القسم، يمكنك استخدام Docker لسحب Java وMaven لتنفيذ البنيات نيابة عنك.
mvn clean package
ملاحظه
استخدمنا mvn clean package الأمر لتوضيح التحديات التشغيلية لعدم استخدام إصدارات Docker متعددة الأجهزة، والتي نغطيها بعد ذلك. مرة أخرى، هذه الخطوة اختيارية. وفي كلتا الحالتين، يمكنك المتابعة بأمان دون تنفيذ أمر Maven.
إذا كانت العملية ناجحة، فإن Maven أنشأ بنجاح نظام حجز الطيران لأرشيف تطبيقات الويب لحجوزات شركات الطيران Artifact AirlinesReservationSample-0.0.1-SNAPSHOT.war، كما هو موضح في الإخراج التالي:
[INFO] Building war: $PROJECT_PATH/containerize-and-deploy-Java-app-to-Azure/Project/Airlines/target/AirlinesReservationSample-0.0.1-SNAPSHOT.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11.776 s
[INFO] Finished at: 2024-11-15T09:33:26+09:00
[INFO] ------------------------------------------------------------------------
تخيل أنك مطور Java وقمت ببناء الخطوط الجويةReservationSample-0.0.1-SNAPSHOT.war. ربما تكون خطوتك التالية هي العمل مع مهندسي العمليات لتوزيع هذه الأداة إما على خادم محلي أو جهاز ظاهري. لكي يبدأ التطبيق ويشغل بنجاح، يجب أن تكون الخوادم والأجهزة الظاهرية متاحة ومكونة مع التبعيات المطلوبة. هذه العملية صعبة وتستغرق وقتا طويلا، خاصة عند الطلب عندما تصل زيادة الحمل إلى التطبيق الخاص بك. مع الحاويات، يتم تخفيف هذه التحديات.
إنشاء Dockerfile
أنت الآن جاهز لإنشاء Dockerfile. Dockerfile هو مستند نصي يحتوي على جميع الأوامر التي سينفذها المستخدم على سطر الأوامر لتجميع صورة حاوية. كل صورة هي طبقة يمكن تخزينها مؤقتا من أجل الكفاءة. تبني الطبقات فوق بعضها البعض.
على سبيل المثال، يحتاج Flight Booking System for Airline Reservations إلى النشر وتشغيله داخل خادم تطبيق. لا يتم حزم خادم التطبيق داخل الخطوط الجويةReservationSample-0.0.1-SNAPSHOT.war. إنها تبعية خارجية مطلوبة لشركة الخطوط الجويةReservationSample-0.0.1-SNAPSHOT.war لتشغيل طلبات HTTP والاستماع إليها ومعالجتها وإدارة جلسات المستخدم وتسهيل حجوزات الطيران. إذا استخدمت توزيعا تقليديا غير حاويات، فسيثبت مهندسو العمليات خادم تطبيق وتكوينه على بعض الخادم الفعلي أو الجهاز الظاهري قبل نشر AirlinesReservationSample-0.0.1-SNAPSHOT.war إليه. سيحتاج مهندسو العمليات هؤلاء أيضا إلى التأكد من أن JDK المستخدم على جهازك - وهو ما mvn clean package يستخدم لتجميع ملف WAR - في الواقع يتوافق مع نفس JRE الذي يستخدمه خادم التطبيق. إدارة هذه التبعيات صعبة وتستغرق وقتا طويلا.
باستخدام Dockerfile، يمكنك كتابة الإرشادات أو الطبقات اللازمة لتحقيق هذا الهدف تلقائيا، عن طريق وضع طبقات في الخطوات اللازمة لضمان أن نظام حجز الطيران لحجوزات شركات الطيران يحتوي على جميع التبعيات اللازمة للنشر في وقت تشغيل حاوية Docker. هذا الحل مقنع عند العمل مع مقياس عند الطلب على فترات زمنية غير مخطط لها. تستخدم كل طبقة ذاكرة التخزين المؤقت Docker، التي تحتوي على حالة صورة الحاوية في كل حدث تعليمي، ما يؤدي إلى تحسين وقت الحساب وإعادة الاستخدام. إذا لم تتغير طبقة، يتم استخدام الطبقات المخزنة مؤقتا. حالات الاستخدام الشائعة للطبقات المخزنة مؤقتا هي وقت تشغيل Java وخادم التطبيق والتبعيات الأخرى لتطبيق ويب Flight Booking System for Airline Reservations. إذا تغير إصدار على طبقة مخزنة مؤقتا مسبقا وعندما يتغير ذلك، يتم إنشاء إدخال جديد مخزن مؤقتا.
يصور الرسم التخطيطي التالي طبقات صورة الحاوية. عند تنفيذ الأوامر في Dockerfile، يتم إنشاء الطبقات. الطبقة العليا هي قراءة / كتابة نظام حجز الطيران لطبقة تطبيق الويب حجوزات الطيران. تم إنشاء هذه الطبقة أعلى طبقات القراءة فقط السابقة.
لدى Docker مفهوم البنيات متعددة المؤسسات، وهي ميزة تمكنك من إنشاء صورة حاوية أصغر مع تخزين مؤقت أفضل وبصمة أمان أصغر، ما يتيح زيادة تحسين وصيانة Dockerfile بمرور الوقت. على سبيل المثال، يمكنك فصل مرحلة إنشاء الحاوية لتحويل التطبيق برمجيا وبناءه من مرحلة تشغيل التطبيق. تمكنك هذه الميزة من نسخ البيانات الاصطناعية التي تم إنشاؤها أثناء الإنشاء فقط إلى صورة حاوية الإنتاج، ما يقلل من البصمة. نظرا لأنه يتم تخزين صور الحاوية مؤقتا، إذا لم تكن هناك تغييرات، يمكن إعادة استخدام الصور المخزنة مؤقتا، ما يقلل من تكلفة التنزيل ووقته من الشبكة.
يجب إدارة الخدمات المكشوفة في بيئة الإنتاج بعناية للأمان. لذلك، تستخدم بيئة الإنتاج صورة حاوية آمنة وتشغلها. يستخدم المثال الصورة التي CBL-Mariner توفرها Microsoft.
CBL-Mariner Linux هو نظام تشغيل خفيف الوزن، يحتوي فقط على الحزم اللازمة لبيئة سحابية. يمكنك تخصيصه من خلال حزم وأدوات مخصصة لتناسب متطلبات التطبيق الخاص بك. تخضع CBL-Mariner لاختبارات التحقق من صحة Azure وهي متوافقة مع عوامل Azure. تقوم Microsoft بإنشاء واختبار CBL-Mariner لتشغيل حالات الاستخدام المختلفة، بدءا من خدمات Azure إلى تشغيل البنية الأساسية ل IoT. إنه توزيع Linux الموصى به داخليا للاستخدام مع خدمات Microsoft السحابية والمنتجات ذات الصلة.
ملاحظه
توفر Microsoft صور حاوية مجمعة مع OpenJDK، بما في ذلك UbuntuCBL-Marinerالصور و وdistroless.
distroless تحتوي الصورة على أصغر حجم للصورة، ولكن تشغيل Tomcat عليها أمر صعب. لتحقيق تصميم خفيف الوزن، distroless تزيل الصورة العديد من الأوامر والأدوات، بما في ذلك shell، ما يعني أنه لا يمكنك استدعاء catalina.sh لبدء تشغيل Tomcat.
distroless الصورة مناسبة لتشغيل JARs القابلة للتنفيذ، مثل تلك المستخدمة مع Spring Boot أو Quarkus.
في المثال التالي، يتم استخدام نفس إصدار Microsoft Build من OpenJDK في كل من مرحلة الإنشاء والمرحلة النهائية. يضمن هذا الأسلوب إنشاء التعليمات البرمجية المصدر بنفس إصدار JDK الذي يستخدمه توزيع الخدمة Tomcat، مما يساعد على تجنب السلوك غير المتوقع بسبب عدم تطابق الإصدار.
تصور الصورة التالية البنية متعددة المراحل وما يحدث في كل مرحلة استنادا إلى الأوامر المحددة في Dockerfile:
في المرحلة 0، يتم تنزيل Tomcat واستخراجه في دليل محدد بواسطة متغير بيئة على صورة Ubuntu.
TOMCAT_VERSION يحدد المتغير إصدار Tomcat المراد تنزيله. إذا تم إصدار إصدار جديد من Tomcat، يجب تحديث رقم الإصدار، حيث يتم إحضار صورة جديدة فقط عند تغيير رقم الإصدار. وإلا، يتم استخدام الصورة المخزنة مؤقتا. يتم نسخ Tomcat التي تم تنزيلها إلى بيئة المرحلة النهائية للاستخدام.
في المرحلة 1، يتم تثبيت Maven على صورة Ubuntu، ويتم نسخ التعليمات البرمجية المصدر وملفات التكوين التي تم إنشاؤها قبل إنشاء مشروع Maven. يتم تخزين كل طبقة مؤقتا، لذا فإن صورة نظام التشغيل وطبقات صورة Maven تعيدان استخدام ذاكرة التخزين المؤقت. إذا تم تحديث ملفات التكوين أو ملفات التعليمات البرمجية المصدر أو دليل الويب، تتم إعادة إنشاء الطبقات من التغييرات فصاعدا. إذا اكتمل البناء بنجاح دون أخطاء أثناء التحويل البرمجي، يتم إنشاء عنصر يسمى AirlinesReservationSample-0.0.1-SNAPSHOT.war ضمن الدليل الهدف . يتم نسخ هذه الأداة إلى بيئة المرحلة النهائية للاستخدام.
في المرحلة الأخيرة، يتم استخدام الصورة الآمنة CBL-Mariner التي توفرها Microsoft لنسخ أدوات بناء Tomcat وJava من المرحلة 0 والمرحلة 1، على التوالي. يمتلك المستخدم المسمى app جميع الملفات المستخدمة داخل المشروع، ويتم تشغيل التطبيق أيضا كمستخدم بدلا من الحصول app على root امتيازات. يضمن هذا الإعداد إمكانية تشغيل صورة الحاوية بشكل آمن دون منح أذونات غير ضرورية. وأخيرا، يتم كشف رقم المنفذ 8080، ويتم تنفيذ البرنامج النصي catalina.sh لبدء تشغيل Tomcat. عند تشغيل هذا على Docker Desktop المحلي، يمكنك الوصول إليه عبر عنوان URL http://localhost:8080/AirlinesReservationSample.
ضمن المجلد الجذر لمشروعك، استخدم الأمر التالي containerize-and-deploy-Java-app-to-Azure/Project/Airlines، لإنشاء ملف يسمى Dockerfile:
vi Dockerfile
أضف المحتويات التالية إلى Dockerfile، ثم احفظها واخرج منها. للحفظ والخروج، اضغط على ESC، واكتب :wq!، ثم اضغط على مفتاح الإدخال Enter.
############################################
# Tomcat Intall stage
############################################
FROM mcr.microsoft.com/openjdk/jdk:17-ubuntu AS tomcat
ENV CATALINA_HOME=/usr/local/tomcat
# Configure Tomcat Version (Be sure to use the latest version)
ENV TOMCAT_VERSION=10.1.33
# Install Tomcat and required packages
RUN apt-get update ; \
apt-get install -y curl ; \
curl -O https://downloads.apache.org/tomcat/tomcat-10/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz ; \
tar xzf apache-tomcat-${TOMCAT_VERSION}.tar.gz ; \
mv apache-tomcat-${TOMCAT_VERSION} ${CATALINA_HOME} ; \
rm apache-tomcat-${TOMCAT_VERSION}.tar.gz && \
apt-get remove --purge -y curl && \
apt-get autoremove -y && \
apt-get clean
############################################
# Build stage (Compiles with Java 17)
############################################
FROM mcr.microsoft.com/openjdk/jdk:17-ubuntu AS build
WORKDIR /build
# Install Maven
RUN apt-get update && apt-get install -y maven && mvn --version
# Copy source code
COPY pom.xml .
COPY src ./src
COPY web ./web
# Build the project
RUN mvn clean package
############################################
# Package final stage
############################################
FROM mcr.microsoft.com/openjdk/jdk:17-mariner
# Configure the location of the Tomcat installation
ENV CATALINA_HOME=/usr/local/tomcat
# Configure the path to the Tomcat binaries
ENV PATH=$CATALINA_HOME/bin:$PATH
# This is the user that runs the Tomcat process
USER app
# Copy the Tomcat installation from the Tomcat stage
COPY --chown=app:app --from=tomcat ${CATALINA_HOME} ${CATALINA_HOME}
# Copy the Tomcat configuration files
COPY --chown=app:app tomcat-users.xml ${CATALINA_HOME}/conf
# Copy the compiled WAR file from the build stage
COPY --chown=app:app --from=build /build/target/*.war ${CATALINA_HOME}/webapps/AirlinesReservationSample.war
# Expose the default Tomcat port
EXPOSE 8080
# Start Tomcat
CMD ["catalina.sh", "run"]
ملاحظه
اختياريا، يمكنك استخدام ملف Dockerfile_Solution في جذر المشروع، والذي يحتوي على المحتويات التي تحتاج إليها.
ينقسم Dockerfile إلى ثلاث مراحل، والتي يتم وصفها في الجداول التالية:
مرحلة تثبيت Tomcat:
أمر Docker وصف FROMFROM mcr.microsoft.com/openjdk/jdk:17-ubuntu AS tomcatيعين الصورة الأساسية إلى Microsoft Build of OpenJDK 17 على Ubuntu، ويسمي هذه المرحلةtomcat. هذا هو المكان الذي يتم فيه تثبيت Tomcat.ENVENV CATALINA_HOME=/usr/local/tomcatتعيين متغير بيئة لدليل تثبيت Tomcat.ENVENV TOMCAT_VERSION=10.1.33تعيين إصدار Tomcat ليتم تثبيته. يجب تحديث هذا إلى أحدث إصدار حسب الحاجة.RUNيقوم RUNالأمر بتحديث قائمة الحزم وتثبيتcurlوتنزيل الإصدار المحدد من Tomcat واستخراجه ونقله إلى الدليل المحدد وتنظيف الملفات والحزم غير الضرورية. وهذا يضمن بقاء الصورة خفيفة الوزن.مرحلة البناء، التي تجمع مع Java 17:
أمر Docker وصف FROMFROM mcr.microsoft.com/openjdk/jdk:17-ubuntu AS buildيعين الصورة الأساسية إلى Microsoft Build of OpenJDK 17 على Ubuntu، ويسمي هذه المرحلةbuild. تستخدم هذه المرحلة لتجميع تطبيق Java.WORKDIRWORKDIR /buildيعين دليل العمل داخل الحاوية إلى/build، حيث يتم نسخ التعليمات البرمجية المصدر وتحويلها برمجيا.RUNRUN apt-get update && apt-get install -y maven && mvn --versionتثبيت Maven، أداة أتمتة البناء المستخدمة لمشاريع Java، والتحقق من تثبيتها.COPYCOPY pom.xml .نسخ ملف تكوين Maven إلى دليل العمل. هذا الملف ضروري لبناء المشروع.COPYCOPY src ./srcنسخ دليل التعليمات البرمجية المصدر في الحاوية. هذا هو المكان الذي توجد فيه التعليمات البرمجية لتطبيق Java.COPYCOPY web ./webنسخ دليل موارد الويب في الحاوية. يتضمن ذلك موارد تطبيق الويب المطلوبة للبناء.RUNRUN mvn clean packageينفذ عملية بناء Maven، والتي تجمع تطبيق Java وتحزمه في ملف WAR.المرحلة النهائية للحزمة:
أمر Docker وصف FROMFROM mcr.microsoft.com/openjdk/jdk:17-marinerيعين الصورة الأساسية إلى Microsoft Build of OpenJDK 17 علىCBL-Mariner، والذي يستخدم للتوزيع النهائي للتطبيق.ENVENV CATALINA_HOME=/usr/local/tomcatتعيين متغير البيئة لدليل تثبيت Tomcat، على غرار مرحلة التثبيت.ENVENV PATH=$CATALINA_HOME/bin:$PATHيضيف دليل Tomcat bin إلى النظامPATH، مما يسمح بتشغيل أوامر Tomcat بسهولة.USERUSER appيحدد المستخدم الذي يتم تشغيل عملية Tomcat بموجبه، ما يعزز الأمان من خلال عدم التشغيل كمستخدم جذر.COPYCOPY --chown=app:app --from=tomcat ${CATALINA_HOME} ${CATALINA_HOME}ينسخ تثبيت Tomcat منtomcatالمرحلة، مع تعيين الملكية للمستخدمapp.COPYCOPY --chown=app:app tomcat-users.xml ${CATALINA_HOME}/confينسخ ملف تكوين مستخدم Tomcat في الحاوية، مع تعيين الملكية للمستخدمapp.COPYCOPY --chown=app:app --from=build /build/target/*.war ${CATALINA_HOME}/webapps/AirlinesReservationSample.warينسخ ملف WAR المحول برمجيا منbuildالمرحلة إلى دليل Tomcat webapps ، مع تعيين الملكية للمستخدمapp.EXPOSEEXPOSE 8080يعرض المنفذ 8080، المنفذ الافتراضي ل Tomcat، ما يسمح بالوصول الخارجي إلى التطبيق.CMDCMD ["catalina.sh", "run"]يحدد الأمر لبدء تشغيل Tomcat عند تشغيل الحاوية.
لمزيد من المعلومات حول بناء Dockerfile، راجع مرجع Dockerfile.