Skip to main content
Version: 3.19.0

Συμβουλές και Κόλπα για την Ανάπτυξη Charts

Αυτός ο οδηγός καλύπτει μερικές από τις συμβουλές και τα κόλπα που έχουν μάθει οι προγραμματιστές charts του Helm κατά τη δημιουργία charts για παραγωγικά περιβάλλοντα.

Γνωρίστε τις Συναρτήσεις Template

Το Helm χρησιμοποιεί Go templates για τη δημιουργία templates στα αρχεία πόρων σας. Αν και η Go παρέχει αρκετές ενσωματωμένες συναρτήσεις, έχουμε προσθέσει πολλές επιπλέον.

Πρώτον, προσθέσαμε όλες τις συναρτήσεις της βιβλιοθήκης Sprig, εκτός από τις env και expandenv, για λόγους ασφαλείας.

Προσθέσαμε επίσης δύο ειδικές συναρτήσεις template: include και required. Η συνάρτηση include σας επιτρέπει να συμπεριλάβετε ένα άλλο template και στη συνέχεια να περάσετε τα αποτελέσματα σε άλλες συναρτήσεις template.

Για παράδειγμα, αυτό το απόσπασμα template συμπεριλαμβάνει ένα template με όνομα mytpl, στη συνέχεια μετατρέπει το αποτέλεσμα σε πεζά και το περικλείει σε διπλά εισαγωγικά.

value: {{ include "mytpl" . | lower | quote }}

Η συνάρτηση required σας επιτρέπει να δηλώσετε μια συγκεκριμένη καταχώρηση values ως υποχρεωτική για την απόδοση του template. Αν η τιμή είναι κενή, η απόδοση του template θα αποτύχει με ένα μήνυμα σφάλματος που ορίζει ο χρήστης.

Το ακόλουθο παράδειγμα της συνάρτησης required δηλώνει ότι η καταχώρηση .Values.who είναι υποχρεωτική και θα εκτυπώσει ένα μήνυμα σφάλματος όταν αυτή η καταχώρηση λείπει:

value: {{ required "A valid .Values.who entry required!" .Values.who }}

Χρησιμοποιήστε Εισαγωγικά για Strings, Όχι για Ακέραιους

Όταν εργάζεστε με δεδομένα τύπου string, είναι πάντα ασφαλέστερο να χρησιμοποιείτε εισαγωγικά αντί να τα αφήνετε χωρίς:

name: {{ .Values.MyName | quote }}

Αλλά όταν εργάζεστε με ακέραιους αριθμούς, μην χρησιμοποιείτε εισαγωγικά. Αυτό μπορεί, σε πολλές περιπτώσεις, να προκαλέσει σφάλματα ανάλυσης μέσα στο Kubernetes.

port: {{ .Values.Port }}

Αυτή η παρατήρηση δεν ισχύει για τιμές μεταβλητών περιβάλλοντος που αναμένονται ως string, ακόμα κι αν αντιπροσωπεύουν ακέραιους:

env:
- name: HOST
value: "http://host"
- name: PORT
value: "1234"

Χρήση της Συνάρτησης 'include'

Η Go παρέχει έναν τρόπο να συμπεριλάβετε ένα template μέσα σε ένα άλλο χρησιμοποιώντας την ενσωματωμένη οδηγία template. Ωστόσο, η ενσωματωμένη συνάρτηση δεν μπορεί να χρησιμοποιηθεί σε pipelines του Go template.

Για να είναι δυνατή η συμπερίληψη ενός template και στη συνέχεια η εκτέλεση μιας λειτουργίας στην έξοδο αυτού του template, το Helm έχει μια ειδική συνάρτηση include:

{{ include "toYaml" $value | indent 2 }}

Το παραπάνω συμπεριλαμβάνει ένα template με όνομα toYaml, του περνάει το $value και στη συνέχεια περνάει την έξοδο αυτού του template στη συνάρτηση indent.

Επειδή το YAML δίνει σημασία στα επίπεδα εσοχής και στα κενά, αυτός είναι ένας εξαιρετικός τρόπος για να συμπεριλαμβάνετε αποσπάσματα κώδικα, χειριζόμενοι την εσοχή στο κατάλληλο πλαίσιο.

Χρήση της Συνάρτησης 'required'

Η Go παρέχει έναν τρόπο για να ορίσετε επιλογές template που ελέγχουν τη συμπεριφορά όταν γίνεται αναζήτηση σε ένα map με κλειδί που δεν υπάρχει. Αυτό συνήθως ορίζεται με template.Options("missingkey=option"), όπου η option μπορεί να είναι default, zero ή error. Αν και η ρύθμιση αυτής της επιλογής σε error θα σταματήσει την εκτέλεση με σφάλμα, αυτό θα ισχύει για κάθε κλειδί που λείπει στο map. Μπορεί να υπάρχουν περιπτώσεις όπου ο προγραμματιστής του chart θέλει να επιβάλει αυτή τη συμπεριφορά για επιλεγμένες τιμές στο αρχείο values.yaml.

Η συνάρτηση required δίνει στους προγραμματιστές τη δυνατότητα να δηλώσουν μια καταχώρηση τιμής ως υποχρεωτική για την απόδοση του template. Αν η καταχώρηση είναι κενή στο values.yaml, το template δεν θα αποδοθεί και θα επιστρέψει ένα μήνυμα σφάλματος που παρέχει ο προγραμματιστής.

Για παράδειγμα:

{{ required "A valid foo is required!" .Values.foo }}

Το παραπάνω θα αποδώσει το template όταν το .Values.foo είναι ορισμένο, αλλά θα αποτύχει να το αποδώσει και θα τερματίσει όταν το .Values.foo δεν είναι ορισμένο.

Χρήση της Συνάρτησης 'tpl'

Η συνάρτηση tpl επιτρέπει στους προγραμματιστές να αξιολογούν strings ως templates μέσα σε ένα template. Αυτό είναι χρήσιμο για τη μετάδοση ενός template string ως τιμή σε ένα chart ή για την απόδοση εξωτερικών αρχείων ρυθμίσεων. Σύνταξη: {{ tpl TEMPLATE_STRING VALUES }}

Παραδείγματα:

# values \{#values} {#values}
template: "{{ .Values.name }}"
name: "Tom"

# template \{#template} {#template}
{{ tpl .Values.template . }}

# output \{#output} {#output}
Tom

Απόδοση εξωτερικού αρχείου ρυθμίσεων:

# external configuration file conf/app.conf \{#external-configuration-file-confappconf}
firstName={{ .Values.firstName }}
lastName={{ .Values.lastName }}

# values
firstName: Peter
lastName: Parker

# template
{{ tpl (.Files.Get "conf/app.conf") . }}

# output
firstName=Peter
lastName=Parker

Δημιουργία Image Pull Secrets

Τα image pull secrets είναι ουσιαστικά ένας συνδυασμός registry, username και password. Μπορεί να τα χρειαστείτε σε μια εφαρμογή που αναπτύσσετε, αλλά για να τα δημιουργήσετε απαιτείται η εκτέλεση του base64 μερικές φορές. Μπορούμε να γράψουμε ένα βοηθητικό template για τη σύνθεση του αρχείου ρυθμίσεων Docker προς χρήση ως payload του Secret. Ακολουθεί ένα παράδειγμα:

Πρώτα, υποθέστε ότι τα credentials ορίζονται στο αρχείο values.yaml ως εξής:

imageCredentials:
registry: quay.io
username: someone
password: sillyness
email: someone@host.com

Στη συνέχεια ορίζουμε το βοηθητικό template ως εξής:

{{- define "imagePullSecret" }}
{{- with .Values.imageCredentials }}
{{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":%s,\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username (.password | quote) .email (printf "%s:%s" .username .password | b64enc) | b64enc }}
{{- end }}
{{- end }}

Τέλος, χρησιμοποιούμε το βοηθητικό template σε ένα μεγαλύτερο template για να δημιουργήσουμε το manifest του Secret:

apiVersion: v1
kind: Secret
metadata:
name: myregistrykey
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: {{ template "imagePullSecret" . }}

Αυτόματη Επανεκκίνηση Deployments

Συχνά τα ConfigMaps ή τα Secrets εισάγονται ως αρχεία ρυθμίσεων σε containers ή υπάρχουν άλλες αλλαγές εξωτερικών εξαρτήσεων που απαιτούν επανεκκίνηση των pods. Ανάλογα με την εφαρμογή, μπορεί να απαιτείται επανεκκίνηση αν αυτά ενημερωθούν με ένα επόμενο helm upgrade, αλλά αν το ίδιο το deployment spec δεν άλλαξε, η εφαρμογή συνεχίζει να εκτελείται με την παλιά ρύθμιση, με αποτέλεσμα ένα ασυνεπές deployment.

Η συνάρτηση sha256sum μπορεί να χρησιμοποιηθεί για να διασφαλίσει ότι η ενότητα annotations ενός deployment ενημερώνεται αν αλλάξει ένα άλλο αρχείο:

kind: Deployment
spec:
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
[...]

ΣΗΜΕΙΩΣΗ: Αν προσθέτετε αυτό σε ένα library chart, δεν θα μπορέσετε να αποκτήσετε πρόσβαση στο αρχείο σας μέσω του $.Template.BasePath. Αντίθετα, μπορείτε να αναφερθείτε στον ορισμό σας με {{ include ("mylibchart.configmap") . | sha256sum }}.

Στην περίπτωση που θέλετε πάντα να κάνετε επανεκκίνηση το deployment σας, μπορείτε να χρησιμοποιήσετε ένα παρόμοιο βήμα annotation όπως παραπάνω, αλλά αντικαθιστώντας με ένα τυχαίο string ώστε να αλλάζει πάντα και να προκαλεί επανεκκίνηση του deployment:

kind: Deployment
spec:
template:
metadata:
annotations:
rollme: {{ randAlphaNum 5 | quote }}
[...]

Κάθε κλήση της συνάρτησης template θα δημιουργήσει ένα μοναδικό τυχαίο string. Αυτό σημαίνει ότι αν είναι απαραίτητο να συγχρονιστούν τα τυχαία strings που χρησιμοποιούνται από πολλαπλούς πόρους, όλοι οι σχετικοί πόροι θα πρέπει να βρίσκονται στο ίδιο αρχείο template.

Και οι δύο αυτές μέθοδοι επιτρέπουν στο Deployment σας να αξιοποιήσει την ενσωματωμένη λογική στρατηγικής ενημέρωσης για να αποφύγει το downtime.

ΣΗΜΕΙΩΣΗ: Στο παρελθόν προτείναμε τη χρήση της επιλογής --recreate-pods ως εναλλακτική. Αυτή η επιλογή έχει επισημανθεί ως deprecated στο Helm 3 υπέρ της πιο δηλωτικής μεθόδου που περιγράφεται παραπάνω.

Αποτροπή Απεγκατάστασης Πόρου από το Helm

Μερικές φορές υπάρχουν πόροι που δεν πρέπει να απεγκατασταθούν όταν το Helm εκτελεί helm uninstall. Οι προγραμματιστές charts μπορούν να προσθέσουν ένα annotation σε έναν πόρο για να αποτρέψουν την απεγκατάστασή του.

kind: Secret
metadata:
annotations:
helm.sh/resource-policy: keep
[...]

Το annotation helm.sh/resource-policy: keep δίνει εντολή στο Helm να παραλείψει τη διαγραφή αυτού του πόρου όταν μια λειτουργία helm (όπως helm uninstall, helm upgrade ή helm rollback) θα είχε ως αποτέλεσμα τη διαγραφή του. Ωστόσο, αυτός ο πόρος γίνεται ορφανός. Το Helm δεν θα τον διαχειρίζεται πλέον με κανέναν τρόπο. Αυτό μπορεί να οδηγήσει σε προβλήματα αν χρησιμοποιείτε helm install --replace σε ένα release που έχει ήδη απεγκατασταθεί, αλλά έχει διατηρήσει πόρους.

Χρήση "Partials" και Συμπερίληψη Templates

Μερικές φορές θέλετε να δημιουργήσετε ορισμένα επαναχρησιμοποιήσιμα μέρη στο chart σας, είτε είναι blocks είτε template partials. Και συχνά, είναι πιο καθαρό να τα κρατάτε στα δικά τους αρχεία.

Στον κατάλογο templates/, οποιοδήποτε αρχείο ξεκινά με underscore (_) δεν αναμένεται να παράγει ένα αρχείο manifest Kubernetes. Έτσι, κατά σύμβαση, τα βοηθητικά templates και τα partials τοποθετούνται σε ένα αρχείο _helpers.tpl.

Σύνθετα Charts με Πολλές Εξαρτήσεις

Πολλά από τα charts στο CNCF Artifact Hub είναι "δομικά στοιχεία" για τη δημιουργία πιο προηγμένων εφαρμογών. Αλλά τα charts μπορούν επίσης να χρησιμοποιηθούν για τη δημιουργία instances μεγάλης κλίμακας εφαρμογών. Σε τέτοιες περιπτώσεις, ένα κεντρικό umbrella chart μπορεί να έχει πολλαπλά subcharts, καθένα από τα οποία λειτουργεί ως μέρος του συνόλου.

Η τρέχουσα βέλτιστη πρακτική για τη σύνθεση μιας σύνθετης εφαρμογής από διακριτά μέρη είναι να δημιουργήσετε ένα κορυφαίο umbrella chart που εκθέτει τις καθολικές ρυθμίσεις και στη συνέχεια να χρησιμοποιήσετε τον υποκατάλογο charts/ για να ενσωματώσετε κάθε ένα από τα components.

Το YAML είναι Υπερσύνολο του JSON

Σύμφωνα με την προδιαγραφή YAML, το YAML είναι υπερσύνολο του JSON. Αυτό σημαίνει ότι οποιαδήποτε έγκυρη δομή JSON θα πρέπει να είναι έγκυρη και σε YAML.

Αυτό έχει ένα πλεονέκτημα: Μερικές φορές οι προγραμματιστές templates μπορεί να βρουν πιο εύκολο να εκφράσουν μια δομή δεδομένων με σύνταξη παρόμοια με JSON αντί να ασχοληθούν με την ευαισθησία του YAML στα κενά.

Ως βέλτιστη πρακτική, τα templates θα πρέπει να ακολουθούν σύνταξη τύπου YAML εκτός αν η σύνταξη JSON μειώνει σημαντικά τον κίνδυνο προβλήματος μορφοποίησης.

Προσοχή κατά τη Δημιουργία Τυχαίων Τιμών

Υπάρχουν συναρτήσεις στο Helm που σας επιτρέπουν να δημιουργείτε τυχαία δεδομένα, κρυπτογραφικά κλειδιά και ούτω καθεξής. Αυτές είναι καλές για χρήση. Αλλά να έχετε υπόψη ότι κατά τις αναβαθμίσεις, τα templates εκτελούνται ξανά. Όταν μια εκτέλεση template δημιουργεί δεδομένα που διαφέρουν από την τελευταία εκτέλεση, αυτό θα ενεργοποιήσει μια ενημέρωση αυτού του πόρου.

Εγκατάσταση ή Αναβάθμιση Release με Μία Εντολή

Το Helm παρέχει έναν τρόπο να εκτελέσετε εγκατάσταση ή αναβάθμιση ως μία εντολή. Χρησιμοποιήστε helm upgrade με την επιλογή --install. Αυτό θα κάνει το Helm να ελέγξει αν το release είναι ήδη εγκατεστημένο. Αν όχι, θα εκτελέσει εγκατάσταση. Αν είναι, τότε το υπάρχον release θα αναβαθμιστεί.

$ helm upgrade --install <release name> --values <values file> <chart directory>