Έργο 13 — Helm στο Kubernetes · Επίπεδο ενδιάμεσο → προχωρημένο · Εκτιμώμενη διάρκεια: 4 έως 6 ώρες
Ξεκινάτε από μια εφαρμογή αποτελούμενη από δύο υπηρεσίες Python (ένα οπτικό portail και μια api backend), και θα την αναπτύξετε τρεις φορές δίπλα-δίπλα — σε DEV (μπλε), STAGING (πορτοκαλί), PROD (πράσινο) — με ένα μόνο Chart Helm και τρία αρχεία τιμών. Στο τέλος, θα κάνετε ένα helm upgrade έπειτα ένα helm rollback, και θα επισκευάσετε τρία πρότυπα γεμάτα πραγματικά σφάλματα που συναντώνται στην επιχείρηση.
Σήμερα, η ομάδα αντιγράφει-επικολλά τα ίδια μανιφέστα YAML για κάθε περιβάλλον αλλάζοντας χειροκίνητα τις διαφορετικές τιμές. Αποτέλεσμα: τα αρχεία αποκλίνουν, μια διόρθωση που εφαρμόστηκε στο dev δεν βρίσκεται στην παραγωγή, και μια ανάπτυξη απαιτεί μισή ημέρα.
Η αποστολή σας: να εκβιομηχανίσετε όλα αυτά με Helm. Ένα μόνο Chart, τρία αρχεία τιμών, μία εντολή ανά περιβάλλον. Θα αποδείξετε ότι λειτουργεί εμφανίζοντας τρεις πίνακες ελέγχου δίπλα-δίπλα στον περιηγητή σας — καθένας με το δικό του χρώμα, τον δικό του αριθμό Pods, και το δικό του μήνυμα.
Ουσιώδεις έννοιες πριν ξεκινήσετε
Αυτό το έγγραφο είναι αυτάρκες. Δεν χρειάζεστε καμία εξωτερική αναφορά για να το ολοκληρώσετε.
1. Ο ρόλος του Helm σε μία πρόταση
Το Helm παράγει μανιφέστα Kubernetes από πρότυπα και μεταβλητές. Εκεί όπου το kubectl apply παίρνει ένα στατικό YAML, το Helm παίρνει ένα πρότυπο YAML και ένα αρχείο τιμών, παράγει το τελικό YAML, έπειτα το εφαρμόζει ως εκδοχημένη μονάδα που ονομάζουμε release.
Τα αρχεία των οποίων το όνομα αρχίζει με _ δεν παράγουν κανένα μανιφέστο: χρησιμεύουν στον ορισμό επαναχρησιμοποιήσιμων «helpers» μέσω {{ include "nom" . }}.
3. Η σύνταξη των προτύπων (Go template)
Γράφεται
Αποδίδεται
{{ .Values.portail.replicas }}
Η τιμή που ορίζεται στο values.yaml
{{ .Release.Name }}
Το όνομα που περάσατε στο helm install (π.χ. hedge-dev)
Μια release είναι μια εγκατάσταση ενός chart. Το ίδιο chart μπορεί να εγκατασταθεί πολλές φορές, καθένα με διαφορετικό όνομα release (hedge-dev, hedge-staging, hedge-prod) — αυτό είναι το θεμέλιο του πολλαπλού περιβάλλοντος.
Το {{ .Release.Name }} αλλάζει σε κάθε install, το {{ .Chart.Name }} μένει ίδιο. Κρατήστε αυτή την αντίθεση: είναι κεντρική.
6. Ο χρυσός κανόνας του αμετάβλητου selector
Το πεδίο spec.selector.matchLabels ενός Deployment είναι σταθερό μία για πάντα στη δημιουργία. Αν το πρότυπό σας βάλει σε αυτό το πεδίο μια τιμή που μπορεί να αλλάξει (όπως μια έκδοση, ένα περιβάλλον, μια ημερομηνία), το πρώτο helm install θα πετύχει, αλλά το πρώτο helm upgrade θα αποτύχει με:
spec.selector: Invalid value: ...: field is immutable
Κανόνας να χαραχτεί στην πέτρα: στο matchLabels, βάλτε μόνο πράγματα που δεν θα αλλάξουν ΠΟΤΕ για αυτή την παρουσία — τυπικά name, instance, component.
Η στοχευμένη αρχιτεκτονική: DEV / STAGING / PROD
Θα αναπτύξετε το ίδιο chart σε τρεις διακριτούς χώρους ονομάτων, καθένας με τις παραμέτρους του:
Παράμετρος
DEV
STAGING
PROD
Namespace
hedge-dev
hedge-staging
hedge-prod
Release name
hedge-dev
hedge-staging
hedge-prod
Χρώμα πανό
μπλε#2563eb
πορτοκαλί#ea580c
πράσινο#16a34a
Μήνυμα
« Περιβάλλον ανάπτυξης… »
« Προ-παραγωγή — μόνο δεδομένα δοκιμής »
« Παραγωγή — κάθε ενέργεια έχει πραγματικό αντίκτυπο »
Αντίγραφα portail
1
2
3
Αντίγραφα api
1
2
3
Εκτεθειμένη θύρα (NodePort)
30130
30131
30132
URL δοκιμής
http://localhost:30130
http://localhost:30131
http://localhost:30132
Στο τέλος του εργαστηρίου, ανοίγετε τρεις καρτέλες δίπλα-δίπλα και βλέπετε τρεις πίνακες ελέγχου χρωματισμένους διαφορετικά, καθένας να εμφανίζει το περιβάλλον του, την έκδοσή του, τα Pods του, και την κατάσταση του backend του.
Διάταξη των αρχείων
Ξεκινάτε από την ακόλουθη δενδροδομή — το ΠΑΡΑΡΤΗΜΑ παρέχει το ακριβές περιεχόμενο κάθε αρχείου:
projet13-kubernetes-helm-tp/├── 00-ENONCE.md <- αυτό το έγγραφο│├── apps/ <- Ο ΚΩΔΙΚΑΣ (ΠΑΡΑΡΤΗΜΑ A) — ΝΑ ΜΗΝ ΤΡΟΠΟΠΟΙΗΘΕΙ│ ├── portail/│ │ ├── app.py│ │ ├── requirements.txt│ │ └── Dockerfile│ └── api/│ ├── app.py│ ├── requirements.txt│ └── Dockerfile│├── chart/ <- ΤΟ CHART ΠΡΟΣ ΣΥΜΠΛΗΡΩΣΗ│ ├── Chart.yaml <- σκελετός (ΠΑΡΑΡΤΗΜΑ B)│ ├── values.yaml <- προεπιλεγμένες τιμές (ΠΑΡΑΡΤΗΜΑ B)│ ││ ├── environments/ <- ΣΕΙΡΑ ΣΑΣ│ │ ├── values-dev.yaml <- σκελετός TODO (ΠΑΡΑΡΤΗΜΑ B)│ │ ├── values-staging.yaml <- σκελετός TODO (ΠΑΡΑΡΤΗΜΑ B)│ │ └── values-prod.yaml <- σκελετός TODO (ΠΑΡΑΡΤΗΜΑ B)│ ││ ├── templates/ <- ΣΕΙΡΑ ΣΑΣ│ │ ├── _helpers.tpl <- σκελετός TODO (ΠΑΡΑΡΤΗΜΑ B)│ │ ├── portail-deployment.yaml <- σκελετός TODO (ΠΑΡΑΡΤΗΜΑ B)│ │ ├── portail-service.yaml <- σκελετός TODO (ΠΑΡΑΡΤΗΜΑ B)│ │ ├── api-deployment.yaml <- σκελετός TODO (ΠΑΡΑΡΤΗΜΑ B)│ │ └── api-service.yaml <- σκελετός TODO (ΠΑΡΑΡΤΗΜΑ B)│ ││ └── casses/ <- ΠΑΡΕΧΟΝΤΑΙ αλλά ΕΛΑΤΤΩΜΑΤΙΚΑ (ΠΑΡΑΡΤΗΜΑ C)│ ├── casse-1-configmap.yaml│ ├── casse-2-worker-deployment.yaml│ └── casse-3-cache-deployment.yaml│├── outils/│ └── valider.ps1 <- ΠΑΡΕΧΕΤΑΙ (ΠΑΡΑΡΤΗΜΑ D)│└── RAPPORT.md <- ΝΑ ΣΥΝΤΑΧΘΕΙ από εσάς
Κρίσιμο σημείο: τα αρχεία του chart/casses/δεν βρίσκονται στο chart/templates/. Το Helm λοιπόν δεν τα φορτώνει αυτόματα. Η αποστολή 6 θα σας ζητήσει να τα αντιγράψετε ένα-ένα στο templates/ για να παρατηρήσετε το σφάλμα, έπειτα να τα επισκευάσετε πριν τα κρατήσετε.
Οι κανόνες του παιχνιδιού
Απόλυτη απαγόρευση τροποποίησης του φακέλου apps/. Ο κώδικας εφαρμογής είναι ήδη γραμμένος — είστε ο DevOps, όχι ο προγραμματιστής.
Τροποποιείτε μόνο τα αρχεία του φακέλου chart/.
Καμία διαμόρφωση περιβάλλοντος κωδικοποιημένη στα σκληρά σε πρότυπο: replicas, nodePort, χρώμα, μήνυμα, περιβάλλον — όλα πρέπει να προέρχονται από ένα .Values.*.
Τα 3 αρχεία values-<env>.yaml πρέπει να διαφέρουν μόνο ως προς τις τιμές που διακρίνουν DEV, STAGING και PROD. Ένα αρχείο values-prod.yaml που επαναορίζει άσκοπα το image.repository ή το service.targetPort είναι σφάλμα — αυτά προέρχονται από το values.yaml.
Εργάζεστε στο ενσωματωμένο Kubernetes του Docker Desktop.
Προετοιμασία
Προαπαιτούμενα — να επαληθευτούν μία μόνο φορά
Το Docker Desktop είναι εκκινημένο και το Kubernetes είναι ενεργό (Settings → Kubernetes → Enable Kubernetes).
Το Docker Desktop διαθέτει τουλάχιστον 4 GB RAM δεσμευμένα (Settings → Resources → Memory ≥ 4 GB). Αυτό το εργαστήριο τρέχει 12 Pods ταυτόχρονα (1+1 + 2+2 + 3+3).
Το Helm είναι εγκατεστημένο:
powershell
helm version --short # πρέπει να εμφανίζει v3.x ή v4.x
Αλλιώς: winget install Helm.Helm (ή choco install kubernetes-helm).
Βρίσκεστε στο σωστό σύμπλεγμα:
powershell
kubectl config use-context docker-desktopkubectl get nodes # docker-desktop Ready
Κατασκευή των εικόνων
Το chart αναφέρεται σε δύο τοπικές εικόνες που πρέπει να κατασκευάσετε μία μόνο φορά:
powershell
docker build -t hedge-portail:1.0 .\apps\portaildocker build -t hedge-api:1.0 .\apps\apidocker images | Select-String "^hedge" # πρέπει να εμφανίζει τις 2 εικόνες
Υπενθύμιση: το Docker Desktop μοιράζεται τον δαίμονά του με το Kubernetes· κανένα βήμα «φόρτωσης» δεν είναι απαραίτητο (σε αντίθεση με το kind ή το minikube).
Οι αποστολές
Αποστολή 1 — Να ζωντανέψετε ένα ελάχιστο Chart (10 βαθμοί)
Συμπληρώστε το chart/Chart.yaml (όνομα, apiVersion, type, version, appVersion). Επαληθεύστε έπειτα:
powershell
helm lint .\chart# πρέπει να εμφανίζει : 1 chart(s) linted, 0 chart(s) failed
Αναμενόμενο: ένα Chart που περνά το lint χωρίς σφάλμα.
Αποστολή 2 — Προτυποποίηση portail και api (20 βαθμοί)
Συμπληρώστε τα 4 αρχεία του chart/templates/:
portail-deployment.yaml — ένα Deployment που χρησιμοποιεί .Values.portail.replicas, .Values.portail.image.*, και εγχέει τις μεταβλητές περιβάλλοντος ENVIRONMENT, APP_VERSION, THEME_COLOR, BANNIERE_MESSAGE, BACKEND_URL, REPLICAS_INFO.
portail-service.yaml — ένα Service NodePort που δείχνει στα Pods του portail.
api-deployment.yaml — ένα Deployment για την api (μεταβλητές ENVIRONMENT, APP_VERSION).
api-service.yaml — ένα Service ClusterIP.
Κρίσιμο σημείο: η μεταβλητή BACKEND_URL του portail πρέπει να περιέχει το όνομα του Service api κατασκευασμένο με {{ .Release.Name }} (π.χ. http://hedge-dev-api), όχι ένα όνομα στα σκληρά.
Επικύρωση:
powershell
helm template check .\chart -f .\chart\environments\values-dev.yaml# πρέπει να εμφανίζει 2 Deployments + 2 Services, όλα με πρόθεμα "check-"
Αποστολή 3 — Να γράψετε καθαρούς helpers (15 βαθμοί)
Συμπληρώστε το chart/templates/_helpers.tpl με τρεις helpers:
Αναμενόμενο: τρεις σελίδες διαφορετικών χρωμάτων, καθεμία να εμφανίζει το περιβάλλον της, την έκδοσή της, τα Pods της, και το backend της σε πράσινο OK.
Αποστολή 5 — Upgrade έπειτα rollback (10 βαθμοί)
Προσομοιώστε ένα περιστατικό παραγωγής, έπειτα ακυρώστε το.
kubectl get pods -n hedge-dev -l app.kubernetes.io/component=portail
Συμβουλευτείτε το ιστορικό:
powershell
helm history hedge-dev -n hedge-dev
Βλέπετε τουλάχιστον 2 αναθεωρήσεις.
Ακυρώστε την αναβάθμιση επιστρέφοντας στην αναθεώρηση 1:
powershell
helm rollback hedge-dev 1 -n hedge-dev
Επαληθεύστε ότι επιστρέψατε σε 1 μόνο Pod portail, και ότι το ιστορικό δείχνει μια νέα αναθεώρηση τύπου Rollback:
powershell
kubectl get pods -n hedge-dev -l app.kubernetes.io/component=portailhelm history hedge-dev -n hedge-dev
Ερώτηση προς επεξεργασία στην έκθεση: ποια είναι η θεμελιώδης διαφορά μεταξύ helm upgrade --set portail.replicas=5 και kubectl scale deploy/hedge-dev-portail --replicas=5; Γιατί το Helm προτιμά να περνάτε από αυτό;
Ο φάκελος chart/casses/ περιέχει τρία ήδη γραμμένα πρότυπα που μεταγλωττίζονται αλλά εισάγουν καθένα ένα πραγματικό σφάλμα που συναντάται στην επιχείρηση. Πρέπει, για καθένα:
να το αντιγράψετε στο chart/templates/·
να αναπαραγάγετε το σύμπτωμα που περιγράφεται στην κορυφή του αρχείου·
να διαγνώσετε την αιτία διαβάζοντας το μήνυμα σφάλματος·
να το επισκευάσετε (τροποποιώντας το πρότυπο στο chart/templates/, όχι το πρωτότυπο στο casses/)·
να αποδείξετε ότι η βλάβη εξαφανίστηκε.
Αρχείο
Προστιθέμενο στοιχείο
Φύση του σφάλματος
casse-1-configmap.yaml
Ένα καθολικό ConfigMap
Σύγκρουση ονόματος μεταξύ releases
casse-2-worker-deployment.yaml
Ένα Deploymentworker
Αμετάβλητος selector παραβιασμένος στο πρώτο helm upgrade
casse-3-cache-deployment.yaml
Ένα Deploymentcache
Εσφαλμένη διαδρομή τιμής (σιωπηλό τυπογραφικό)
Συμβουλή έρευνας:
powershell
# ΣΤΕΓΝΗ απόδοση ενός μόνο προτύπου (δεν εγκαθιστά τίποτα)helm template hedge-dev .\chart -f .\chart\environments\values-dev.yaml ` --show-only templates/casse-3-cache-deployment.yaml --debug
Αυτή η εντολή εκτυπώνει ακριβώς αυτό που το Helm θα έστελνε στο Kubernetes. Είναι το πρώτο σας εργαλείο διάγνωσης — χρησιμοποιήστε την χωρίς μέτρο.
Αποστολή 7 — Μπόνους: η εκλέπτυνση (5 βαθμοί)
Κατ' επιλογή, ένα μόνο αρκεί:
a) Προσθέστε ένα hook pre-install (Job) που εμφανίζει Bienvenue dans <environnement> στα ημερολόγια Helm. Η release πρέπει να περιμένει το τέλος του Job πριν συνεχίσει.
b) Κάντε τον αριθμό αντιγράφων δυναμικό με μια τιμή values.yaml που έχει εμφωλευμένη δομή (π.χ. portail.autoscaling.enabled, portail.autoscaling.min, portail.autoscaling.max) και δημιουργήστε υπό συνθήκη ένα HorizontalPodAutoscaler ανάλογα με το .enabled.
c) Προσθέστε ένα NOTES.txt στο templates/ που εμφανίζει, μετά από κάθε helm install, το ακριβές URL για άνοιγμα του πίνακα ελέγχου (με το σωστό nodePort σύμφωνα με τα Values).
Αυτόματη επικύρωση
Ένα σενάριο σας δίνει τη βαθμολογία σας ανά πάσα στιγμή:
powershell
.\outils\valider.ps1
Παράδειγμα εξόδου σε μερικώς ολοκληρωμένη εργασία:
Ο πλήρης φάκελος chart/, σε λειτουργική κατάσταση (helm lint καθαρό).
Ένα RAPPORT.md που περιέχει:
την έξοδο του helm list -A που δείχνει τις 3 releases σας·
ένα στιγμιότυπο ανά περιβάλλον (3 χρωματιστοί πίνακες ελέγχου)·
το πλήρες ιστορικό του hedge-dev (με upgrade + rollback)·
για κάθε βλάβη της αποστολής 6: εντολή διάγνωσης, αιτία, διόρθωση, απόδειξη·
τις απαντήσεις σας στις ερωτήσεις προβληματισμού.
Την τελική έξοδο του .\outils\valider.ps1.
Ερωτήσεις προβληματισμού
Γιατί το πεδίο spec.selector.matchLabels είναι αμετάβλητο στο Kubernetes; Ποιο πρόβλημα λύνει αυτός ο περιορισμός;
Έχετε 3 περιβάλλοντα σήμερα. Αύριο, η ομάδα DevSecOps ζητά ένα 4ο (« pre-prod »). Ποια αρχεία δημιουργείτε και ποια δεν αγγίζετε;
Ποια είναι η διαφορά μεταξύ helm upgrade --set replicas=5 και kubectl scale, από την άποψη της ιχνηλασιμότητας και του rollback;
Το portail εμφανίζει « backend OK » — γιατί αυτή η πληροφορία είναι πιο αξιόπιστη από ένα απλό kubectl get svc api;
Τι συμβαίνει αν διαγράψετε ένα Pod με kubectl delete pod, ενώ δημιουργήθηκε από ένα Deployment μέσω Helm; Το Helm γνωρίζει την «απώλεια»;
Ένας συνάδελφος σας προτείνει να βάλετε app.kubernetes.io/version: {{ .Chart.AppVersion }} στο matchLabels ενός Deployment. Τι του απαντάτε;
Βαθμολόγιο
Στοιχείο
Βαθμοί
Αποστολή 1 — Έγκυρο Chart και καθαρό lint
10
Αποστολή 2 — Προτυποποίηση portail + api
20
Αποστολή 3 — Επαναχρησιμοποιήσιμοι helpers και ετικέτες
15
Αποστολή 4 — Τρία περιβάλλοντα δίπλα-δίπλα
20
Αποστολή 5 — Ιχνηλατημένα upgrade + rollback
10
Αποστολή 6 — Διάγνωση + επισκευή των 3 βλαβών
20
Ποιότητα της έκθεσης και αιτιολόγηση των επιλογών
5
Μπόνους — Αποστολή 7
+5
Σύνολο
100 (+5)
Ποινές:
−10 ανά τιμή περιβάλλοντος κωδικοποιημένη στα σκληρά σε πρότυπο (replicas: 3 κατά λέξη αντί για .Values....).
−5 ανά άσκοπη επαναορισμό σε values-<env>.yaml (μια τιμή που δεν έχει λόγο να διαφέρει μεταξύ περιβαλλόντων).
−10 ανά τροποποίηση αρχείου του apps/.
Εργαλειοθήκη Helm
powershell
# ΑΝΑΛΥΣΗ (καμία ανάπτυξη)helm lint .\chart # σύνταξη + καλές πρακτικέςhelm template <release> .\chart -f <values.yaml> # πλήρης απόδοσηhelm template <release> .\chart -f <values.yaml> --show-only templates/<fichier> # στοχευμένη απόδοσηhelm template <release> .\chart -f <values.yaml> --debug # με ίχνηhelm show values .\chart # προεπιλεγμένες τιμές# ΑΝΑΠΤΥΞΗhelm install <release> .\chart -f <values.yaml> -n <ns> --create-namespacehelm upgrade <release> .\chart -f <values.yaml> -n <ns>helm upgrade <release> .\chart -f <values.yaml> --set portail.replicas=5 -n <ns>helm rollback <release> <revision> -n <ns>helm uninstall <release> -n <ns># ΠΑΡΑΤΗΡΗΣΗhelm list -A # όλες οι releaseshelm status <release> -n <ns>helm history <release> -n <ns>helm get values <release> -n <ns> # οι ενεργές τιμέςhelm get manifest <release> -n <ns> # τα εφαρμοσμένα μανιφέστα
Τα 3 αντανακλαστικά σε περίπτωση σφάλματος:
Πάντα να ξεκινάτε από το helm template — είναι ΣΤΕΓΝΗ απόδοση, χωρίς κίνδυνο, που δείχνει ακριβώς τι θα σταλεί στο Kubernetes.
Διαβάστε τη διαδρομή στο μήνυμα σφάλματος — το Helm δίνει πάντα το αρχείο + τη γραμμή + την εσφαλμένη διαδρομή .Values.*.
Το helm get manifest σας δείχνει τι είναι αυτή τη στιγμή στο σύμπλεγμα (χρήσιμο για σύγκριση με αυτό που παράγει το νέο σας πρότυπο).
ΠΑΡΑΡΤΗΜΑ A — Οι εφαρμογές
Μην τροποποιήσετε κανένα από αυτά τα αρχεία. Αντιγράψτε τα ως έχουν στις υποδεικνυόμενες διαδρομές.
A.1 — Το portail (πίνακας ελέγχου πολλαπλών περιβαλλόντων)
Όλες οι εμφανιζόμενες τιμές προέρχονται από μεταβλητές περιβάλλοντος που εγχέει το Helm. Η ίδια εικόνα συμπεριφέρεται διαφορετικά ανάλογα με τα env: του Deployment.
Αρχείο: apps/portail/app.py
python
"""Portail — tableau de bord multi-environnement.Ce Pod affiche l'environnement dans lequel il tourne (DEV / STAGING / PROD),la version applicative, le nombre de replicas, et l'etat du backend.Toutes les valeurs affichees viennent de VARIABLES D'ENVIRONNEMENT injecteespar Helm depuis values-<env>.yaml. Le meme code s'adapte a chaqueenvironnement sans aucune modification."""import osimport socketimport timeimport urllib.errorimport urllib.requestfrom flask import Flask, jsonify, requestapp = Flask(__name__)DEMARRAGE = time.time()def cfg(): return { "env": os.environ.get("ENVIRONMENT", "inconnu"), "version": os.environ.get("APP_VERSION", "0.0.0"), "theme": os.environ.get("THEME_COLOR", "#64748b"), "message": os.environ.get("BANNIERE_MESSAGE", "Deploye avec Helm"), "backend_url": os.environ.get("BACKEND_URL", "http://api"), "replicas_info": os.environ.get("REPLICAS_INFO", "?"), "pod": socket.gethostname(), "uptime": int(time.time() - DEMARRAGE), }def tester_backend(url): try: with urllib.request.urlopen(url + "/ping", timeout=1.5) as reponse: corps = reponse.read(200).decode("utf-8", "ignore") return "ok", corps.strip() except urllib.error.HTTPError as err: return "http", "HTTP %s" % err.code except Exception as err: return "ko", type(err).__name__@app.route("/health")def health(): return "OK", 200@app.route("/api-json")def api_json(): """Route utile pour la validation automatique.""" c = cfg() etat, detail = tester_backend(c["backend_url"]) return jsonify(pod=c["pod"], env=c["env"], version=c["version"], backend=etat, backend_detail=detail, uptime=c["uptime"])@app.route("/")def accueil(): c = cfg() etat, detail = tester_backend(c["backend_url"]) # ... (πλήρες πρότυπο HTML στο αρχείο — δεν επαναλαμβάνεται εδώ για αναγνωσιμότητα)
Το πλήρες αρχείο παρέχεται στο apps/portail/app.py.
Αντιγράψτε αυτά τα αρχεία, έπειτα αντικαταστήστε κάθε TODO με τη σωστή τιμή.
Οι γραμμές που προηγούνται από # ? είναι ερωτήσεις προς απόφαση: σε εσάς εναπόκειται να αποφασίσετε πώς θα συμπληρώσετε τον κώδικα.
Αρχείο: chart/Chart.yaml
yaml
# ? Συμπληρώστε τα υποχρεωτικά πεδία ενός Chart Helm.# ? Το apiVersion πρέπει να είναι v2 (το v1 είναι παρωχημένο από το Helm 3).# ? Το type είναι "application" (σε αντίθεση με "library").apiVersion: TODOname: hedgedescription: TODOtype: TODOversion: 0.1.0appVersion: "1.0.0"
Αρχείο: chart/values.yaml
yaml
# values.yaml — προεπιλεγμένες τιμές του chart hedge.# Κάθε περιβάλλον παρέχει ένα αρχείο values-<env>.yaml που ΥΠΕΡΙΣΧΥΕΙ# αυτών των τιμών από πάνω. Κρατήστε αυτό το αρχείο ΟΥΔΕΤΕΡΟ (καμία τιμή# ειδική για ένα περιβάλλον).environment: defaultbanniere: message: "Chart Helm — application multi-environnement" couleur: "#64748b"portail: image: repository: hedge-portail tag: "1.0" pullPolicy: IfNotPresent replicas: 1 service: type: NodePort port: 80 targetPort: 5000 nodePort: 30130api: image: repository: hedge-api tag: "1.0" pullPolicy: IfNotPresent replicas: 1 service: type: ClusterIP port: 80 targetPort: 8000
Αρχείο: chart/templates/_helpers.tpl
yaml
{{/*Πλήρες όνομα ενός πόρου : "<release>-<composant>".Χρήση : {{ include "hedge.fullname" (dict "root" . "composant" "portail") }}*/}}{{- define "hedge.fullname" -}}{{- printf "TODO" .root.Release.Name .composant | trunc 63 | trimSuffix "-" -}}{{- end -}}{{/*Κοινές ετικέτες όλων των πόρων.Χρήση : {{ include "hedge.labels" (dict "root" . "composant" "portail") | nindent 4 }}*/}}{{- define "hedge.labels" -}}# ? συμπληρώστε τις 7 ετικέτες που ζητούνται στην Αποστολή 3app.kubernetes.io/name: TODOapp.kubernetes.io/instance: TODO# ... συνεχίστε ...{{- end -}}{{/*Selector labels : ΣΤΑΘΕΡΟ υποσύνολο των ετικετών.Βάλτε εδώ ΜΟΝΟ ετικέτες που δεν θα αλλάξουν ΠΟΤΕ για μια παρουσία.*/}}{{- define "hedge.selectorLabels" -}}# ? μόνο οι 3 ΑΥΣΤΗΡΑ αμετάβλητες ετικέτες{{- end -}}
Αρχείο: chart/templates/portail-deployment.yaml
yaml
# ? Deployment του portail. Χρησιμοποιήστε :# - .Values.portail.replicas# - .Values.portail.image.{repository,tag,pullPolicy}# - .Values.portail.service.targetPort# - .Values.environment# - .Values.banniere.{couleur,message}# - .Chart.AppVersion (για APP_VERSION)# - Το ΟΝΟΜΑ του Service api κατασκευασμένο με .Release.Name (για BACKEND_URL)apiVersion: apps/v1kind: Deploymentmetadata: name: TODO labels: TODOspec: replicas: TODO selector: matchLabels: TODO template: metadata: labels: TODO spec: containers: - name: portail image: TODO imagePullPolicy: TODO ports: - containerPort: TODO env: - name: ENVIRONMENT value: TODO # ? προσθέστε APP_VERSION, THEME_COLOR, BANNIERE_MESSAGE, # BACKEND_URL, REPLICAS_INFO readinessProbe: httpGet: path: /health port: TODO initialDelaySeconds: 3 periodSeconds: 5
Αρχείο: chart/templates/portail-service.yaml
yaml
# ? Service για το portail. Τύπος NodePort. Χρησιμοποιήστε τη συνθήκη# {{- if eq .Values.portail.service.type "NodePort" }} ... {{- end }}# για να συμπεριλάβετε το "nodePort" ΜΟΝΟ αν είναι όντως NodePort.apiVersion: v1kind: Servicemetadata: name: TODO labels: TODOspec: type: TODO selector: TODO ports: - port: TODO targetPort: TODO # ? nodePort μόνο αν type == NodePort
Αρχείο: chart/templates/api-deployment.yaml
yaml
# ? Ίδια δομή με το portail-deployment.yaml, αλλά :# - composant = "api"# - μεταβλητές περιβάλλοντος : ENVIRONMENT και APP_VERSION μόνο# - θύρα κοντέινερ = .Values.api.service.targetPort (8000)apiVersion: apps/v1kind: Deploymentmetadata: name: TODOspec: # ... (παρόμοια δομή με το portail) ...
Αρχείο: chart/templates/api-service.yaml
yaml
# ? Service ClusterIP για την api. Μία μόνο θύρα. Χωρίς nodePort.apiVersion: v1kind: Servicemetadata: name: TODOspec: type: TODO selector: TODO ports: - port: TODO targetPort: TODO
Αρχείο: chart/environments/values-dev.yaml
yaml
# ? Περιβάλλον DEV : 1 αντίγραφο, μπλε πανό #2563eb, NodePort 30130.environment: TODObanniere: message: TODO couleur: TODOportail: replicas: TODO service: nodePort: TODOapi: replicas: TODO
Αρχείο: chart/environments/values-staging.yaml
yaml
# ? Περιβάλλον STAGING : 2 αντίγραφα, πορτοκαλί πανό #ea580c, NodePort 30131.environment: TODO# ... συμπληρώστε στο μοντέλο του values-dev.yaml ...
Κάθε αρχείο παρακάτω βρίσκεται στο chart/casses/. Μην τροποποιήσετε τα πρωτότυπα — αντιγράψτε τα στο chart/templates/, αναπαραγάγετε το σφάλμα, έπειτα διορθώστε το αντίγραφο.
Αρχείο: chart/casses/casse-1-configmap.yaml
yaml
# ΒΛΑΒΗ 1# Σύμπτωμα : αναπτύξτε hedge-dev, έπειτα δοκιμάστε να αναπτύξετε hedge-staging# ΣΤΟΝ ΙΔΙΟ ΧΩΡΟ ΟΝΟΜΑΤΩΝ. Η δεύτερη εγκατάσταση αποτυγχάνει με :# ConfigMap "hedge-config" ... exists and cannot be imported ...apiVersion: v1kind: ConfigMapmetadata: name: hedge-config labels: {{- include "hedge.labels" (dict "root" . "composant" "config") | nindent 4 }}data: timezone: "America/Toronto" langue: "fr-CA"
Το αρχείο outils/valider.ps1 παρέχεται ως έχει. Δεν δίνει καμία λύση — μόνο μια βαθμολογία και το πρώτο σημείο προς διόρθωση. Εκτελέστε το ανά πάσα στιγμή:
powershell
.\outils\valider.ps1
Τι επαληθεύει το σενάριο:
Αποστολή
Αυτόματα κριτήρια
1
Το helm lint περνά, το Chart.yaml έχει apiVersion: v2, type: application
2
Το helm template παράγει όντως 2 Deployments και 2 Services, ονόματα με πρόθεμα τη release
3
Το _helpers.tpl ορίζει τους 3 helpers, παρούσες οι τυπικές ετικέτες
4
Τα 3 αρχεία values-<env>.yaml υπάρχουν με τις σωστές τιμές (env, replicas, port, χρώμα), οι 3 releases είναι αναπτυγμένες
5
Η release hedge-dev έχει ≥ 2 αναθεωρήσεις και ένα rollback στο ιστορικό
6
Κανένα hedge-config στα σκληρά, καμία μεταβλητή ετικέτα στο matchLabels, κανένα .Values.portal (με τυπογραφικό)
Το σενάριο δεν εκτελεί από μόνο του καμία εντολή helm install: είναι δική σας ευθύνη να αναπτύξετε πριν την επικύρωση.
Μάθημα δημιουργημένο από τον Dr. Haythem REHOUMA — Ανάπτυξη και ανάπτυξη λύσεων δεδομένων