Kiat & trik Kubernetes: memindahkan sumber daya kluster ke Helm 2



Kebutuhan untuk mengambil sumber daya dari gugus Kubernetes dapat muncul dalam kondisi pertempuran ketika Anda tidak bisa membuatnya hanya dengan alat Helm. Dua alasan utama dapat dibedakan:

  • Ini akan sederhana - terlepas dari apakah Anda memiliki cloud atau bare metal.
  • Setelah dihapus, layanan di cloud mungkin hilang, serta Load Balancers terkait di Kubernetes akan terbang.

Dalam kasus kami, solusi diperlukan untuk menangkap ingress-nginx saat mengintegrasikan operator Kubernet kami.

Sangat tidak dapat diterima bagi Helm bahwa sumber daya yang dikelolanya tidak diciptakan olehnya.

"Jika sumber daya rilis tim Anda dapat diubah secara manual, bersiap-siap untuk menghadapi masalah yang dijelaskan di bagian: [BUG] Setelah diluncurkan, status sumber daya rilis di cluster tidak sesuai dengan bagan Helm yang dijelaskan ." (dari artikel terakhir kami)

Seperti disebutkan sebelumnya, Helm bekerja sebagai berikut:

  1. Setiap instalasi (pemasangan helm install , perintah helm upgrade ) Helm menyimpan manifes rilis yang dihasilkan di backend penyimpanan . Secara default, ConfigMaps digunakan: untuk setiap revisi rilis, ConfigMap dibuat di namespace yang sama di mana Tiller dijalankan.
  2. Selama peluncuran berulang (perintah helm upgrade ) Helm membandingkan manifes yang dibuat baru dengan manifes lama dari revisi rilis DEPLOYED terbaru dari ConfigMap, dan menerapkan perbedaan yang dihasilkan di Kubernetes.

Berdasarkan fitur-fitur ini, kami sampai pada kesimpulan bahwa itu sudah cukup untuk menambal ConfigMap (rilis backend penyimpanan) untuk diambil , mis. mengadopsi sumber daya yang ada di cluster.

Tiller merujuk ke ConfigMap dalam format berikut: %RELEASE_NAME.v%REVISION . Untuk mendapatkan entri yang ada, Anda harus menjalankan perintah kubectl get cm -l OWNER=TILLER --namespace kube-system (secara default, Tiller dipasang di namespace kube-system - jika tidak, Anda harus menentukan yang digunakan).

 $ kubectl get cm -l OWNER=TILLER -n kube-system NAME DATA AGE release_name_1.v618 1 5d release_name_1.v619 1 1d release_name_2.v1 1 2d release_name_2.v2 1 3d 

Setiap ConfigMap disajikan dalam format ini:

 apiVersion: v1 data: release: H4sIAHEEd1wCA5WQwWrDMAyG734Kwc52mtvwtafdAh27FsURjaljG1kp5O3nNGGjhcJ21M/nT7+stVZvcEozO7LAFAgLnSNOdG4boSkHFCpNIb55R2bBKSjM/ou4+BQt3Fp19XGwcNoINZHggIJWAayaH6leJ/24oTIBewplpQEwZ3Ode+JIdanxqXkw/D4CGClMpoyNG5HlmdAH05rDC6WPRTC6p2Iv4AkjXmjQ/WLh04dArEomt9aVJVfHMcxFiD+6muTEsl+i74OF961FpZEvJN09HEXyHmdOklwK1X7s9my7eYdK7egk8b8/6M+HfwNgE0MSAgIAAA== kind: ConfigMap metadata: creationTimestamp: 2019-02-08T11:12:38Z labels: MODIFIED_AT: "1550488348" NAME: release_name_1 OWNER: TILLER STATUS: DEPLOYED VERSION: "618" name: release_name_1.v618 namespace: kube-system resourceVersion: "298818981" selfLink: /api/v1/namespaces/kube-system/configmaps/release_name_1.v618 uid: 71c3e6f3-2b92-11e9-9b3c-525400a97005 ou4 + BQt3Fp19XGwcNoINZHggIJWAayaH6leJ / 24oTIBewplpQEwZ3Ode + JIdanxqXkw / D4CGClMpoyNG5HlmdAH05rDC6WPRTC6p2Iv4AkjXmjQ / WLh04dArEomt9aVJVfHMcxFiD + 6muTEsl + i74OF961FpZEvJN09HEXyHmdOklwK1X7s9my7eYdK7egk8b8 / 6M + HfwNgE0MSAgIAAA == apiVersion: v1 data: release: H4sIAHEEd1wCA5WQwWrDMAyG734Kwc52mtvwtafdAh27FsURjaljG1kp5O3nNGGjhcJ21M/nT7+stVZvcEozO7LAFAgLnSNOdG4boSkHFCpNIb55R2bBKSjM/ou4+BQt3Fp19XGwcNoINZHggIJWAayaH6leJ/24oTIBewplpQEwZ3Ode+JIdanxqXkw/D4CGClMpoyNG5HlmdAH05rDC6WPRTC6p2Iv4AkjXmjQ/WLh04dArEomt9aVJVfHMcxFiD+6muTEsl+i74OF961FpZEvJN09HEXyHmdOklwK1X7s9my7eYdK7egk8b8/6M+HfwNgE0MSAgIAAA== kind: ConfigMap metadata: creationTimestamp: 2019-02-08T11:12:38Z labels: MODIFIED_AT: "1550488348" NAME: release_name_1 OWNER: TILLER STATUS: DEPLOYED VERSION: "618" name: release_name_1.v618 namespace: kube-system resourceVersion: "298818981" selfLink: /api/v1/namespaces/kube-system/configmaps/release_name_1.v618 uid: 71c3e6f3-2b92-11e9-9b3c-525400a97005 

Manifes yang dihasilkan disimpan dalam bentuk biner (dalam contoh di atas dengan kunci .data.release ), jadi kami memutuskan untuk membuat rilis menggunakan alat Helm standar, tetapi dengan rintisan khusus, yang kemudian diganti dengan manifes sumber daya yang dipilih.

Implementasi


Algoritma solusinya adalah sebagai berikut:

  1. Kami sedang menyiapkan file manifest.yaml dengan manifes sumber daya untuk diadopsi (item ini akan dibahas lebih rinci di bawah).
  2. Kami membuat bagan di mana ada satu templat tunggal dengan ConfigMap sementara, karena Helm tidak dapat membuat rilis tanpa sumber daya.
  3. Kami membuat templates/stub.yaml dengan stub yang panjangnya akan sama dengan jumlah karakter di manifest.yaml (selama percobaan ternyata jumlah byte harus cocok). Sebagai sebuah rintisan, set karakter yang dapat direproduksi harus dipilih, yang akan tetap setelah generasi dan disimpan di backend penyimpanan. Untuk kesederhanaan dan kejelasan, # digunakan, yaitu .:

     {{ repeat ${manifest_file_length} "#" }} 
  4. Instal grafik: helm install helm upgrade --install dan helm upgrade --install .
  5. Kami mengganti rintisan dalam rilis backend penyimpanan dengan manifest.yaml sumber daya dari manifest.yaml yang dipilih untuk diadopsi pada langkah pertama:

     stub=$(printf '#%.0s' $(seq 1 ${manifest_file_length})) release_data=$(kubectl get -n ${tiller_namespace} cm/${release_name}.v1 -o json | jq .data.release -r) updated_release_data=$(echo ${release_data} | base64 -d | zcat | sed "s/${stub}/$(sed -z 's/\n/\\n/g' ${manifest_file_path} | sed -z 's/\//\\\//g')/" | gzip -9 | base64 -w0) kubectl patch -n ${tiller_namespace} cm/${release_name}.v1 -p '{"data":{"release":"'${updated_release_data}'"}}' 
  6. Kami memeriksa bahwa Anakan tersedia dan mengambil perubahan kami.
  7. Hapus ConfigMap sementara (dari langkah kedua).
  8. Lebih jauh, bekerja dengan rilis tidak berbeda dari yang biasa.

