Seperti solusi lainnya, Helm - manajer paket untuk Kubernetes - memiliki pro, kontra, dan cakupan, jadi ketika menggunakannya, Anda harus mengevaluasi harapan Anda dengan benar ...
Kami menggunakan Helm di gudang alat bergulir kontinu. Pada saat penulisan, ada
lebih dari seribu aplikasi dalam kelompok kami dan sekitar 4000 instalasi aplikasi ini dalam berbagai variasi. Secara berkala kami mengalami masalah, tetapi secara umum kami puas dengan solusinya, kami tidak memiliki downtime dan kehilangan data.
Motif utama untuk menulis artikel ini adalah untuk memberikan
penilaian obyektif terhadap masalah utama Helm 2 kepada pengguna tanpa kesimpulan pasti, serta keinginan untuk berbagi pengalaman dan solusi kami.
[BUG] Setelah diluncurkan, status sumber daya rilis di cluster tidak sesuai dengan bagan Helm yang dijelaskan
Saat bekerja, Helm tidak memperhitungkan status sumber daya rilis di cluster. Saat menginstal ulang, hasilnya hanya ditentukan oleh konfigurasi saat ini dan yang disimpan. Dengan demikian, keadaan sumber daya di cluster dan registri Helm berbeda, dan Helm tidak memperhitungkannya.
Pertimbangkan bagaimana masalah ini memanifestasikan dirinya:
- Templat sumber daya pada bagan sesuai dengan negara X.
- Pengguna menginstal grafik (Tiller menyimpan status sumber daya X).
- Selanjutnya, pengguna secara manual mengubah sumber daya dalam klaster (status berubah dari X ke Y).
- Tanpa membuat perubahan, itu melakukan
helm upgrade
... Dan sumber daya masih dalam kondisi Y, meskipun pengguna mengharapkan X.
Dan itu belum semuanya. Pada titik tertentu, pengguna mengubah templat sumber daya pada bagan (status W baru) - maka kami memiliki dua skenario setelah
helm upgrade
:
- Aplikasi patch XW sedang jatuh.
- Setelah menerapkan tambalan, sumber daya masuk ke status Z, yang tidak sesuai dengan yang diinginkan.
Untuk menghindari masalah seperti itu, diusulkan untuk mengatur pekerjaan dengan rilis sebagai berikut:
tidak ada yang harus mengubah sumber daya secara manual , Helm adalah satu-satunya alat untuk bekerja dengan sumber daya rilis. Idealnya, perubahan grafik diversi dalam repositori Git dan diterapkan
secara eksklusif dalam CD.
Jika opsi ini tidak cocok, maka Anda dapat
memantau sinkronisasi status sumber daya rilis. Sinkronisasi manual mungkin terlihat seperti ini:
- Kami mencari tahu status sumber daya rilis melalui
helm get
. - Cari tahu status sumber daya di Kubernetes via
kubectl get
. - Jika sumber dayanya berbeda, maka kami menyinkronkan Helm dengan Kubernetes:
- Buat cabang terpisah.
- Memperbarui manifes grafik. Template harus cocok dengan status sumber daya di Kubernetes.
- Kami melakukan penyebaran. Kami menyinkronkan status dalam registri dan klaster Helm.
- Setelah itu, cabang dapat dihapus dan melanjutkan pekerjaan rutin.
Saat menerapkan tambalan menggunakan
kubectl apply
, apa yang disebut
penggabungan 3-arah dieksekusi, mis. keadaan sebenarnya dari sumber daya yang diperbarui diperhitungkan. Anda dapat melihat kode algoritme di
sini , dan membacanya di
sini .
Pada saat penulisan, pengembang Helm sedang mencari cara untuk menerapkan 3-cara-penggabungan di Helm 3. Dengan Helm 2, hal-hal tidak begitu cerah: penggabungan 3 arah tidak direncanakan untuk diterapkan, tetapi ada PR untuk memperbaiki cara sumber daya dibuat - Anda dapat mengetahui detail atau bahkan berpartisipasi sebagai bagian dari
masalah yang relevan .
[BUG] Kesalahan: tidak ada SUMBER DAYA dengan nama NAMA ditemukan
Masalahnya memanifestasikan dirinya jika
sumber daya baru berhasil dibuat ketika peluncuran diulang, dan peluncuran itu sendiri akhirnya gagal.
Sumber daya baru berarti
sumber daya yang tidak ada dalam pemasangan bagan terakhir.
Jika peluncuran gagal, rilis disimpan dalam registri bertanda
GAGAL , dan selama instalasi Helm bergantung pada keadaan rilis
DEPLOYED terbaru, yang dalam hal ini tidak tahu apa-apa tentang sumber daya baru. Akibatnya, Helm mencoba menciptakan kembali sumber daya ini dan gagal dengan kesalahan "tidak ada SUMBER DAYA dengan nama yang ditemukan NAME" (kesalahan mengatakan sebaliknya, tetapi ini masalahnya). Bagian dari masalahnya adalah bahwa Helm tidak memperhitungkan status sumber daya rilis di cluster saat membuat patch, seperti yang dijelaskan di bagian sebelumnya.
Untuk saat ini, satu-satunya solusi adalah menghapus sumber daya baru secara manual.
Untuk menghindari keadaan seperti itu, dimungkinkan untuk secara otomatis menghapus sumber daya baru yang dibuat dalam pemutakhiran / kembalikan saat ini jika perintah akhirnya gagal. Setelah diskusi panjang dengan pengembang di Helm, untuk perintah upgrade / rollback, opsi
--cleanup-on-fail
ditambahkan, yang mengaktifkan pembersihan otomatis ketika peluncuran gagal.
PR kami sedang dalam diskusi, mencari solusi terbaik.
Dimulai dengan Helm versi 2.13, opsi
--atomic
muncul di perintah
helm install/upgrade
, yang mengaktifkan pembersihan dan kembalikan selama instalasi gagal (untuk lebih jelasnya, lihat
PR ).
[BUG] Kesalahan: menonton ditutup sebelum Hingga batas waktu habis
Masalahnya dapat terjadi ketika kait Helm dieksekusi terlalu lama (misalnya, selama migrasi) - meskipun batas waktu
helm install/upgrade
ditentukan dan
spec.activeDeadlineSeconds
Pekerjaan yang sesuai tidak dilampaui.
Kesalahan ini dihasilkan oleh server API Kubernetes sambil menunggu pekerjaan hook selesai. Helm tidak menangani kesalahan ini dan langsung macet - alih-alih mencoba kembali permintaan tunggu.
Sebagai solusi, Anda dapat meningkatkan batas waktu di api-server:
--min-request-timeout=xxx
dalam file
/etc/kubernetes/manifests/kube-apiserver.yaml
.
[BUG] Kesalahan: UPGRADE GAGAL: “foo” tidak memiliki rilis yang digunakan
Jika rilis pertama melalui
helm install
gagal,
helm upgrade
berikutnya akan menghasilkan kesalahan yang sama.
Tampaknya solusinya cukup sederhana: Anda harus secara manual melakukan
helm delete --purge
setelah instalasi pertama gagal, tetapi tindakan manual ini merusak otomatisasi CI / CD. Agar tidak mengganggu pelaksanaan perintah manual, Anda dapat menggunakan fitur
werf untuk menjalankan. Saat menggunakan werf, rilis yang bermasalah akan secara otomatis diciptakan kembali setelah instalasi ulang.
Selain itu, dimulai dengan versi Helm 2.13, di perintah
helm install
dan
helm upgrade --install
instalasi
helm upgrade --install
cukup tentukan opsi
--atomic
dan setelah instalasi yang gagal rilis akan secara otomatis dihapus (lihat
PR untuk rinciannya).
Autorollback
Helm tidak memiliki opsi
--autorollback
, yang, ketika
--autorollback
, akan mengingat revisi yang berhasil saat ini (akan turun jika revisi terakhir tidak berhasil) dan, setelah upaya penyebaran yang tidak berhasil, akan mundur ke revisi yang disimpan.
Karena sangat penting bagi produk untuk bekerja tanpa gangguan, maka perlu dicari solusinya, peluncuran harus dapat diprediksi. Untuk meminimalkan kemungkinan downtime produk,
pendekatan dengan beberapa kontur (misalnya, staging, qa, dan produksi) sering digunakan, yang terdiri dari peluncuran berurutan ke kontur. Dengan pendekatan ini, sebagian besar masalah diperbaiki sebelum diluncurkan ke yang produktif dan bersamaan dengan autorolback memungkinkan Anda untuk mencapai hasil yang baik.
Untuk mengatur autorollback, Anda dapat menggunakan plugin
helm-monitor , yang memungkinkan Anda untuk mengikat rollback ke metrik dari Prometheus. Artikel bagus yang menggambarkan pendekatan ini tersedia di
sini .
Untuk beberapa proyek kami, pendekatan yang cukup sederhana digunakan:
- Sebelum penyebaran, kami mengingat revisi saat ini (kami percaya bahwa dalam situasi normal, jika rilis ada, maka itu harus dalam keadaan TERGANTUNG):
export _RELEASE_NAME=myrelease export _LAST_DEPLOYED_RELEASE=$(helm list -adr | \ grep $_RELEASE_NAME | grep DEPLOYED | head -n2 | awk '{print $2}')
- Jalankan instal atau tingkatkan:
helm install/upgrade ... || export _DEPLOY_FAILED=1
- Kami memeriksa status penggunaan dan melakukan rollback ke status tersimpan:
if [ "$_DEPLOY_FAILED" == "1" ] && [ "x$_LAST_DEPLOYED_RELEASE" != "x" ] ; then helm rollback $_RELEASE_NAME $_LAST_DEPLOYED_RELEASE fi
- Kami mengakhiri pipa dengan kesalahan jika penyebaran tidak berhasil:
if [ "$_DEPLOY_FAILED" == "1" ] ; then exit 1 ; fi
Sekali lagi, dimulai dengan Helm versi 2.13, saat memanggil
helm upgrade
cukup untuk menentukan opsi
--atomic
dan setelah kegagalan instalasi rollback akan dilakukan secara otomatis (lihat
PR untuk detailnya).
Menunggu ketersediaan sumber daya rilis dan umpan balik pada saat peluncuran
Seperti yang direncanakan, Helm harus memantau pelaksanaan tes
--wait
dan readiness yang sesuai saat menggunakan opsi
--wait
:
--wait if set, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful. It will wait for as long as --timeout
Fungsi ini tidak berfungsi dengan baik sekarang: tidak semua sumber daya dan tidak semua versi API didukung. Dan proses penantian yang diumumkan itu sendiri tidak memuaskan kebutuhan kita.
Seperti
kubectl wait
, tidak ada umpan balik cepat dan tidak ada cara untuk mengatur perilaku ini. Jika peluncuran gagal, maka kita akan mengetahuinya
hanya setelah batas waktu . Dalam hal instalasi yang bermasalah, perlu untuk menyelesaikan proses peluncuran sedini mungkin, membalikkan pipa CI / CD, memutar kembali rilis ke versi yang berfungsi dan melanjutkan ke debugging.
Jika rilis yang bermasalah dibatalkan, dan Helm tidak mengembalikan informasi apa pun selama proses peluncuran, lalu tentang apa yang debug? Dalam hal
kubectl wait
Anda dapat mengatur proses terpisah untuk menampilkan log, yang akan memerlukan nama sumber rilis. Cara mengatur solusi yang sederhana dan berfungsi tidak segera jelas. Dan selain log pod, informasi yang berguna dapat dimuat dalam proses peluncuran, acara sumber daya ...
Utilitas CI / CD
werf kami dapat menggunakan grafik Helm dan memantau ketersediaan sumber daya, serta menampilkan informasi yang terkait dengan peluncuran. Semua data digabungkan menjadi satu aliran dan dikeluarkan ke log.
Logika ini dibuat dalam solusi
kubedog terpisah. Dengan menggunakan utilitas, Anda dapat berlangganan ke sumber daya dan menerima acara dan log, serta mempelajari tentang peluncuran gagal pada waktu yang tepat. Yaitu sebagai solusi, setelah memanggil
helm install/upgrade
tanpa opsi
--wait
,
--wait
dapat menghubungi kubedog untuk setiap sumber daya rilis.
Kami bertujuan untuk membuat alat yang akan memberikan semua informasi yang diperlukan untuk debugging dalam output pipa CI / CD. Baca lebih lanjut tentang utilitas di
artikel terbaru kami .
Mungkin di Helm 3 suatu hari nanti solusi serupa akan muncul, tetapi sejauh ini
masalah kami dalam keadaan ditangguhkan.
Keamanan saat menggunakan helm init secara default
Secara default, ketika perintah
helm init
dijalankan, komponen server dipasang di cluster dengan hak istimewa yang mirip dengan superuser, yang dapat menyebabkan konsekuensi yang tidak diinginkan ketika diakses oleh pihak ketiga.
Untuk memastikan keamanan cluster, perlu untuk membatasi kemampuan Tiller, serta menjaga koneksi - keamanan jaringan di mana komunikasi antara komponen Helm berlangsung.
Yang pertama dapat dicapai melalui penggunaan mekanisme Kubernetes RBAC standar, yang akan membatasi tindakan anakan, dan yang kedua - dengan menetapkan SSL. Baca lebih lanjut di dokumentasi Helm:
Mengamankan Instalasi Helm Anda .
Diyakini bahwa kehadiran komponen server - Tiller - adalah kesalahan arsitektur yang serius , secara harfiah sumber daya asing dengan hak pengguna super di ekosistem Kubernetes. Sebagian, kami setuju: implementasinya tidak sempurna, tetapi mari kita lihat dari sisi lain . Jika Anda mengganggu proses penyebaran dan membunuh klien Helm, sistem tidak akan tetap dalam keadaan tidak terdefinisi, mis. Anakan akan membawa status rilis ke valid. Perlu juga dipahami bahwa terlepas dari kenyataan bahwa Tiller ditinggalkan di Helm 3, fungsi-fungsi ini entah bagaimana akan dilakukan oleh pengontrol CRD.Templat Martian Go
Go-templates memiliki ambang masuk yang besar, tetapi teknologi ini tidak memiliki batasan pada kemampuan dan masalah dengan KERING. Prinsip-prinsip dasar, sintaksis, fungsi dan operator dibahas dalam
artikel kami
sebelumnya di seri Helm.
Kurangnya rahasia di luar kotak
Sangat mudah untuk menyimpan dan memelihara kode aplikasi, infrastruktur, dan template peluncuran ketika mereka berada di satu tempat. Dan rahasia tidak terkecuali.
Helm tidak mendukung rahasia di luar kotak, namun plugin
helm-rahasia tersedia, yang pada dasarnya merupakan lapisan antara
sops , manajer rahasia Mozilla, dan Helm.
Ketika bekerja dengan rahasia, kami menggunakan solusi kami sendiri yang diimplementasikan dalam
werf (
dokumentasi rahasia ). Fitur:
- Kemudahan implementasi.
- Menjaga rahasia dalam file, bukan hanya di YAML. Nyaman saat menyimpan sertifikat, kunci.
- Regenerasi rahasia dengan kunci baru.
- Peluncuran tanpa kunci rahasia (saat menggunakan werf). Mungkin bermanfaat untuk kasus-kasus ketika pengembang tidak memiliki kunci rahasia ini, tetapi ada kebutuhan untuk meluncurkan penyebaran pada tes atau sirkuit lokal.
Kesimpulan
Helm 2 diposisikan sebagai produk yang stabil, tetapi pada saat yang sama ada banyak bug yang menggantung di limbo (beberapa dari mereka bertahan selama beberapa tahun!). Alih-alih solusi, atau setidaknya tambalan, semua upaya dicurahkan untuk mengembangkan Helm 3.
Terlepas dari kenyataan bahwa MR dan masalah dapat bertahan selama berbulan-bulan (
berikut adalah contoh bagaimana kami menambahkan
before-hook-creation policy
kait sebelumnya untuk kait selama beberapa bulan), Anda masih dapat berpartisipasi dalam pengembangan proyek. Setiap Kamis, demonstrasi setengah jam dari para pengembang Helm berlangsung, di mana Anda dapat mempelajari tentang prioritas dan arah tim saat ini, mengajukan pertanyaan dan memaksakan praktik terbaik Anda sendiri. Tentang mete dan saluran komunikasi lainnya ditulis secara rinci di
sini .
Apakah menggunakan Helm atau tidak, itu terserah Anda, tentu saja. Hari ini kami sendiri berpegang teguh pada posisi yang, meskipun ada kekurangan, Helm adalah solusi yang dapat diterima untuk penempatan dan berguna bagi seluruh masyarakat untuk berpartisipasi dalam pengembangannya.
PS
Baca juga di blog kami: