Kubernetes : clusters et Helm charts
Kubernetes : clusters et Helm charts
1) Architecture de cluster - vue d'en haut
Control Plane : 'kube-apiserver', 'etcd', 'kube-scheduler', 'kube-controller-manager', (dans les nuages contrôlés, la partie est cachée).
Worker : 'kubelet', CRI-rantime (containerd/CRI-O), plugin CNI, kube-proxy/ebpf-proxy.
Réseau interne : Pod-to-Pod, Service-VIP/ClusterIP, DNS CoreDNS.
Stockage : Pilotes CSI, activation dynamique du PVC → PV (StorageClass).
Limites d'échec : nœud/AZ/région. Placez les répliques par zone (TopologySpreadConstraints/anti-affinité).
Rôles types
Commande de plateforme : création/mise à niveau de clusters, CNI/CSI/Ingress, politique et GitOps.
Équipes de produits : Dépliez les charts/sorties, suivez les politiques de sécurité et les ressources.
2) Cycle de vie du cluster
Création : kOps, kubeadm, Rancher, EKS/AKS/GKE. Activez immédiatement l'authentification OIDC et l'audit.
Mises à jour : versions mineures à tour de rôle (control plane → noeuds) contrôlées par maxUnavailable, tests sur le stajing.
Add-ons (tous via Helm/GitOps) : CNI (Calico/Cilium), pilote CSI, contrôleur Ingress (API/Contour/Traefik), Metrics-Server, Cluster-Auter oscaler, Node-Local DNS, loging/métriques/trace.
Backups : etcd snapshot (si self-managed), Velero pour namespace/PVC.
3) Réseaux, services et ingress
CNI: Calico (NetworkPolicy), Cilium (eBPF/servicemesh-фичи).
Service : 'ClusterIP', 'NodePort', 'LoadBalancer', 'ExternalName'.
API Ingress/Gateway : routage L7, TLS, historique rate-limit/WAF sur le périmètre.
NetworkPolicy : par défaut, deny-all + allow explicite par namespace/label.
Headless-service ('clusterIP : None') pour StatefulSet et service-discovery.
4) Entrepôts (CSI) et états
StorageClass : 'reclaimPolicy', 'volumeBindingMode' ('WaitForFirstConsumer' pour un meilleur hébergement).
StatefulSet : noms/volumes stables ('volumeClaimTemplates'), 'podManagementPolicy : Parallel' pour les déploiements rapides.
ReadWriteMany : utilisez les fichiers distribués (EFS/Filestore) avec prudence - évaluez la latence.
Photos : 'VolumeSnapshotClass' + cron-backaps.
5) Polyvalence et politique
Namespaces par produit/mercredi.
RBAC : rôles minimaux, comptes-services individuels, 'Role '/' RoleBinding' au lieu de 'ClusterRole', si possible.
PSA (Pod Security Admission) : modes 'baseline '/' restricted' (remplacement PSP).
ResourceQuota / LimitRange: потолки CPU/Memory/PVC/LoadBalancer.
OPA Gatekeeper/Kyverno : politique d'admission (par exemple, interdiction ': latest', exigence 'ressources', 'readOnlyRootFilesystem').
ImagePolicy/webhooks : vérifie la signature des images (cosign/policy-controller).
6) Observabilité et exploitation
Métriques : Prometheus-pile, kube-state-metrics, node-exportateurs.
Logs : Bit/vecteur fluent → objet/ES/OpenSearch, rotation sur les nœuds.
Tracs : OpenTelemetry Collector.
SLO-dashboards : modèle RED sur ingress et services clés.
Auto Skale : HPA (selon les métriques de l'application), VPA pour le background, Cluster-Autoscaler pour les nœuds.
7) Modèles de manifestes (triche)
Deployment (extrait) :yaml apiVersion: apps/v1 kind: Deployment metadata: { name: api, labels: { app: api } }
spec:
replicas: 3 strategy: { type: RollingUpdate, rollingUpdate: { maxUnavailable: 0, maxSurge: 1 } }
selector: { matchLabels: { app: api } }
template:
metadata:
labels: { app: api }
spec:
serviceAccountName: api-sa securityContext: { runAsNonRoot: true, fsGroup: 2000 }
containers:
- name: api image: registry. example. com/api:1. 2. 3 ports: [{ containerPort: 8080 }]
resources: { requests: { cpu: "200m", memory: "256Mi" }, limits: { cpu: "1", memory: "512Mi" } }
readinessProbe: { httpGet: { path: /healthz, port: 8080 }, periodSeconds: 5 }
livenessProbe: { httpGet: { path: /livez, port: 8080 }, initialDelaySeconds: 20 }
StatefulSet (fragment) :
yaml apiVersion: apps/v1 kind: StatefulSet metadata: { name: db }
spec:
serviceName: db replicas: 3 podManagementPolicy: Parallel selector: { matchLabels: { app: db } }
template:
metadata: { labels: { app: db } }
spec:
containers:
- name: db image: postgres:16-alpine volumeMounts: [{ name: data, mountPath: /var/lib/postgresql/data }]
volumeClaimTemplates:
- metadata: { name: data }
spec:
accessModes: ["ReadWriteOnce"]
resources: { requests: { storage: 100Gi } }
storageClassName: fast-ssd
PDB (PodDisruptionBudget):
yaml apiVersion: policy/v1 kind: PodDisruptionBudget metadata: { name: api-pdb }
spec:
minAvailable: 2 selector: { matchLabels: { app: api } }
Ingress (Nginx, bref) :
yaml apiVersion: networking. k8s. io/v1 kind: Ingress metadata:
name: api annotations:
nginx. ingress. kubernetes. io/proxy-read-timeout: "30"
spec:
tls: [{ hosts: ["api. example. com"], secretName: api-tls }]
rules:
- host: api. example. com http:
paths:
- path: /
pathType: Prefix backend: { service: { name: api, port: { number: 80 } } }
8) Helm v3 - bases et structure
Chart = modèles + valeurs + métadonnées.
mychart/
Chart. yaml # name, version (semver), type (application/library), dependencies values. yaml # default values. schema. json # (recommended) validation values templates/# .yaml. gotmpl (Deployment, Service, Ingress, …)
templates/tests/ # helm tests (smoke)
charts/# local dependencies (or OCI dependencies)
Chart. yaml (exemple) :
yaml apiVersion: v2 name: api description: API service type: application version: 1. 4. 0 # chart version (semver)
appVersion: "1. 2. 3" # dependencies application version:
- name: redis version: 17. x.x repository: "oci://registry. example. com/charts"
9) Modèles d'aide - pratiques
Utilisez helpers dans '_ helpers. tpl 'pour les noms/étiquettes/annotations.
Spécifiez « ressources », « securityContext », « read..../liveness » partout.
Générer des étiquettes selon un schéma standardisé ('app. kubernetes. io/`).
Rendre les fiches optionnelles via 'values' (ingress/hpa/pdb/servicemonitor).
Incluez 'values. schema. json '- stop des confits infidèles.
Pour les données sensibles - Secrets des opérateurs externes (SOPS) plutôt que de les stocker dans des valeurs.
gotmpl
{{- define "api. fullname" -}}
{{- printf "%s-%s".Chart. Name. Release. Name trunc 63 trimSuffix "-" -}}
{{- end -}}
Deployment. tpl (fragment) :
gotmpl apiVersion: apps/v1 kind: Deployment metadata:
name: {{ include "api. fullname". }}
labels: {{- include "api. labels". nindent 4 }}
spec:
replicas: {{.Values. replicaCount }}
strategy:
rollingUpdate:
maxSurge: 1 maxUnavailable: 0 selector:
matchLabels: {{- include "api. selectorLabels". nindent 6 }}
template:
metadata:
labels: {{- include "api. selectorLabels". nindent 8 }}
spec:
serviceAccountName: {{ include "api. serviceAccountName". }}
securityContext: {{- toYaml. Values. podSecurityContext nindent 8 }}
containers:
- name: {{.Chart. Name }}
image: "{{.Values. image. repository }}:{{.Values. image. tag }}"
imagePullPolicy: IfNotPresent ports: [{ containerPort: {{.Values. service. port }} }]
resources: {{- toYaml. Values. resources nindent 10 }}
envFrom:
- secretRef: { name: {{.Values. secretsRef }} }
10) Dépendances, référentiels et OCI
Helm v3 prend en charge les registres OCI : 'oci ://registry/org/charts'.
Lisez la version des dépendances ('^ 1. 2. 0`, `~1. 2 ') et lancer' helm dependency build'.
Signez la charte (bou), stockez les artefacts dans le dépôt d'artefact CI.
Charts de bibliothèque : modèles partagés (ingress/servicemonitor) à réutiliser.
11) Hooks, CRD et ordre des opérations
Hooks: `pre-install`, `post-install`, `pre-upgrade`, `post-upgrade`, `test`. Ajoutez des politiques ('before-hook-creation', 'hook-succeeded').
CRD : mettre dans 'crds/' (s'installent jusqu'aux timplates), éviter les updates CRD « à la volée » - faire les migrations séparément.
Migration OBD/initialisation - job-hook avec idempotency et temporisation.
12) Les tests Chart et CI
'helm lint' + validation du schéma.
Helm unittest (unit), chart-testing (ct) - assemblage/installation en kind/minikube en CI.
Tests de modèle snapshot ('helm template' → comparer avec la référence).
Smoke-tests 'helm test' (soulever 'Pod' avec les contrôles).
13) GitOps (Argo CD/Flux)
La source de la vérité est le référentiel. La charte est stockée comme HelmRelease/HelmChart (Flux) ou Application (Argo).
Stratégies de sync : auto-sync avec prune/self-heal, statuts et health-checks.
Version promotionnelle : tag-bots/semver-range, PR-flow.
Divisez repo en apps (charts) et bou (overrides/values).
Gestion secrète : SOPS (age/KMS), Secrets externes.
14) Sécurité : minimum nécessaire
PSA restreint : sans privilèges, sans hostPath, avec capabilities limitées, read-only rootfs.
ImagePolicy : seulement les images signées/de confiance.
NetworkPolicy : « enfermé par défaut ».
RBAC : compte de service par application, 'Role '/' RoleBinding' en namespace.
Contrôle d'admission : Gatekeeper/Kyverno règles (ressources/limites, labels, no latest).
Secrets : SOPS/Secrets externes ; ne pas mettre de secrets dans values/plain Git.
15) Anti-modèles
« : latest » dans les charts et les images ; l'absence de 'values. schema. json`.
C'est un énorme tableau pour tout au lieu des modulaires.
Les CRD sont mis à jour par des modèles dans 'templates/' → chaos sur les mises à niveau.
Noms/port/namespace durement cachés dans les modèles.
Manque de ressources/limites et d'échantillons → latence et instabilité.
Pas de PDB → downtime nul impossible avec drain/upgrades.
Secrets dans Git sans cryptage ; manifestes sans politiques-checks.
16) Chèque de mise en œuvre (0-45 jours)
0-10 jours
Avoir un squelette de base avec '_ helpers. tpl ', labels, probes, ressources, PDB/Ingress en option.
Включить PSA restricted, NetworkPolicy deny-all, ResourceQuota/LimitRange.
Configurer GitOps (Argo/Flux), registre privé, signature d'images/charts.
11-25 jours
Diviser le tableau en modules/dépendances, ajouter 'values. schema. json ', tests (' helm lint ', unit, ct).
Connectez observability (ServiceMonitor/PodMonitor), agents logs, OTel.
Entrez le processus de mise à niveau : staging → canary → prod, hook-migration avec rollback.
26-45 jours
Automatiser les mises à jour des dépendances (bots/semver-ranges + PR).
Ajouter Gatekeeper/Kyverno politiques et policy-reports à CI.
Documenter le runbook de mise à niveau du cluster, les procédures DR (Velero/etcd snapshot).
17) Métriques de maturité
100 % des applications sont déployées via Helm/GitOps, sans 'kubectl apply' manuellement.
Tous les charts ont des valeurs. schema. json ', tests, signature et versions fixes des dépendances.
PSA restricted/NetworkPolicy est inclus dans tous les namespace.
L'APB et l'APH sont présents dans tous les services critiques.
Secrets sécurisés (SOPS/External Secrets), stratégie « no latest », signature d'image.
Les mises à niveau du cluster et du tableau se déroulent sans downtime (canary/blue-green), les tests restore sont réguliers.
18) Conclusion
Fondation forte Kubernetes = architecture de cluster robuste + politique stricte + Charte de qualité industrielle Helm gérée par GitOps. Uniformiser les modèles, protéger l'environnement PSA/NetworkPolicy/RBAC, valider les valeurs et automatiser les tests, la signature et la promotion. Les mises à jour et les versions deviendront alors prévisibles et la plate-forme sera durable et conviviale pour les équipes de produits.