Lebih baik terlambat daripada tidak sama sekali. Atau bagaimana kami hampir membuat kesalahan serius, tidak memiliki dukungan Dockerfiles biasa untuk membangun gambar aplikasi.
Kami akan berbicara tentang
werf , sebuah utilitas GitOps yang terintegrasi dengan sistem CI / CD dan menyediakan kontrol atas seluruh siklus hidup aplikasi, memungkinkan Anda untuk:
- Kumpulkan dan publikasikan gambar
- Menyebarkan aplikasi di Kubernetes
- Hapus gambar yang tidak digunakan menggunakan kebijakan khusus.
Filosofi dari proyek ini adalah untuk merakit alat tingkat rendah ke dalam satu sistem terpadu yang memberi para insinyur DevOps kendali atas aplikasi. Jika memungkinkan, utilitas yang ada (seperti Helm dan Docker) harus dilibatkan. Jika tidak ada solusi untuk masalah, kami dapat membuat dan memelihara semua yang diperlukan untuk ini.
Latar Belakang: Kolektor Gambar Anda
Inilah yang terjadi dengan kolektor gambar di werf: kami tidak memiliki Dockerfile biasa. Jika Anda dengan cepat terjun ke dalam sejarah proyek, maka masalah ini memanifestasikan dirinya dalam versi pertama werf (kemudian masih
dikenal sebagai dapp ).
Membuat alat untuk membangun aplikasi dalam gambar Docker, kami segera menyadari bahwa Dockerfile tidak cocok untuk beberapa tugas yang sangat spesifik:
- Kebutuhan untuk membangun aplikasi web kecil yang khas sesuai dengan skema standar berikut:
- Instal dependensi aplikasi di seluruh sistem
- instal bundel pustaka dependensi aplikasi,
- mengumpulkan aset
- dan yang paling penting, perbarui kode dalam gambar dengan cepat dan efisien.
- Ketika perubahan dibuat untuk memproyeksikan file, pembangun harus dengan cepat membuat layer baru dengan menerapkan patch ke file yang dimodifikasi.
- Jika file tertentu telah berubah, maka perlu untuk membangun kembali tahap dependen yang sesuai.
Hari ini di pengumpul kami ada banyak kemungkinan lain, tetapi keinginan dan dorongan awal adalah mereka.
Secara umum, tanpa berpikir dua kali, kami mempersenjatai diri dengan bahasa pemrograman yang digunakan
(lihat di bawah) dan mulai bekerja - terapkan
DSL kami sendiri ! Sesuai dengan tugas, itu dimaksudkan untuk menggambarkan proses perakitan secara bertahap dan untuk menentukan dependensi dari tahapan ini pada file. Dan dilengkapi oleh
kolektornya sendiri , yang mengubah DSL menjadi tujuan akhir - gambar rakitan. Pada awalnya, DSL berada di Ruby, dan ketika kami
beralih ke Golang , konfigurasi kolektor kami mulai dijelaskan dalam file YAML.
Konfigurasi lama untuk dapp di Ruby
Konfigurasi saat ini untuk werf di YAMLMekanisme kolektor juga berubah seiring waktu. Pertama, kami hanya membuat Dockerfile sementara sementara dari konfigurasi kami dengan cepat, dan kemudian mulai menjalankan instruksi perakitan dalam wadah sementara dan membuat komit.
NB : Saat ini, kolektor kami, yang bekerja dengan konfigurasi (dalam YAML) dan disebut sebagai kolektor-Stapel, telah berkembang menjadi alat yang cukup kuat. Penjelasan terperincinya layak untuk artikel terpisah, dan detail utama dapat ditemukan dalam dokumentasi .Kesadaran masalah
Tetapi kami menyadari, dan tidak segera, bahwa kami melakukan satu kesalahan: kami tidak menambahkan kemampuan
untuk mengumpulkan gambar melalui Dockerfile standar dan mengintegrasikannya ke dalam infrastruktur yang sama untuk manajemen aplikasi terintegrasi (mis., Mengumpulkan gambar, menyebarkan dan membersihkannya). Bagaimana Anda bisa membuat alat penyebaran di Kubernetes dan tidak mengimplementasikan dukungan Dockerfile, mis. cara standar untuk menggambarkan gambar untuk sebagian besar proyek? ..
Alih-alih menjawab pertanyaan seperti itu, kami menawarkan solusi. Bagaimana jika Anda sudah memiliki Dockerfile (atau satu set Dockerfiles) dan ingin menggunakan werf?
NB : Ngomong-ngomong, mengapa Anda bahkan ingin menggunakan werf? Fitur utama adalah sebagai berikut:- siklus manajemen aplikasi lengkap termasuk pembersihan gambar;
- kemampuan untuk mengontrol perakitan beberapa gambar dari satu konfigurasi;
- Peningkatan proses penyebaran bagan Helm yang kompatibel.
Daftar yang lebih lengkap dapat ditemukan di halaman proyek .Jadi, jika sebelumnya kami menyarankan untuk menulis ulang Dockerfile ke konfigurasi kami, sekarang sekarang kami akan dengan senang mengatakan: "Biarkan kami membangun Dockerfile Anda!"
Bagaimana cara menggunakan
Implementasi penuh fitur ini muncul dalam
rilis werf v1.0.3-beta.1 . Prinsip umum sederhana: pengguna menentukan path ke Dockerfile yang ada di konfigurasi werf, dan kemudian menjalankan
werf build
...
werf build
dan hanya itu - werf akan mengumpulkan gambar. Pertimbangkan contoh abstrak.
Dockerfile
berikut di root proyek:
FROM ubuntu:18.04 RUN echo Building ...
Dan nyatakan
werf.yaml
yang menggunakan
Dockerfile
ini:
configVersion: 1 project: dockerfile-example --- image: ~ dockerfile: ./Dockerfile
Itu saja! Tetap
menjalankan werf build
:

