De Docker Compose à Kubernetes : architecture complète, distributions (K8s, K3s, K0s, MicroK8s), objets fondamentaux, networking, Ingress, scaling automatique et déploiement en production.
Un cluster K8s en production implique quatre domaines que ce chapitre couvre : le scaling automatique (HPA), la gestion des droits (RBAC), la packaging des applications (Helm), et le monitoring (Prometheus + Grafana).
La stratégie RollingUpdate (défaut) remplace les pods un par un. Avec maxUnavailable: 0, aucun pod n'est coupé avant que le nouveau soit Ready.
# Mettre à jour l'image
kubectl set image deployment/mon-app app=mon-registry/mon-app:2.0.0 -n production
# Suivre le rollout
kubectl rollout status deployment/mon-app -n production
# Waiting for deployment "mon-app" rollout to finish: 1 out of 3 new replicas have been updated...
# Waiting for deployment "mon-app" rollout to finish: 1 old replicas are pending termination...
# deployment "mon-app" successfully rolled out
# Historique
kubectl rollout history deployment/mon-app -n production
# REVISION CHANGE-CAUSE
# 1 <none>
# 2 <none>
# Annoter les révisions (bonne pratique)
kubectl annotate deployment mon-app \
kubernetes.io/change-cause="Deploy v2.0.0 - ajout feature X" -n production
# Rollback immédiat
kubectl rollout undo deployment/mon-app -n production
# Rollback à une révision spécifique
kubectl rollout undo deployment/mon-app --to-revision=1 -n productionLe HPA scale automatiquement le nombre de replicas selon l'utilisation CPU/mémoire ou des métriques custom.
Prérequis : metrics-server doit être installé.
# K3s inclut metrics-server par défaut
kubectl top nodes
kubectl top pods -n productionapiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: mon-app-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: mon-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # scale up si CPU > 70%
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80kubectl apply -f hpa.yaml
kubectl get hpa -n production
# NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
# mon-app-hpa Deployment/mon-app 45%/70% 2 10 3Points d'attention HPA :
resources.requests définis — sans ça, le HPA ne peut pas calculer le pourcentage d'utilisationreplicas fixe dans le Deployment (conflit)minReplicas: 2 minimum en production — jamais 1 (single point of failure)Pendant un scale-up, les nouveaux pods ne reçoivent pas de trafic tant que leur readinessProbe n'est pas passée. C'est le mécanisme qui garantit que vous ne routez pas vers des pods pas encore prêts.
Pendant un scale-down, K8s attend que les connexions actives se terminent avant de supprimer un pod (grace period) :
spec:
template:
spec:
terminationGracePeriodSeconds: 30 # secondes pour terminer proprement
containers:
- name: app
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 5"] # flush les connexionsRBAC (Role-Based Access Control) définit qui peut faire quoi dans le cluster. Indispensable quand plusieurs équipes partagent le même cluster.
# ServiceAccount pour l'application
apiVersion: v1
kind: ServiceAccount
metadata:
name: mon-app-sa
namespace: production
---
# Role : lire les secrets et configmaps du namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: app-reader
namespace: production
rules:
- apiGroups: [""]
resources: ["secrets", "configmaps"]
verbs: ["get", "list"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch"]
---
# Lier le role au service account
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-reader-binding
namespace: production
subjects:
- kind: ServiceAccount
name: mon-app-sa
namespace: production
roleRef:
kind: Role
apiRef: app-reader
apiGroup: rbac.authorization.k8s.io# Créer un kubeconfig limité pour un développeur
# (accès en lecture seule au namespace staging)
kubectl create serviceaccount dev-user -n staging
kubectl create rolebinding dev-readonly \
--clusterrole=view \
--serviceaccount=staging:dev-user \
-n staging
# Générer le token
kubectl create token dev-user -n staging --duration=168hHelm est le gestionnaire de paquets de Kubernetes. Il permet de packager des manifestes K8s en "charts" réutilisables et versionnés.
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# Installer PostgreSQL
helm install postgres bitnami/postgresql \
--namespace production \
--set auth.postgresPassword=mon-mot-de-passe \
--set primary.persistence.size=20Gi \
--set primary.resources.requests.memory=256Mi
# Lister les releases
helm list -n production
# Mettre à jour
helm upgrade postgres bitnami/postgresql -n production --set image.tag=16.3.0
# Rollback
helm rollback postgres 1 -n production
# Désinstaller
helm uninstall postgres -n productionhelm create mon-app
# Crée la structure :
# mon-app/
# ├── Chart.yaml ← métadonnées
# ├── values.yaml ← valeurs par défaut
# └── templates/
# ├── deployment.yaml
# ├── service.yaml
# ├── ingress.yaml
# └── _helpers.tplimage:
repository: mon-registry/mon-app
tag: "1.0.0"
pullPolicy: IfNotPresent
replicaCount: 3
service:
type: ClusterIP
port: 80
ingress:
enabled: true
host: mon-app.example.com
tls: true
resources:
requests:
memory: 128Mi
cpu: 100m
limits:
memory: 256Mi
cpu: 500m# Valider le chart
helm lint mon-app/
# Voir le YAML généré
helm template mon-app/ --values custom-values.yaml
# Déployer
helm install mon-app ./mon-app/ -n production --values production-values.yamlLe chart kube-prometheus-stack installe Prometheus, Grafana, AlertManager et les règles d'alerting par défaut en une commande.
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install monitoring prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set grafana.adminPassword=mon-mot-de-passe \
--set prometheus.prometheusSpec.retention=15dAccéder à Grafana :
kubectl port-forward -n monitoring service/monitoring-grafana 3000:80
# http://localhost:3000 — admin / mon-mot-de-passeLes dashboards par défaut couvrent : utilisation CPU/mémoire par nœud et namespace, latence des pods, état des PersistentVolumes, métriques etcd, et état de l'API Server.
import { Registry, collectDefaultMetrics, Counter, Histogram } from 'prom-client'
const registry = new Registry()
collectDefaultMetrics({ register: registry })
const httpRequests = new Counter({
name: 'http_requests_total',
help: 'Total HTTP requests',
labelNames: ['method', 'path', 'status'],
registers: [registry],
})
const httpDuration = new Histogram({
name: 'http_request_duration_seconds',
help: 'HTTP request duration',
labelNames: ['method', 'path'],
registers: [registry],
})
// Route /metrics
app.get('/metrics', async (req, res) => {
res.set('Content-Type', registry.contentType)
res.send(await registry.metrics())
})apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: mon-app
namespace: production
labels:
release: monitoring # doit matcher le selector du Prometheus
spec:
selector:
matchLabels:
app: mon-app
endpoints:
- port: http
path: /metrics
interval: 30sSécurité
readOnlyRootFilesystem: true dans le securityContext des conteneursrunAsNonRoot: true — pas de conteneur en rootFiabilité
readinessProbe et livenessProbe sur tous les conteneursresources.requests et resources.limits définisminReplicas: 2 minimumObservabilité
Vous avez maintenant une vision complète de Kubernetes : des raisons de l'adopter jusqu'au déploiement en production sécurisé avec monitoring. Pour le déploiement de bases de données Redis en cluster dans K8s, le chapitre Redis de cette formation couvre les patterns spécifiques.