
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:
- 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. - 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:
- Kami sedang menyiapkan file
manifest.yaml
dengan manifes sumber daya untuk diadopsi (item ini akan dibahas lebih rinci di bawah). - Kami membuat bagan di mana ada satu templat tunggal dengan ConfigMap sementara, karena Helm tidak dapat membuat rilis tanpa sumber daya.
- 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} "#" }}
- Instal grafik:
helm install
helm upgrade --install
dan helm upgrade --install
. - 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}'"}}'
- Kami memeriksa bahwa Anakan tersedia dan mengambil perubahan kami.
- Hapus ConfigMap sementara (dari langkah kedua).
- 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: