Optimasi Docker untuk Production

Optimasi Docker untuk Production

Dalam lingkungan produksi, Docker memudahkan untuk membuat, menyebarkan, dan menjalankan aplikasi di dalam kontainer. Kontainer memungkinkan pengembang mengumpulkan aplikasi dan semua kebutuhan inti dan dependensinya menjadi satu paket yang dapat Anda ubah menjadi image Docker dan direplikasi. image Docker dibuat dari Dockerfiles. Dockerfile adalah file tempat Anda menentukan seperti apa image itu, sistem operasi dasar apa yang akan dimilikinya, dan perintah mana yang akan berjalan di dalamnya.

image Docker besar dapat memperpanjang waktu yang dibutuhkan untuk membangun dan mengirim image antara cluster dan penyedia cloud. Jika, misalnya, Anda memiliki image berukuran gigabyte untuk mendorong setiap kali salah satu pengembang Anda memicu membangun, throughput yang Anda buat di jaringan Anda akan bertambah selama proses CI / CD, membuat aplikasi Anda lamban dan akhirnya menghabiskan banyak sumber daya Anda . Karena itu, image Docker yang cocok untuk produksi seharusnya hanya memiliki kebutuhan telanjang yang diinstal.

Ada beberapa cara untuk mengurangi ukuran image Docker untuk dioptimalkan untuk produksi. Pertama, image-image ini biasanya tidak memerlukan alat bantu untuk menjalankan aplikasi mereka, jadi tidak perlu menambahkannya sama sekali. Dengan menggunakan proses pembuatan multi-tahap, Anda dapat menggunakan image perantara untuk mengkompilasi dan membangun kode, menginstal dependensi, dan mengemas semuanya ke dalam ukuran sekecil mungkin, lalu menyalin versi final aplikasi Anda ke image kosong tanpa alat build. Selain itu, Anda dapat menggunakan image dengan basis kecil, seperti Alpine Linux. Alpine adalah distribusi Linux yang cocok untuk produksi karena hanya memiliki kebutuhan telanjang yang harus dijalankan oleh aplikasi Anda.

Dalam tutorial ini, Anda akan mengoptimalkan image Docker dalam beberapa langkah sederhana, menjadikannya lebih kecil, lebih cepat, dan lebih cocok untuk produksi. Anda akan membuat image untuk API contoh Go di beberapa wadah Docker yang berbeda, mulai dengan Ubuntu dan image khusus bahasa, kemudian beralih ke distribusi Alpine. Anda juga akan menggunakan pembuatan multi-tahap untuk mengoptimalkan image Anda untuk produksi. Tujuan akhir dari tutorial ini adalah untuk menunjukkan perbedaan ukuran antara menggunakan image-image default Ubuntu dan rekan-rekan yang dioptimalkan, dan untuk menunjukkan keuntungan dari pembuatan multi-tahap. Setelah membaca tutorial ini, Anda akan dapat menerapkan teknik ini untuk proyek Anda sendiri dan jalur pipa CI / CD.

Langkah 1 - Mengunduh API Sample Go

Sebelum mengoptimalkan image Docker Anda, Anda harus terlebih dahulu mengunduh sampel API tempat Anda akan membuat image Docker. Menggunakan Go API sederhana akan memamerkan semua langkah kunci membangun dan menjalankan aplikasi di dalam wadah Docker. Tutorial ini menggunakan Go karena bahasa yang dikompilasi seperti C ++ atau Java, tetapi tidak seperti mereka, memiliki jejak yang sangat kecil.

Di server Anda, mulailah dengan mengkloning sampel Go API:

git clone https://github.com/do-community/mux-go-api.git

Setelah Anda mengkloning proyek, Anda akan memiliki direktori bernama mux-go-api di server Anda. Pindah ke direktori ini dengan cd:

cd mux-go-api

Ini akan menjadi direktori home untuk proyek Anda. Anda akan membangun image Docker Anda dari direktori ini. Di dalam, Anda akan menemukan kode sumber untuk API yang ditulis dalam Go di file api.go. Meskipun API ini minimal dan hanya memiliki beberapa titik akhir, itu akan sesuai untuk mensimulasikan API siap produksi untuk keperluan tutorial ini.

Sekarang Anda telah mengunduh contoh Go API, Anda siap membuat image dasar Docker Ubuntu, yang dapat dibandingkan dengan image Docker yang dioptimalkan kemudian.

Langkah 2 - Membangun Base Image Ubuntu

Untuk image Docker pertama Anda, akan berguna untuk melihat seperti apa tampilannya saat Anda memulai dengan image dasar Ubuntu. Ini akan mengemas API sampel Anda di lingkungan yang mirip dengan perangkat lunak yang sudah Anda jalankan di server Ubuntu Anda. Di dalam image, Anda akan menginstal berbagai paket dan modul yang Anda perlukan untuk menjalankan aplikasi Anda. Anda akan menemukan, bagaimanapun, bahwa proses ini menciptakan image Ubuntu yang agak berat yang akan memengaruhi waktu pembuatan dan pembacaan kode Dockerfile Anda.

Mulailah dengan menulis Dockerfile yang menginstruksikan Docker untuk membuat image Ubuntu, instal Go, dan jalankan contoh API. Pastikan untuk membuat Dockerfile di direktori repo hasil kloning. Jika Anda dikloning ke direktori home, itu harus $ HOME/mux-go-api.

Buat file baru bernama Dockerfile.ubuntu. Buka di nano atau editor teks favorit Anda:

FROM ubuntu:18.04

RUN apt-get update -y \
  && apt-get install -y git gcc make golang-1.10

ENV GOROOT /usr/lib/go-1.10
ENV PATH $GOROOT/bin:$PATH
ENV GOPATH /root/go
ENV APIPATH /root/go/src/api

WORKDIR $APIPATH
COPY . .

RUN \
  go get -d -v \
  && go install -v \
  && go build

EXPOSE 3000
CMD ["./api"]

Mulai dari atas, perintah FROM menentukan sistem operasi dasar mana yang akan dimiliki image. Kemudian perintah RUN menginstal bahasa Go selama pembuatan image. ENV menetapkan variabel lingkungan spesifik yang dibutuhkan kompilator Go untuk berfungsi dengan benar. WORKDIR menentukan direktori tempat kami ingin menyalin kode, dan perintah COPY mengambil kode dari direktori tempat Dockerfile.ubuntu berada dan menyalinnya ke dalam image. Perintah RUN terakhir menginstal dependensi Go yang diperlukan untuk kode sumber untuk mengkompilasi dan menjalankan API.

Simpan dan keluar dari file. Sekarang Anda dapat menjalankan perintah build untuk membuat image Docker dari Dockerfile yang baru saja Anda buat:

docker build -f Dockerfile.ubuntu -t ubuntu .

Perintah build membangun image dari Dockerfile. Bendera -f menentukan bahwa Anda ingin membangun dari file Dockerfile.ubuntu, sedangkan -t adalah singkatan dari tag, artinya Anda menandainya dengan nama ubuntu. Titik terakhir mewakili konteks saat ini di mana Dockerfile.ubuntu berada.

Ini akan memakan waktu cukup lama, jadi silakan istirahat. Setelah pembangunan selesai, Anda akan memiliki image Ubuntu yang siap untuk menjalankan API Anda. Tetapi ukuran akhir image mungkin tidak ideal; apa pun di atas beberapa ratus MB untuk API ini akan dianggap sebagai image yang terlalu besar.

Jalankan perintah berikut untuk mencantumkan semua image Docker dan temukan ukuran image Ubuntu Anda:

docker images

Anda akan melihat output yang menunjukkan image yang baru saja Anda buat:

# Output
REPOSITORY  TAG     IMAGE ID        CREATED         SIZE
ubuntu      latest  61b2096f6871    33 seconds ago  636MB
. . .

Seperti yang disorot dalam output, image ini memiliki ukuran 636MB untuk API Golang dasar, angka yang mungkin sedikit berbeda dari mesin ke mesin. Lebih dari beberapa build, ukuran besar ini akan secara signifikan mempengaruhi waktu penyebaran dan throughput jaringan.

Di bagian ini, Anda membuat image Ubuntu dengan semua alat Go dan dependensi yang diperlukan untuk menjalankan API yang Anda kloning pada Langkah 1. Di bagian berikutnya, Anda akan menggunakan image Docker khusus bahasa yang dibuat sebelumnya untuk menyederhanakan Dockerfile Anda dan merampingkan proses pembangunan.

Langkah 3 - Membangun image Dasar Bahasa-Khusus

image yang dibuat sebelumnya adalah image dasar biasa yang telah dimodifikasi pengguna untuk memasukkan alat khusus situasi. Pengguna kemudian dapat mendorong image-image ini ke repositori image Docker Hub, memungkinkan pengguna lain untuk menggunakan image yang dibagikan alih-alih harus menulis sendiri Dockerfiles mereka sendiri. Ini adalah proses umum dalam situasi produksi, dan Anda dapat menemukan berbagai image yang dibuat sebelumnya di Docker Hub untuk hampir semua kasus penggunaan. Pada langkah ini, Anda akan membuat sampel API Anda menggunakan image khusus Go yang sudah memiliki kompilator dan dependensi yang diinstal.

Dengan image dasar pra-dibangun sudah berisi alat yang Anda butuhkan untuk membangun dan menjalankan aplikasi Anda, Anda dapat mengurangi waktu pembuatan secara signifikan. Karena Anda mulai dengan basis yang memiliki semua alat yang diperlukan telah diinstal sebelumnya, Anda dapat melewati menambahkan ini ke Dockerfile Anda, membuatnya terlihat jauh lebih bersih dan akhirnya mengurangi waktu pembuatan.

Silakan dan buat Dockerfile lain dan beri nama Dockerfile.golang. Buka di editor teks Anda:

nano ~/mux-go-api/Dockerfile.golang

File ini akan jauh lebih ringkas daripada yang sebelumnya karena memiliki semua dependensi, alat, dan kompilator pra-instal Go.

Sekarang, tambahkan baris berikut:

FROM golang:1.10

WORKDIR /go/src/api
COPY . .

RUN \
    go get -d -v \
    && go install -v \
    && go build

EXPOSE 3000
CMD ["./api"]

Mulai dari atas, Anda akan menemukan bahwa pernyataan FROM sekarang adalah golang: 1.10. Ini berarti Docker akan mengambil image Go yang sudah dibuat sebelumnya dari Docker Hub yang sudah menginstal semua alat Go yang diperlukan.

Sekarang, sekali lagi, buat image Docker dengan:

docker build -f Dockerfile.golang -t golang .

Periksa ukuran akhir gambar dengan perintah berikut:

docker images

Ini akan menghasilkan output yang mirip dengan yang berikut:

# Output
REPOSITORY  TAG     IMAGE ID        CREATED         SIZE
golang      latest  eaee5f524da2    40 seconds ago  744MB
. . .

Langkah 4 — Bangun Base Alpine Images