Intinya dengan implementasi yang dijelaskan di atas tersedia di:

 $ ./script.sh Example: ./script.sh foo bar-prod manifest.yaml Usage: ./script.sh CHART_NAME RELEASE_NAME MANIFEST_FILE_TO_ADOPT [TILLER_NAMESPACE] 

Sebagai hasil dari skrip, rilis RELEASE_NAME dibuat. Ini terkait dengan sumber daya yang manifesnya dijelaskan dalam file MANIFEST_FILE_TO_ADOPT . Bagan CHART_NAME juga dibuat, yang dapat digunakan untuk lebih lanjut menyertai manifes dan rilis khususnya.

Saat menyiapkan manifes dengan sumber daya, perlu untuk menghapus bidang layanan yang digunakan oleh Kubernetes (ini adalah data layanan dinamis, oleh karena itu tidak benar untuk versi mereka di Helm). Di dunia yang ideal, pelatihan datang ke satu perintah: kubectl get RESOURCE -o yaml --export . Bagaimanapun, dokumentasi mengatakan:

  --export=false: If true, use 'export' for the resources. Exported resources are stripped of cluster-specific information. 

... tetapi, seperti yang telah ditunjukkan oleh latihan, opsi --export masih --export , jadi pemformatan manifes tambahan akan diperlukan. Di service/release-name-habr bawah ini, Anda harus menghapus bidang creationTimestamp dan selfLink .

versi kubectl
 $ kubectl version Client Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.3", GitCommit:"721bfa751924da8d1680787490c54b9179b1fed0", GitTreeState:"clean", BuildDate:"2019-02-01T20:08:12Z", GoVersion:"go1.11.5", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.3", GitCommit:"721bfa751924da8d1680787490c54b9179b1fed0", GitTreeState:"clean", BuildDate:"2019-02-01T20:00:57Z", GoVersion:"go1.11.5", Compiler:"gc", Platform:"linux/amd64"} 

kubectl mendapatkan layanan / rilis-nama-habr -o yaml --export
 apiVersion: v1 kind: Service metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"release-name","app.kubernetes.io/managed-by":"Tiller","app.kubernetes.io/name":"habr","helm.sh/chart":"habr-0.1.0"},"name":"release-name-habr","namespace":"default"},"spec":{"ports":[{"name":"http","port":80,"protocol":"TCP","targetPort":"http"}],"selector":{"app.kubernetes.io/instance":"release-name","app.kubernetes.io/name":"habr"},"type":"ClusterIP"}} creationTimestamp: null labels: app.kubernetes.io/instance: release-name app.kubernetes.io/managed-by: Tiller app.kubernetes.io/name: habr helm.sh/chart: habr-0.1.0 name: release-name-habr selfLink: /api/v1/namespaces/default/services/release-name-habr spec: ports: - name: http port: 80 protocol: TCP targetPort: http selector: app.kubernetes.io/instance: release-name app.kubernetes.io/name: habr sessionAffinity: None type: ClusterIP status: loadBalancer: {} 

Berikut ini adalah contoh penggunaan skrip. Keduanya mendemonstrasikan cara menggunakan skrip untuk mengadopsi sumber daya yang bekerja di cluster dan kemudian menghapusnya menggunakan alat Helm.

Contoh 1




Contoh 2




Kesimpulan


Solusi yang dijelaskan dalam artikel ini dapat diselesaikan dan digunakan tidak hanya untuk mengadopsi sumber daya Kubernetes dari awal, tetapi juga untuk menambahkannya ke rilis yang ada.

Saat ini tidak ada solusi yang memungkinkan untuk mengambil sumber daya yang ada di cluster, mentransfernya ke manajemen Helm. Ada kemungkinan bahwa Helm 3 akan menerapkan solusi untuk mengatasi masalah ini (setidaknya ada proposal tentang hal ini).

PS


Lainnya dari siklus tips & trik K8:


Baca juga di blog kami:

Source: https://habr.com/ru/post/id441964/


All Articles