Sesuatu terjadi yang kami (dan bukan hanya kami) telah menunggu:
werf , utilitas Open Source kami untuk membangun aplikasi dan mengirimkannya ke Kubernetes, sekarang mendukung penerapan perubahan menggunakan tambalan penggabungan 3 arah! Selain itu, dimungkinkan untuk mengadopsi sumber daya K8 yang ada ke dalam rilis Helm tanpa menciptakan kembali sumber daya ini.

Jika ini sangat singkat, maka atur
WERF_THREE_WAY_MERGE=enabled
- kami mendapatkan penyebaran "seperti di
kubectl apply
", kompatibel dengan instalasi yang ada di Helm 2 dan bahkan sedikit lagi.
Tapi mari kita mulai dengan teorinya: apa patch 3-way-merge secara umum, bagaimana orang-orang sampai pada pendekatan dengan generasi mereka, dan mengapa mereka penting dalam proses CI / CD dengan infrastruktur berbasis Kubernet? Dan setelah itu - mari kita lihat apakah penggabungan 3-arah dalam werf itu, mode apa yang digunakan secara default dan bagaimana cara mengelolanya.
Apa itu tambalan 3 arah?
Jadi, mari kita mulai dengan tugas meluncurkan sumber daya yang dijelaskan dalam manifes YAML di Kubernetes.
Untuk bekerja dengan sumber daya, API Kubernetes menawarkan operasi dasar berikut: membuat, menambal, mengganti, dan menghapus. Diasumsikan bahwa dengan bantuan mereka perlu untuk membangun peluncuran sumber daya yang berkesinambungan untuk cluster. Bagaimana?
Tim kubectl yang imperatif
Pendekatan pertama untuk mengelola objek di Kubernetes adalah menggunakan perintah kubectl imperatif untuk membuat, memodifikasi, dan menghapus objek-objek ini. Sederhananya:
Pandangan seperti itu mungkin tampak nyaman pada pandangan pertama. Namun, ada masalah:
- Sulit untuk diotomatisasi .
- Bagaimana cara mencerminkan konfigurasi di Git? Bagaimana cara meninjau perubahan yang terjadi pada sebuah cluster?
- Bagaimana memastikan reproduksibilitas konfigurasi saat restart?
- ...
Jelas bahwa pendekatan ini tidak cocok dengan menyimpan kode aplikasi dan infrastruktur sebagai kode (IaC; atau bahkan
GitOps sebagai opsi yang lebih modern, mendapatkan popularitas di ekosistem Kubernetes). Karenanya, tim-tim ini tidak menerima pengembangan lebih lanjut di kubectl.
Buat, dapatkan, ganti, dan hapus operasi
Dengan
kreasi utama
, semuanya sederhana: kami mengirim manifes ke operasi
create
api kubus dan sumber daya dibuat. Representasi YAML dari manifes dapat disimpan di Git, dan untuk membuat, gunakan perintah
kubectl create -f manifest.yaml
.
Menghapus juga sederhana: kita mengganti
manifest.yaml
sama dari Git ke perintah
kubectl delete -f manifest.yaml
.
Operasi
replace
memungkinkan Anda untuk sepenuhnya mengganti konfigurasi sumber daya dengan yang baru, tanpa membuat ulang sumber daya. Ini berarti bahwa sebelum membuat perubahan ke sumber daya, logis untuk meminta versi saat ini dengan operasi
get
, ubah, dan perbarui dengan operasi
replace
. Penguncian optimis dibangun ke dalam apiserver kubus, dan jika objek telah berubah setelah
get
operasi, operasi
replace
akan gagal.
Untuk menyimpan konfigurasi di Git dan memperbarui menggunakan penggantian, Anda harus melakukan operasi
get
, tahan konfigurasi dari Git dengan apa yang kami dapatkan, dan lakukan
replace
. Biasanya, kubectl hanya memungkinkan Anda untuk menggunakan perintah
kubectl replace -f manifest.yaml
, di mana
manifest.yaml
adalah
manifest.yaml
yang disiapkan sepenuhnya (dalam kasus kami, disatukan) yang perlu diinstal. Ternyata pengguna perlu menerapkan manifes gabungan, tetapi ini bukan masalah sepele ...
Perlu dicatat bahwa walaupun
manifest.yaml
disimpan di Git, kita tidak dapat mengetahui sebelumnya apakah kita perlu membuat objek atau memperbaruinya - ini harus dilakukan oleh perangkat lunak pengguna.
Intinya:
dapatkah kita membangun peluncuran berkelanjutan hanya dengan membuat, mengganti, dan menghapus, memastikan bahwa konfigurasi infrastruktur disimpan di Git bersama dengan kode dan CI / CD yang nyaman?
Pada dasarnya, kita dapat ... Untuk melakukan ini, kita
perlu mengimplementasikan operasi gabungan manifes dan semacam ikatan yang:
- memeriksa keberadaan objek di kluster,
- melakukan penciptaan awal sumber daya,
- memperbarui atau menghapusnya.
Saat memperbarui, Anda perlu mempertimbangkan bahwa
sumber daya mungkin telah berubah sejak yang terakhir
get
dan secara otomatis menangani kasus penguncian yang optimis - lakukan upaya berulang untuk memperbarui.
Namun, mengapa menciptakan kembali roda ketika kube-apiserver menawarkan cara lain untuk memperbarui sumber daya: operasi
patch
, yang menghilangkan beberapa masalah yang dijelaskan dari pengguna?
Tambalan
Jadi kami sampai di tambalan.
Patch adalah cara utama untuk menerapkan perubahan pada objek yang ada di Kubernetes. Operasi
patch
berfungsi agar:
- pengguna kube-apiserver perlu mengirim patch dalam format JSON dan menentukan objek,
- dan apiserver itu sendiri akan menangani keadaan objek saat ini dan membawanya ke bentuk yang diinginkan.
Penguncian optimis dalam hal ini tidak diperlukan. Operasi ini lebih deklaratif dibandingkan dengan penggantian, meskipun pada awalnya mungkin tampak sebaliknya.
Dengan cara ini:
- menggunakan operasi
create
, kita membuat objek dari manifes dari Git, - menggunakan
delete
- hapus jika objek tidak lagi diperlukan, - menggunakan
patch
- kita memodifikasi objek, membawanya ke bentuk yang dijelaskan dalam Git.
Namun, untuk melakukan ini, Anda harus membuat
tambalan yang benar !
Bagaimana tambalan bekerja di Helm 2: 2-way-merge
Pertama kali rilis diinstal, Helm melakukan operasi
create
pada sumber daya grafik.
Saat memperbarui rilis Helm untuk setiap sumber daya:
- menghitung tambalan antara versi sumber daya dari bagan sebelumnya dan versi bagan saat ini,
- terapkan tambalan ini.
Kami akan menyebutnya patch
2-way-merge patch , karena 2 manifesto berpartisipasi dalam pembuatannya:
- Manifes sumber daya dari rilis sebelumnya,
- Manifes sumber daya dari sumber daya saat ini.
Saat menghapus, operasi
delete
dalam apiserver kubus dipanggil untuk sumber daya yang dideklarasikan dalam rilis sebelumnya tetapi tidak dideklarasikan dalam yang sekarang.
Pendekatan dengan 2 cara menggabungkan tambalan memiliki masalah: itu mengarah ke
desync keadaan sebenarnya dari sumber daya di cluster dan manifes di Git .
Contoh masalah
- Di Git, manifes disimpan pada bagan tempat bidang
image
Penerapan memiliki nilai ubuntu:18.04
. - Pengguna melalui
kubectl edit
mengubah nilai bidang ini ke ubuntu:19.04
. - Saat Anda menggunakan kembali bagan, Helm tidak menghasilkan tambalan , karena bidang
image
di versi rilis sebelumnya dan di bagan saat ini adalah sama. - Setelah penyebaran
image
berulang, ubuntu:19.04
tetap, meskipun ubuntu:18.04
ditulis pada bagan.
Kami mendapatkan desync dan kehilangan declarativeness.
Apa itu sumber daya yang disinkronkan?
Secara umum, tidak mungkin untuk mendapatkan kecocokan
lengkap antara manifes sumber daya dalam menjalankan cluster dan manifes dari Git. Karena dalam manifes nyata mungkin ada anotasi layanan / label, wadah tambahan dan data lainnya ditambahkan dan dihapus secara dinamis oleh beberapa pengontrol dari sumber daya. Kami tidak bisa dan tidak ingin menyimpan data ini di Git. Namun, kami ingin saat meluncurkan, bidang yang kami tentukan secara eksplisit di Git mengambil nilai yang sesuai.
Ternyata ini
aturan umum
dari sumber daya yang disinkronkan : ketika Anda meluncurkan sumber daya, Anda dapat mengubah atau menghapus hanya bidang-bidang yang secara eksplisit ditentukan dalam manifes dari Git (atau terdaftar di versi sebelumnya, tetapi sekarang dihapus).
Patch 3-arah-gabung
Gagasan utama
tambalan penggabungan 3-arah : kami membuat tambalan antara versi terapan terakhir manifes dari Git dan versi target manifes dari Git, dengan mempertimbangkan versi manifes saat ini dari gugus kerja. Tambalan terakhir harus mematuhi aturan sumber daya yang disinkronkan:
- bidang baru yang ditambahkan ke versi target ditambahkan menggunakan tambalan;
- bidang yang sebelumnya ada dalam versi terakhir yang diterapkan dan tidak ada di bidang target diatur ulang menggunakan tambalan;
- Bidang dalam versi objek saat ini yang berbeda dari versi target manifes diperbarui menggunakan tambalan.
Dengan prinsip inilah
kubectl apply
tambalan dihasilkan:
- versi terapan yang terakhir dari manifes disimpan dalam anotasi objek itu sendiri,
- target - diambil dari file YAML yang ditentukan,
- saat ini - dari cluster yang berfungsi.
Sekarang setelah kami memahami teorinya, saatnya untuk memberi tahu Anda apa yang kami lakukan di werf.
Terapkan perubahan ke werf
Sebelumnya, werf, seperti Helm 2, menggunakan patch 2-way-merge.
Perbaikan tambalan
Untuk beralih ke jenis tambalan baru - 3-way-merge - langkah pertama kami memperkenalkan
tambalan perbaikan yang disebut.
Saat digunakan, tambalan penggabungan 2 arah standar digunakan, tetapi tidak juga menghasilkan tambalan yang menyinkronkan keadaan sebenarnya dari sumber daya dengan apa yang ditulis dalam Git (tambalan semacam itu dibuat menggunakan aturan sumber daya tersinkronisasi yang sama seperti dijelaskan di atas).
Dalam hal rassynchrony, pada akhir penyebaran, pengguna menerima PERINGATAN dengan pesan dan tambalan yang sesuai, yang harus diterapkan untuk membawa sumber daya ke formulir yang disinkronkan. Juga, tambalan ini dicatat dalam
werf.io/repair-patch
anotasi khusus. Diasumsikan bahwa pengguna
sendiri akan menerapkan tambalan ini dengan tangannya: werf pada prinsipnya tidak akan menerapkannya.
Membuat tambalan perbaikan adalah tindakan sementara yang memungkinkan Anda untuk benar-benar menguji pembuatan tambalan pada prinsip penggabungan 3 arah, tetapi tidak secara otomatis menerapkan tambalan ini. Saat ini, mode operasi ini diaktifkan secara default.
Patch 3-arah-gabung hanya untuk rilis baru
Mulai 1 Desember 2019, versi beta dan alfa dari werf mulai
secara default untuk menggunakan patch 3-way-merge penuh untuk menerapkan perubahan hanya untuk rilis Helm baru yang diluncurkan melalui werf. Rilis yang ada akan terus menggunakan pendekatan perbaikan patch 2-arah-gabung +.
Anda dapat mengaktifkan mode operasi ini secara eksplisit dengan mengatur
WERF_THREE_WAY_MERGE_MODE=onlyNewReleases
sekarang.
Catatan : fitur muncul di werf lebih dari beberapa rilis: di saluran alpha menjadi siap dari versi v1.0.5-alpha.19 , dan di saluran beta dengan v1.0.4-beta.20 .Patch 3-arah-gabung untuk semua rilis
Mulai 15 Desember 2019, versi beta dan alfa dari werf mulai menggunakan tambalan penggabungan 3-arah sepenuhnya secara default untuk menerapkan perubahan untuk semua rilis.
Mode operasi ini dapat
WERF_THREE_WAY_MERGE_MODE=enabled
secara eksplisit
WERF_THREE_WAY_MERGE_MODE=enabled
menetapkan
WERF_THREE_WAY_MERGE_MODE=enabled
sekarang.
Apa yang harus dilakukan dengan sumber daya autoscaling?
Kubernetes memiliki 2 jenis autoscaling: HPA (horizontal) dan VPA (vertikal).
Horisontal otomatis memilih jumlah replika, vertikal - jumlah sumber daya. Baik jumlah replika dan persyaratan sumber daya ditentukan dalam manifes sumber daya (lihat
spec.replicas
atau
spec.containers[].resources.limits.cpu
,
spec.containers[].resources.limits.memory
dan
lainnya ).
Masalah: jika pengguna mengkonfigurasi sumber daya pada bagan sehingga menampilkan nilai spesifik untuk sumber daya atau replika dan auto-scaler diaktifkan untuk sumber daya ini, maka dengan setiap penerapan werf akan mereset nilai-nilai ini ke apa yang tertulis dalam manifes grafik.
Ada dua solusi untuk masalah ini. Sebagai permulaan, yang terbaik adalah membuang nilai autoscale yang ditentukan secara eksplisit dalam manifes grafik. Jika karena alasan tertentu opsi ini tidak cocok (misalnya, karena nyaman untuk menetapkan batas sumber daya awal dan jumlah replika pada grafik), maka werf menawarkan anotasi berikut:
werf.io/set-replicas-only-on-creation=true
werf.io/set-resources-only-on-creation=true
Jika anotasi semacam itu ada, werf tidak akan mereset nilai yang sesuai pada setiap penyebaran, tetapi hanya menetapkannya pada awal pembuatan sumber daya.
Untuk informasi lebih lanjut, lihat dokumentasi proyek untuk
HPA dan
VPA .
Tolak penggunaan patch 3-way-merge
Pengguna masih dapat melarang penggunaan tambalan baru di werf menggunakan variabel lingkungan
WERF_THREE_WAY_MERGE_MODE=disabled
. Namun, mulai
1 Maret 2020, larangan ini akan berhenti berfungsi dan hanya akan mungkin menggunakan tambalan penggabungan 3 arah.
Adopsi sumber daya di werf
Menguasai metode menerapkan perubahan dalam 3-way-merge-patch memungkinkan kami untuk segera mengimplementasikan fitur seperti adopsi sumber daya yang ada di cluster dalam rilis Helm.
Helm 2 memiliki masalah: Anda tidak dapat menambahkan ke manifes bagan sumber daya yang sudah ada di cluster tanpa membuat ulang sumber ini dari awal (lihat
# 6031 ,
# 3275 ). Kami mengajar werf untuk menerima sumber daya yang ada dalam rilis. Untuk melakukan ini, Anda perlu menetapkan anotasi pada versi sumber daya saat ini dari sebuah cluster yang berjalan (misalnya, menggunakan
kubectl edit
):
"werf.io/allow-adoption-by-release": RELEASE_NAME
Sekarang sumber daya perlu dijelaskan pada bagan dan pada penyebaran berikutnya oleh rilis werf dari rilis dengan nama yang sesuai, sumber daya yang ada akan diterima ke dalam rilis ini dan akan tetap di bawah kendali. Selain itu, dalam proses menerima sumber daya untuk dirilis, werf akan membawa status sumber daya saat ini dari kelompok kerja ke negara yang dijelaskan pada bagan menggunakan tambalan penggabungan 3 arah yang sama dan aturan sumber daya yang disinkronkan.
Catatan : pengaturan WERF_THREE_WAY_MERGE_MODE
tidak memengaruhi adopsi sumber daya - dalam hal adopsi, patch gabungan 3 arah selalu digunakan.Detailnya ada di
dokumentasi .
Kesimpulan dan Rencana Masa Depan
Saya berharap bahwa setelah artikel ini menjadi lebih jelas apa patch 3-way-merge dan mengapa mereka datang kepada mereka. Dari sudut pandang praktis pengembangan proyek werf, implementasi mereka adalah langkah lain menuju peningkatan penyebaran Helm-seperti. Sekarang Anda dapat melupakan masalah dengan sinkronisasi konfigurasi, yang sering terjadi ketika menggunakan Helm 2. Pada saat yang sama, fitur baru yang bermanfaat dari adopsi sumber daya Kubernet yang sudah diunggah ke rilis Helm telah ditambahkan.
Masih ada beberapa masalah dan kesulitan dalam penerapan seperti Helm, seperti penggunaan templat-Go, dan kami akan terus menyelesaikannya.
Informasi tentang metode pembaruan sumber daya dan adopsi juga dapat ditemukan di
halaman dokumentasi ini .
Helm 3
Catatan khusus layak untuk versi utama Helm yang baru dirilis baru-baru ini - v3 - yang juga menggunakan tambalan penggabungan 3 arah dan menyingkirkan Tiller. Versi baru Helm memerlukan
migrasi instalasi yang ada untuk mengubahnya menjadi format penyimpanan rilis baru.
Werf, pada bagiannya, sekarang telah menghilangkan penggunaan Tiller, beralih ke penggabungan 3-arah dan menambahkan
lebih banyak , sambil tetap kompatibel dengan instalasi yang ada di Helm 2 (tidak ada skrip migrasi yang diperlukan). Oleh karena itu, sampai werf beralih ke Helm 3, pengguna werf tidak kehilangan keunggulan utama Helm 3 dibandingkan Helm 2 (mereka juga ada di werf).
Namun, beralih werf ke basis kode Helm 3 tidak bisa dihindari dan akan terjadi dalam waktu dekat. Agaknya itu bukan werf 1.1 atau werf 1.2 (saat ini, versi utama werf adalah 1.0; untuk rincian lebih lanjut tentang perangkat versi werf lihat di
sini ). Selama waktu ini, Helm 3 akan memiliki waktu untuk stabil.
PS
Baca juga di blog kami: