Perbandingan Betul Kubernetes Guna, Ganti dan Tampal

Kubernetes mempunyai beberapa pilihan untuk mengemas kini sumber: gunakan, edit, tampal dan ganti. Terdapat kekeliruan tentang apa yang setiap orang lakukan dan bila untuk menggunakannya. Mari kita fikirkan.

Perbandingan Betul Kubernetes Guna, Ganti dan Tampal

Jika cari di Google frasa "kubernetes apply vs replace" terletak balas kepada StackOverflow, yang tidak betul. Apabila mencari "kubernetes apply vs patch" pautan pertama ialah dokumentasi untuk kubectl patch, yang tidak termasuk perbandingan apply ΠΈ patch. Artikel ini akan melihat pilihan yang berbeza, serta penggunaan yang betul bagi setiap satu.

Semasa kitaran hayat sumber Kubernetes (perkhidmatan, penggunaan, kemasukan, dll.), kadangkala anda perlu menukar, menambah atau mengalih keluar beberapa sifat sumber ini. Contohnya, tambah nota, tambah atau kurangkan bilangan replika.

Kubernetes CLI

Jika anda sudah bekerja dengan kluster Kubernetes melalui CLI, anda sudah biasa dengannya apply ΠΈ edit. Pasukan apply membaca spesifikasi sumber daripada fail dan membuat "upsert" kepada gugusan Kubernetes, i.e. mencipta sumber jika ia tidak wujud dan mengemas kininya jika ia wujud. Pasukan edit membaca sumber melalui API, kemudian menulis spesifikasi sumber ke fail setempat, yang kemudiannya dibuka dalam editor teks. Selepas anda mengedit dan menyimpan fail, kubectl akan menghantar semula perubahan yang dibuat melalui API, yang akan menggunakan perubahan ini dengan teliti pada sumber.

Tidak semua orang tahu arahan patch ΠΈ replace. Pasukan patch membolehkan anda menukar sebahagian daripada spesifikasi sumber, hanya menyediakan bahagian yang diubah pada baris arahan. Pasukan replace berfungsi sama seperti edit, tetapi semuanya perlu dilakukan secara manual: anda perlu memuat turun versi semasa spesifikasi sumber, contohnya, menggunakan kubectl get -o yaml, editnya, kemudian gunakan replace untuk mengemas kini sumber mengikut spesifikasi yang diubah. Pasukan replace tidak akan berfungsi jika sebarang perubahan berlaku antara membaca dan menggantikan sumber.

API Kubernetes

Anda mungkin sudah biasa dengan kaedahnya CoreV1().Pods().Update(), replaceNamespacedService atau patch_namespaced_deployment, jika anda bekerja dengan kelompok melalui perpustakaan pelanggan untuk API Kubernetes menggunakan beberapa bahasa pengaturcaraan. Perpustakaan mengendalikan kaedah ini melalui permintaan HTTP menggunakan kaedah PUT ΠΈ PATCH... Di mana update ΠΈ replace menggunakan PUTDan patch, tidak kira betapa remehnya ia mungkin, menggunakan PATCH.

Ia harus diperhatikan bahawa kubectl juga berfungsi dengan kluster melalui API. Dalam kata lain, kubectlialah pembalut di atas pustaka pelanggan untuk bahasa Go, yang sebahagian besarnya menyediakan keupayaan untuk menyediakan subperintah dalam bentuk yang lebih padat dan boleh dibaca sebagai tambahan kepada keupayaan API standard. Sebagai contoh, seperti yang anda mungkin telah perasan, kaedah apply tidak disebutkan di atas dalam perenggan sebelumnya. Pada masa ini (Mei 2020, lebih kurang penterjemah) semua logik kubectl apply, iaitu mencipta sumber yang tidak wujud dan mengemas kini yang sedia ada, berfungsi sepenuhnya pada bahagian kod kubectl. Usaha sedang dilakukan mengenai pemindahan logik apply ke bahagian API, tetapi ia masih dalam versi beta. Saya akan menulis dengan lebih terperinci di bawah.

Tampal secara lalai

Terbaik digunakan patch, jika anda ingin mengemas kini sumber. Beginilah cara kedua-dua perpustakaan pelanggan berfungsi di atas API Kubernetes dan kubectl (tidak menghairankan, kerana ia adalah pembungkus untuk perpustakaan pelanggan, lebih kurang penterjemah).

Bekerja secara strategik

Semua pasukan kubectl apply, edit ΠΈ patch gunakan kaedah PATCH dalam HTTP meminta untuk mengemas kini sumber sedia ada. Jika anda menyelidiki pelaksanaan arahan dengan lebih terperinci, maka kesemuanya menggunakan pendekatan tersebut tampalan gabungan strategik untuk mengemas kini sumber, walaupun arahan patch boleh menggunakan pendekatan lain (lebih lanjut mengenai ini di bawah). Pendekatan tampalan gabungan strategik cuba "membetulkannya" dengan menggabungkan spesifikasi yang dibekalkan dengan spesifikasi sedia ada. Lebih khusus lagi, ia cuba menggabungkan kedua-dua objek dan tatasusunan, yang bermaksud perubahan cenderung menjadi tambahan. Sebagai contoh, menjalankan arahan patch dengan pembolehubah persekitaran baharu dalam spesifikasi bekas pod, menyebabkan pembolehubah persekitaran itu ditambahkan pada pembolehubah persekitaran sedia ada dan bukannya menimpanya. Untuk mengalih keluar menggunakan pendekatan ini, anda mesti memaksa nilai parameter menjadi batal dalam spesifikasi yang disediakan. Mana satu pasukan kubectl Adakah yang terbaik untuk digunakan untuk mengemas kini?

Jika anda mencipta dan mengurus sumber anda menggunakan kubectl apply, apabila mengemas kini adalah lebih baik untuk sentiasa digunakan kubectl apply, kepada kubectl boleh mengurus konfigurasi dan menjejaki perubahan yang diminta dengan betul dari aplikasi ke aplikasi. Kelebihan selalu guna apply ialah ia menjejaki spesifikasi yang digunakan sebelum ini, membolehkannya mengetahui apabila sifat spesifikasi dan elemen tatasusunan dialih keluar secara eksplisit. Ini membolehkan anda menggunakan apply untuk mengalih keluar sifat dan elemen tatasusunan, manakala gabungan strategik biasa tidak akan berfungsi. Pasukan edit ΠΈ patch jangan kemas kini nota itu kubectl apply digunakan untuk menjejaki perubahannya, jadi sebarang perubahan yang dijejaki dan dibuat melalui API Kubernetes, tetapi dibuat melalui arahan edit ΠΈ patch, tidak dapat dilihat oleh arahan berikutnya applyIaitu, apply tidak mengeluarkannya walaupun ia tidak muncul dalam spesifikasi input untuk apply (Dokumentasi mengatakan bahawa edit ΠΈ patch membuat kemas kini kepada nota yang digunakan apply, tetapi dalam amalan - tidak).

Jika anda tidak menggunakan arahan apply, boleh digunakan sebagai editDan patch, memilih arahan yang paling sesuai dengan perubahan yang dibuat. Apabila menambah dan menukar sifat BOM, kedua-dua pendekatan adalah lebih kurang sama. Apabila memadam sifat spesifikasi atau elemen tatasusunan edit berkelakuan seperti pelancaran sekali sahaja apply, termasuk menjejaki keadaan spesifikasi sebelum dan selepas ia diedit, supaya anda boleh mengalih keluar sifat dan elemen tatasusunan secara eksplisit daripada sumber. Anda perlu menetapkan nilai harta secara eksplisit kepada null dalam spesifikasi untuk patchuntuk mengeluarkannya daripada sumber. Mengalih keluar elemen tatasusunan menggunakan tampalan gabungan strategik adalah lebih kompleks kerana ia memerlukan penggunaan arahan gabungan. Lihat pendekatan naik taraf lain di bawah untuk alternatif yang lebih berdaya maju.

Untuk melaksanakan kaedah kemas kini dalam pustaka klien yang berkelakuan serupa dengan arahan di atas kubectl, hendaklah ditetapkan dalam permintaan content-type Π² application/strategic-merge-patch+json. Jika anda ingin mengalih keluar sifat dalam spesifikasi, anda perlu menetapkan nilainya secara eksplisit kepada null dengan cara yang sama kubectl patch. Jika anda perlu mengalih keluar elemen tatasusunan, anda harus memasukkan arahan gabungan dalam spesifikasi kemas kini atau menggunakan pendekatan yang berbeza untuk kemas kini.

Pendekatan lain untuk kemas kini

