Membuat kontainer aplikasi Java
Di unit ini, Anda membuat kontainer aplikasi Java.
Seperti disebutkan sebelumnya, kontainer berjalan langsung di atas sistem operasi host, kernel, dan perangkat keras sebagai proses sistem biasa. Kontainer memerlukan lebih sedikit sumber daya sistem, menghasilkan jejak yang lebih kecil, lebih sedikit overhead, dan waktu mulai aplikasi yang lebih cepat. Manfaat ini adalah kasus penggunaan yang bagus untuk penskalaan sesuai permintaan.
Ada kontainer Windows dan kontainer Linux. Dalam modul ini, Anda menggunakan runtime Docker yang banyak digunakan untuk membangun gambar kontainer Linux. Anda kemudian menyebarkan gambar kontainer Linux ke sistem operasi host komputer lokal Anda. Terakhir, Anda menyebarkan gambar kontainer Linux ke Azure Kubernetes Service.
Gambaran umum Docker
Docker runtime digunakan untuk membuat, mengambil, menjalankan, dan mengunggah citra kontainer, seperti yang ditunjukkan dalam diagram berikut.
Tabel berikut ini menjelaskan setiap perintah Docker:
| Perintah Docker | Deskripsi |
|---|---|
docker build |
Membangun gambar kontainer yang terdiri dari instruksi atau lapisan yang diperlukan Docker untuk membuat kontainer yang sedang berjalan dari gambar. Hasil dari perintah ini adalah gambar. |
docker pull |
Mengunduh image dari registri ke penyimpanan image daemon Docker yang dipilih oleh klien. Lapisan gambar yang ada dapat digunakan kembali. Dalam modul ini, lingkungan Docker lokal Anda menggunakan gambar dari registri selama pengembangan; nantinya, simpul AKS menarik gambar aplikasi dari Azure Container Registry untuk penyebaran. |
docker run |
Membuat dan memulai kontainer baru dari gambar. Kontainer menjalankan proses startup yang dikonfigurasi, yang dapat ditimpa melalui argumen baris perintah. Lapisan image menyediakan sistem file kontainer; Instruksi build Dockerfile tidak dijalankan lagi saat kontainer dimulai. |
docker push |
Azure Container Registry menyimpan citra sehingga tersedia dan berada dekat dengan jaringan untuk penerapan dan penskalaan Azure. |
Mengkloning aplikasi Java
Pertama, kloning repositori Flight Booking System for Airline Reservations dan navigasikan ke folder proyek aplikasi web Airlines.
Nota
Jika pembuatan Azure Kubernetes Service selesai di tab CLI Anda, gunakan tab tersebut. Jika masih berjalan, buka tab baru dan navigasikan ke lokasi tempat Anda lebih suka mengkloning Sistem Pemesanan Penerbangan untuk Reservasi Maskapai.
Jalankan perintah berikut:
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
Secara opsional, jika Anda telah menginstal Java dan Maven, Anda dapat menjalankan perintah berikut di konsol terminal Anda untuk merasakan pengalaman membangun aplikasi tanpa Docker. Jika Anda tidak menginstal Java dan Maven, Anda dapat dengan aman melanjutkan ke bagian berikutnya, Membuat file Docker. Di bagian itu, Anda menggunakan Docker untuk menarik Java dan Maven untuk menjalankan build atas nama Anda.
mvn clean package
Nota
Kami menggunakan perintah mvn clean package untuk mengilustrasikan tantangan operasional dari tidak menggunakan Docker build multistage, yang akan kami bahas berikutnya. Sekali lagi, langkah ini bersifat opsional. Bagaimanapun, Anda dapat dengan aman melanjutkan tanpa menjalankan perintah Maven.
Jika proses berhasil, Maven berhasil membangun artefak Web Application Archive (WAR) AirlinesReservationSample-0.0.1-SNAPSHOT.war untuk Sistem Pemesanan Penerbangan Aplikasi Web Reservasi Maskapai, seperti yang diilustrasikan oleh output historis berikut. Tanda waktu dan durasi build Anda dapat berbeda:
[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] ------------------------------------------------------------------------
Bayangkan Anda adalah pengembang Java dan Anda baru saja membuat AirlinesReservationSample-0.0.1-SNAPSHOT.war. Langkah Anda selanjutnya mungkin bekerja dengan teknisi operasi untuk menyebarkan artefak ini ke server lokal atau komputer virtual. Agar aplikasi berhasil memulai dan berjalan, server dan komputer virtual harus tersedia dan dikonfigurasi dengan dependensi yang diperlukan. Proses ini menantang dan memakan waktu, terutama sesuai permintaan ketika peningkatan beban mencapai aplikasi Anda. Dengan kontainer, tantangan ini dikurangi.
Membuat Dockerfile
Anda sekarang siap untuk membangun Dockerfile. Dockerfile adalah dokumen teks yang berisi semua perintah yang akan dijalankan pengguna pada baris perintah untuk merakit gambar kontainer. Image kontainer dapat berisi beberapa lapisan sistem file baca-saja. Docker dapat menggunakan kembali hasil build yang di-cache untuk langkah-langkah yang tidak berubah. Lapisan-lapisan dibangun di atas satu sama lain.
Misalnya, Sistem Pemesanan Penerbangan untuk Reservasi Maskapai perlu disebarkan dan dijalankan di dalam server aplikasi. Server aplikasi tidak termasuk dalam AirlinesReservationSample-0.0.1-SNAPSHOT.war. Ini adalah dependensi eksternal yang diperlukan agar AirlinesReservationSample-0.0.1-SNAPSHOT.war berjalan, mendengarkan, dan memproses permintaan HTTP, mengelola sesi pengguna, dan memfasilitasi pemesanan penerbangan. Jika Anda menggunakan penyebaran tradisional dan non-kontainer, teknisi operasi akan menginstal dan mengonfigurasi server aplikasi di beberapa server fisik atau komputer virtual sebelum menyebarkan AirlinesReservationSample-0.0.1-SNAPSHOT.war ke dalamnya. Teknisi operasi ini juga perlu memastikan bahwa JDK yang digunakan pada komputer Anda - yang merupakan apa yang mvn clean package digunakan untuk mengkompilasi file WAR - sebenarnya sesuai dengan JRE yang sama yang digunakan oleh server aplikasi. Mengelola dependensi ini menantang dan memakan waktu.
Dengan Dockerfile, Anda dapat menulis instruksi atau lapisan yang diperlukan untuk secara otomatis mencapai tujuan ini, dengan menambahkan langkah-langkah yang diperlukan untuk memastikan bahwa Sistem Pemesanan Tiket Penerbangan untuk Reservasi Maskapai memiliki semua dependensi yang diperlukan untuk disebarkan ke lingkungan Docker container. Solusi ini menarik ketika Anda bekerja dengan skala sesuai permintaan pada interval yang tidak terencana. Setiap lapisan menggunakan cache Docker, yang berisi status gambar kontainer pada setiap tonggak instruksional, mengoptimalkan waktu komputasi dan menggunakan kembali. Jika lapisan tidak berubah, lapisan yang di-cache akan digunakan. Kasus penggunaan umum untuk lapisan cache adalah runtime Java, server aplikasi, dan dependensi lain untuk aplikasi Web Flight Booking System for Airline Reservations. Jika dan ketika versi berubah pada lapisan yang di-cache sebelumnya, entri cache baru dibuat.
Image kontainer berisi lapisan sistem file baca-saja. Dalam contoh ini, Dockerfile menyalin Tomcat dan file WAR Sistem Pemesanan Penerbangan ke dalam image pada waktu build. Docker menambahkan lapisan bisa-tulis terpisah saat membuat kontainer dari gambar. Lapisan yang dapat ditulis milik setiap kontainer merekam perubahan sistem filenya sendiri tanpa memodifikasi lapisan image.
Nota
Untuk file yang disimpan dalam lapisan yang dapat ditulis milik kontainer, penambahan, modifikasi, dan penghapusan memengaruhi kontainer tersebut daripada image asli. Mengubah file yang berasal dari lapisan image menggunakan mekanisme copy-on-write.
Docker memiliki konsep build multitahap, fitur yang memungkinkan Anda membuat gambar kontainer yang lebih kecil dengan cache yang lebih baik dan dampak keamanan yang lebih kecil, memungkinkan peningkatan pengoptimalan dan pemeliharaan Dockerfile dari waktu ke waktu. Misalnya, Anda dapat memisahkan tahap build kontainer untuk mengkompilasi dan membangun aplikasi dari tahap untuk menjalankan aplikasi. Fitur ini memungkinkan Anda untuk hanya menyalin artefak yang dihasilkan selama proses pembangunan ke dalam gambar kontainer produksi, yang dapat mengurangi ukuran atau penggunaan sumber daya. Karena gambar kontainer di-cache, jika tidak ada perubahan, gambar yang di-cache dapat digunakan kembali, mengurangi biaya dan waktu pengunduhan dari jaringan.
Layanan yang diekspos di lingkungan produksi harus dikelola dengan hati-hati untuk keamanan. Oleh karena itu, lingkungan produksi menggunakan dan mengoperasikan gambar kontainer yang aman. Contohnya menggunakan image Linux Azure yang disediakan oleh Microsoft.
Tahap akhir menggunakan Microsoft Build di OpenJDK 17 pada Azure Linux 3.0. Tag 17-azurelinux ini secara eksplisit menyebutkan basis ini. Tag lama 17-mariner tetap menjadi alias kompatibilitas yang mencerminkan image Azure Linux; tidak boleh disamakan dengan image 17-mariner-cm2 dan 17-mariner-cm1 yang telah dihentikan. Untuk informasi selengkapnya, lihat image kontainer Microsoft Build di OpenJDK.
Nota
Microsoft menyediakan gambar kontainer yang dibundel dengan OpenJDK, termasuk gambar Ubuntu, Azure Linux, dan distroless. Gambar distroless memiliki ukuran gambar terkecil, tetapi menjalankan Tomcat di atasnya sangat menantang. Untuk mencapai desain yang ringan, distroless gambar menghapus banyak perintah dan alat, termasuk shell, yang berarti Anda tidak dapat memanggil catalina.sh untuk memulai Tomcat. Gambar distroless ini cocok untuk menjalankan JAR yang dapat dieksekusi, seperti yang digunakan dengan Spring Boot atau Quarkus.
Dalam contoh berikut, versi Microsoft Build di OpenJDK yang sama digunakan dalam tahap build dan tahap akhir. Pendekatan ini memastikan bahwa Anda mengompilasi kode sumber dengan versi JDK yang sama dengan yang digunakan dalam penyebaran layanan Tomcat, yang membantu menghindari masalah tak terduga akibat ketidakcocokan versi.
Gambar berikut menggambarkan build multitahap dan apa yang terjadi di setiap tahap berdasarkan perintah yang ditentukan dalam Dockerfile:
Pada tahap 0, Tomcat diunduh dari arsip Apache khusus versi, diverifikasi dengan checksum SHA-512, dan diekstrak ke direktori yang ditentukan oleh variabel lingkungan pada gambar Ubuntu. Variabel TOMCAT_VERSION menentukan rilis, dan argumen build TOMCAT_SHA512 menentukan checksum yang diharapkan. Perbarui kedua nilai bersama-sama saat memilih rilis yang didukung yang lebih baru. Docker dapat menggunakan kembali lapisan penginstalan yang di-cache sementara instruksi dan inputnya tidak berubah. Penginstalan Tomcat disalin ke lingkungan tahap akhir untuk digunakan.
Pada tahap 1, Maven diinstal pada gambar Ubuntu, dan kode sumber dan file konfigurasi yang dibuat disalin sebelum membangun proyek Maven. Setiap lapisan di-cache, sehingga gambar OS dan lapisan gambar Maven menggunakan kembali cache. Jika file konfigurasi, file kode sumber, atau direktori web diperbarui, lapisan dari perubahan dan seterusnya dibangun kembali. Jika build berhasil diselesaikan tanpa kesalahan selama kompilasi, artefak bernama AirlinesReservationSample-0.0.1-SNAPSHOT.war dihasilkan di bawah direktori target . Artefak ini disalin ke lingkungan tahap akhir untuk digunakan.
Pada tahap akhir, artefak hasil build Tomcat dan Java dari tahap 0 dan tahap 1, masing-masing, disalin ke dalam image Microsoft Build di OpenJDK 17 pada Azure Linux 3.0. Pengguna bernama app memiliki semua file yang digunakan dalam proyek, dan aplikasi juga dijalankan sebagai app pengguna alih-alih memiliki root hak istimewa. Penyiapan ini memastikan bahwa gambar kontainer dapat dioperasikan dengan aman tanpa memberikan izin yang tidak perlu. Akhirnya, nomor port 8080 diekspos, dan skrip catalina.sh dijalankan untuk memulai Tomcat. Ketika ini dijalankan di Docker Desktop lokal Anda, Anda dapat mengaksesnya melalui URL http://localhost:8080/AirlinesReservationSample.
Di containerize-and-deploy-Java-app-to-Azure/Project/Airlines, gunakan editor teks yang diinstal untuk membuat file bernama Dockerfile. Tambahkan konten berikut dan simpan file:
Important
Sebelum membuat image yang akan Anda ekspos secara publik, periksa rilis Tomcat 10.1.x yang didukung saat ini di halaman unduhan Apache Tomcat dan tinjau pemberitahuan keamanan. Perbarui TOMCAT_VERSION dan TOMCAT_SHA512 bersama-sama menggunakan informasi rilis apache yang diterbitkan. Artefak yang masih tersedia di arsip Apache tidak berarti bahwa versinya mutakhir atau direkomendasikan.
############################################
# Tomcat Intall stage
############################################
FROM mcr.microsoft.com/openjdk/jdk:17-ubuntu AS tomcat
ENV CATALINA_HOME=/usr/local/tomcat
# Configure the reviewed Tomcat version and checksum
ENV TOMCAT_VERSION=10.1.61
ARG TOMCAT_SHA512=35120a2b1182bac3d55438fbec0dc581d03b0f1c16ce692a930f3bb6a1097cf896b94b389152257071a87cb2928ac8c15f1bad08387c14acc7c17dbc1bb598fb
# Install Tomcat and required packages
RUN apt-get update && \
apt-get install -y --no-install-recommends curl ca-certificates && \
curl -fSL \
"https://archive.apache.org/dist/tomcat/tomcat-10/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz" \
-o /tmp/tomcat.tar.gz && \
echo "${TOMCAT_SHA512} /tmp/tomcat.tar.gz" | sha512sum -c - && \
mkdir -p "${CATALINA_HOME}" && \
tar -xzf /tmp/tomcat.tar.gz --strip-components=1 -C "${CATALINA_HOME}" && \
rm /tmp/tomcat.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-azurelinux
# 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"]
Nota
Gunakan Dockerfile yang ditampilkan di unit ini untuk latihan ini. Aplikasi harus disalin ke webapps/AirlinesReservationSample.war agar URL di unit berikut menggunakan konteks /AirlinesReservationSample/. Nama file WAR yang berbeda mengubah konteks aplikasi Tomcat default.
Dockerfile dibagi menjadi tiga tahap, yang dijelaskan dalam tabel berikut:
Tahap penginstalan Tomcat:
Perintah Docker Deskripsi FROMFROM mcr.microsoft.com/openjdk/jdk:17-ubuntu AS tomcatmengatur gambar dasar ke Microsoft Build OpenJDK 17 di Ubuntu, dan menamai tahap initomcat. Di sinilah Tomcat diinstal.ENVENV CATALINA_HOME=/usr/local/tomcatmengatur variabel lingkungan untuk direktori penginstalan Tomcat.ENVENV TOMCAT_VERSION=10.1.61mengatur rilis Tomcat yang disematkan untuk contoh ini. Tinjau rilis yang didukung dan perbarui bersamaTOMCAT_SHA512sesuai kebutuhan.ARGARG TOMCAT_SHA512menyediakan checksum SHA-512 apache yang diterbitkan untuk arsip yang dipilih sebagai argumen build.RUNMenginstal curldan sertifikat CA, lalu menggunakancurl -fSLuntuk mengunduh arsip Apache khusus versi.-fmembuat error HTTP menyebabkan kegagalan;-Lmengikuti pengalihan. Arsip diverifikasi dengansha512sum -c -sebelum ekstraksi ke dalamCATALINA_HOMEdengan--strip-components=1. Rantai&&berhenti pada kegagalan alih-alih menutupi kesalahan selama pembersihan. Terakhir, ini menghapus arsip dan paket yang tidak diperlukan dan membersihkan cache paket.Tahap Build, yang menggunakan Java 17 untuk kompilasi:
Perintah Docker Deskripsi FROMFROM mcr.microsoft.com/openjdk/jdk:17-ubuntu AS buildmengatur gambar dasar ke Microsoft Build OpenJDK 17 di Ubuntu, dan menamai tahap inibuild. Tahap ini digunakan untuk mengkompilasi aplikasi Java.WORKDIRWORKDIR /buildmengatur direktori kerja di dalam kontainer ke/build, tempat kode sumber disalin dan dikompilasi.RUNRUN apt-get update && apt-get install -y maven && mvn --versionmenginstal Maven, alat otomatisasi build yang digunakan untuk proyek Java, dan memverifikasi penginstalannya.COPYCOPY pom.xml .menyalin file konfigurasi Maven ke direktori kerja. File ini sangat penting untuk membangun proyek.COPYCOPY src ./srcmenyalin direktori kode sumber ke dalam kontainer. Di sinilah kode aplikasi Java berada.COPYCOPY web ./webmenyalin direktori sumber daya web ke dalam kontainer. Ini termasuk sumber daya aplikasi web yang diperlukan untuk pembangunan.RUNRUN mvn clean packagemenjalankan proses build Maven, yang mengkompilasi aplikasi Java dan mengemasnya ke dalam file WAR.Tahap akhir Paket:
Perintah Docker Deskripsi FROMFROM mcr.microsoft.com/openjdk/jdk:17-azurelinuxmengatur image dasar ke Microsoft Build di OpenJDK 17 pada Azure Linux 3.0, yang digunakan untuk penyebaran akhir aplikasi.ENVENV CATALINA_HOME=/usr/local/tomcatmengatur variabel lingkungan untuk direktori penginstalan Tomcat, mirip dengan tahap penginstalan.ENVENV PATH=$CATALINA_HOME/bin:$PATHmenambahkan direktori bin Tomcat ke sistemPATH, yang memungkinkan perintah Tomcat dijalankan dengan mudah.USERUSER appmenentukan pengguna di bawah tempat proses Tomcat berjalan, meningkatkan keamanan dengan tidak berjalan sebagai pengguna root.COPYCOPY --chown=app:app --from=tomcat ${CATALINA_HOME} ${CATALINA_HOME}menyalin penginstalan Tomcat daritomcatstaging, menetapkan kepemilikan kepada penggunaapp.COPYCOPY --chown=app:app tomcat-users.xml ${CATALINA_HOME}/confmenyalin file konfigurasi pengguna Tomcat ke dalam kontainer, menjadikanappsebagai pemilik.COPYCOPY --chown=app:app --from=build /build/target/*.war ${CATALINA_HOME}/webapps/AirlinesReservationSample.warmenyalin file WAR yang dikompilasi daribuildtahap ke direktori aplikasi web Tomcat, mengatur kepemilikan kepadaapppengguna.EXPOSEEXPOSE 8080mendokumentasikan bahwa aplikasi diharapkan mendengarkan pada port TCP 8080. Ini tidak mengekspos port host. Unit berikutnya mengekspos port dengan opsi-p 8080:8080padadocker run.CMDCMD ["catalina.sh", "run"]menentukan perintah untuk memulai Tomcat saat kontainer dijalankan.
Untuk informasi selengkapnya tentang konstruksi Dockerfile, lihat referensi Dockerfile.