Selain itu, Anda dapat mendeklarasikan
werf.yaml
berikut untuk membuat beberapa gambar dari Dockerfiles yang berbeda sekaligus:
configVersion: 1 project: dockerfile-example --- image: backend dockerfile: ./dockerfiles/Dockerfile-backend --- image: frontend dockerfile: ./dockerfiles/Dockerfile-frontend
Akhirnya, ia juga mendukung transfer parameter build tambahan - seperti
--build-arg
dan
--add-host
- melalui konfigurasi werf. Deskripsi lengkap tentang konfigurasi gambar Dockerfile tersedia di
halaman dokumentasi .
Bagaimana cara kerjanya?
Selama proses pembuatan, cache lapisan lokal standar dalam fungsi Docker. Namun, yang penting, werf juga
mengintegrasikan konfigurasi Dockerfile ke dalam infrastrukturnya . Apa artinya ini?
- Setiap gambar yang dikumpulkan dari Dockerfile terdiri dari satu tahap yang disebut
dockerfile
(lebih lanjut tentang tahap apa dalam werf, Anda dapat membaca di sini ). - Untuk tahap,
dockerfile
tidak menghitung tanda tangan, yang tergantung pada isi konfigurasi Dockerfile. Ketika konfigurasi Dockerfile diubah, tanda tangan tahap dockerfile
dan tidak memulai pembangunan kembali tahap ini dengan konfigurasi Dockerfile baru. Jika tanda tangan tidak berubah, maka werf mengambil gambar dari cache (detail lebih lanjut tentang penggunaan tanda tangan di werf dijelaskan dalam laporan ini ) . - Selanjutnya, gambar yang dikumpulkan dapat dipublikasikan
werf publish
(atau werf build-and-publish
) dan digunakan untuk penyebaran di Kubernetes. Gambar yang diterbitkan dalam Docker Registry akan dibersihkan dengan pembersih werf standar, yaitu itu akan secara otomatis membersihkan gambar lama (lebih tua dari N hari), gambar yang terkait dengan cabang Git yang tidak ada, dan kebijakan lainnya.
Anda dapat mempelajari lebih lanjut tentang poin-poin yang dijelaskan di sini dari dokumentasi:
Catatan dan Tindakan Pencegahan
1. URL eksternal di ADD tidak didukung
Menggunakan URL eksternal dalam arahan
ADD
saat ini tidak didukung. Werf tidak akan memulai pembangunan kembali ketika sumber daya berubah ke URL yang ditentukan. Segera direncanakan untuk menambahkan fitur ini.
2. Anda tidak dapat menambahkan .git ke gambar
Secara umum, menambahkan direktori
.git
ke gambar adalah praktik buruk yang
keji , dan inilah alasannya:
- Jika
.git
tetap di gambar akhir, ini melanggar prinsip-prinsip aplikasi 12 faktor : karena gambar akhir harus dikaitkan dengan satu komit, seharusnya tidak mungkin untuk melakukan git checkout
komit yang sewenang-wenang. .git
meningkatkan ukuran gambar (repositori mungkin besar karena fakta bahwa file-file besar pernah ditambahkan ke dalamnya dan kemudian dihapus). Ukuran pohon-kerja, yang hanya dikaitkan dengan komit tertentu, tidak akan bergantung pada riwayat operasi di Git. Pada saat yang sama, menambahkan dan kemudian menghapus .git
dari gambar terakhir tidak akan berfungsi: gambar masih akan mendapatkan lapisan tambahan - ini adalah cara kerja Docker.- Docker dapat memulai pembangunan kembali yang tidak perlu, bahkan jika komit yang sama sedang dibangun, tetapi dari pohon kerja yang berbeda. Misalnya, GitLab membuat direktori kloning terpisah di
/home/gitlab-runner/builds/HASH/[0-N]/yourproject
ketika perakitan paralel diaktifkan. Rekondisi tambahan akan disebabkan oleh fakta bahwa direktori .git
berbeda dalam versi kloning berbeda dari repositori yang sama, bahkan jika komit yang sama dikumpulkan.
Poin terakhir memiliki konsekuensi ketika menggunakan werf. Jika mengharuskan cache yang dikumpulkan hadir ketika perintah tertentu dijalankan (misalnya,
werf deploy
). Selama operasi perintah tersebut, werf menghitung tanda tangan panggung untuk gambar yang ditentukan dalam
werf.yaml
, dan mereka harus berada dalam cache rakitan - jika tidak tim tidak akan dapat terus bekerja. Jika tanda tangan tahap akan bergantung pada isi
.git
, maka kita mendapatkan cache yang tidak stabil untuk perubahan file yang tidak relevan, dan werf tidak akan dapat memaafkan pengawasan seperti itu (lihat
dokumentasi untuk lebih jelasnya)
Secara umum,
menambahkan hanya file-file tertentu yang diperlukan melalui instruksi
ADD
dalam hal apa pun meningkatkan efisiensi dan keandalan
Dockerfile
ditulis, dan juga meningkatkan stabilitas cache yang disusun oleh
Dockerfile
ini terhadap perubahan yang tidak relevan dalam Git.
Ringkasan
Cara awal kami menulis kompiler kami sendiri untuk kebutuhan tertentu adalah sulit, jujur ββdan langsung: daripada menggunakan kruk di atas Dockerfile standar, kami menulis solusi kami sendiri dengan sintaks khusus. Dan ini memberikan keuntungannya: pembangun-Stapel berupaya dengan tugasnya dengan sempurna.
Namun, dalam proses penulisan kolektor kami sendiri, kami mengabaikan dukungan Dockerfiles yang ada. Sekarang cacat ini telah diperbaiki, dan di masa depan kami berencana untuk mengembangkan dukungan Dockerfile bersama dengan kolektor Stapel kustom kami untuk perakitan terdistribusi dan untuk perakitan menggunakan Kubernet (mis. Perakitan pada pelari di dalam Kubernetes, seperti yang dilakukan di kaniko).
Jadi jika Anda tiba-tiba memiliki beberapa Dockerfiles tergeletak di sekitar ...
cobalah werf !
PS Daftar dokumentasi terkait
Baca juga di blog kami: β
werf adalah alat CI / CD kami di Kubernetes (laporan ulasan dan video) .β