Kubernetes menyokong dua pendekatan kemas kini lain: patch gabungan JSON ΠΈ Tampalan JSON. Pendekatan tampalan gabungan JSON mengambil spesifikasi Kubernetes separa sebagai input dan menyokong objek penggabungan serupa dengan pendekatan tampalan gabungan strategik. Perbezaan antara keduanya ialah ia hanya menyokong penggantian tatasusunan, termasuk tatasusunan kontena dalam spesifikasi pod. Ini bermakna apabila menggunakan tampung gabungan JSON, anda perlu menyediakan spesifikasi lengkap untuk semua bekas sekiranya sebarang sifat bagi sebarang bekas berubah. Jadi pendekatan ini berguna untuk mengalih keluar elemen daripada tatasusunan dalam BOM. Pada baris arahan anda boleh memilih tampung gabungan JSON menggunakan kubectl patch --type=merge. Apabila bekerja dengan API Kubernetes, anda harus menggunakan kaedah permintaan PATCH dan pemasangan content-type Π² application/merge-patch+json.

Pendekatan tampalan JSON, dan bukannya menyediakan spesifikasi separa sumber, menggunakan menyediakan perubahan yang anda ingin buat pada sumber sebagai tatasusunan, di mana setiap elemen tatasusunan mewakili perihalan perubahan yang dibuat pada sumber itu. Pendekatan ini ialah cara yang lebih fleksibel dan berkuasa untuk menyatakan perubahan yang dibuat, tetapi dengan kos penyenaraian perubahan yang dibuat dalam format yang berasingan, bukan Kubernetes, dan bukannya menghantar spesifikasi sumber separa. DALAM kubectl anda boleh memilih tampung JSON menggunakan kubectl patch --type=json. Apabila menggunakan API Kubernetes, pendekatan ini berfungsi menggunakan kaedah permintaan PATCH dan pemasangan content-type Π² application/json-patch+json.

Kami memerlukan keyakinan - gunakan ganti

Dalam sesetengah kes, anda perlu memastikan bahawa tiada perubahan dibuat pada sumber antara masa sumber itu dibaca dan apabila ia dikemas kini. Dalam erti kata lain, anda harus memastikan bahawa semua perubahan akan berlaku atom. Dalam kes ini, untuk mengemas kini sumber yang anda patut gunakan replace. Sebagai contoh, jika anda mempunyai ConfigMap dengan kaunter yang dikemas kini oleh berbilang sumber, anda harus memastikan bahawa dua sumber tidak mengemas kini kaunter pada masa yang sama, menyebabkan kemas kini hilang. Untuk menunjukkan, bayangkan urutan peristiwa menggunakan pendekatan patch:

  • A dan B mendapat keadaan semasa sumber daripada API
  • Setiap satu mengemas kini spesifikasi secara tempatan dengan menambah satu pembilang dan juga menambah "A" atau "B" masing-masing pada nota "dikemas kini oleh"
  • Dan ia mengemas kini sumber dengan lebih pantas sedikit
  • B mengemas kini sumber

Akibatnya, kemas kini A hilang. Operasi terakhir patch menang, pembilang ditambah dengan satu dan bukannya dua, dan nilai nota "dikemas kini oleh" berakhir dengan "B" dan tidak mengandungi "A". Mari bandingkan perkara di atas dengan perkara yang berlaku apabila kemas kini dilakukan menggunakan pendekatan replace:

  • A dan B mendapat keadaan semasa sumber daripada API
  • Setiap satu mengemas kini spesifikasi secara tempatan dengan menambah satu pembilang dan juga menambah "A" atau "B" masing-masing pada nota "dikemas kini oleh"
  • Dan ia mengemas kini sumber dengan lebih pantas sedikit
  • B cuba mengemas kini sumber, tetapi kemas kini ditolak oleh API kerana versi sumber adalah dalam spesifikasi replace tidak sepadan dengan versi semasa sumber dalam Kubernetes kerana versi sumber telah ditingkatkan oleh operasi ganti A.

Dalam kes di atas, B perlu mengambil semula sumber, membuat perubahan pada keadaan baharu dan cuba lagi replace. Ini akan menyebabkan kaunter ditambah dua dan nota "dikemas kini oleh" untuk memasukkan "AB" pada penghujungnya.

Contoh di atas menunjukkan bahawa apabila melaksanakan replace Keseluruhan sumber diganti sepenuhnya. Spesifikasi yang digunakan untuk replace, tidak boleh sebahagian, atau sebahagian seperti dalam apply, tetapi lengkap, termasuk penambahan resourceVersion ke dalam metadata spesifikasi. Jika anda belum mendayakan resourceVersion atau versi yang anda berikan bukan semasa, penggantian akan ditolak. Jadi pendekatan terbaik untuk digunakan ialah replace – baca sumber, kemas kini dan gantikannya dengan segera. menggunakan kubectl, mungkin kelihatan seperti ini:

$ kubectl get deployment my-deployment -o json 
    | jq '.spec.template.spec.containers[0].env[1].value = "new value"' 
    | kubectl replace -f -

Perlu diingat bahawa dua arahan berikut, dilaksanakan secara berurutan, akan dilaksanakan dengan jayanya, kerana deployment.yaml tidak mengandungi harta .metadata.resourceVersion

$ kubectl create -f deployment.yaml
$ kubectl replace -f deployment.yaml

Ini nampaknya bercanggah dengan apa yang dikatakan di atas, i.e. "tambah resourceVersion ke dalam metadata spesifikasi." Adakah salah untuk mengatakan itu? Tidak, tidak, kerana jika kubectl notis yang anda tidak nyatakan resourceVersion, ia akan membacanya daripada sumber dan menambahkannya pada spesifikasi yang anda tentukan, dan hanya kemudian melaksanakannya replace. Kerana ini berpotensi berbahaya jika anda bergantung pada atomicity, sihir berfungsi sepenuhnya di sisi kubectl, anda tidak seharusnya bergantung padanya apabila menggunakan perpustakaan klien yang berfungsi dengan API. Dalam kes ini, anda perlu membaca spesifikasi sumber semasa, kemas kini dan kemudian laksanakan PUT permintaan.

Anda tidak boleh melakukan tampalan - kami melakukan penggantian

Kadangkala anda perlu membuat beberapa perubahan yang tidak boleh dikendalikan oleh API. Dalam kes ini, anda boleh memaksa penggantian sumber dengan memadam dan menciptanya semula. Ini dilakukan menggunakan kubectl replace --force. Menjalankan arahan segera mengalih keluar sumber dan kemudian menciptanya semula daripada spesifikasi yang dibekalkan. Tiada pengendali "ganti paksa" dalam API, dan untuk berbuat demikian melalui API, anda perlu melakukan dua operasi. Mula-mula anda perlu memadamkan sumber dengan menetapkannya gracePeriodSeconds kepada sifar (0) dan propagationPolicy dalam "Latar Belakang" dan kemudian cipta semula sumber ini dengan spesifikasi yang diingini.

Amaran: Pendekatan ini berpotensi berbahaya dan boleh membawa kepada keadaan yang tidak ditentukan.

Sapukan pada bahagian pelayan

Seperti yang dinyatakan di atas, pembangun Kubernetes sedang berusaha untuk melaksanakan logik apply daripada kubectl dalam API Kubernetes. Logik apply tersedia dalam Kubernetes 1.18 melalui kubectl apply --server-side atau melalui API menggunakan kaedah PATCH с content-type application/apply-patch+YAML.

Nota: JSON juga adalah YAML yang sah, jadi anda boleh menghantar spesifikasi sebagai JSON walaupun jika content-type akan application/apply-patch+yaml.

Selain logik itu kubectl tersedia kepada semua orang melalui API, apply di bahagian pelayan, menjejaki siapa yang bertanggungjawab ke atas medan dalam spesifikasi, sekali gus membenarkan akses berbilang selamat untuk penyuntingan bebas konfliknya. Dengan kata lain, jika apply pada bahagian pelayan akan menjadi lebih meluas, antara muka pengurusan sumber selamat universal akan muncul untuk pelanggan yang berbeza, contohnya, kubectl, Pulumi atau Terraform, GitOps, serta skrip tulisan sendiri menggunakan perpustakaan klien.

Keputusan

Saya harap gambaran ringkas tentang cara yang berbeza untuk mengemas kini sumber dalam kluster ini berguna kepada anda. Adalah baik untuk mengetahui bahawa ia bukan hanya digunakan berbanding ganti; ia mungkin untuk mengemas kini sumber menggunakan gunakan, edit, tampal atau ganti. Lagipun, pada dasarnya, setiap pendekatan mempunyai kawasan aplikasinya sendiri. Untuk perubahan atom, ganti adalah lebih baik; jika tidak, anda harus menggunakan tampung gabungan strategik melalui aplikasi. Sekurang-kurangnya, saya mengharapkan anda memahami bahawa anda tidak boleh mempercayai Google atau StackOerflow apabila mencari "kubernetes apply vs replace". Sekurang-kurangnya sehingga artikel ini menggantikan jawapan semasa.

Perbandingan Betul Kubernetes Guna, Ganti dan Tampal

Sumber: www.habr.com

Tambah komen